diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-06-05 11:47:01 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-06-05 11:47:01 +0200 |
commit | 40a2bc5b5c03c7219f40be1f5be51089a156b974 (patch) | |
tree | b0f7a9bbf7b64727a0f1b35f70ead1a4d2809736 | |
parent | 7d9e0d94f09501482a336a7a2e692c159ec4c9a9 (diff) | |
download | patches-40a2bc5b5c03c7219f40be1f5be51089a156b974.tar.gz |
refresh and move some patches out of the main queue
-rw-r--r-- | 0001-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch | 5 | ||||
-rw-r--r-- | 0002-Introduce-CONFIG_READONLY_USERMODEHELPER.patch | 65 | ||||
-rw-r--r-- | 0003-add-CONFIG_READONLY_USERMODEHELPER-support-for-lots-.patch | 341 | ||||
-rw-r--r-- | c04.patch | 4 | ||||
-rw-r--r-- | c06.patch | 6 | ||||
-rw-r--r-- | c08.patch | 77 | ||||
-rw-r--r-- | c10.patch | 51 | ||||
-rw-r--r-- | d01.patch | 10 | ||||
-rw-r--r-- | d05.patch | 2 | ||||
-rw-r--r-- | d10.patch | 4 | ||||
-rw-r--r-- | d11.patch | 4 | ||||
-rw-r--r-- | d99.patch | 2 | ||||
-rw-r--r-- | goldfish_pipe-an-implementation-of-more-parallel-pipe.patch | 1256 | ||||
-rw-r--r-- | old/csdio2.patch (renamed from csdio2.patch) | 0 | ||||
-rw-r--r-- | old/defer-input-nodes-and-led-support (renamed from defer-input-nodes-and-led-support) | 0 | ||||
-rw-r--r-- | old/e.patch (renamed from e.patch) | 0 | ||||
-rw-r--r-- | old/input-xpad-disconnect-all-wireless-controllers-at-init.patch (renamed from input-xpad-disconnect-all-wireless-controllers-at-init.patch) | 0 | ||||
-rw-r--r-- | old/input-xpad-handle-present-and-gone-correctly.patch (renamed from input-xpad-handle-present-and-gone-correctly.patch) | 0 | ||||
-rw-r--r-- | old/input-xpad-move-the-input-device-creation-to-a-new-function.patch (renamed from input-xpad-move-the-input-device-creation-to-a-new-function.patch) | 0 | ||||
-rw-r--r-- | old/input-xpad-properly-name-the-led-class-devices.patch (renamed from input-xpad-properly-name-the-led-class-devices.patch) | 0 | ||||
-rw-r--r-- | old/input-xpad-set-the-correct-led-number.patch (renamed from input-xpad-set-the-correct-led-number.patch) | 0 | ||||
-rw-r--r-- | old/input-xpad-set-the-leds-properly-on-xbox-wireless-controllers.patch (renamed from input-xpad-set-the-leds-properly-on-xbox-wireless-controllers.patch) | 0 | ||||
-rw-r--r-- | old/simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch (renamed from simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch) | 0 | ||||
-rw-r--r-- | old/staging-exfat-add-filesystem-to-drivers-staging-exfat.patch (renamed from staging-exfat-add-filesystem-to-drivers-staging-exfat.patch) | 0 | ||||
-rw-r--r-- | old/staging-exfat-add-filesystem-to-the-build.patch (renamed from staging-exfat-add-filesystem-to-the-build.patch) | 13 | ||||
-rw-r--r-- | old/staging-exfat-hlist_for_each-api-change.patch (renamed from staging-exfat-hlist_for_each-api-change.patch) | 0 | ||||
-rw-r--r-- | old/staging-exfat-include-aio.h.patch (renamed from staging-exfat-include-aio.h.patch) | 0 | ||||
-rw-r--r-- | old/staging-exfat-kuid-fixes.patch (renamed from staging-exfat-kuid-fixes.patch) | 0 | ||||
-rw-r--r-- | old/staging-exfat-readdir-to-iterate-change.patch (renamed from staging-exfat-readdir-to-iterate-change.patch) | 0 | ||||
-rw-r--r-- | old/staging-exfat-truncage_pagecache-api-change.patch (renamed from staging-exfat-truncage_pagecache-api-change.patch) | 0 | ||||
-rw-r--r-- | p26.patch | 11 | ||||
-rw-r--r-- | p28.patch | 9 | ||||
-rw-r--r-- | pci_groups.patch | 12 | ||||
-rw-r--r-- | qlcnic_sysfs.patch | 2 | ||||
-rw-r--r-- | series | 24 |
35 files changed, 38 insertions, 1860 deletions
diff --git a/0001-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch b/0001-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch index bbfbc2cb30ba5e..196f4d4288472c 100644 --- a/0001-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch +++ b/0001-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch @@ -6,13 +6,12 @@ Subject: [PATCH 1/3] drbd: rename "usermode_helper" to "drbd_usermode_helper" Nothing like having a very generic global variable in a tiny driver subsystem to make a mess of the global namespace... -Anyway, clean it up in anticipation of making drbd_usermode_helper -read-only in a future patch. - Note, there are many other "generic" named global variables in the drbd subsystem, someone should fix those up one day before they hit a linking error. +Cc: Philipp Reisner <philipp.reisner@linbit.com> +Cc: Lars Ellenberg <lars.ellenberg@linbit.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- drivers/block/drbd/drbd_int.h | 2 +- diff --git a/0002-Introduce-CONFIG_READONLY_USERMODEHELPER.patch b/0002-Introduce-CONFIG_READONLY_USERMODEHELPER.patch deleted file mode 100644 index 0e8475a831e77e..00000000000000 --- a/0002-Introduce-CONFIG_READONLY_USERMODEHELPER.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 7c57d60d77d05ad26fe7ea6effb9c02fcf5208cc Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 15 Dec 2016 13:07:19 -0800 -Subject: [PATCH 2/3] Introduce CONFIG_READONLY_USERMODEHELPER - -If you can write to kernel memory, an "easy" way to get the kernel to -run any application is to change the pointer of one of the usermode -helper program names. To try to mitigate this, create a new config -option, CONFIG_READONLY_USERMODEHELPER. - -This option only allows "predefined" binaries to be called. A number of -drivers and subsystems allow for the name of the binary to be changed, -and this config option disables that capability, so be aware of that. - -Note: Still a proof-of-concept at this point in time, doesn't cover all -of the call_usermodehelper() calls just yet, including the "fun" of -coredumps, it's still a work in progress. - -Not-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> ---- - include/linux/kmod.h | 6 ++++++ - security/Kconfig | 17 +++++++++++++++++ - 2 files changed, 23 insertions(+) - ---- a/include/linux/kmod.h -+++ b/include/linux/kmod.h -@@ -53,6 +53,12 @@ struct file; - #define UMH_WAIT_PROC 2 /* wait for the process to complete */ - #define UMH_KILLABLE 4 /* wait for EXEC/PROC killable */ - -+#ifdef CONFIG_READONLY_USERMODEHELPER -+# define __ro_umh const -+#else -+# define __ro_umh /**/ -+#endif -+ - struct subprocess_info { - struct work_struct work; - struct completion *complete; ---- a/security/Kconfig -+++ b/security/Kconfig -@@ -189,6 +189,23 @@ config STATIC_USERMODEHELPER_PATH - If you wish for all usermode helper programs to be disabled, - specify an empty string here (i.e. ""). - -+config READONLY_USERMODEHELPER -+ bool "Make User Mode Helper program names read-only" -+ default N -+ help -+ Some user mode helper program names can be changed at runtime -+ by userspace programs. Prevent this from happening by "hard -+ coding" all user mode helper program names at kernel build -+ time, moving the names into read-only memory, making it harder -+ for any arbritrary program to be run as root if something were -+ to go wrong. -+ -+ Note, some subsystems and drivers allow their user mode helper -+ binary to be changed with a module parameter, sysctl, sysfs -+ file, or some combination of these. Enabling this option -+ prevents the binary name to be changed, which might not be -+ good for some systems. -+ - source security/selinux/Kconfig - source security/smack/Kconfig - source security/tomoyo/Kconfig diff --git a/0003-add-CONFIG_READONLY_USERMODEHELPER-support-for-lots-.patch b/0003-add-CONFIG_READONLY_USERMODEHELPER-support-for-lots-.patch deleted file mode 100644 index a03d8803c89240..00000000000000 --- a/0003-add-CONFIG_READONLY_USERMODEHELPER-support-for-lots-.patch +++ /dev/null @@ -1,341 +0,0 @@ -From dd1c428188101dd5428aa7bb9ed1a1329a052763 Mon Sep 17 00:00:00 2001 -From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Date: Thu, 15 Dec 2016 13:09:59 -0800 -Subject: [PATCH 3/3] add CONFIG_READONLY_USERMODEHELPER support for lots of - places. - -Dynamic usermode helper should be stopped, so support it... ---- - arch/x86/kernel/cpu/mcheck/mce.c | 12 ++++++++---- - drivers/block/drbd/drbd_int.h | 2 +- - drivers/block/drbd/drbd_main.c | 4 +++- - drivers/block/drbd/drbd_nl.c | 4 ++-- - drivers/video/fbdev/uvesafb.c | 17 +++++++++++------ - fs/nfs/cache_lib.c | 12 +++++++++--- - include/linux/kobject.h | 3 ++- - include/linux/reboot.h | 3 ++- - kernel/ksysfs.c | 6 +++++- - kernel/reboot.c | 2 +- - kernel/sysctl.c | 4 ++++ - lib/kobject_uevent.c | 4 ++-- - 12 files changed, 50 insertions(+), 23 deletions(-) - ---- a/arch/x86/kernel/cpu/mcheck/mce.c -+++ b/arch/x86/kernel/cpu/mcheck/mce.c -@@ -2292,15 +2292,16 @@ static ssize_t set_bank(struct device *s - } - - static ssize_t --show_trigger(struct device *s, struct device_attribute *attr, char *buf) -+trigger_show(struct device *s, struct device_attribute *attr, char *buf) - { - strcpy(buf, mce_helper); - strcat(buf, "\n"); - return strlen(mce_helper) + 1; - } - --static ssize_t set_trigger(struct device *s, struct device_attribute *attr, -- const char *buf, size_t siz) -+#ifndef CONFIG_READONLY_USERMODEHELPER -+static ssize_t trigger_store(struct device *s, struct device_attribute *attr, -+ const char *buf, size_t siz) - { - char *p; - -@@ -2313,6 +2314,10 @@ static ssize_t set_trigger(struct device - - return strlen(mce_helper) + !!p; - } -+static DEVICE_ATTR_RW(trigger); -+#else -+static DEVICE_ATTR_RO(trigger); -+#endif - - static ssize_t set_ignore_ce(struct device *s, - struct device_attribute *attr, -@@ -2370,7 +2375,6 @@ static ssize_t store_int_with_restart(st - return ret; - } - --static DEVICE_ATTR(trigger, 0644, show_trigger, set_trigger); - static DEVICE_INT_ATTR(tolerant, 0644, mca_cfg.tolerant); - static DEVICE_INT_ATTR(monarch_timeout, 0644, mca_cfg.monarch_timeout); - static DEVICE_BOOL_ATTR(dont_log_ce, 0644, mca_cfg.dont_log_ce); ---- a/drivers/block/drbd/drbd_int.h -+++ b/drivers/block/drbd/drbd_int.h -@@ -75,7 +75,7 @@ extern int fault_rate; - extern int fault_devs; - #endif - --extern char drbd_usermode_helper[]; -+extern char __ro_umh drbd_usermode_helper[]; - - - /* This is used to stop/restart our threads. ---- a/drivers/block/drbd/drbd_main.c -+++ b/drivers/block/drbd/drbd_main.c -@@ -109,9 +109,11 @@ int proc_details; /* Detail level - - /* Module parameter for setting the user mode helper program - * to run. Default is /sbin/drbdadm */ --char drbd_usermode_helper[80] = "/sbin/drbdadm"; -+char __ro_umh drbd_usermode_helper[80] = "/sbin/drbdadm"; - -+#ifndef CONFIG_READONLY_USERMODEHELPER - module_param_string(usermode_helper, drbd_usermode_helper, sizeof(drbd_usermode_helper), 0644); -+#endif - - /* in 2.6.x, our device mapping and config info contains our virtual gendisks - * as member "struct gendisk *vdisk;" ---- a/drivers/block/drbd/drbd_nl.c -+++ b/drivers/block/drbd/drbd_nl.c -@@ -344,7 +344,7 @@ int drbd_khelper(struct drbd_device *dev - (char[60]) { }, /* address */ - NULL }; - char mb[14]; -- char *argv[] = {drbd_usermode_helper, cmd, mb, NULL }; -+ char *argv[] = {(char *)drbd_usermode_helper, cmd, mb, NULL }; - struct drbd_connection *connection = first_peer_device(device)->connection; - struct sib_info sib; - int ret; -@@ -396,7 +396,7 @@ enum drbd_peer_state conn_khelper(struct - (char[60]) { }, /* address */ - NULL }; - char *resource_name = connection->resource->name; -- char *argv[] = {drbd_usermode_helper, cmd, resource_name, NULL }; -+ char *argv[] = {(char *)drbd_usermode_helper, cmd, resource_name, NULL }; - int ret; - - setup_khelper_env(connection, envp); ---- a/drivers/video/fbdev/uvesafb.c -+++ b/drivers/video/fbdev/uvesafb.c -@@ -30,7 +30,7 @@ static struct cb_id uvesafb_cn_id = { - .idx = CN_IDX_V86D, - .val = CN_VAL_V86D_UVESAFB - }; --static char v86d_path[PATH_MAX] = "/sbin/v86d"; -+static char __ro_umh v86d_path[PATH_MAX] = "/sbin/v86d"; - static char v86d_started; /* has v86d been started by uvesafb? */ - - static const struct fb_fix_screeninfo uvesafb_fix = { -@@ -114,7 +114,7 @@ static int uvesafb_helper_start(void) - }; - - char *argv[] = { -- v86d_path, -+ (char *)v86d_path, - NULL, - }; - -@@ -1883,19 +1883,22 @@ static int uvesafb_setup(char *options) - } - #endif /* !MODULE */ - --static ssize_t show_v86d(struct device_driver *dev, char *buf) -+static ssize_t v86d_show(struct device_driver *dev, char *buf) - { - return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path); - } - --static ssize_t store_v86d(struct device_driver *dev, const char *buf, -+#ifndef CONFIG_READONLY_USERMODEHELPER -+static ssize_t v86d_store(struct device_driver *dev, const char *buf, - size_t count) - { - strncpy(v86d_path, buf, PATH_MAX); - return count; - } -- --static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d); -+static DRIVER_ATTR_RW(v86d); -+#else -+static DRIVER_ATTR_RO(v86d); -+#endif - - static int uvesafb_init(void) - { -@@ -2017,8 +2020,10 @@ MODULE_PARM_DESC(mode_option, - module_param(vbemode, ushort, 0); - MODULE_PARM_DESC(vbemode, - "VBE mode number to set, overrides the 'mode' option"); -+#ifndef CONFIG_READONLY_USERMODEHELPER - module_param_string(v86d, v86d_path, PATH_MAX, 0660); - MODULE_PARM_DESC(v86d, "Path to the v86d userspace helper."); -+#endif - - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Michal Januszewski <spock@gentoo.org>"); ---- a/fs/nfs/cache_lib.c -+++ b/fs/nfs/cache_lib.c -@@ -20,13 +20,16 @@ - #define NFS_CACHE_UPCALL_PATHLEN 256 - #define NFS_CACHE_UPCALL_TIMEOUT 15 - --static char nfs_cache_getent_prog[NFS_CACHE_UPCALL_PATHLEN] = -+static char __ro_umh nfs_cache_getent_prog[NFS_CACHE_UPCALL_PATHLEN] = - "/sbin/nfs_cache_getent"; - static unsigned long nfs_cache_getent_timeout = NFS_CACHE_UPCALL_TIMEOUT; - -+#ifndef CONFIG_READONLY_USERMODEHELPER - module_param_string(cache_getent, nfs_cache_getent_prog, - sizeof(nfs_cache_getent_prog), 0600); - MODULE_PARM_DESC(cache_getent, "Path to the client cache upcall program"); -+#endif -+ - module_param_named(cache_getent_timeout, nfs_cache_getent_timeout, ulong, 0600); - MODULE_PARM_DESC(cache_getent_timeout, "Timeout (in seconds) after which " - "the cache upcall is assumed to have failed"); -@@ -39,7 +42,7 @@ int nfs_cache_upcall(struct cache_detail - NULL - }; - char *argv[] = { -- nfs_cache_getent_prog, -+ (char *)nfs_cache_getent_prog, - cd->name, - entry_name, - NULL -@@ -48,15 +51,18 @@ int nfs_cache_upcall(struct cache_detail - - if (nfs_cache_getent_prog[0] == '\0') - goto out; -- ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); -+ ret = call_usermodehelper(nfs_cache_getent_prog, argv, envp, -+ UMH_WAIT_EXEC); - /* - * Disable the upcall mechanism if we're getting an ENOENT or - * EACCES error. The admin can re-enable it on the fly by using - * sysfs to set the 'cache_getent' parameter once the problem - * has been fixed. - */ -+#ifndef CONFIG_READONLY_USERMODEHELPER - if (ret == -ENOENT || ret == -EACCES) - nfs_cache_getent_prog[0] = '\0'; -+#endif - out: - return ret > 0 ? 0 : ret; - } ---- a/include/linux/kobject.h -+++ b/include/linux/kobject.h -@@ -27,6 +27,7 @@ - #include <linux/wait.h> - #include <linux/atomic.h> - #include <linux/workqueue.h> -+#include <linux/kmod.h> - - #define UEVENT_HELPER_PATH_LEN 256 - #define UEVENT_NUM_ENVP 32 /* number of env pointers */ -@@ -34,7 +35,7 @@ - - #ifdef CONFIG_UEVENT_HELPER - /* path to the userspace helper executed on an event */ --extern char uevent_helper[]; -+extern char __ro_umh uevent_helper[]; - #endif - - /* counter to tag the uevent, read only except for the kobject core */ ---- a/include/linux/reboot.h -+++ b/include/linux/reboot.h -@@ -3,6 +3,7 @@ - - - #include <linux/notifier.h> -+#include <linux/kmod.h> - #include <uapi/linux/reboot.h> - - #define SYS_DOWN 0x0001 /* Notify of system down */ -@@ -68,7 +69,7 @@ extern int C_A_D; /* for sysctl */ - void ctrl_alt_del(void); - - #define POWEROFF_CMD_PATH_LEN 256 --extern char poweroff_cmd[POWEROFF_CMD_PATH_LEN]; -+extern char __ro_umh poweroff_cmd[]; - - extern void orderly_poweroff(bool force); - extern void orderly_reboot(void); ---- a/kernel/ksysfs.c -+++ b/kernel/ksysfs.c -@@ -44,6 +44,7 @@ static ssize_t uevent_helper_show(struct - { - return sprintf(buf, "%s\n", uevent_helper); - } -+#ifndef CONFIG_READONLY_USERMODEHELPER - static ssize_t uevent_helper_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t count) -@@ -57,7 +58,10 @@ static ssize_t uevent_helper_store(struc - return count; - } - KERNEL_ATTR_RW(uevent_helper); --#endif -+#else -+KERNEL_ATTR_RO(uevent_helper); -+#endif /* CONFIG_READONLY_USERMODEHELPER */ -+#endif /* CONFIG_UEVENT_HELPER */ - - #ifdef CONFIG_PROFILING - static ssize_t profiling_show(struct kobject *kobj, ---- a/kernel/reboot.c -+++ b/kernel/reboot.c -@@ -386,7 +386,7 @@ void ctrl_alt_del(void) - kill_cad_pid(SIGINT, 1); - } - --char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff"; -+char __ro_umh poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff"; - static const char reboot_cmd[] = "/sbin/reboot"; - - static int run_cmd(const char *cmd) ---- a/kernel/sysctl.c -+++ b/kernel/sysctl.c -@@ -663,6 +663,7 @@ static struct ctl_table kern_table[] = { - }, - #endif - #ifdef CONFIG_UEVENT_HELPER -+#ifndef CONFIG_READONLY_USERMODEHELPER - { - .procname = "hotplug", - .data = &uevent_helper, -@@ -671,6 +672,7 @@ static struct ctl_table kern_table[] = { - .proc_handler = proc_dostring, - }, - #endif -+#endif - #ifdef CONFIG_CHR_DEV_SG - { - .procname = "sg-big-buff", -@@ -1080,6 +1082,7 @@ static struct ctl_table kern_table[] = { - .proc_handler = proc_dointvec, - }, - #endif -+#ifndef CONFIG_READONLY_USERMODEHELPER - { - .procname = "poweroff_cmd", - .data = &poweroff_cmd, -@@ -1087,6 +1090,7 @@ static struct ctl_table kern_table[] = { - .mode = 0644, - .proc_handler = proc_dostring, - }, -+#endif - #ifdef CONFIG_KEYS - { - .procname = "keys", ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -29,7 +29,7 @@ - - u64 uevent_seqnum; - #ifdef CONFIG_UEVENT_HELPER --char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH; -+char __ro_umh uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH; - #endif - #ifdef CONFIG_NET - struct uevent_sock { -@@ -137,7 +137,7 @@ static int init_uevent_argv(struct kobj_ - return -ENOMEM; - } - -- env->argv[0] = uevent_helper; -+ env->argv[0] = (char *)uevent_helper; - env->argv[1] = &env->buf[env->buflen]; - env->argv[2] = NULL; - diff --git a/c04.patch b/c04.patch index f1361b576559f6..a791340312ac57 100644 --- a/c04.patch +++ b/c04.patch @@ -4,7 +4,7 @@ --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c -@@ -3851,10 +3851,6 @@ static const struct target_core_fabric_o +@@ -3934,10 +3934,6 @@ static const struct target_core_fabric_o static void ibmvscsis_dev_release(struct device *dev) {}; @@ -15,7 +15,7 @@ static struct device_attribute dev_attr_system_id = __ATTR(system_id, S_IRUGO, system_id_show, NULL); -@@ -3874,7 +3870,6 @@ ATTRIBUTE_GROUPS(ibmvscsis_dev); +@@ -3957,7 +3953,6 @@ ATTRIBUTE_GROUPS(ibmvscsis_dev); static struct class ibmvscsis_class = { .name = "ibmvscsis", .dev_release = ibmvscsis_dev_release, diff --git a/c06.patch b/c06.patch index d639cf4f9734ed..45871306c927d6 100644 --- a/c06.patch +++ b/c06.patch @@ -4,7 +4,7 @@ --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c -@@ -1276,6 +1276,13 @@ static int zram_remove(struct zram *zram +@@ -1272,6 +1272,13 @@ static int zram_remove(struct zram *zram } /* zram-control sysfs attributes */ @@ -18,7 +18,7 @@ static ssize_t hot_add_show(struct class *class, struct class_attribute *attr, char *buf) -@@ -1290,6 +1297,7 @@ static ssize_t hot_add_show(struct class +@@ -1286,6 +1293,7 @@ static ssize_t hot_add_show(struct class return ret; return scnprintf(buf, PAGE_SIZE, "%d\n", ret); } @@ -26,7 +26,7 @@ static ssize_t hot_remove_store(struct class *class, struct class_attribute *attr, -@@ -1320,23 +1328,19 @@ static ssize_t hot_remove_store(struct c +@@ -1316,23 +1324,19 @@ static ssize_t hot_remove_store(struct c mutex_unlock(&zram_index_mutex); return ret ? ret : count; } diff --git a/c08.patch b/c08.patch deleted file mode 100644 index 0f5b92fa40e06a..00000000000000 --- a/c08.patch +++ /dev/null @@ -1,77 +0,0 @@ ---- - drivers/block/osdblk.c | 32 ++++++++++++++++---------------- - 1 file changed, 16 insertions(+), 16 deletions(-) - ---- a/drivers/block/osdblk.c -+++ b/drivers/block/osdblk.c -@@ -462,9 +462,8 @@ static void class_osdblk_release(struct - kfree(cls); - } - --static ssize_t class_osdblk_list(struct class *c, -- struct class_attribute *attr, -- char *data) -+static ssize_t list_show(struct class *c, struct class_attribute *attr, -+ char *data) - { - int n = 0; - struct list_head *tmp; -@@ -487,10 +486,10 @@ static ssize_t class_osdblk_list(struct - mutex_unlock(&ctl_mutex); - return n; - } -+static CLASS_ATTR_RO(list); - --static ssize_t class_osdblk_add(struct class *c, -- struct class_attribute *attr, -- const char *buf, size_t count) -+static ssize_t add_store(struct class *c, struct class_attribute *attr, -+ const char *buf, size_t count) - { - struct osdblk_device *osdev; - ssize_t rc; -@@ -581,11 +580,10 @@ err_out_mod: - module_put(THIS_MODULE); - return rc; - } -+static CLASS_ATTR_WO(add); - --static ssize_t class_osdblk_remove(struct class *c, -- struct class_attribute *attr, -- const char *buf, -- size_t count) -+static ssize_t remove_store(struct class *c, struct class_attribute *attr, -+ const char *buf, size_t count) - { - struct osdblk_device *osdev = NULL; - int target_id, rc; -@@ -629,13 +627,15 @@ static ssize_t class_osdblk_remove(struc - - return count; - } -+static CLASS_ATTR_WO(remove); - --static struct class_attribute class_osdblk_attrs[] = { -- __ATTR(add, 0200, NULL, class_osdblk_add), -- __ATTR(remove, 0200, NULL, class_osdblk_remove), -- __ATTR(list, 0444, class_osdblk_list, NULL), -- __ATTR_NULL -+static struct attribute *class_osdblk_attrs[] = { -+ &class_attr_list.attr, -+ &class_attr_remove.attr, -+ &class_attr_list.attr, -+ NULL, - }; -+ATTRIBUTE_GROUPS(class_osdblk); - - static int osdblk_sysfs_init(void) - { -@@ -652,7 +652,7 @@ static int osdblk_sysfs_init(void) - class_osdblk->name = DRV_NAME; - class_osdblk->owner = THIS_MODULE; - class_osdblk->class_release = class_osdblk_release; -- class_osdblk->class_attrs = class_osdblk_attrs; -+ class_osdblk->class_groups = class_osdblk_groups; - - ret = class_register(class_osdblk); - if (ret) { diff --git a/c10.patch b/c10.patch deleted file mode 100644 index f55fd6edc0bff7..00000000000000 --- a/c10.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- - arch/avr32/boards/merisc/merisc_sysfs.c | 17 ++++++++++------- - 1 file changed, 10 insertions(+), 7 deletions(-) - ---- a/arch/avr32/boards/merisc/merisc_sysfs.c -+++ b/arch/avr32/boards/merisc/merisc_sysfs.c -@@ -18,7 +18,7 @@ - #include <linux/ctype.h> - #include "merisc.h" - --static ssize_t merisc_model_show(struct class *class, char *buf) -+static ssize_t model_show(struct class *class, char *buf) - { - ssize_t ret = 0; - -@@ -27,8 +27,9 @@ static ssize_t merisc_model_show(struct - - return ret; - } -+static CLASS_ATTR_RO(model); - --static ssize_t merisc_revision_show(struct class *class, char *buf) -+static ssize_t revision_show(struct class *class, char *buf) - { - ssize_t ret = 0; - -@@ -37,17 +38,19 @@ static ssize_t merisc_revision_show(stru - - return ret; - } -+static CLASS_ATTR_RO(revision); - --static struct class_attribute merisc_class_attrs[] = { -- __ATTR(model, S_IRUGO, merisc_model_show, NULL), -- __ATTR(revision, S_IRUGO, merisc_revision_show, NULL), -- __ATTR_NULL, -+static struct attribute *merisc_class_attrs[] = { -+ &class_attr_model.attr, -+ &class_attr_revision.attr, -+ NULL, - }; -+ATTRIBUTE_GROUPS(merisc_class); - - struct class merisc_class = { - .name = "merisc", - .owner = THIS_MODULE, -- .class_attrs = merisc_class_attrs, -+ .class_groups = merisc_class_groups, - }; - - static int __init merisc_sysfs_init(void) diff --git a/d01.patch b/d01.patch index 61d439d69cf7fe..875ce8da064aba 100644 --- a/d01.patch +++ b/d01.patch @@ -4,7 +4,7 @@ --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c -@@ -2140,7 +2140,7 @@ struct hid_dynid { +@@ -2147,7 +2147,7 @@ struct hid_dynid { * Adds a new dynamic hid device ID to this driver, * and causes the driver to probe for all devices again. */ @@ -13,7 +13,7 @@ size_t count) { struct hid_driver *hdrv = to_hid_driver(drv); -@@ -2172,7 +2172,13 @@ static ssize_t store_new_id(struct devic +@@ -2179,7 +2179,13 @@ static ssize_t store_new_id(struct devic return ret ? : count; } @@ -28,7 +28,7 @@ static void hid_free_dynids(struct hid_driver *hdrv) { -@@ -2336,6 +2342,7 @@ static int hid_uevent(struct device *dev +@@ -2343,6 +2349,7 @@ static int hid_uevent(struct device *dev static struct bus_type hid_bus_type = { .name = "hid", .dev_groups = hid_dev_groups, @@ -36,7 +36,7 @@ .match = hid_bus_match, .probe = hid_device_probe, .remove = hid_device_remove, -@@ -2775,8 +2782,6 @@ EXPORT_SYMBOL_GPL(hid_destroy_device); +@@ -2782,8 +2789,6 @@ EXPORT_SYMBOL_GPL(hid_destroy_device); int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, const char *mod_name) { @@ -45,7 +45,7 @@ hdrv->driver.name = hdrv->name; hdrv->driver.bus = &hid_bus_type; hdrv->driver.owner = owner; -@@ -2785,21 +2790,12 @@ int __hid_register_driver(struct hid_dri +@@ -2792,21 +2797,12 @@ int __hid_register_driver(struct hid_dri INIT_LIST_HEAD(&hdrv->dyn_list); spin_lock_init(&hdrv->dyn_lock); diff --git a/d05.patch b/d05.patch index 4be80f6a799b6e..badfd7b7587d57 100644 --- a/d05.patch +++ b/d05.patch @@ -6,7 +6,7 @@ --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c -@@ -957,11 +957,11 @@ static int asd_scan_finished(struct Scsi +@@ -956,11 +956,11 @@ static int asd_scan_finished(struct Scsi return 1; } diff --git a/d10.patch b/d10.patch index 08b9f0221ce6fc..0d68a7e2688f25 100644 --- a/d10.patch +++ b/d10.patch @@ -169,7 +169,7 @@ #endif /* --------------------------------------------------------------------- */ -@@ -8537,14 +8505,13 @@ static ssize_t fan_fan2_input_show(struc +@@ -8606,14 +8574,13 @@ static ssize_t fan_fan2_input_show(struc static DEVICE_ATTR(fan2_input, S_IRUGO, fan_fan2_input_show, NULL); /* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ @@ -187,7 +187,7 @@ { unsigned long t; -@@ -8561,9 +8528,7 @@ static ssize_t fan_fan_watchdog_store(st +@@ -8630,9 +8597,7 @@ static ssize_t fan_fan_watchdog_store(st return count; } diff --git a/d11.patch b/d11.patch index 61a7158b508010..01b01d7edb99b9 100644 --- a/d11.patch +++ b/d11.patch @@ -125,7 +125,7 @@ &driver_attr_connection.attr, --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c -@@ -5738,8 +5738,8 @@ static struct ccwgroup_driver qeth_core_ +@@ -5800,8 +5800,8 @@ static struct ccwgroup_driver qeth_core_ .restore = qeth_core_restore, }; @@ -136,7 +136,7 @@ { int err; -@@ -5748,7 +5748,7 @@ static ssize_t qeth_core_driver_group_st +@@ -5810,7 +5810,7 @@ static ssize_t qeth_core_driver_group_st return err ? err : count; } diff --git a/d99.patch b/d99.patch index 861c5a1ebc1403..c993196623b5c2 100644 --- a/d99.patch +++ b/d99.patch @@ -51,7 +51,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- a/include/linux/device.h +++ b/include/linux/device.h -@@ -303,8 +303,6 @@ struct driver_attribute { +@@ -307,8 +307,6 @@ struct driver_attribute { size_t count); }; diff --git a/goldfish_pipe-an-implementation-of-more-parallel-pipe.patch b/goldfish_pipe-an-implementation-of-more-parallel-pipe.patch deleted file mode 100644 index 3477c8d04aeb70..00000000000000 --- a/goldfish_pipe-an-implementation-of-more-parallel-pipe.patch +++ /dev/null @@ -1,1256 +0,0 @@ -From c53b6059ba261505317a4d8de63832846c9c92fb Mon Sep 17 00:00:00 2001 -From: Jin Qian <jinqian@android.com> -Date: Mon, 27 Feb 2017 12:06:21 -0800 -Subject: goldfish_pipe: An implementation of more parallel pipe - -From: Jin Qian <jinqian@android.com> - -This is a driver code for a redesigned android pipe. -Currently it works for x86 and x64 emulators with the following -performance results: - ADB push to /dev/null, - Ubuntu, - 400 MB file, - times are for (1 / 10 / 100) parallel adb commands -x86 adb push: (4.4s / 11.5s / 2m10s) -> (2.8s / 6s / 51s) -x64 adb push: (7s / 15s / (too long, 6m+) -> (2.7s / 6.2s / 52s) - -ADB pull and push to /data/ have the same %% of speedup -More importantly, I don't see any signs of slowdowns when -run in parallel with Antutu benchmark, so it is definitely -making much better job at multithreading. - -Signed-off-by: Yurii Zubrytskyi <zyy@google.com> -Signed-off-by: Jin Qian <jinqian@android.com> ---- - drivers/platform/goldfish/goldfish_pipe.c | 976 +++++++++++++++-------- - ---- - drivers/platform/goldfish/goldfish_pipe.c | 976 +++++++++++++++++++----------- - 1 file changed, 644 insertions(+), 332 deletions(-) - ---- a/drivers/platform/goldfish/goldfish_pipe.c -+++ b/drivers/platform/goldfish/goldfish_pipe.c -@@ -1,8 +1,8 @@ - /* -- * Copyright (C) 2011 Google, Inc. - * Copyright (C) 2012 Intel, Inc. - * Copyright (C) 2013 Intel, Inc. - * Copyright (C) 2014 Linaro Limited -+ * Copyright (C) 2011-2016 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and -@@ -46,6 +46,7 @@ - * exchange is properly mapped during a transfer. - */ - -+ - #include <linux/module.h> - #include <linux/interrupt.h> - #include <linux/kernel.h> -@@ -63,122 +64,232 @@ - #include <linux/acpi.h> - - /* -+ * Update this when something changes in the driver's behavior so the host -+ * can benefit from knowing it -+ */ -+enum { -+ PIPE_DRIVER_VERSION = 2, -+ PIPE_CURRENT_DEVICE_VERSION = 2 -+}; -+ -+/* - * IMPORTANT: The following constants must match the ones used and defined - * in external/qemu/hw/goldfish_pipe.c in the Android source tree. - */ - --/* pipe device registers */ --#define PIPE_REG_COMMAND 0x00 /* write: value = command */ --#define PIPE_REG_STATUS 0x04 /* read */ --#define PIPE_REG_CHANNEL 0x08 /* read/write: channel id */ --#define PIPE_REG_CHANNEL_HIGH 0x30 /* read/write: channel id */ --#define PIPE_REG_SIZE 0x0c /* read/write: buffer size */ --#define PIPE_REG_ADDRESS 0x10 /* write: physical address */ --#define PIPE_REG_ADDRESS_HIGH 0x34 /* write: physical address */ --#define PIPE_REG_WAKES 0x14 /* read: wake flags */ --#define PIPE_REG_PARAMS_ADDR_LOW 0x18 /* read/write: batch data address */ --#define PIPE_REG_PARAMS_ADDR_HIGH 0x1c /* read/write: batch data address */ --#define PIPE_REG_ACCESS_PARAMS 0x20 /* write: batch access */ --#define PIPE_REG_VERSION 0x24 /* read: device version */ -- --/* list of commands for PIPE_REG_COMMAND */ --#define CMD_OPEN 1 /* open new channel */ --#define CMD_CLOSE 2 /* close channel (from guest) */ --#define CMD_POLL 3 /* poll read/write status */ -- - /* List of bitflags returned in status of CMD_POLL command */ --#define PIPE_POLL_IN (1 << 0) --#define PIPE_POLL_OUT (1 << 1) --#define PIPE_POLL_HUP (1 << 2) -- --/* The following commands are related to write operations */ --#define CMD_WRITE_BUFFER 4 /* send a user buffer to the emulator */ --#define CMD_WAKE_ON_WRITE 5 /* tell the emulator to wake us when writing -- is possible */ --#define CMD_READ_BUFFER 6 /* receive a user buffer from the emulator */ --#define CMD_WAKE_ON_READ 7 /* tell the emulator to wake us when reading -- * is possible */ -+enum PipePollFlags { -+ PIPE_POLL_IN = 1 << 0, -+ PIPE_POLL_OUT = 1 << 1, -+ PIPE_POLL_HUP = 1 << 2 -+}; - - /* Possible status values used to signal errors - see goldfish_pipe_error_convert */ --#define PIPE_ERROR_INVAL -1 --#define PIPE_ERROR_AGAIN -2 --#define PIPE_ERROR_NOMEM -3 --#define PIPE_ERROR_IO -4 -+enum PipeErrors { -+ PIPE_ERROR_INVAL = -1, -+ PIPE_ERROR_AGAIN = -2, -+ PIPE_ERROR_NOMEM = -3, -+ PIPE_ERROR_IO = -4 -+}; - - /* Bit-flags used to signal events from the emulator */ --#define PIPE_WAKE_CLOSED (1 << 0) /* emulator closed pipe */ --#define PIPE_WAKE_READ (1 << 1) /* pipe can now be read from */ --#define PIPE_WAKE_WRITE (1 << 2) /* pipe can now be written to */ -- --struct access_params { -- unsigned long channel; -- u32 size; -- unsigned long address; -- u32 cmd; -- u32 result; -- /* reserved for future extension */ -+enum PipeWakeFlags { -+ PIPE_WAKE_CLOSED = 1 << 0, /* emulator closed pipe */ -+ PIPE_WAKE_READ = 1 << 1, /* pipe can now be read from */ -+ PIPE_WAKE_WRITE = 1 << 2 /* pipe can now be written to */ -+}; -+ -+/* Bit flags for the 'flags' field */ -+enum PipeFlagsBits { -+ BIT_CLOSED_ON_HOST = 0, /* pipe closed by host */ -+ BIT_WAKE_ON_WRITE = 1, /* want to be woken on writes */ -+ BIT_WAKE_ON_READ = 2, /* want to be woken on reads */ -+}; -+ -+enum PipeRegs { -+ PIPE_REG_CMD = 0, -+ -+ PIPE_REG_SIGNAL_BUFFER_HIGH = 4, -+ PIPE_REG_SIGNAL_BUFFER = 8, -+ PIPE_REG_SIGNAL_BUFFER_COUNT = 12, -+ -+ PIPE_REG_OPEN_BUFFER_HIGH = 20, -+ PIPE_REG_OPEN_BUFFER = 24, -+ -+ PIPE_REG_VERSION = 36, -+ -+ PIPE_REG_GET_SIGNALLED = 48, -+}; -+ -+enum PipeCmdCode { -+ PIPE_CMD_OPEN = 1, /* to be used by the pipe device itself */ -+ PIPE_CMD_CLOSE, -+ PIPE_CMD_POLL, -+ PIPE_CMD_WRITE, -+ PIPE_CMD_WAKE_ON_WRITE, -+ PIPE_CMD_READ, -+ PIPE_CMD_WAKE_ON_READ, -+ -+ /* -+ * TODO(zyy): implement a deferred read/write execution to allow -+ * parallel processing of pipe operations on the host. -+ */ -+ PIPE_CMD_WAKE_ON_DONE_IO, -+}; -+ -+enum { -+ MAX_BUFFERS_PER_COMMAND = 336, -+ MAX_SIGNALLED_PIPES = 64, -+ INITIAL_PIPES_CAPACITY = 64 -+}; -+ -+struct goldfish_pipe_dev; -+struct goldfish_pipe; -+struct goldfish_pipe_command; -+ -+/* A per-pipe command structure, shared with the host */ -+struct goldfish_pipe_command { -+ s32 cmd; /* PipeCmdCode, guest -> host */ -+ s32 id; /* pipe id, guest -> host */ -+ s32 status; /* command execution status, host -> guest */ -+ s32 reserved; /* to pad to 64-bit boundary */ -+ union { -+ /* Parameters for PIPE_CMD_{READ,WRITE} */ -+ struct { -+ /* number of buffers, guest -> host */ -+ u32 buffers_count; -+ /* number of consumed bytes, host -> guest */ -+ s32 consumed_size; -+ /* buffer pointers, guest -> host */ -+ u64 ptrs[MAX_BUFFERS_PER_COMMAND]; -+ /* buffer sizes, guest -> host */ -+ u32 sizes[MAX_BUFFERS_PER_COMMAND]; -+ } rw_params; -+ }; -+}; -+ -+/* A single signalled pipe information */ -+struct signalled_pipe_buffer { -+ u32 id; - u32 flags; - }; - --/* The global driver data. Holds a reference to the i/o page used to -- * communicate with the emulator, and a wake queue for blocked tasks -- * waiting to be awoken. -- */ --struct goldfish_pipe_dev { -- spinlock_t lock; -- unsigned char __iomem *base; -- struct access_params *aps; -- int irq; -- u32 version; -+/* Parameters for the PIPE_CMD_OPEN command */ -+struct open_command_param { -+ u64 command_buffer_ptr; -+ u32 rw_params_max_count; - }; - --static struct goldfish_pipe_dev pipe_dev[1]; -+/* Device-level set of buffers shared with the host */ -+struct goldfish_pipe_dev_buffers { -+ struct open_command_param open_command_params; -+ struct signalled_pipe_buffer signalled_pipe_buffers[ -+ MAX_SIGNALLED_PIPES]; -+}; - - /* This data type models a given pipe instance */ - struct goldfish_pipe { -- struct goldfish_pipe_dev *dev; -- struct mutex lock; -+ /* pipe ID - index into goldfish_pipe_dev::pipes array */ -+ u32 id; -+ /* The wake flags pipe is waiting for -+ * Note: not protected with any lock, uses atomic operations -+ * and barriers to make it thread-safe. -+ */ - unsigned long flags; -+ /* wake flags host have signalled, -+ * - protected by goldfish_pipe_dev::lock -+ */ -+ unsigned long signalled_flags; -+ -+ /* A pointer to command buffer */ -+ struct goldfish_pipe_command *command_buffer; -+ -+ /* doubly linked list of signalled pipes, protected by -+ * goldfish_pipe_dev::lock -+ */ -+ struct goldfish_pipe *prev_signalled; -+ struct goldfish_pipe *next_signalled; -+ -+ /* -+ * A pipe's own lock. Protects the following: -+ * - *command_buffer - makes sure a command can safely write its -+ * parameters to the host and read the results back. -+ */ -+ struct mutex lock; -+ -+ /* A wake queue for sleeping until host signals an event */ - wait_queue_head_t wake_queue; -+ /* Pointer to the parent goldfish_pipe_dev instance */ -+ struct goldfish_pipe_dev *dev; - }; - -+/* The global driver data. Holds a reference to the i/o page used to -+ * communicate with the emulator, and a wake queue for blocked tasks -+ * waiting to be awoken. -+ */ -+struct goldfish_pipe_dev { -+ /* -+ * Global device spinlock. Protects the following members: -+ * - pipes, pipes_capacity -+ * - [*pipes, *pipes + pipes_capacity) - array data -+ * - first_signalled_pipe, -+ * goldfish_pipe::prev_signalled, -+ * goldfish_pipe::next_signalled, -+ * goldfish_pipe::signalled_flags - all singnalled-related fields, -+ * in all allocated pipes -+ * - open_command_params - PIPE_CMD_OPEN-related buffers -+ * -+ * It looks like a lot of different fields, but the trick is that -+ * the only operation that happens often is the signalled pipes array -+ * manipulation. That's why it's OK for now to keep the rest of the -+ * fields under the same lock. If we notice too much contention because -+ * of PIPE_CMD_OPEN, then we should add a separate lock there. -+ */ -+ spinlock_t lock; - --/* Bit flags for the 'flags' field */ --enum { -- BIT_CLOSED_ON_HOST = 0, /* pipe closed by host */ -- BIT_WAKE_ON_WRITE = 1, /* want to be woken on writes */ -- BIT_WAKE_ON_READ = 2, /* want to be woken on reads */ -+ /* -+ * Array of the pipes of |pipes_capacity| elements, -+ * indexed by goldfish_pipe::id -+ */ -+ struct goldfish_pipe **pipes; -+ u32 pipes_capacity; -+ -+ /* Pointers to the buffers host uses for interaction with this driver */ -+ struct goldfish_pipe_dev_buffers *buffers; -+ -+ /* Head of a doubly linked list of signalled pipes */ -+ struct goldfish_pipe *first_signalled_pipe; -+ -+ /* Some device-specific data */ -+ int irq; -+ int version; -+ unsigned char __iomem *base; - }; - -+struct goldfish_pipe_dev pipe_dev[1] = {}; - --static u32 goldfish_cmd_status(struct goldfish_pipe *pipe, u32 cmd) -+static int goldfish_cmd_locked(struct goldfish_pipe *pipe, enum PipeCmdCode cmd) - { -- unsigned long flags; -- u32 status; -- struct goldfish_pipe_dev *dev = pipe->dev; -- -- spin_lock_irqsave(&dev->lock, flags); -- gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL, -- dev->base + PIPE_REG_CHANNEL_HIGH); -- writel(cmd, dev->base + PIPE_REG_COMMAND); -- status = readl(dev->base + PIPE_REG_STATUS); -- spin_unlock_irqrestore(&dev->lock, flags); -- return status; -+ pipe->command_buffer->cmd = cmd; -+ /* failure by default */ -+ pipe->command_buffer->status = PIPE_ERROR_INVAL; -+ writel(pipe->id, pipe->dev->base + PIPE_REG_CMD); -+ return pipe->command_buffer->status; - } - --static void goldfish_cmd(struct goldfish_pipe *pipe, u32 cmd) -+static int goldfish_cmd(struct goldfish_pipe *pipe, enum PipeCmdCode cmd) - { -- unsigned long flags; -- struct goldfish_pipe_dev *dev = pipe->dev; -+ int status; - -- spin_lock_irqsave(&dev->lock, flags); -- gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL, -- dev->base + PIPE_REG_CHANNEL_HIGH); -- writel(cmd, dev->base + PIPE_REG_COMMAND); -- spin_unlock_irqrestore(&dev->lock, flags); -+ if (mutex_lock_interruptible(&pipe->lock)) -+ return PIPE_ERROR_IO; -+ status = goldfish_cmd_locked(pipe, cmd); -+ mutex_unlock(&pipe->lock); -+ return status; - } - --/* This function converts an error code returned by the emulator through -+/* -+ * This function converts an error code returned by the emulator through - * the PIPE_REG_STATUS i/o register into a valid negative errno value. - */ - static int goldfish_pipe_error_convert(int status) -@@ -195,184 +306,202 @@ static int goldfish_pipe_error_convert(i - } - } - --/* -- * Notice: QEMU will return 0 for un-known register access, indicating -- * param_acess is supported or not -- */ --static int valid_batchbuffer_addr(struct goldfish_pipe_dev *dev, -- struct access_params *aps) -+static int pin_user_pages(unsigned long first_page, unsigned long last_page, -+ unsigned int last_page_size, int is_write, -+ struct page *pages[MAX_BUFFERS_PER_COMMAND], -+ unsigned int *iter_last_page_size) -+{ -+ int ret; -+ int requested_pages = ((last_page - first_page) >> PAGE_SHIFT) + 1; -+ -+ if (requested_pages > MAX_BUFFERS_PER_COMMAND) { -+ requested_pages = MAX_BUFFERS_PER_COMMAND; -+ *iter_last_page_size = PAGE_SIZE; -+ } else { -+ *iter_last_page_size = last_page_size; -+ } -+ -+ ret = get_user_pages_fast( -+ first_page, requested_pages, !is_write, pages); -+ if (ret <= 0) -+ return -EFAULT; -+ if (ret < requested_pages) -+ *iter_last_page_size = PAGE_SIZE; -+ return ret; -+ -+} -+ -+static void release_user_pages(struct page **pages, int pages_count, -+ int is_write, s32 consumed_size) - { -- u32 aph, apl; -- u64 paddr; -- aph = readl(dev->base + PIPE_REG_PARAMS_ADDR_HIGH); -- apl = readl(dev->base + PIPE_REG_PARAMS_ADDR_LOW); -+ int i; - -- paddr = ((u64)aph << 32) | apl; -- if (paddr != (__pa(aps))) -- return 0; -- return 1; -+ for (i = 0; i < pages_count; i++) { -+ if (!is_write && consumed_size > 0) -+ set_page_dirty(pages[i]); -+ put_page(pages[i]); -+ } -+} -+ -+/* Populate the call parameters, merging adjacent pages together */ -+static void populate_rw_params( -+ struct page **pages, int pages_count, -+ unsigned long address, unsigned long address_end, -+ unsigned long first_page, unsigned long last_page, -+ unsigned int iter_last_page_size, int is_write, -+ struct goldfish_pipe_command *command) -+{ -+ /* -+ * Process the first page separately - it's the only page that -+ * needs special handling for its start address. -+ */ -+ unsigned long xaddr = page_to_phys(pages[0]); -+ unsigned long xaddr_prev = xaddr; -+ int buffer_idx = 0; -+ int i = 1; -+ int size_on_page = first_page == last_page -+ ? (int)(address_end - address) -+ : (PAGE_SIZE - (address & ~PAGE_MASK)); -+ command->rw_params.ptrs[0] = (u64)(xaddr | (address & ~PAGE_MASK)); -+ command->rw_params.sizes[0] = size_on_page; -+ for (; i < pages_count; ++i) { -+ xaddr = page_to_phys(pages[i]); -+ size_on_page = (i == pages_count - 1) ? -+ iter_last_page_size : PAGE_SIZE; -+ if (xaddr == xaddr_prev + PAGE_SIZE) { -+ command->rw_params.sizes[buffer_idx] += size_on_page; -+ } else { -+ ++buffer_idx; -+ command->rw_params.ptrs[buffer_idx] = (u64)xaddr; -+ command->rw_params.sizes[buffer_idx] = size_on_page; -+ } -+ xaddr_prev = xaddr; -+ } -+ command->rw_params.buffers_count = buffer_idx + 1; - } - --/* 0 on success */ --static int setup_access_params_addr(struct platform_device *pdev, -- struct goldfish_pipe_dev *dev) -+static int transfer_max_buffers(struct goldfish_pipe *pipe, -+ unsigned long address, unsigned long address_end, int is_write, -+ unsigned long last_page, unsigned int last_page_size, -+ s32 *consumed_size, int *status) - { -- dma_addr_t dma_handle; -- struct access_params *aps; -+ struct page *pages[MAX_BUFFERS_PER_COMMAND]; -+ unsigned long first_page = address & PAGE_MASK; -+ unsigned int iter_last_page_size; -+ int pages_count = pin_user_pages(first_page, last_page, -+ last_page_size, is_write, -+ pages, &iter_last_page_size); - -- aps = dmam_alloc_coherent(&pdev->dev, sizeof(struct access_params), -- &dma_handle, GFP_KERNEL); -- if (!aps) -- return -ENOMEM; -+ if (pages_count < 0) -+ return pages_count; - -- writel(upper_32_bits(dma_handle), dev->base + PIPE_REG_PARAMS_ADDR_HIGH); -- writel(lower_32_bits(dma_handle), dev->base + PIPE_REG_PARAMS_ADDR_LOW); -+ /* Serialize access to the pipe command buffers */ -+ if (mutex_lock_interruptible(&pipe->lock)) -+ return -ERESTARTSYS; - -- if (valid_batchbuffer_addr(dev, aps)) { -- dev->aps = aps; -- return 0; -- } else -- return -1; -+ populate_rw_params(pages, pages_count, address, address_end, -+ first_page, last_page, iter_last_page_size, is_write, -+ pipe->command_buffer); -+ -+ /* Transfer the data */ -+ *status = goldfish_cmd_locked(pipe, -+ is_write ? PIPE_CMD_WRITE : PIPE_CMD_READ); -+ -+ *consumed_size = pipe->command_buffer->rw_params.consumed_size; -+ -+ mutex_unlock(&pipe->lock); -+ -+ release_user_pages(pages, pages_count, is_write, *consumed_size); -+ -+ return 0; - } - --/* A value that will not be set by qemu emulator */ --#define INITIAL_BATCH_RESULT (0xdeadbeaf) --static int access_with_param(struct goldfish_pipe_dev *dev, const int cmd, -- unsigned long address, unsigned long avail, -- struct goldfish_pipe *pipe, int *status) --{ -- struct access_params *aps = dev->aps; -- -- if (aps == NULL) -- return -1; -- -- aps->result = INITIAL_BATCH_RESULT; -- aps->channel = (unsigned long)pipe; -- aps->size = avail; -- aps->address = address; -- aps->cmd = cmd; -- writel(cmd, dev->base + PIPE_REG_ACCESS_PARAMS); -- /* -- * If the aps->result has not changed, that means -- * that the batch command failed -- */ -- if (aps->result == INITIAL_BATCH_RESULT) -- return -1; -- *status = aps->result; -+static int wait_for_host_signal(struct goldfish_pipe *pipe, int is_write) -+{ -+ u32 wakeBit = is_write ? BIT_WAKE_ON_WRITE : BIT_WAKE_ON_READ; -+ -+ set_bit(wakeBit, &pipe->flags); -+ -+ /* Tell the emulator we're going to wait for a wake event */ -+ (void)goldfish_cmd(pipe, -+ is_write ? PIPE_CMD_WAKE_ON_WRITE : PIPE_CMD_WAKE_ON_READ); -+ -+ while (test_bit(wakeBit, &pipe->flags)) { -+ if (wait_event_interruptible( -+ pipe->wake_queue, -+ !test_bit(wakeBit, &pipe->flags))) -+ return -ERESTARTSYS; -+ -+ if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) -+ return -EIO; -+ } -+ - return 0; - } - --static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer, -- size_t bufflen, int is_write) -+static ssize_t goldfish_pipe_read_write(struct file *filp, -+ char __user *buffer, size_t bufflen, int is_write) - { -- unsigned long irq_flags; - struct goldfish_pipe *pipe = filp->private_data; -- struct goldfish_pipe_dev *dev = pipe->dev; -- unsigned long address, address_end; - int count = 0, ret = -EINVAL; -+ unsigned long address, address_end, last_page; -+ unsigned int last_page_size; - - /* If the emulator already closed the pipe, no need to go further */ -- if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) -+ if (unlikely(test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))) - return -EIO; -- - /* Null reads or writes succeeds */ - if (unlikely(bufflen == 0)) - return 0; -- - /* Check the buffer range for access */ -- if (!access_ok(is_write ? VERIFY_WRITE : VERIFY_READ, -- buffer, bufflen)) -+ if (unlikely(!access_ok(is_write ? VERIFY_WRITE : VERIFY_READ, -+ buffer, bufflen))) - return -EFAULT; - -- /* Serialize access to the pipe */ -- if (mutex_lock_interruptible(&pipe->lock)) -- return -ERESTARTSYS; -- -- address = (unsigned long)(void *)buffer; -+ address = (unsigned long)buffer; - address_end = address + bufflen; -+ last_page = (address_end - 1) & PAGE_MASK; -+ last_page_size = ((address_end - 1) & ~PAGE_MASK) + 1; - - while (address < address_end) { -- unsigned long page_end = (address & PAGE_MASK) + PAGE_SIZE; -- unsigned long next = page_end < address_end ? page_end -- : address_end; -- unsigned long avail = next - address; -- int status, wakeBit; -- struct page *page; -- -- /* Either vaddr or paddr depending on the device version */ -- unsigned long xaddr; -+ s32 consumed_size; -+ int status; - -- /* -- * We grab the pages on a page-by-page basis in case user -- * space gives us a potentially huge buffer but the read only -- * returns a small amount, then there's no need to pin that -- * much memory to the process. -- */ -- ret = get_user_pages_unlocked(address, 1, &page, -- is_write ? 0 : FOLL_WRITE); -+ ret = transfer_max_buffers(pipe, address, address_end, is_write, -+ last_page, last_page_size, &consumed_size, -+ &status); - if (ret < 0) - break; - -- if (dev->version) { -- /* Device version 1 or newer (qemu-android) expects the -- * physical address. -+ if (consumed_size > 0) { -+ /* No matter what's the status, we've transferred -+ * something. - */ -- xaddr = page_to_phys(page) | (address & ~PAGE_MASK); -- } else { -- /* Device version 0 (classic emulator) expects the -- * virtual address. -- */ -- xaddr = address; -+ count += consumed_size; -+ address += consumed_size; - } -- -- /* Now, try to transfer the bytes in the current page */ -- spin_lock_irqsave(&dev->lock, irq_flags); -- if (access_with_param(dev, -- is_write ? CMD_WRITE_BUFFER : CMD_READ_BUFFER, -- xaddr, avail, pipe, &status)) { -- gf_write_ptr(pipe, dev->base + PIPE_REG_CHANNEL, -- dev->base + PIPE_REG_CHANNEL_HIGH); -- writel(avail, dev->base + PIPE_REG_SIZE); -- gf_write_ptr((void *)xaddr, -- dev->base + PIPE_REG_ADDRESS, -- dev->base + PIPE_REG_ADDRESS_HIGH); -- writel(is_write ? CMD_WRITE_BUFFER : CMD_READ_BUFFER, -- dev->base + PIPE_REG_COMMAND); -- status = readl(dev->base + PIPE_REG_STATUS); -- } -- spin_unlock_irqrestore(&dev->lock, irq_flags); -- -- if (status > 0 && !is_write) -- set_page_dirty(page); -- put_page(page); -- -- if (status > 0) { /* Correct transfer */ -- count += status; -- address += status; -+ if (status > 0) - continue; -- } else if (status == 0) { /* EOF */ -+ if (status == 0) { -+ /* EOF */ - ret = 0; - break; -- } else if (status < 0 && count > 0) { -+ } -+ if (count > 0) { - /* -- * An error occurred and we already transferred -- * something on one of the previous pages. -+ * An error occurred, but we already transferred -+ * something on one of the previous iterations. - * Just return what we already copied and log this - * err. -- * -- * Note: This seems like an incorrect approach but -- * cannot change it until we check if any user space -- * ABI relies on this behavior. - */ - if (status != PIPE_ERROR_AGAIN) -- pr_info_ratelimited("goldfish_pipe: backend returned error %d on %s\n", -+ pr_info_ratelimited("goldfish_pipe: backend error %d on %s\n", - status, is_write ? "write" : "read"); -- ret = 0; - break; - } - - /* -- * If the error is not PIPE_ERROR_AGAIN, or if we are not in -+ * If the error is not PIPE_ERROR_AGAIN, or if we are in - * non-blocking mode, just return the error code. - */ - if (status != PIPE_ERROR_AGAIN || -@@ -381,139 +510,214 @@ static ssize_t goldfish_pipe_read_write( - break; - } - -- /* -- * The backend blocked the read/write, wait until the backend -- * tells us it's ready to process more data. -- */ -- wakeBit = is_write ? BIT_WAKE_ON_WRITE : BIT_WAKE_ON_READ; -- set_bit(wakeBit, &pipe->flags); -- -- /* Tell the emulator we're going to wait for a wake event */ -- goldfish_cmd(pipe, -- is_write ? CMD_WAKE_ON_WRITE : CMD_WAKE_ON_READ); -- -- /* Unlock the pipe, then wait for the wake signal */ -- mutex_unlock(&pipe->lock); -- -- while (test_bit(wakeBit, &pipe->flags)) { -- if (wait_event_interruptible( -- pipe->wake_queue, -- !test_bit(wakeBit, &pipe->flags))) -- return -ERESTARTSYS; -- -- if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) -- return -EIO; -- } -- -- /* Try to re-acquire the lock */ -- if (mutex_lock_interruptible(&pipe->lock)) -- return -ERESTARTSYS; -+ status = wait_for_host_signal(pipe, is_write); -+ if (status < 0) -+ return status; - } -- mutex_unlock(&pipe->lock); - -- if (ret < 0) -- return ret; -- else -+ if (count > 0) - return count; -+ return ret; - } - - static ssize_t goldfish_pipe_read(struct file *filp, char __user *buffer, -- size_t bufflen, loff_t *ppos) -+ size_t bufflen, loff_t *ppos) - { -- return goldfish_pipe_read_write(filp, buffer, bufflen, 0); -+ return goldfish_pipe_read_write(filp, buffer, bufflen, -+ /* is_write */ 0); - } - - static ssize_t goldfish_pipe_write(struct file *filp, - const char __user *buffer, size_t bufflen, - loff_t *ppos) - { -- return goldfish_pipe_read_write(filp, (char __user *)buffer, -- bufflen, 1); -+ return goldfish_pipe_read_write(filp, -+ /* cast away the const */(char __user *)buffer, bufflen, -+ /* is_write */ 1); - } - -- - static unsigned int goldfish_pipe_poll(struct file *filp, poll_table *wait) - { - struct goldfish_pipe *pipe = filp->private_data; - unsigned int mask = 0; - int status; - -- mutex_lock(&pipe->lock); -- - poll_wait(filp, &pipe->wake_queue, wait); - -- status = goldfish_cmd_status(pipe, CMD_POLL); -- -- mutex_unlock(&pipe->lock); -+ status = goldfish_cmd(pipe, PIPE_CMD_POLL); -+ if (status < 0) -+ return -ERESTARTSYS; - - if (status & PIPE_POLL_IN) - mask |= POLLIN | POLLRDNORM; -- - if (status & PIPE_POLL_OUT) - mask |= POLLOUT | POLLWRNORM; -- - if (status & PIPE_POLL_HUP) - mask |= POLLHUP; -- - if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) - mask |= POLLERR; - - return mask; - } - --static irqreturn_t goldfish_pipe_interrupt(int irq, void *dev_id) -+static void signalled_pipes_add_locked(struct goldfish_pipe_dev *dev, -+ u32 id, u32 flags) - { -- struct goldfish_pipe_dev *dev = dev_id; -- unsigned long irq_flags; -- int count = 0; -+ struct goldfish_pipe *pipe; - -- /* -- * We're going to read from the emulator a list of (channel,flags) -- * pairs corresponding to the wake events that occurred on each -- * blocked pipe (i.e. channel). -- */ -- spin_lock_irqsave(&dev->lock, irq_flags); -- for (;;) { -- /* First read the channel, 0 means the end of the list */ -- struct goldfish_pipe *pipe; -- unsigned long wakes; -- unsigned long channel = 0; -+ if (WARN_ON(id >= dev->pipes_capacity)) -+ return; - --#ifdef CONFIG_64BIT -- channel = (u64)readl(dev->base + PIPE_REG_CHANNEL_HIGH) << 32; -+ pipe = dev->pipes[id]; -+ if (!pipe) -+ return; -+ pipe->signalled_flags |= flags; -+ -+ if (pipe->prev_signalled || pipe->next_signalled -+ || dev->first_signalled_pipe == pipe) -+ return; /* already in the list */ -+ pipe->next_signalled = dev->first_signalled_pipe; -+ if (dev->first_signalled_pipe) -+ dev->first_signalled_pipe->prev_signalled = pipe; -+ dev->first_signalled_pipe = pipe; -+} -+ -+static void signalled_pipes_remove_locked(struct goldfish_pipe_dev *dev, -+ struct goldfish_pipe *pipe) { -+ if (pipe->prev_signalled) -+ pipe->prev_signalled->next_signalled = pipe->next_signalled; -+ if (pipe->next_signalled) -+ pipe->next_signalled->prev_signalled = pipe->prev_signalled; -+ if (pipe == dev->first_signalled_pipe) -+ dev->first_signalled_pipe = pipe->next_signalled; -+ pipe->prev_signalled = NULL; -+ pipe->next_signalled = NULL; -+} - -- if (channel == 0) -- break; --#endif -- channel |= readl(dev->base + PIPE_REG_CHANNEL); -+static struct goldfish_pipe *signalled_pipes_pop_front( -+ struct goldfish_pipe_dev *dev, int *wakes) -+{ -+ struct goldfish_pipe *pipe; -+ unsigned long flags; - -- if (channel == 0) -- break; -+ spin_lock_irqsave(&dev->lock, flags); - -- /* Convert channel to struct pipe pointer + read wake flags */ -- wakes = readl(dev->base + PIPE_REG_WAKES); -- pipe = (struct goldfish_pipe *)(ptrdiff_t)channel; -+ pipe = dev->first_signalled_pipe; -+ if (pipe) { -+ *wakes = pipe->signalled_flags; -+ pipe->signalled_flags = 0; -+ /* -+ * This is an optimized version of -+ * signalled_pipes_remove_locked() -+ * - We want to make it as fast as possible to -+ * wake the sleeping pipe operations faster. -+ */ -+ dev->first_signalled_pipe = pipe->next_signalled; -+ if (dev->first_signalled_pipe) -+ dev->first_signalled_pipe->prev_signalled = NULL; -+ pipe->next_signalled = NULL; -+ } - -- /* Did the emulator just closed a pipe? */ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ return pipe; -+} -+ -+static void goldfish_interrupt_task(unsigned long unused) -+{ -+ struct goldfish_pipe_dev *dev = pipe_dev; -+ /* Iterate over the signalled pipes and wake them one by one */ -+ struct goldfish_pipe *pipe; -+ int wakes; -+ -+ while ((pipe = signalled_pipes_pop_front(dev, &wakes)) != NULL) { - if (wakes & PIPE_WAKE_CLOSED) { -- set_bit(BIT_CLOSED_ON_HOST, &pipe->flags); -- wakes |= PIPE_WAKE_READ | PIPE_WAKE_WRITE; -+ pipe->flags = 1 << BIT_CLOSED_ON_HOST; -+ } else { -+ if (wakes & PIPE_WAKE_READ) -+ clear_bit(BIT_WAKE_ON_READ, &pipe->flags); -+ if (wakes & PIPE_WAKE_WRITE) -+ clear_bit(BIT_WAKE_ON_WRITE, &pipe->flags); - } -- if (wakes & PIPE_WAKE_READ) -- clear_bit(BIT_WAKE_ON_READ, &pipe->flags); -- if (wakes & PIPE_WAKE_WRITE) -- clear_bit(BIT_WAKE_ON_WRITE, &pipe->flags); -- -+ /* -+ * wake_up_interruptible() implies a write barrier, so don't -+ * explicitly add another one here. -+ */ - wake_up_interruptible(&pipe->wake_queue); -- count++; - } -- spin_unlock_irqrestore(&dev->lock, irq_flags); -+} -+DECLARE_TASKLET(goldfish_interrupt_tasklet, goldfish_interrupt_task, 0); -+ -+/* -+ * The general idea of the interrupt handling: -+ * -+ * 1. device raises an interrupt if there's at least one signalled pipe -+ * 2. IRQ handler reads the signalled pipes and their count from the device -+ * 3. device writes them into a shared buffer and returns the count -+ * it only resets the IRQ if it has returned all signalled pipes, -+ * otherwise it leaves it raised, so IRQ handler will be called -+ * again for the next chunk -+ * 4. IRQ handler adds all returned pipes to the device's signalled pipes list -+ * 5. IRQ handler launches a tasklet to process the signalled pipes from the -+ * list in a separate context -+ */ -+static irqreturn_t goldfish_pipe_interrupt(int irq, void *dev_id) -+{ -+ u32 count; -+ u32 i; -+ unsigned long flags; -+ struct goldfish_pipe_dev *dev = dev_id; -+ -+ if (dev != pipe_dev) -+ return IRQ_NONE; -+ -+ /* Request the signalled pipes from the device */ -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ count = readl(dev->base + PIPE_REG_GET_SIGNALLED); -+ if (count == 0) { -+ spin_unlock_irqrestore(&dev->lock, flags); -+ return IRQ_NONE; -+ } -+ if (count > MAX_SIGNALLED_PIPES) -+ count = MAX_SIGNALLED_PIPES; - -- return (count == 0) ? IRQ_NONE : IRQ_HANDLED; -+ for (i = 0; i < count; ++i) -+ signalled_pipes_add_locked(dev, -+ dev->buffers->signalled_pipe_buffers[i].id, -+ dev->buffers->signalled_pipe_buffers[i].flags); -+ -+ spin_unlock_irqrestore(&dev->lock, flags); -+ -+ tasklet_schedule(&goldfish_interrupt_tasklet); -+ return IRQ_HANDLED; -+} -+ -+static int get_free_pipe_id_locked(struct goldfish_pipe_dev *dev) -+{ -+ int id; -+ -+ for (id = 0; id < dev->pipes_capacity; ++id) -+ if (!dev->pipes[id]) -+ return id; -+ -+ { -+ /* Reallocate the array */ -+ u32 new_capacity = 2 * dev->pipes_capacity; -+ struct goldfish_pipe **pipes = -+ kcalloc(new_capacity, sizeof(*pipes), GFP_KERNEL); -+ if (!pipes) -+ return -ENOMEM; -+ memcpy(pipes, dev->pipes, sizeof(*pipes) * dev->pipes_capacity); -+ kfree(dev->pipes); -+ dev->pipes = pipes; -+ id = dev->pipes_capacity; -+ dev->pipes_capacity = new_capacity; -+ } -+ return id; - } - - /** -- * goldfish_pipe_open - open a channel to the AVD -+ * goldfish_pipe_open - open a channel to the AVD - * @inode: inode of device - * @file: file struct of opener - * -@@ -525,12 +729,13 @@ static irqreturn_t goldfish_pipe_interru - */ - static int goldfish_pipe_open(struct inode *inode, struct file *file) - { -- struct goldfish_pipe *pipe; - struct goldfish_pipe_dev *dev = pipe_dev; -- int32_t status; -+ unsigned long flags; -+ int id; -+ int status; - - /* Allocate new pipe kernel object */ -- pipe = kzalloc(sizeof(*pipe), GFP_KERNEL); -+ struct goldfish_pipe *pipe = kzalloc(sizeof(*pipe), GFP_KERNEL); - if (pipe == NULL) - return -ENOMEM; - -@@ -539,29 +744,69 @@ static int goldfish_pipe_open(struct ino - init_waitqueue_head(&pipe->wake_queue); - - /* -- * Now, tell the emulator we're opening a new pipe. We use the -- * pipe object's address as the channel identifier for simplicity. -+ * Command buffer needs to be allocated on its own page to make sure -+ * it is physically contiguous in host's address space. - */ -+ pipe->command_buffer = -+ (struct goldfish_pipe_command *)__get_free_page(GFP_KERNEL); -+ if (!pipe->command_buffer) { -+ status = -ENOMEM; -+ goto err_pipe; -+ } - -- status = goldfish_cmd_status(pipe, CMD_OPEN); -- if (status < 0) { -- kfree(pipe); -- return status; -+ spin_lock_irqsave(&dev->lock, flags); -+ -+ id = get_free_pipe_id_locked(dev); -+ if (id < 0) { -+ status = id; -+ goto err_id_locked; - } - -+ dev->pipes[id] = pipe; -+ pipe->id = id; -+ pipe->command_buffer->id = id; -+ -+ /* Now tell the emulator we're opening a new pipe. */ -+ dev->buffers->open_command_params.rw_params_max_count = -+ MAX_BUFFERS_PER_COMMAND; -+ dev->buffers->open_command_params.command_buffer_ptr = -+ (u64)(unsigned long)__pa(pipe->command_buffer); -+ status = goldfish_cmd_locked(pipe, PIPE_CMD_OPEN); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ if (status < 0) -+ goto err_cmd; - /* All is done, save the pipe into the file's private data field */ - file->private_data = pipe; - return 0; -+ -+err_cmd: -+ spin_lock_irqsave(&dev->lock, flags); -+ dev->pipes[id] = NULL; -+err_id_locked: -+ spin_unlock_irqrestore(&dev->lock, flags); -+ free_page((unsigned long)pipe->command_buffer); -+err_pipe: -+ kfree(pipe); -+ return status; - } - - static int goldfish_pipe_release(struct inode *inode, struct file *filp) - { -+ unsigned long flags; - struct goldfish_pipe *pipe = filp->private_data; -+ struct goldfish_pipe_dev *dev = pipe->dev; - - /* The guest is closing the channel, so tell the emulator right now */ -- goldfish_cmd(pipe, CMD_CLOSE); -- kfree(pipe); -+ (void)goldfish_cmd(pipe, PIPE_CMD_CLOSE); -+ -+ spin_lock_irqsave(&dev->lock, flags); -+ dev->pipes[pipe->id] = NULL; -+ signalled_pipes_remove_locked(dev, pipe); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ - filp->private_data = NULL; -+ free_page((unsigned long)pipe->command_buffer); -+ kfree(pipe); - return 0; - } - -@@ -574,18 +819,91 @@ static const struct file_operations gold - .release = goldfish_pipe_release, - }; - --static struct miscdevice goldfish_pipe_device = { -+static struct miscdevice goldfish_pipe_dev = { - .minor = MISC_DYNAMIC_MINOR, - .name = "goldfish_pipe", - .fops = &goldfish_pipe_fops, - }; - -+static int goldfish_pipe_device_init(struct platform_device *pdev) -+{ -+ char *page; -+ struct goldfish_pipe_dev *dev = pipe_dev; -+ int err = devm_request_irq(&pdev->dev, dev->irq, -+ goldfish_pipe_interrupt, -+ IRQF_SHARED, "goldfish_pipe", dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to allocate IRQ for v2\n"); -+ return err; -+ } -+ -+ err = misc_register(&goldfish_pipe_dev); -+ if (err) { -+ dev_err(&pdev->dev, "unable to register v2 device\n"); -+ return err; -+ } -+ -+ dev->first_signalled_pipe = NULL; -+ dev->pipes_capacity = INITIAL_PIPES_CAPACITY; -+ dev->pipes = kcalloc(dev->pipes_capacity, sizeof(*dev->pipes), -+ GFP_KERNEL); -+ if (!dev->pipes) -+ return -ENOMEM; -+ -+ /* -+ * We're going to pass two buffers, open_command_params and -+ * signalled_pipe_buffers, to the host. This means each of those buffers -+ * needs to be contained in a single physical page. The easiest choice -+ * is to just allocate a page and place the buffers in it. -+ */ -+ if (WARN_ON(sizeof(*dev->buffers) > PAGE_SIZE)) -+ return -ENOMEM; -+ -+ page = (char *)__get_free_page(GFP_KERNEL); -+ if (!page) { -+ kfree(dev->pipes); -+ return -ENOMEM; -+ } -+ dev->buffers = (struct goldfish_pipe_dev_buffers *)page; -+ -+ /* Send the buffer addresses to the host */ -+ { -+ u64 paddr = __pa(&dev->buffers->signalled_pipe_buffers); -+ -+ writel((u32)(unsigned long)(paddr >> 32), -+ dev->base + PIPE_REG_SIGNAL_BUFFER_HIGH); -+ writel((u32)(unsigned long)paddr, -+ dev->base + PIPE_REG_SIGNAL_BUFFER); -+ writel((u32)MAX_SIGNALLED_PIPES, -+ dev->base + PIPE_REG_SIGNAL_BUFFER_COUNT); -+ -+ paddr = __pa(&dev->buffers->open_command_params); -+ writel((u32)(unsigned long)(paddr >> 32), -+ dev->base + PIPE_REG_OPEN_BUFFER_HIGH); -+ writel((u32)(unsigned long)paddr, -+ dev->base + PIPE_REG_OPEN_BUFFER); -+ } -+ return 0; -+} -+ -+static void goldfish_pipe_device_deinit(struct platform_device *pdev) -+{ -+ struct goldfish_pipe_dev *dev = pipe_dev; -+ -+ misc_deregister(&goldfish_pipe_dev); -+ kfree(dev->pipes); -+ free_page((unsigned long)dev->buffers); -+} -+ - static int goldfish_pipe_probe(struct platform_device *pdev) - { - int err; - struct resource *r; - struct goldfish_pipe_dev *dev = pipe_dev; - -+ if (WARN_ON(sizeof(struct goldfish_pipe_command) > PAGE_SIZE)) -+ return -ENOMEM; -+ - /* not thread safe, but this should not happen */ - WARN_ON(dev->base != NULL); - -@@ -609,26 +927,21 @@ static int goldfish_pipe_probe(struct pl - } - dev->irq = r->start; - -- err = devm_request_irq(&pdev->dev, dev->irq, goldfish_pipe_interrupt, -- IRQF_SHARED, "goldfish_pipe", dev); -- if (err) { -- dev_err(&pdev->dev, "unable to allocate IRQ\n"); -- goto error; -- } -- -- err = misc_register(&goldfish_pipe_device); -- if (err) { -- dev_err(&pdev->dev, "unable to register device\n"); -- goto error; -- } -- setup_access_params_addr(pdev, dev); -- -- /* Although the pipe device in the classic Android emulator does not -- * recognize the 'version' register, it won't treat this as an error -- * either and will simply return 0, which is fine. -+ /* -+ * Exchange the versions with the host device -+ * -+ * Note: v1 driver used to not report its version, so we write it before -+ * reading device version back: this allows the host implementation to -+ * detect the old driver (if there was no version write before read). - */ -+ writel((u32)PIPE_DRIVER_VERSION, dev->base + PIPE_REG_VERSION); - dev->version = readl(dev->base + PIPE_REG_VERSION); -- return 0; -+ if (WARN_ON(dev->version < PIPE_CURRENT_DEVICE_VERSION)) -+ return -EINVAL; -+ -+ err = goldfish_pipe_device_init(pdev); -+ if (!err) -+ return 0; - - error: - dev->base = NULL; -@@ -638,7 +951,7 @@ error: - static int goldfish_pipe_remove(struct platform_device *pdev) - { - struct goldfish_pipe_dev *dev = pipe_dev; -- misc_deregister(&goldfish_pipe_device); -+ goldfish_pipe_device_deinit(pdev); - dev->base = NULL; - return 0; - } -@@ -655,17 +968,16 @@ static const struct of_device_id goldfis - }; - MODULE_DEVICE_TABLE(of, goldfish_pipe_of_match); - --static struct platform_driver goldfish_pipe = { -+static struct platform_driver goldfish_pipe_driver = { - .probe = goldfish_pipe_probe, - .remove = goldfish_pipe_remove, - .driver = { - .name = "goldfish_pipe", -- .owner = THIS_MODULE, - .of_match_table = goldfish_pipe_of_match, - .acpi_match_table = ACPI_PTR(goldfish_pipe_acpi_match), - } - }; - --module_platform_driver(goldfish_pipe); -+module_platform_driver(goldfish_pipe_driver); - MODULE_AUTHOR("David Turner <digit@google.com>"); - MODULE_LICENSE("GPL"); diff --git a/csdio2.patch b/old/csdio2.patch index 2c6a7a363a8232..2c6a7a363a8232 100644 --- a/csdio2.patch +++ b/old/csdio2.patch diff --git a/defer-input-nodes-and-led-support b/old/defer-input-nodes-and-led-support index 96b8acc24aaa43..96b8acc24aaa43 100644 --- a/defer-input-nodes-and-led-support +++ b/old/defer-input-nodes-and-led-support diff --git a/e.patch b/old/e.patch index ef62199b0ba9d3..ef62199b0ba9d3 100644 --- a/e.patch +++ b/old/e.patch diff --git a/input-xpad-disconnect-all-wireless-controllers-at-init.patch b/old/input-xpad-disconnect-all-wireless-controllers-at-init.patch index ec1e05dca47995..ec1e05dca47995 100644 --- a/input-xpad-disconnect-all-wireless-controllers-at-init.patch +++ b/old/input-xpad-disconnect-all-wireless-controllers-at-init.patch diff --git a/input-xpad-handle-present-and-gone-correctly.patch b/old/input-xpad-handle-present-and-gone-correctly.patch index 95ec89103d6166..95ec89103d6166 100644 --- a/input-xpad-handle-present-and-gone-correctly.patch +++ b/old/input-xpad-handle-present-and-gone-correctly.patch diff --git a/input-xpad-move-the-input-device-creation-to-a-new-function.patch b/old/input-xpad-move-the-input-device-creation-to-a-new-function.patch index db918fd23b0ce9..db918fd23b0ce9 100644 --- a/input-xpad-move-the-input-device-creation-to-a-new-function.patch +++ b/old/input-xpad-move-the-input-device-creation-to-a-new-function.patch diff --git a/input-xpad-properly-name-the-led-class-devices.patch b/old/input-xpad-properly-name-the-led-class-devices.patch index 5bb65928d5fd17..5bb65928d5fd17 100644 --- a/input-xpad-properly-name-the-led-class-devices.patch +++ b/old/input-xpad-properly-name-the-led-class-devices.patch diff --git a/input-xpad-set-the-correct-led-number.patch b/old/input-xpad-set-the-correct-led-number.patch index 58d8ab57950d58..58d8ab57950d58 100644 --- a/input-xpad-set-the-correct-led-number.patch +++ b/old/input-xpad-set-the-correct-led-number.patch diff --git a/input-xpad-set-the-leds-properly-on-xbox-wireless-controllers.patch b/old/input-xpad-set-the-leds-properly-on-xbox-wireless-controllers.patch index 3bab0f4ced9693..3bab0f4ced9693 100644 --- a/input-xpad-set-the-leds-properly-on-xbox-wireless-controllers.patch +++ b/old/input-xpad-set-the-leds-properly-on-xbox-wireless-controllers.patch diff --git a/simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch b/old/simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch index e032b0f2987886..e032b0f2987886 100644 --- a/simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch +++ b/old/simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch diff --git a/staging-exfat-add-filesystem-to-drivers-staging-exfat.patch b/old/staging-exfat-add-filesystem-to-drivers-staging-exfat.patch index 5a138e378f2f92..5a138e378f2f92 100644 --- a/staging-exfat-add-filesystem-to-drivers-staging-exfat.patch +++ b/old/staging-exfat-add-filesystem-to-drivers-staging-exfat.patch diff --git a/staging-exfat-add-filesystem-to-the-build.patch b/old/staging-exfat-add-filesystem-to-the-build.patch index e1aa356a329e2e..773bbf425be9fb 100644 --- a/staging-exfat-add-filesystem-to-the-build.patch +++ b/old/staging-exfat-add-filesystem-to-the-build.patch @@ -11,27 +11,26 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- drivers/staging/Kconfig | 2 ++ - drivers/staging/Makefile | 2 +- + drivers/staging/Makefile | 1 + drivers/staging/exfat/Kconfig | 4 ++++ drivers/staging/exfat/Makefile | 14 ++++---------- - 4 files changed, 11 insertions(+), 11 deletions(-) + 4 files changed, 11 insertions(+), 10 deletions(-) --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig -@@ -104,4 +104,6 @@ source "drivers/staging/vc04_services/Kc +@@ -110,4 +110,6 @@ source "drivers/staging/ccree/Kconfig" - source "drivers/staging/bcm2835-audio/Kconfig" + source "drivers/staging/typec/Kconfig" +source "drivers/staging/exfat/Kconfig" + endif # STAGING --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile -@@ -41,4 +41,4 @@ obj-$(CONFIG_KS7010) += ks7010/ +@@ -44,3 +44,4 @@ obj-$(CONFIG_KS7010) += ks7010/ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ - obj-$(CONFIG_SND_BCM2835) += bcm2835-audio/ -- + obj-$(CONFIG_CRYPTO_DEV_CCREE) += ccree/ +obj-$(CONFIG_EXFAT_FS) += exfat/ --- /dev/null +++ b/drivers/staging/exfat/Kconfig diff --git a/staging-exfat-hlist_for_each-api-change.patch b/old/staging-exfat-hlist_for_each-api-change.patch index 18ecaade36243a..18ecaade36243a 100644 --- a/staging-exfat-hlist_for_each-api-change.patch +++ b/old/staging-exfat-hlist_for_each-api-change.patch diff --git a/staging-exfat-include-aio.h.patch b/old/staging-exfat-include-aio.h.patch index d0bc12038fc698..d0bc12038fc698 100644 --- a/staging-exfat-include-aio.h.patch +++ b/old/staging-exfat-include-aio.h.patch diff --git a/staging-exfat-kuid-fixes.patch b/old/staging-exfat-kuid-fixes.patch index afd26c7a4ed384..afd26c7a4ed384 100644 --- a/staging-exfat-kuid-fixes.patch +++ b/old/staging-exfat-kuid-fixes.patch diff --git a/staging-exfat-readdir-to-iterate-change.patch b/old/staging-exfat-readdir-to-iterate-change.patch index 925198d4280c50..925198d4280c50 100644 --- a/staging-exfat-readdir-to-iterate-change.patch +++ b/old/staging-exfat-readdir-to-iterate-change.patch diff --git a/staging-exfat-truncage_pagecache-api-change.patch b/old/staging-exfat-truncage_pagecache-api-change.patch index d9bb8fff2a48cc..d9bb8fff2a48cc 100644 --- a/staging-exfat-truncage_pagecache-api-change.patch +++ b/old/staging-exfat-truncage_pagecache-api-change.patch diff --git a/p26.patch b/p26.patch index eac8789f6c314d..aa898527fcea52 100644 --- a/p26.patch +++ b/p26.patch @@ -43,18 +43,11 @@ static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, char *buf) -@@ -48,6 +50,7 @@ static ssize_t modalias_show (struct dev - - return len+1; - } -+static DEVICE_ATTR_RO(modalias); - - static ssize_t devspec_show(struct device *dev, - struct device_attribute *attr, char *buf) -@@ -57,15 +60,25 @@ static ssize_t devspec_show(struct devic +@@ -52,15 +54,26 @@ static ssize_t devspec_show(struct devic ofdev = to_platform_device(dev); return sprintf(buf, "%s\n", ofdev->dev.of_node->full_name); } ++static DEVICE_ATTR_RO(modalias); +static DEVICE_ATTR_RO(devspec); macio_config_of_attr (name, "%s\n"); diff --git a/p28.patch b/p28.patch index a19fb142ba5dae..66a9ef27869dd3 100644 --- a/p28.patch +++ b/p28.patch @@ -12,7 +12,7 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf) -@@ -406,6 +407,7 @@ static ssize_t name_show(struct device * +@@ -406,19 +407,22 @@ static ssize_t name_show(struct device * ofdev = to_platform_device(dev); return sprintf(buf, "%s\n", ofdev->dev.of_node->name); } @@ -20,9 +20,8 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) -@@ -415,13 +417,15 @@ static ssize_t modalias_show(struct devi - buf[len+1] = 0; - return len+1; + { + return of_device_modalias(dev, buf, PAGE_SIZE); } +static DEVICE_ATTR_RO(modalias); @@ -41,7 +40,7 @@ struct bus_type ibmebus_bus_type = { .name = "ibmebus", -@@ -431,7 +435,7 @@ struct bus_type ibmebus_bus_type = { +@@ -428,7 +432,7 @@ struct bus_type ibmebus_bus_type = { .probe = ibmebus_bus_device_probe, .remove = ibmebus_bus_device_remove, .shutdown = ibmebus_bus_device_shutdown, diff --git a/pci_groups.patch b/pci_groups.patch index 5617216362a447..a9bd7d50871427 100644 --- a/pci_groups.patch +++ b/pci_groups.patch @@ -6,7 +6,7 @@ --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c -@@ -809,13 +809,6 @@ static void nes_remove(struct pci_dev *p +@@ -808,13 +808,6 @@ static void nes_remove(struct pci_dev *p } @@ -20,7 +20,7 @@ static ssize_t adapter_show(struct device_driver *ddp, char *buf) { unsigned int devfn = 0xffffffff; -@@ -1157,35 +1150,29 @@ static DRIVER_ATTR_RW(idx_addr); +@@ -1156,35 +1149,29 @@ static DRIVER_ATTR_RW(idx_addr); static DRIVER_ATTR_RW(idx_data); static DRIVER_ATTR_RW(wqm_quanta); @@ -79,7 +79,7 @@ /** * nes_init_module - module initialization entry point -@@ -1193,20 +1180,13 @@ static void nes_remove_driver_sysfs(stru +@@ -1192,20 +1179,13 @@ static void nes_remove_driver_sysfs(stru static int __init nes_init_module(void) { int retval; @@ -101,7 +101,7 @@ } -@@ -1216,7 +1196,6 @@ static int __init nes_init_module(void) +@@ -1215,7 +1195,6 @@ static int __init nes_init_module(void) static void __exit nes_exit_module(void) { nes_cm_stop(); @@ -111,7 +111,7 @@ } --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c -@@ -1289,6 +1289,7 @@ int __pci_register_driver(struct pci_dri +@@ -1299,6 +1299,7 @@ int __pci_register_driver(struct pci_dri drv->driver.bus = &pci_bus_type; drv->driver.owner = owner; drv->driver.mod_name = mod_name; @@ -121,7 +121,7 @@ INIT_LIST_HEAD(&drv->dynids.list); --- a/include/linux/pci.h +++ b/include/linux/pci.h -@@ -689,6 +689,7 @@ struct pci_driver { +@@ -716,6 +716,7 @@ struct pci_driver { void (*shutdown) (struct pci_dev *dev); int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */ const struct pci_error_handlers *err_handler; diff --git a/qlcnic_sysfs.patch b/qlcnic_sysfs.patch index 608c30181bb8da..48714c4fe0fdc3 100644 --- a/qlcnic_sysfs.patch +++ b/qlcnic_sysfs.patch @@ -113,7 +113,7 @@ - .store = qlcnic_store_beacon, -}; - - static struct bin_attribute bin_attr_crb = { + static const struct bin_attribute bin_attr_crb = { .attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)}, .size = 0, @@ -1317,6 +1300,24 @@ void qlcnic_unregister_hwmon_dev(struct @@ -1,4 +1,4 @@ -#goldfish_pipe-an-implementation-of-more-parallel-pipe.patch +# tests-convert-the-membarrier-test-to-tap-format.patch lib-vsprintf-additional-kernel-pointer-filtering-options.patch lib-vsprintf-whitelist-stack-traces.patch @@ -9,28 +9,11 @@ drivers-uio-un-restrict-sysfs-pointers-for-uio.patch 0002-CHROMIUM-android-fix-warning-when-releasing-active-s.patch 0003-goldfish-Add-goldfish-sync-driver.patch 0001-drbd-rename-usermode_helper-to-drbd_usermode_helper.patch -0002-Introduce-CONFIG_READONLY_USERMODEHELPER.patch -0003-add-CONFIG_READONLY_USERMODEHELPER-support-for-lots-.patch ## broken patch! # -csdio2.patch -##input-xpad-set-the-leds-properly-on-xbox-wireless-controllers.patch -##defer-input-nodes-and-led-support -##input-xpad-move-the-input-device-creation-to-a-new-function.patch -##input-xpad-set-the-correct-led-number.patch -##input-xpad-disconnect-all-wireless-controllers-at-init.patch -##input-xpad-handle-present-and-gone-correctly.patch -##input-xpad-properly-name-the-led-class-devices.patch # # -staging-exfat-add-filesystem-to-drivers-staging-exfat.patch -staging-exfat-add-filesystem-to-the-build.patch -staging-exfat-include-aio.h.patch -staging-exfat-hlist_for_each-api-change.patch -staging-exfat-truncage_pagecache-api-change.patch -staging-exfat-readdir-to-iterate-change.patch -staging-exfat-kuid-fixes.patch # # ## patches already in my git trees, but still here so I don't loose them. @@ -45,9 +28,6 @@ staging-exfat-kuid-fixes.patch ## dev_groups to struct class work # # -e.patch -simulate-fake-fn-key-on-ps-2-keyboards-w-o-one-eg.-chromebook-pixel.patch -# ##gregkh/gkh-version.patch # driver-core-remove-struct-bus_type.dev_attrs.patch @@ -71,9 +51,7 @@ c04.patch c05.patch c06.patch c07.patch -c08.patch c09.patch -c10.patch c99.patch # |