From b111064c3018ecd21dc279565bb3ff9bc5172d2e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 1 Feb 2013 11:08:49 +0100 Subject: [PATCH] 3.7-stable patches added patches: efi-make-efi_enabled-a-function-to-query-efi-facilities.patch hid-usbhid-quirk-for-formosa-ir-receiver.patch nfs-don-t-silently-fail-setattr-requests-on-mountpoints.patch nfs-fix-error-reporting-in-nfs_xdev_mount.patch nfsv4.1-ensure-that-nfs41_walk_client_list-does-start-lease-recovery.patch nfsv4.1-handle-nfs4err_delay-when-resetting-the-nfsv4.1-session.patch nfsv4-fix-nfsv4-reference-counting-for-trunked-sessions.patch nfsv4-fix-nfsv4-trunking-discovery.patch samsung-laptop-disable-on-efi-hardware.patch smp-fix-smp-function-call-empty-cpu-mask-race.patch x86-msr-add-capabilities-check.patch --- ...d-a-function-to-query-efi-facilities.patch | 464 ++++++++++++++++++ ...usbhid-quirk-for-formosa-ir-receiver.patch | 47 ++ ...fail-setattr-requests-on-mountpoints.patch | 61 +++ ...ix-error-reporting-in-nfs_xdev_mount.patch | 64 +++ ...erence-counting-for-trunked-sessions.patch | 105 ++++ .../nfsv4-fix-nfsv4-trunking-discovery.patch | 112 +++++ ...lient_list-does-start-lease-recovery.patch | 42 ++ ...y-when-resetting-the-nfsv4.1-session.patch | 46 ++ ...msung-laptop-disable-on-efi-hardware.patch | 55 +++ queue-3.7/series | 11 + ...mp-function-call-empty-cpu-mask-race.patch | 101 ++++ .../x86-msr-add-capabilities-check.patch | 52 ++ 12 files changed, 1160 insertions(+) create mode 100644 queue-3.7/efi-make-efi_enabled-a-function-to-query-efi-facilities.patch create mode 100644 queue-3.7/hid-usbhid-quirk-for-formosa-ir-receiver.patch create mode 100644 queue-3.7/nfs-don-t-silently-fail-setattr-requests-on-mountpoints.patch create mode 100644 queue-3.7/nfs-fix-error-reporting-in-nfs_xdev_mount.patch create mode 100644 queue-3.7/nfsv4-fix-nfsv4-reference-counting-for-trunked-sessions.patch create mode 100644 queue-3.7/nfsv4-fix-nfsv4-trunking-discovery.patch create mode 100644 queue-3.7/nfsv4.1-ensure-that-nfs41_walk_client_list-does-start-lease-recovery.patch create mode 100644 queue-3.7/nfsv4.1-handle-nfs4err_delay-when-resetting-the-nfsv4.1-session.patch create mode 100644 queue-3.7/samsung-laptop-disable-on-efi-hardware.patch create mode 100644 queue-3.7/smp-fix-smp-function-call-empty-cpu-mask-race.patch create mode 100644 queue-3.7/x86-msr-add-capabilities-check.patch diff --git a/queue-3.7/efi-make-efi_enabled-a-function-to-query-efi-facilities.patch b/queue-3.7/efi-make-efi_enabled-a-function-to-query-efi-facilities.patch new file mode 100644 index 00000000000..a693ff391e8 --- /dev/null +++ b/queue-3.7/efi-make-efi_enabled-a-function-to-query-efi-facilities.patch @@ -0,0 +1,464 @@ +From 83e68189745ad931c2afd45d8ee3303929233e7f Mon Sep 17 00:00:00 2001 +From: Matt Fleming +Date: Wed, 14 Nov 2012 09:42:35 +0000 +Subject: efi: Make 'efi_enabled' a function to query EFI facilities + +From: Matt Fleming + +commit 83e68189745ad931c2afd45d8ee3303929233e7f upstream. + +Originally 'efi_enabled' indicated whether a kernel was booted from +EFI firmware. Over time its semantics have changed, and it now +indicates whether or not we are booted on an EFI machine with +bit-native firmware, e.g. 64-bit kernel with 64-bit firmware. + +The immediate motivation for this patch is the bug report at, + + https://bugs.launchpad.net/ubuntu-cdimage/+bug/1040557 + +which details how running a platform driver on an EFI machine that is +designed to run under BIOS can cause the machine to become +bricked. Also, the following report, + + https://bugzilla.kernel.org/show_bug.cgi?id=47121 + +details how running said driver can also cause Machine Check +Exceptions. Drivers need a new means of detecting whether they're +running on an EFI machine, as sadly the expression, + + if (!efi_enabled) + +hasn't been a sufficient condition for quite some time. + +Users actually want to query 'efi_enabled' for different reasons - +what they really want access to is the list of available EFI +facilities. + +For instance, the x86 reboot code needs to know whether it can invoke +the ResetSystem() function provided by the EFI runtime services, while +the ACPI OSL code wants to know whether the EFI config tables were +mapped successfully. There are also checks in some of the platform +driver code to simply see if they're running on an EFI machine (which +would make it a bad idea to do BIOS-y things). + +This patch is a prereq for the samsung-laptop fix patch. + +Signed-off-by: Matt Fleming +Cc: David Airlie +Cc: Corentin Chary +Cc: Matthew Garrett +Cc: Dave Jiang +Cc: Olof Johansson +Cc: Peter Jones +Cc: Colin Ian King +Cc: Steve Langasek +Cc: Tony Luck +Cc: Konrad Rzeszutek Wilk +Cc: Rafael J. Wysocki +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/efi.h | 1 + arch/x86/kernel/reboot.c | 2 - + arch/x86/kernel/setup.c | 28 ++++++++-------- + arch/x86/platform/efi/efi.c | 57 +++++++++++++++++++-------------- + drivers/acpi/osl.c | 2 - + drivers/firmware/dmi_scan.c | 2 - + drivers/firmware/efivars.c | 4 +- + drivers/firmware/iscsi_ibft_find.c | 2 - + drivers/gpu/drm/radeon/radeon_device.c | 3 + + drivers/platform/x86/ibm_rtl.c | 2 - + drivers/scsi/isci/init.c | 2 - + include/linux/efi.h | 24 ++++++++++--- + init/main.c | 4 +- + 13 files changed, 79 insertions(+), 54 deletions(-) + +--- a/arch/x86/include/asm/efi.h ++++ b/arch/x86/include/asm/efi.h +@@ -94,6 +94,7 @@ extern void __iomem *efi_ioremap(unsigne + #endif /* CONFIG_X86_32 */ + + extern int add_efi_memmap; ++extern unsigned long x86_efi_facility; + extern void efi_set_executable(efi_memory_desc_t *md, bool executable); + extern int efi_memblock_x86_reserve_range(void); + extern void efi_call_phys_prelog(void); +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -584,7 +584,7 @@ static void native_machine_emergency_res + break; + + case BOOT_EFI: +- if (efi_enabled) ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) + efi.reset_system(reboot_mode ? + EFI_RESET_WARM : + EFI_RESET_COLD, +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -809,15 +809,15 @@ void __init setup_arch(char **cmdline_p) + #ifdef CONFIG_EFI + if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, + "EL32", 4)) { +- efi_enabled = 1; +- efi_64bit = false; ++ set_bit(EFI_BOOT, &x86_efi_facility); + } else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, + "EL64", 4)) { +- efi_enabled = 1; +- efi_64bit = true; ++ set_bit(EFI_BOOT, &x86_efi_facility); ++ set_bit(EFI_64BIT, &x86_efi_facility); + } +- if (efi_enabled && efi_memblock_x86_reserve_range()) +- efi_enabled = 0; ++ ++ if (efi_enabled(EFI_BOOT)) ++ efi_memblock_x86_reserve_range(); + #endif + + x86_init.oem.arch_setup(); +@@ -890,7 +890,7 @@ void __init setup_arch(char **cmdline_p) + + finish_e820_parsing(); + +- if (efi_enabled) ++ if (efi_enabled(EFI_BOOT)) + efi_init(); + + dmi_scan_machine(); +@@ -973,7 +973,7 @@ void __init setup_arch(char **cmdline_p) + * The EFI specification says that boot service code won't be called + * after ExitBootServices(). This is, in fact, a lie. + */ +- if (efi_enabled) ++ if (efi_enabled(EFI_MEMMAP)) + efi_reserve_boot_services(); + + /* preallocate 4k for mptable mpc */ +@@ -1112,7 +1112,7 @@ void __init setup_arch(char **cmdline_p) + + #ifdef CONFIG_VT + #if defined(CONFIG_VGA_CONSOLE) +- if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) ++ if (!efi_enabled(EFI_BOOT) || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) + conswitchp = &vga_con; + #elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +@@ -1129,14 +1129,14 @@ void __init setup_arch(char **cmdline_p) + register_refined_jiffies(CLOCK_TICK_RATE); + + #ifdef CONFIG_EFI +- /* Once setup is done above, disable efi_enabled on mismatched +- * firmware/kernel archtectures since there is no support for +- * runtime services. ++ /* Once setup is done above, unmap the EFI memory map on ++ * mismatched firmware/kernel archtectures since there is no ++ * support for runtime services. + */ +- if (efi_enabled && IS_ENABLED(CONFIG_X86_64) != efi_64bit) { ++ if (efi_enabled(EFI_BOOT) && ++ IS_ENABLED(CONFIG_X86_64) != efi_enabled(EFI_64BIT)) { + pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); + efi_unmap_memmap(); +- efi_enabled = 0; + } + #endif + } +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -51,9 +51,6 @@ + + #define EFI_DEBUG 1 + +-int efi_enabled; +-EXPORT_SYMBOL(efi_enabled); +- + struct efi __read_mostly efi = { + .mps = EFI_INVALID_TABLE_ADDR, + .acpi = EFI_INVALID_TABLE_ADDR, +@@ -69,19 +66,28 @@ EXPORT_SYMBOL(efi); + + struct efi_memory_map memmap; + +-bool efi_64bit; +- + static struct efi efi_phys __initdata; + static efi_system_table_t efi_systab __initdata; + + static inline bool efi_is_native(void) + { +- return IS_ENABLED(CONFIG_X86_64) == efi_64bit; ++ return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT); ++} ++ ++unsigned long x86_efi_facility; ++ ++/* ++ * Returns 1 if 'facility' is enabled, 0 otherwise. ++ */ ++int efi_enabled(int facility) ++{ ++ return test_bit(facility, &x86_efi_facility) != 0; + } ++EXPORT_SYMBOL(efi_enabled); + + static int __init setup_noefi(char *arg) + { +- efi_enabled = 0; ++ clear_bit(EFI_BOOT, &x86_efi_facility); + return 0; + } + early_param("noefi", setup_noefi); +@@ -426,6 +432,7 @@ void __init efi_reserve_boot_services(vo + + void __init efi_unmap_memmap(void) + { ++ clear_bit(EFI_MEMMAP, &x86_efi_facility); + if (memmap.map) { + early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); + memmap.map = NULL; +@@ -460,7 +467,7 @@ void __init efi_free_boot_services(void) + + static int __init efi_systab_init(void *phys) + { +- if (efi_64bit) { ++ if (efi_enabled(EFI_64BIT)) { + efi_system_table_64_t *systab64; + u64 tmp = 0; + +@@ -552,7 +559,7 @@ static int __init efi_config_init(u64 ta + void *config_tables, *tablep; + int i, sz; + +- if (efi_64bit) ++ if (efi_enabled(EFI_64BIT)) + sz = sizeof(efi_config_table_64_t); + else + sz = sizeof(efi_config_table_32_t); +@@ -572,7 +579,7 @@ static int __init efi_config_init(u64 ta + efi_guid_t guid; + unsigned long table; + +- if (efi_64bit) { ++ if (efi_enabled(EFI_64BIT)) { + u64 table64; + guid = ((efi_config_table_64_t *)tablep)->guid; + table64 = ((efi_config_table_64_t *)tablep)->table; +@@ -684,7 +691,6 @@ void __init efi_init(void) + if (boot_params.efi_info.efi_systab_hi || + boot_params.efi_info.efi_memmap_hi) { + pr_info("Table located above 4GB, disabling EFI.\n"); +- efi_enabled = 0; + return; + } + efi_phys.systab = (efi_system_table_t *)boot_params.efi_info.efi_systab; +@@ -694,10 +700,10 @@ void __init efi_init(void) + ((__u64)boot_params.efi_info.efi_systab_hi<<32)); + #endif + +- if (efi_systab_init(efi_phys.systab)) { +- efi_enabled = 0; ++ if (efi_systab_init(efi_phys.systab)) + return; +- } ++ ++ set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); + + /* + * Show what we know for posterity +@@ -715,10 +721,10 @@ void __init efi_init(void) + efi.systab->hdr.revision >> 16, + efi.systab->hdr.revision & 0xffff, vendor); + +- if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) { +- efi_enabled = 0; ++ if (efi_config_init(efi.systab->tables, efi.systab->nr_tables)) + return; +- } ++ ++ set_bit(EFI_CONFIG_TABLES, &x86_efi_facility); + + /* + * Note: We currently don't support runtime services on an EFI +@@ -727,15 +733,17 @@ void __init efi_init(void) + + if (!efi_is_native()) + pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); +- else if (efi_runtime_init()) { +- efi_enabled = 0; +- return; ++ else { ++ if (efi_runtime_init()) ++ return; ++ set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility); + } + +- if (efi_memmap_init()) { +- efi_enabled = 0; ++ if (efi_memmap_init()) + return; +- } ++ ++ set_bit(EFI_MEMMAP, &x86_efi_facility); ++ + #ifdef CONFIG_X86_32 + if (efi_is_native()) { + x86_platform.get_wallclock = efi_get_time; +@@ -969,6 +977,9 @@ u32 efi_mem_type(unsigned long phys_addr + efi_memory_desc_t *md; + void *p; + ++ if (!efi_enabled(EFI_MEMMAP)) ++ return 0; ++ + for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { + md = p; + if ((md->phys_addr <= phys_addr) && +--- a/drivers/acpi/osl.c ++++ b/drivers/acpi/osl.c +@@ -250,7 +250,7 @@ acpi_physical_address __init acpi_os_get + return acpi_rsdp; + #endif + +- if (efi_enabled) { ++ if (efi_enabled(EFI_CONFIG_TABLES)) { + if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) + return efi.acpi20; + else if (efi.acpi != EFI_INVALID_TABLE_ADDR) +--- a/drivers/firmware/dmi_scan.c ++++ b/drivers/firmware/dmi_scan.c +@@ -471,7 +471,7 @@ void __init dmi_scan_machine(void) + char __iomem *p, *q; + int rc; + +- if (efi_enabled) { ++ if (efi_enabled(EFI_CONFIG_TABLES)) { + if (efi.smbios == EFI_INVALID_TABLE_ADDR) + goto error; + +--- a/drivers/firmware/efivars.c ++++ b/drivers/firmware/efivars.c +@@ -1224,7 +1224,7 @@ efivars_init(void) + printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, + EFIVARS_DATE); + +- if (!efi_enabled) ++ if (!efi_enabled(EFI_RUNTIME_SERVICES)) + return 0; + + /* For now we'll register the efi directory at /sys/firmware/efi */ +@@ -1262,7 +1262,7 @@ err_put: + static void __exit + efivars_exit(void) + { +- if (efi_enabled) { ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) { + unregister_efivars(&__efivars); + kobject_put(efi_kobj); + } +--- a/drivers/firmware/iscsi_ibft_find.c ++++ b/drivers/firmware/iscsi_ibft_find.c +@@ -99,7 +99,7 @@ unsigned long __init find_ibft_region(un + /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will + * only use ACPI for this */ + +- if (!efi_enabled) ++ if (!efi_enabled(EFI_BOOT)) + find_ibft_in_mem(); + + if (ibft_addr) { +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -429,7 +429,8 @@ bool radeon_card_posted(struct radeon_de + { + uint32_t reg; + +- if (efi_enabled && rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) ++ if (efi_enabled(EFI_BOOT) && ++ rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) + return false; + + /* first check CRTCs */ +--- a/drivers/platform/x86/ibm_rtl.c ++++ b/drivers/platform/x86/ibm_rtl.c +@@ -244,7 +244,7 @@ static int __init ibm_rtl_init(void) { + if (force) + pr_warn("module loaded by force\n"); + /* first ensure that we are running on IBM HW */ +- else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table)) ++ else if (efi_enabled(EFI_BOOT) || !dmi_check_system(ibm_rtl_dmi_table)) + return -ENODEV; + + /* Get the address for the Extended BIOS Data Area */ +--- a/drivers/scsi/isci/init.c ++++ b/drivers/scsi/isci/init.c +@@ -633,7 +633,7 @@ static int __devinit isci_pci_probe(stru + return -ENOMEM; + pci_set_drvdata(pdev, pci_info); + +- if (efi_enabled) ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) + orom = isci_get_efi_var(pdev); + + if (!orom) +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -542,18 +542,30 @@ extern int __init efi_setup_pcdp_console + #endif + + /* +- * We play games with efi_enabled so that the compiler will, if possible, remove +- * EFI-related code altogether. ++ * We play games with efi_enabled so that the compiler will, if ++ * possible, remove EFI-related code altogether. + */ ++#define EFI_BOOT 0 /* Were we booted from EFI? */ ++#define EFI_SYSTEM_TABLES 1 /* Can we use EFI system tables? */ ++#define EFI_CONFIG_TABLES 2 /* Can we use EFI config tables? */ ++#define EFI_RUNTIME_SERVICES 3 /* Can we use runtime services? */ ++#define EFI_MEMMAP 4 /* Can we use EFI memory map? */ ++#define EFI_64BIT 5 /* Is the firmware 64-bit? */ ++ + #ifdef CONFIG_EFI + # ifdef CONFIG_X86 +- extern int efi_enabled; +- extern bool efi_64bit; ++extern int efi_enabled(int facility); + # else +-# define efi_enabled 1 ++static inline int efi_enabled(int facility) ++{ ++ return 1; ++} + # endif + #else +-# define efi_enabled 0 ++static inline int efi_enabled(int facility) ++{ ++ return 0; ++} + #endif + + /* +--- a/init/main.c ++++ b/init/main.c +@@ -604,7 +604,7 @@ asmlinkage void __init start_kernel(void + pidmap_init(); + anon_vma_init(); + #ifdef CONFIG_X86 +- if (efi_enabled) ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) + efi_enter_virtual_mode(); + #endif + thread_info_cache_init(); +@@ -632,7 +632,7 @@ asmlinkage void __init start_kernel(void + acpi_early_init(); /* before LAPIC and SMP init */ + sfi_init_late(); + +- if (efi_enabled) { ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) { + efi_late_init(); + efi_free_boot_services(); + } diff --git a/queue-3.7/hid-usbhid-quirk-for-formosa-ir-receiver.patch b/queue-3.7/hid-usbhid-quirk-for-formosa-ir-receiver.patch new file mode 100644 index 00000000000..ac84772645c --- /dev/null +++ b/queue-3.7/hid-usbhid-quirk-for-formosa-ir-receiver.patch @@ -0,0 +1,47 @@ +From 320cde19a4e8f122b19d2df7a5c00636e11ca3fb Mon Sep 17 00:00:00 2001 +From: Nicholas Santos +Date: Fri, 28 Dec 2012 22:07:02 -0500 +Subject: HID: usbhid: quirk for Formosa IR receiver + +From: Nicholas Santos + +commit 320cde19a4e8f122b19d2df7a5c00636e11ca3fb upstream. + +Patch to add the Formosa Industrial Computing, Inc. Infrared Receiver +[IR605A/Q] to hid-ids.h and hid-quirks.c. This IR receiver causes about a 10 +second timeout when the usbhid driver attempts to initialze the device. Adding +this device to the quirks list with HID_QUIRK_NO_INIT_REPORTS removes the +delay. + +Signed-off-by: Nicholas Santos +[jkosina@suse.cz: fix ordering] +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-ids.h | 3 +++ + drivers/hid/usbhid/hid-quirks.c | 1 + + 2 files changed, 4 insertions(+) + +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -305,6 +305,9 @@ + #define USB_VENDOR_ID_EZKEY 0x0518 + #define USB_DEVICE_ID_BTC_8193 0x0002 + ++#define USB_VENDOR_ID_FORMOSA 0x147a ++#define USB_DEVICE_ID_FORMOSA_IR_RECEIVER 0xe03e ++ + #define USB_VENDOR_ID_FREESCALE 0x15A2 + #define USB_DEVICE_ID_FREESCALE_MX28 0x004F + +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -70,6 +70,7 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, ++ { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, diff --git a/queue-3.7/nfs-don-t-silently-fail-setattr-requests-on-mountpoints.patch b/queue-3.7/nfs-don-t-silently-fail-setattr-requests-on-mountpoints.patch new file mode 100644 index 00000000000..85adfa455f7 --- /dev/null +++ b/queue-3.7/nfs-don-t-silently-fail-setattr-requests-on-mountpoints.patch @@ -0,0 +1,61 @@ +From ab225417825963b6dc66be7ea80f94ac1378dfdf Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Tue, 22 Jan 2013 00:17:06 -0500 +Subject: NFS: Don't silently fail setattr() requests on mountpoints + +From: Trond Myklebust + +commit ab225417825963b6dc66be7ea80f94ac1378dfdf upstream. + +Ensure that any setattr and getattr requests for junctions and/or +mountpoints are sent to the server. Ever since commit +0ec26fd0698 (vfs: automount should ignore LOOKUP_FOLLOW), we have +silently dropped any setattr requests to a server-side mountpoint. +For referrals, we have silently dropped both getattr and setattr +requests. + +This patch restores the original behaviour for setattr on mountpoints, +and tries to do the same for referrals, provided that we have a +filehandle... + +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/namespace.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/fs/nfs/namespace.c ++++ b/fs/nfs/namespace.c +@@ -177,11 +177,31 @@ out_nofree: + return mnt; + } + ++static int ++nfs_namespace_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) ++{ ++ if (NFS_FH(dentry->d_inode)->size != 0) ++ return nfs_getattr(mnt, dentry, stat); ++ generic_fillattr(dentry->d_inode, stat); ++ return 0; ++} ++ ++static int ++nfs_namespace_setattr(struct dentry *dentry, struct iattr *attr) ++{ ++ if (NFS_FH(dentry->d_inode)->size != 0) ++ return nfs_setattr(dentry, attr); ++ return -EACCES; ++} ++ + const struct inode_operations nfs_mountpoint_inode_operations = { + .getattr = nfs_getattr, ++ .setattr = nfs_setattr, + }; + + const struct inode_operations nfs_referral_inode_operations = { ++ .getattr = nfs_namespace_getattr, ++ .setattr = nfs_namespace_setattr, + }; + + static void nfs_expire_automounts(struct work_struct *work) diff --git a/queue-3.7/nfs-fix-error-reporting-in-nfs_xdev_mount.patch b/queue-3.7/nfs-fix-error-reporting-in-nfs_xdev_mount.patch new file mode 100644 index 00000000000..e495aeea6f4 --- /dev/null +++ b/queue-3.7/nfs-fix-error-reporting-in-nfs_xdev_mount.patch @@ -0,0 +1,64 @@ +From dee972b967ae111ad5705733de17a3bfc4632311 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Wed, 16 Jan 2013 15:05:44 -0500 +Subject: NFS: Fix error reporting in nfs_xdev_mount + +From: Trond Myklebust + +commit dee972b967ae111ad5705733de17a3bfc4632311 upstream. + +Currently, nfs_xdev_mount converts all errors from clone_server() to +ENOMEM, which can then leak to userspace (for instance to 'mount'). Fix that. +Also ensure that if nfs_fs_mount_common() returns an error, we +don't dprintk(0)... + +The regression originated in commit 3d176e3fe4f6dc379b252bf43e2e146a8f7caf01 +(NFS: Use nfs_fs_mount_common() for xdev mounts) + +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/super.c | 24 ++++++++++-------------- + 1 file changed, 10 insertions(+), 14 deletions(-) + +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -2576,27 +2576,23 @@ nfs_xdev_mount(struct file_system_type * + struct nfs_server *server; + struct dentry *mntroot = ERR_PTR(-ENOMEM); + struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod; +- int error; + +- dprintk("--> nfs_xdev_mount_common()\n"); ++ dprintk("--> nfs_xdev_mount()\n"); + + mount_info.mntfh = mount_info.cloned->fh; + + /* create a new volume representation */ + server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); +- if (IS_ERR(server)) { +- error = PTR_ERR(server); +- goto out_err; +- } +- +- mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, nfs_mod); +- dprintk("<-- nfs_xdev_mount_common() = 0\n"); +-out: +- return mntroot; + +-out_err: +- dprintk("<-- nfs_xdev_mount_common() = %d [error]\n", error); +- goto out; ++ if (IS_ERR(server)) ++ mntroot = ERR_CAST(server); ++ else ++ mntroot = nfs_fs_mount_common(server, flags, ++ dev_name, &mount_info, nfs_mod); ++ ++ dprintk("<-- nfs_xdev_mount() = %ld\n", ++ IS_ERR(mntroot) ? PTR_ERR(mntroot) : 0L); ++ return mntroot; + } + + #if IS_ENABLED(CONFIG_NFS_V4) diff --git a/queue-3.7/nfsv4-fix-nfsv4-reference-counting-for-trunked-sessions.patch b/queue-3.7/nfsv4-fix-nfsv4-reference-counting-for-trunked-sessions.patch new file mode 100644 index 00000000000..d1a3683ca85 --- /dev/null +++ b/queue-3.7/nfsv4-fix-nfsv4-reference-counting-for-trunked-sessions.patch @@ -0,0 +1,105 @@ +From 4ae19c2dd713edb7b8ad3d4ab9d234ed5dcb6b98 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 18 Jan 2013 22:41:53 -0500 +Subject: NFSv4: Fix NFSv4 reference counting for trunked sessions + +From: Trond Myklebust + +commit 4ae19c2dd713edb7b8ad3d4ab9d234ed5dcb6b98 upstream. + +The reference counting in nfs4_init_client assumes wongly that it +is safe for nfs4_discover_server_trunking() to return a pointer to a +nfs_client prior to bumping the reference count. + +Signed-off-by: Trond Myklebust +Cc: Chuck Lever +Cc: Ben Greear +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4client.c | 31 +++++++++++++++---------------- + 1 file changed, 15 insertions(+), 16 deletions(-) + +--- a/fs/nfs/nfs4client.c ++++ b/fs/nfs/nfs4client.c +@@ -235,11 +235,10 @@ struct nfs_client *nfs4_init_client(stru + error = nfs4_discover_server_trunking(clp, &old); + if (error < 0) + goto error; ++ nfs_put_client(clp); + if (clp != old) { + clp->cl_preserve_clid = true; +- nfs_put_client(clp); + clp = old; +- atomic_inc(&clp->cl_count); + } + + return clp; +@@ -305,7 +304,7 @@ int nfs40_walk_client_list(struct nfs_cl + .clientid = new->cl_clientid, + .confirm = new->cl_confirm, + }; +- int status; ++ int status = -NFS4ERR_STALE_CLIENTID; + + spin_lock(&nn->nfs_client_lock); + list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { +@@ -331,28 +330,28 @@ int nfs40_walk_client_list(struct nfs_cl + + if (prev) + nfs_put_client(prev); ++ prev = pos; + + status = nfs4_proc_setclientid_confirm(pos, &clid, cred); +- if (status == 0) { ++ switch (status) { ++ case -NFS4ERR_STALE_CLIENTID: ++ break; ++ case 0: + nfs4_swap_callback_idents(pos, new); + +- nfs_put_client(pos); ++ prev = NULL; + *result = pos; + dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", + __func__, pos, atomic_read(&pos->cl_count)); +- return 0; +- } +- if (status != -NFS4ERR_STALE_CLIENTID) { +- nfs_put_client(pos); +- dprintk("NFS: <-- %s status = %d, no result\n", +- __func__, status); +- return status; ++ default: ++ goto out; + } + + spin_lock(&nn->nfs_client_lock); +- prev = pos; + } ++ spin_unlock(&nn->nfs_client_lock); + ++out: + /* + * No matching nfs_client found. This should be impossible, + * because the new nfs_client has already been added to +@@ -362,9 +361,8 @@ int nfs40_walk_client_list(struct nfs_cl + */ + if (prev) + nfs_put_client(prev); +- spin_unlock(&nn->nfs_client_lock); +- pr_err("NFS: %s Error: no matching nfs_client found\n", __func__); +- return -NFS4ERR_STALE_CLIENTID; ++ dprintk("NFS: <-- %s status = %d\n", __func__, status); ++ return status; + } + + #ifdef CONFIG_NFS_V4_1 +@@ -472,6 +470,7 @@ int nfs41_walk_client_list(struct nfs_cl + if (!nfs4_match_serverowners(pos, new)) + continue; + ++ atomic_inc(&pos->cl_count); + spin_unlock(&nn->nfs_client_lock); + dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n", + __func__, pos, atomic_read(&pos->cl_count)); diff --git a/queue-3.7/nfsv4-fix-nfsv4-trunking-discovery.patch b/queue-3.7/nfsv4-fix-nfsv4-trunking-discovery.patch new file mode 100644 index 00000000000..e643c2eecd3 --- /dev/null +++ b/queue-3.7/nfsv4-fix-nfsv4-trunking-discovery.patch @@ -0,0 +1,112 @@ +From 202c312dba7d95b96493b412c606163a0cd83984 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 18 Jan 2013 22:56:23 -0500 +Subject: NFSv4: Fix NFSv4 trunking discovery + +From: Trond Myklebust + +commit 202c312dba7d95b96493b412c606163a0cd83984 upstream. + +If walking the list in nfs4[01]_walk_client_list fails, then the most +likely explanation is that the server dropped the clientid before we +actually managed to confirm it. As long as our nfs_client is the very +last one in the list to be tested, the caller can be assured that this +is the case when the final return value is NFS4ERR_STALE_CLIENTID. + +Reported-by: Ben Greear +Signed-off-by: Trond Myklebust +Cc: Chuck Lever +Tested-by: Ben Greear +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4client.c | 26 +++++++------------------- + fs/nfs/nfs4state.c | 8 ++------ + 2 files changed, 9 insertions(+), 25 deletions(-) + +--- a/fs/nfs/nfs4client.c ++++ b/fs/nfs/nfs4client.c +@@ -351,14 +351,8 @@ int nfs40_walk_client_list(struct nfs_cl + } + spin_unlock(&nn->nfs_client_lock); + ++ /* No match found. The server lost our clientid */ + out: +- /* +- * No matching nfs_client found. This should be impossible, +- * because the new nfs_client has already been added to +- * nfs_client_list by nfs_get_client(). +- * +- * Don't BUG(), since the caller is holding a mutex. +- */ + if (prev) + nfs_put_client(prev); + dprintk("NFS: <-- %s status = %d\n", __func__, status); +@@ -429,7 +423,7 @@ int nfs41_walk_client_list(struct nfs_cl + { + struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id); + struct nfs_client *pos, *n, *prev = NULL; +- int error; ++ int status = -NFS4ERR_STALE_CLIENTID; + + spin_lock(&nn->nfs_client_lock); + list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) { +@@ -445,8 +439,8 @@ int nfs41_walk_client_list(struct nfs_cl + nfs_put_client(prev); + prev = pos; + +- error = nfs_wait_client_init_complete(pos); +- if (error < 0) { ++ status = nfs_wait_client_init_complete(pos); ++ if (status < 0) { + nfs_put_client(pos); + spin_lock(&nn->nfs_client_lock); + continue; +@@ -479,16 +473,10 @@ int nfs41_walk_client_list(struct nfs_cl + return 0; + } + +- /* +- * No matching nfs_client found. This should be impossible, +- * because the new nfs_client has already been added to +- * nfs_client_list by nfs_get_client(). +- * +- * Don't BUG(), since the caller is holding a mutex. +- */ ++ /* No matching nfs_client found. */ + spin_unlock(&nn->nfs_client_lock); +- pr_err("NFS: %s Error: no matching nfs_client found\n", __func__); +- return -NFS4ERR_STALE_CLIENTID; ++ dprintk("NFS: <-- %s status = %d\n", __func__, status); ++ return status; + } + #endif /* CONFIG_NFS_V4_1 */ + +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -136,16 +136,11 @@ int nfs40_discover_server_trunking(struc + clp->cl_confirm = clid.confirm; + + status = nfs40_walk_client_list(clp, result, cred); +- switch (status) { +- case -NFS4ERR_STALE_CLIENTID: +- set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state); +- case 0: ++ if (status == 0) { + /* Sustain the lease, even if it's empty. If the clientid4 + * goes stale it's of no use for trunking discovery. */ + nfs4_schedule_state_renewal(*result); +- break; + } +- + out: + return status; + } +@@ -1850,6 +1845,7 @@ again: + case -ETIMEDOUT: + case -EAGAIN: + ssleep(1); ++ case -NFS4ERR_STALE_CLIENTID: + dprintk("NFS: %s after status %d, retrying\n", + __func__, status); + goto again; diff --git a/queue-3.7/nfsv4.1-ensure-that-nfs41_walk_client_list-does-start-lease-recovery.patch b/queue-3.7/nfsv4.1-ensure-that-nfs41_walk_client_list-does-start-lease-recovery.patch new file mode 100644 index 00000000000..4d134dd7f3a --- /dev/null +++ b/queue-3.7/nfsv4.1-ensure-that-nfs41_walk_client_list-does-start-lease-recovery.patch @@ -0,0 +1,42 @@ +From 65436ec0c8e344d9b23302b686e418f2a7b7cf7b Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 18 Jan 2013 23:01:43 -0500 +Subject: NFSv4.1: Ensure that nfs41_walk_client_list() does start lease recovery + +From: Trond Myklebust + +commit 65436ec0c8e344d9b23302b686e418f2a7b7cf7b upstream. + +We do need to start the lease recovery thread prior to waiting for the +client initialisation to complete in NFSv4.1. + +Signed-off-by: Trond Myklebust +Cc: Chuck Lever +Cc: Ben Greear +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4client.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/nfs/nfs4client.c ++++ b/fs/nfs/nfs4client.c +@@ -439,14 +439,17 @@ int nfs41_walk_client_list(struct nfs_cl + nfs_put_client(prev); + prev = pos; + ++ nfs4_schedule_lease_recovery(pos); + status = nfs_wait_client_init_complete(pos); + if (status < 0) { + nfs_put_client(pos); + spin_lock(&nn->nfs_client_lock); + continue; + } +- ++ status = pos->cl_cons_state; + spin_lock(&nn->nfs_client_lock); ++ if (status < 0) ++ continue; + } + + if (pos->rpc_ops != new->rpc_ops) diff --git a/queue-3.7/nfsv4.1-handle-nfs4err_delay-when-resetting-the-nfsv4.1-session.patch b/queue-3.7/nfsv4.1-handle-nfs4err_delay-when-resetting-the-nfsv4.1-session.patch new file mode 100644 index 00000000000..7238b93feed --- /dev/null +++ b/queue-3.7/nfsv4.1-handle-nfs4err_delay-when-resetting-the-nfsv4.1-session.patch @@ -0,0 +1,46 @@ +From c489ee290bdbbace6bb63ebe6ebd4dd605819495 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Wed, 30 Jan 2013 13:04:10 -0500 +Subject: NFSv4.1: Handle NFS4ERR_DELAY when resetting the NFSv4.1 session + +From: Trond Myklebust + +commit c489ee290bdbbace6bb63ebe6ebd4dd605819495 upstream. + +NFS4ERR_DELAY is a legal reply when we call DESTROY_SESSION. It +usually means that the server is busy handling an unfinished RPC +request. Just sleep for a second and then retry. +We also need to be able to handle the NFS4ERR_BACK_CHAN_BUSY return +value. If the NFS server has outstanding callbacks, we just want to +similarly sleep & retry. + +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4state.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/fs/nfs/nfs4state.c ++++ b/fs/nfs/nfs4state.c +@@ -1997,8 +1997,18 @@ static int nfs4_reset_session(struct nfs + nfs4_begin_drain_session(clp); + cred = nfs4_get_exchange_id_cred(clp); + status = nfs4_proc_destroy_session(clp->cl_session, cred); +- if (status && status != -NFS4ERR_BADSESSION && +- status != -NFS4ERR_DEADSESSION) { ++ switch (status) { ++ case 0: ++ case -NFS4ERR_BADSESSION: ++ case -NFS4ERR_DEADSESSION: ++ break; ++ case -NFS4ERR_BACK_CHAN_BUSY: ++ case -NFS4ERR_DELAY: ++ set_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state); ++ status = 0; ++ ssleep(1); ++ goto out; ++ default: + status = nfs4_recovery_handle_error(clp, status); + goto out; + } diff --git a/queue-3.7/samsung-laptop-disable-on-efi-hardware.patch b/queue-3.7/samsung-laptop-disable-on-efi-hardware.patch new file mode 100644 index 00000000000..e966a52a284 --- /dev/null +++ b/queue-3.7/samsung-laptop-disable-on-efi-hardware.patch @@ -0,0 +1,55 @@ +From e0094244e41c4d0c7ad69920681972fc45d8ce34 Mon Sep 17 00:00:00 2001 +From: Matt Fleming +Date: Thu, 3 Jan 2013 09:02:37 +0000 +Subject: samsung-laptop: Disable on EFI hardware + +From: Matt Fleming + +commit e0094244e41c4d0c7ad69920681972fc45d8ce34 upstream. + +It has been reported that running this driver on some Samsung laptops +with EFI can cause those machines to become bricked as detailed in the +following report, + + https://bugs.launchpad.net/ubuntu-cdimage/+bug/1040557 + +There have also been reports of this driver causing Machine Check +Exceptions on recent EFI-enabled Samsung laptops, + + https://bugzilla.kernel.org/show_bug.cgi?id=47121 + +So disable it if booting from EFI since this driver relies on +grovelling around in the BIOS memory map which isn't going to work. + +Signed-off-by: Matt Fleming +Cc: Corentin Chary +Cc: Matthew Garrett +Cc: Colin Ian King +Cc: Steve Langasek +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/samsung-laptop.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/platform/x86/samsung-laptop.c ++++ b/drivers/platform/x86/samsung-laptop.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + #include + + /* +@@ -1544,6 +1545,9 @@ static int __init samsung_init(void) + struct samsung_laptop *samsung; + int ret; + ++ if (efi_enabled(EFI_BOOT)) ++ return -ENODEV; ++ + quirks = &samsung_unknown; + if (!force && !dmi_check_system(samsung_dmi_table)) + return -ENODEV; diff --git a/queue-3.7/series b/queue-3.7/series index 98d9f9e4606..e37e6d2a8c6 100644 --- a/queue-3.7/series +++ b/queue-3.7/series @@ -50,3 +50,14 @@ asoc-arizona-use-actual-rather-than-desired-bclk-when-calculating-lrclk.patch asoc-wm2200-correct-mixer-values-and-text.patch bluetooth-fix-incorrect-strncpy-in-hidp_setup_hid.patch iommu-intel-disable-dmar-for-g4x-integrated-gfx.patch +nfs-fix-error-reporting-in-nfs_xdev_mount.patch +nfs-don-t-silently-fail-setattr-requests-on-mountpoints.patch +nfsv4-fix-nfsv4-reference-counting-for-trunked-sessions.patch +nfsv4-fix-nfsv4-trunking-discovery.patch +nfsv4.1-ensure-that-nfs41_walk_client_list-does-start-lease-recovery.patch +nfsv4.1-handle-nfs4err_delay-when-resetting-the-nfsv4.1-session.patch +hid-usbhid-quirk-for-formosa-ir-receiver.patch +smp-fix-smp-function-call-empty-cpu-mask-race.patch +x86-msr-add-capabilities-check.patch +efi-make-efi_enabled-a-function-to-query-efi-facilities.patch +samsung-laptop-disable-on-efi-hardware.patch diff --git a/queue-3.7/smp-fix-smp-function-call-empty-cpu-mask-race.patch b/queue-3.7/smp-fix-smp-function-call-empty-cpu-mask-race.patch new file mode 100644 index 00000000000..b7426a756a4 --- /dev/null +++ b/queue-3.7/smp-fix-smp-function-call-empty-cpu-mask-race.patch @@ -0,0 +1,101 @@ +From f44310b98ddb7f0d06550d73ed67df5865e3eda5 Mon Sep 17 00:00:00 2001 +From: Wang YanQing +Date: Sat, 26 Jan 2013 15:53:57 +0800 +Subject: smp: Fix SMP function call empty cpu mask race + +From: Wang YanQing + +commit f44310b98ddb7f0d06550d73ed67df5865e3eda5 upstream. + +I get the following warning every day with v3.7, once or +twice a day: + + [ 2235.186027] WARNING: at /mnt/sda7/kernel/linux/arch/x86/kernel/apic/ipi.c:109 default_send_IPI_mask_logical+0x2f/0xb8() + +As explained by Linus as well: + + | + | Once we've done the "list_add_rcu()" to add it to the + | queue, we can have (another) IPI to the target CPU that can + | now see it and clear the mask. + | + | So by the time we get to actually send the IPI, the mask might + | have been cleared by another IPI. + | + +This patch also fixes a system hang problem, if the data->cpumask +gets cleared after passing this point: + + if (WARN_ONCE(!mask, "empty IPI mask")) + return; + +then the problem in commit 83d349f35e1a ("x86: don't send an IPI to +the empty set of CPU's") will happen again. + +Signed-off-by: Wang YanQing +Acked-by: Linus Torvalds +Acked-by: Jan Beulich +Cc: Paul E. McKenney +Cc: Andrew Morton +Cc: peterz@infradead.org +Cc: mina86@mina86.org +Cc: srivatsa.bhat@linux.vnet.ibm.com +Link: http://lkml.kernel.org/r/20130126075357.GA3205@udknight +[ Tidied up the changelog and the comment in the code. ] +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/smp.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/kernel/smp.c ++++ b/kernel/smp.c +@@ -33,6 +33,7 @@ struct call_function_data { + struct call_single_data csd; + atomic_t refs; + cpumask_var_t cpumask; ++ cpumask_var_t cpumask_ipi; + }; + + static DEFINE_PER_CPU_SHARED_ALIGNED(struct call_function_data, cfd_data); +@@ -56,6 +57,9 @@ hotplug_cfd(struct notifier_block *nfb, + if (!zalloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL, + cpu_to_node(cpu))) + return notifier_from_errno(-ENOMEM); ++ if (!zalloc_cpumask_var_node(&cfd->cpumask_ipi, GFP_KERNEL, ++ cpu_to_node(cpu))) ++ return notifier_from_errno(-ENOMEM); + break; + + #ifdef CONFIG_HOTPLUG_CPU +@@ -65,6 +69,7 @@ hotplug_cfd(struct notifier_block *nfb, + case CPU_DEAD: + case CPU_DEAD_FROZEN: + free_cpumask_var(cfd->cpumask); ++ free_cpumask_var(cfd->cpumask_ipi); + break; + #endif + }; +@@ -526,6 +531,12 @@ void smp_call_function_many(const struct + return; + } + ++ /* ++ * After we put an entry into the list, data->cpumask ++ * may be cleared again when another CPU sends another IPI for ++ * a SMP function call, so data->cpumask will be zero. ++ */ ++ cpumask_copy(data->cpumask_ipi, data->cpumask); + raw_spin_lock_irqsave(&call_function.lock, flags); + /* + * Place entry at the _HEAD_ of the list, so that any cpu still +@@ -549,7 +560,7 @@ void smp_call_function_many(const struct + smp_mb(); + + /* Send a message to all CPUs in the map */ +- arch_send_call_function_ipi_mask(data->cpumask); ++ arch_send_call_function_ipi_mask(data->cpumask_ipi); + + /* Optionally wait for the CPUs to complete */ + if (wait) diff --git a/queue-3.7/x86-msr-add-capabilities-check.patch b/queue-3.7/x86-msr-add-capabilities-check.patch new file mode 100644 index 00000000000..0e6aea0cea0 --- /dev/null +++ b/queue-3.7/x86-msr-add-capabilities-check.patch @@ -0,0 +1,52 @@ +From c903f0456bc69176912dee6dd25c6a66ee1aed00 Mon Sep 17 00:00:00 2001 +From: Alan Cox +Date: Thu, 15 Nov 2012 13:06:22 +0000 +Subject: x86/msr: Add capabilities check + +From: Alan Cox + +commit c903f0456bc69176912dee6dd25c6a66ee1aed00 upstream. + +At the moment the MSR driver only relies upon file system +checks. This means that anything as root with any capability set +can write to MSRs. Historically that wasn't very interesting but +on modern processors the MSRs are such that writing to them +provides several ways to execute arbitary code in kernel space. +Sample code and documentation on doing this is circulating and +MSR attacks are used on Windows 64bit rootkits already. + +In the Linux case you still need to be able to open the device +file so the impact is fairly limited and reduces the security of +some capability and security model based systems down towards +that of a generic "root owns the box" setup. + +Therefore they should require CAP_SYS_RAWIO to prevent an +elevation of capabilities. The impact of this is fairly minimal +on most setups because they don't have heavy use of +capabilities. Those using SELinux, SMACK or AppArmor rules might +want to consider if their rulesets on the MSR driver could be +tighter. + +Signed-off-by: Alan Cox +Cc: Linus Torvalds +Cc: Andrew Morton +Cc: Peter Zijlstra +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/msr.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/x86/kernel/msr.c ++++ b/arch/x86/kernel/msr.c +@@ -174,6 +174,9 @@ static int msr_open(struct inode *inode, + unsigned int cpu; + struct cpuinfo_x86 *c; + ++ if (!capable(CAP_SYS_RAWIO)) ++ return -EPERM; ++ + cpu = iminor(file->f_path.dentry->d_inode); + if (cpu >= nr_cpu_ids || !cpu_online(cpu)) + return -ENXIO; /* No such CPU */ -- 2.47.3