--- /dev/null
+From 83e68189745ad931c2afd45d8ee3303929233e7f Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Wed, 14 Nov 2012 09:42:35 +0000
+Subject: efi: Make 'efi_enabled' a function to query EFI facilities
+
+From: Matt Fleming <matt.fleming@intel.com>
+
+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 <matt.fleming@intel.com>
+Cc: David Airlie <airlied@linux.ie>
+Cc: Corentin Chary <corentincj@iksaif.net>
+Cc: Matthew Garrett <mjg59@srcf.ucam.org>
+Cc: Dave Jiang <dave.jiang@intel.com>
+Cc: Olof Johansson <olof@lixom.net>
+Cc: Peter Jones <pjones@redhat.com>
+Cc: Colin Ian King <colin.king@canonical.com>
+Cc: Steve Langasek <steve.langasek@canonical.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: Konrad Rzeszutek Wilk <konrad@kernel.org>
+Cc: Rafael J. Wysocki <rjw@sisk.pl>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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();
+ }
--- /dev/null
+From 320cde19a4e8f122b19d2df7a5c00636e11ca3fb Mon Sep 17 00:00:00 2001
+From: Nicholas Santos <nicholas.santos@gmail.com>
+Date: Fri, 28 Dec 2012 22:07:02 -0500
+Subject: HID: usbhid: quirk for Formosa IR receiver
+
+From: Nicholas Santos <nicholas.santos@gmail.com>
+
+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 <nicholas.santos@gmail.com>
+[jkosina@suse.cz: fix ordering]
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 },
--- /dev/null
+From ab225417825963b6dc66be7ea80f94ac1378dfdf Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Tue, 22 Jan 2013 00:17:06 -0500
+Subject: NFS: Don't silently fail setattr() requests on mountpoints
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+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 <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)
--- /dev/null
+From dee972b967ae111ad5705733de17a3bfc4632311 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Wed, 16 Jan 2013 15:05:44 -0500
+Subject: NFS: Fix error reporting in nfs_xdev_mount
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+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 <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)
--- /dev/null
+From 4ae19c2dd713edb7b8ad3d4ab9d234ed5dcb6b98 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Fri, 18 Jan 2013 22:41:53 -0500
+Subject: NFSv4: Fix NFSv4 reference counting for trunked sessions
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+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 <Trond.Myklebust@netapp.com>
+Cc: Chuck Lever <chuck.lever@oracle.com>
+Cc: Ben Greear <greearb@candelatech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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));
--- /dev/null
+From 202c312dba7d95b96493b412c606163a0cd83984 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Fri, 18 Jan 2013 22:56:23 -0500
+Subject: NFSv4: Fix NFSv4 trunking discovery
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+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 <greearb@candelatech.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Cc: Chuck Lever <chuck.lever@oracle.com>
+Tested-by: Ben Greear <greearb@candelatech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 65436ec0c8e344d9b23302b686e418f2a7b7cf7b Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+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 <Trond.Myklebust@netapp.com>
+
+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 <Trond.Myklebust@netapp.com>
+Cc: Chuck Lever <chuck.lever@oracle.com>
+Cc: Ben Greear <greearb@candelatech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)
--- /dev/null
+From c489ee290bdbbace6bb63ebe6ebd4dd605819495 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Wed, 30 Jan 2013 13:04:10 -0500
+Subject: NFSv4.1: Handle NFS4ERR_DELAY when resetting the NFSv4.1 session
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+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 <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
--- /dev/null
+From e0094244e41c4d0c7ad69920681972fc45d8ce34 Mon Sep 17 00:00:00 2001
+From: Matt Fleming <matt.fleming@intel.com>
+Date: Thu, 3 Jan 2013 09:02:37 +0000
+Subject: samsung-laptop: Disable on EFI hardware
+
+From: Matt Fleming <matt.fleming@intel.com>
+
+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 <matt.fleming@intel.com>
+Cc: Corentin Chary <corentincj@iksaif.net>
+Cc: Matthew Garrett <mjg59@srcf.ucam.org>
+Cc: Colin Ian King <colin.king@canonical.com>
+Cc: Steve Langasek <steve.langasek@canonical.com>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/seq_file.h>
+ #include <linux/debugfs.h>
+ #include <linux/ctype.h>
++#include <linux/efi.h>
+ #include <acpi/video.h>
+
+ /*
+@@ -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;
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
--- /dev/null
+From f44310b98ddb7f0d06550d73ed67df5865e3eda5 Mon Sep 17 00:00:00 2001
+From: Wang YanQing <udknight@gmail.com>
+Date: Sat, 26 Jan 2013 15:53:57 +0800
+Subject: smp: Fix SMP function call empty cpu mask race
+
+From: Wang YanQing <udknight@gmail.com>
+
+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 <udknight@gmail.com>
+Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
+Acked-by: Jan Beulich <jbeulich@suse.com>
+Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+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 <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)
--- /dev/null
+From c903f0456bc69176912dee6dd25c6a66ee1aed00 Mon Sep 17 00:00:00 2001
+From: Alan Cox <alan@linux.intel.com>
+Date: Thu, 15 Nov 2012 13:06:22 +0000
+Subject: x86/msr: Add capabilities check
+
+From: Alan Cox <alan@linux.intel.com>
+
+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 <alan@linux.intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 */