]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Apr 2018 15:19:44 +0000 (17:19 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Apr 2018 15:19:44 +0000 (17:19 +0200)
added patches:
cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch
lan78xx-correctly-indicate-invalid-otp.patch
slip-check-if-rstate-is-initialized-before-uncompressing.patch
x86-hweight-don-t-clobber-rdi.patch
x86-hweight-get-rid-of-the-special-calling-convention.patch

queue-4.4/cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch [new file with mode: 0644]
queue-4.4/lan78xx-correctly-indicate-invalid-otp.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/slip-check-if-rstate-is-initialized-before-uncompressing.patch [new file with mode: 0644]
queue-4.4/x86-hweight-don-t-clobber-rdi.patch [new file with mode: 0644]
queue-4.4/x86-hweight-get-rid-of-the-special-calling-convention.patch [new file with mode: 0644]

diff --git a/queue-4.4/cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch b/queue-4.4/cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch
new file mode 100644 (file)
index 0000000..8de4db1
--- /dev/null
@@ -0,0 +1,42 @@
+From foo@baz Tue Apr 17 16:59:41 CEST 2018
+From: Bassem Boubaker <bassem.boubaker@actia.fr>
+Date: Wed, 11 Apr 2018 13:15:53 +0200
+Subject: cdc_ether: flag the Cinterion AHS8 modem by gemalto as WWAN
+
+From: Bassem Boubaker <bassem.boubaker@actia.fr>
+
+
+[ Upstream commit 53765341ee821c0a0f1dec41adc89c9096ad694c ]
+
+The Cinterion AHS8 is a 3G device with one embedded WWAN interface
+using cdc_ether as a driver.
+
+The modem is controlled via AT commands through the exposed TTYs.
+
+AT+CGDCONT write command can be used to activate or deactivate a WWAN
+connection for a PDP context defined with the same command. UE
+supports one WWAN adapter.
+
+Signed-off-by: Bassem Boubaker <bassem.boubaker@actia.fr>
+Acked-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/cdc_ether.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/usb/cdc_ether.c
++++ b/drivers/net/usb/cdc_ether.c
+@@ -705,6 +705,12 @@ static const struct usb_device_id produc
+                                     USB_CDC_PROTO_NONE),
+       .driver_info = (unsigned long)&wwan_info,
+ }, {
++      /* Cinterion AHS3 modem by GEMALTO */
++      USB_DEVICE_AND_INTERFACE_INFO(0x1e2d, 0x0055, USB_CLASS_COMM,
++                                    USB_CDC_SUBCLASS_ETHERNET,
++                                    USB_CDC_PROTO_NONE),
++      .driver_info = (unsigned long)&wwan_info,
++}, {
+       /* Telit modules */
+       USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM,
+                       USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
diff --git a/queue-4.4/lan78xx-correctly-indicate-invalid-otp.patch b/queue-4.4/lan78xx-correctly-indicate-invalid-otp.patch
new file mode 100644 (file)
index 0000000..80365de
--- /dev/null
@@ -0,0 +1,35 @@
+From foo@baz Tue Apr 17 16:59:41 CEST 2018
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Wed, 11 Apr 2018 10:59:17 +0100
+Subject: lan78xx: Correctly indicate invalid OTP
+
+From: Phil Elwell <phil@raspberrypi.org>
+
+
+[ Upstream commit 4bfc33807a9a02764bdd1e42e794b3b401240f27 ]
+
+lan78xx_read_otp tries to return -EINVAL in the event of invalid OTP
+content, but the value gets overwritten before it is returned and the
+read goes ahead anyway. Make the read conditional as it should be
+and preserve the error code.
+
+Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver")
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/lan78xx.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/usb/lan78xx.c
++++ b/drivers/net/usb/lan78xx.c
+@@ -618,7 +618,8 @@ static int lan78xx_read_otp(struct lan78
+                       offset += 0x100;
+               else
+                       ret = -EINVAL;
+-              ret = lan78xx_read_raw_otp(dev, offset, length, data);
++              if (!ret)
++                      ret = lan78xx_read_raw_otp(dev, offset, length, data);
+       }
+       return ret;
index 91751703499e95b54ac863c2d0c73c40c40a8328..a3eb87483e15f6029cefb8bd1f57002fc11ddc9a 100644 (file)
@@ -13,3 +13,8 @@ s390-ipl-ensure-loadparm-valid-flag-is-set.patch
 getname_kernel-needs-to-make-sure-that-name-iname-in-long-case.patch
 rtl8187-fix-null-pointer-dereference-in-priv-conf_mutex.patch
 hwmon-ina2xx-fix-access-to-uninitialized-mutex.patch
+cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch
+slip-check-if-rstate-is-initialized-before-uncompressing.patch
+lan78xx-correctly-indicate-invalid-otp.patch
+x86-hweight-get-rid-of-the-special-calling-convention.patch
+x86-hweight-don-t-clobber-rdi.patch
diff --git a/queue-4.4/slip-check-if-rstate-is-initialized-before-uncompressing.patch b/queue-4.4/slip-check-if-rstate-is-initialized-before-uncompressing.patch
new file mode 100644 (file)
index 0000000..bd05c7c
--- /dev/null
@@ -0,0 +1,76 @@
+From foo@baz Tue Apr 17 16:59:41 CEST 2018
+From: Tejaswi Tanikella <tejaswit@codeaurora.org>
+Date: Wed, 11 Apr 2018 16:34:47 +0530
+Subject: slip: Check if rstate is initialized before uncompressing
+
+From: Tejaswi Tanikella <tejaswit@codeaurora.org>
+
+
+[ Upstream commit 3f01ddb962dc506916c243f9524e8bef97119b77 ]
+
+On receiving a packet the state index points to the rstate which must be
+used to fill up IP and TCP headers. But if the state index points to a
+rstate which is unitialized, i.e. filled with zeros, it gets stuck in an
+infinite loop inside ip_fast_csum trying to compute the ip checsum of a
+header with zero length.
+
+89.666953:   <2> [<ffffff9dd3e94d38>] slhc_uncompress+0x464/0x468
+89.666965:   <2> [<ffffff9dd3e87d88>] ppp_receive_nonmp_frame+0x3b4/0x65c
+89.666978:   <2> [<ffffff9dd3e89dd4>] ppp_receive_frame+0x64/0x7e0
+89.666991:   <2> [<ffffff9dd3e8a708>] ppp_input+0x104/0x198
+89.667005:   <2> [<ffffff9dd3e93868>] pppopns_recv_core+0x238/0x370
+89.667027:   <2> [<ffffff9dd4428fc8>] __sk_receive_skb+0xdc/0x250
+89.667040:   <2> [<ffffff9dd3e939e4>] pppopns_recv+0x44/0x60
+89.667053:   <2> [<ffffff9dd4426848>] __sock_queue_rcv_skb+0x16c/0x24c
+89.667065:   <2> [<ffffff9dd4426954>] sock_queue_rcv_skb+0x2c/0x38
+89.667085:   <2> [<ffffff9dd44f7358>] raw_rcv+0x124/0x154
+89.667098:   <2> [<ffffff9dd44f7568>] raw_local_deliver+0x1e0/0x22c
+89.667117:   <2> [<ffffff9dd44c8ba0>] ip_local_deliver_finish+0x70/0x24c
+89.667131:   <2> [<ffffff9dd44c92f4>] ip_local_deliver+0x100/0x10c
+
+./scripts/faddr2line vmlinux slhc_uncompress+0x464/0x468 output:
+ ip_fast_csum at arch/arm64/include/asm/checksum.h:40
+ (inlined by) slhc_uncompress at drivers/net/slip/slhc.c:615
+
+Adding a variable to indicate if the current rstate is initialized. If
+such a packet arrives, move to toss state.
+
+Signed-off-by: Tejaswi Tanikella <tejaswit@codeaurora.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/slip/slhc.c |    5 +++++
+ include/net/slhc_vj.h   |    1 +
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/net/slip/slhc.c
++++ b/drivers/net/slip/slhc.c
+@@ -509,6 +509,10 @@ slhc_uncompress(struct slcompress *comp,
+               if(x < 0 || x > comp->rslot_limit)
+                       goto bad;
++              /* Check if the cstate is initialized */
++              if (!comp->rstate[x].initialized)
++                      goto bad;
++
+               comp->flags &=~ SLF_TOSS;
+               comp->recv_current = x;
+       } else {
+@@ -673,6 +677,7 @@ slhc_remember(struct slcompress *comp, u
+       if (cs->cs_tcp.doff > 5)
+         memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4);
+       cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2;
++      cs->initialized = true;
+       /* Put headers back on packet
+        * Neither header checksum is recalculated
+        */
+--- a/include/net/slhc_vj.h
++++ b/include/net/slhc_vj.h
+@@ -127,6 +127,7 @@ typedef __u32 int32;
+  */
+ struct cstate {
+       byte_t  cs_this;        /* connection id number (xmit) */
++      bool    initialized;    /* true if initialized */
+       struct cstate *next;    /* next in ring (xmit) */
+       struct iphdr cs_ip;     /* ip/tcp hdr from most recent packet */
+       struct tcphdr cs_tcp;
diff --git a/queue-4.4/x86-hweight-don-t-clobber-rdi.patch b/queue-4.4/x86-hweight-don-t-clobber-rdi.patch
new file mode 100644 (file)
index 0000000..29d2f97
--- /dev/null
@@ -0,0 +1,105 @@
+From 65ea11ec6a82b1d44aba62b59e9eb20247e57c6e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Mon, 8 Aug 2016 20:35:29 +0300
+Subject: x86/hweight: Don't clobber %rdi
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ville Syrjälä <ville.syrjala@linux.intel.com>
+
+commit 65ea11ec6a82b1d44aba62b59e9eb20247e57c6e upstream.
+
+The caller expects %rdi to remain intact, push+pop it make that happen.
+
+Fixes the following kind of explosions on my core2duo machine when
+trying to reboot or shut down:
+
+  general protection fault: 0000 [#1] PREEMPT SMP
+  Modules linked in: i915 i2c_algo_bit drm_kms_helper cfbfillrect syscopyarea cfbimgblt sysfillrect sysimgblt fb_sys_fops cfbcopyarea drm netconsole configfs binfmt_misc iTCO_wdt psmouse pcspkr snd_hda_codec_idt e100 coretemp hwmon snd_hda_codec_generic i2c_i801 mii i2c_smbus lpc_ich mfd_core snd_hda_intel uhci_hcd snd_hda_codec snd_hwdep snd_hda_core ehci_pci 8250 ehci_hcd snd_pcm 8250_base usbcore evdev serial_core usb_common parport_pc parport snd_timer snd soundcore
+  CPU: 0 PID: 3070 Comm: reboot Not tainted 4.8.0-rc1-perf-dirty #69
+  Hardware name:                  /D946GZIS, BIOS TS94610J.86A.0087.2007.1107.1049 11/07/2007
+  task: ffff88012a0b4080 task.stack: ffff880123850000
+  RIP: 0010:[<ffffffff81003c92>]  [<ffffffff81003c92>] x86_perf_event_update+0x52/0xc0
+  RSP: 0018:ffff880123853b60  EFLAGS: 00010087
+  RAX: 0000000000000001 RBX: ffff88012fc0a3c0 RCX: 000000000000001e
+  RDX: 0000000000000000 RSI: 0000000040000000 RDI: ffff88012b014800
+  RBP: ffff880123853b88 R08: ffffffffffffffff R09: 0000000000000000
+  R10: ffffea0004a012c0 R11: ffffea0004acedc0 R12: ffffffff80000001
+  R13: ffff88012b0149c0 R14: ffff88012b014800 R15: 0000000000000018
+  FS:  00007f8b155cd700(0000) GS:ffff88012fc00000(0000) knlGS:0000000000000000
+  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+  CR2: 00007f8b155f5000 CR3: 000000012a2d7000 CR4: 00000000000006f0
+  Stack:
+   ffff88012fc0a3c0 ffff88012b014800 0000000000000004 0000000000000001
+   ffff88012fc1b750 ffff880123853bb0 ffffffff81003d59 ffff88012b014800
+   ffff88012fc0a3c0 ffff88012b014800 ffff880123853bd8 ffffffff81003e13
+  Call Trace:
+   [<ffffffff81003d59>] x86_pmu_stop+0x59/0xd0
+   [<ffffffff81003e13>] x86_pmu_del+0x43/0x140
+   [<ffffffff8111705d>] event_sched_out.isra.105+0xbd/0x260
+   [<ffffffff8111738d>] __perf_remove_from_context+0x2d/0xb0
+   [<ffffffff8111745d>] __perf_event_exit_context+0x4d/0x70
+   [<ffffffff810c8826>] generic_exec_single+0xb6/0x140
+   [<ffffffff81117410>] ? __perf_remove_from_context+0xb0/0xb0
+   [<ffffffff81117410>] ? __perf_remove_from_context+0xb0/0xb0
+   [<ffffffff810c898f>] smp_call_function_single+0xdf/0x140
+   [<ffffffff81113d27>] perf_event_exit_cpu_context+0x87/0xc0
+   [<ffffffff81113d73>] perf_reboot+0x13/0x40
+   [<ffffffff8107578a>] notifier_call_chain+0x4a/0x70
+   [<ffffffff81075ad7>] __blocking_notifier_call_chain+0x47/0x60
+   [<ffffffff81075b06>] blocking_notifier_call_chain+0x16/0x20
+   [<ffffffff81076a1d>] kernel_restart_prepare+0x1d/0x40
+   [<ffffffff81076ae2>] kernel_restart+0x12/0x60
+   [<ffffffff81076d56>] SYSC_reboot+0xf6/0x1b0
+   [<ffffffff811a823c>] ? mntput_no_expire+0x2c/0x1b0
+   [<ffffffff811a83e4>] ? mntput+0x24/0x40
+   [<ffffffff811894fc>] ? __fput+0x16c/0x1e0
+   [<ffffffff811895ae>] ? ____fput+0xe/0x10
+   [<ffffffff81072fc3>] ? task_work_run+0x83/0xa0
+   [<ffffffff81001623>] ? exit_to_usermode_loop+0x53/0xc0
+   [<ffffffff8100105a>] ? trace_hardirqs_on_thunk+0x1a/0x1c
+   [<ffffffff81076e6e>] SyS_reboot+0xe/0x10
+   [<ffffffff814c4ba5>] entry_SYSCALL_64_fastpath+0x18/0xa3
+  Code: 7c 4c 8d af c0 01 00 00 49 89 fe eb 10 48 09 c2 4c 89 e0 49 0f b1 55 00 4c 39 e0 74 35 4d 8b a6 c0 01 00 00 41 8b 8e 60 01 00 00 <0f> 33 8b 35 6e 02 8c 00 48 c1 e2 20 85 f6 7e d2 48 89 d3 89 cf
+  RIP  [<ffffffff81003c92>] x86_perf_event_update+0x52/0xc0
+   RSP <ffff880123853b60>
+  ---[ end trace 7ec95181faf211be ]---
+  note: reboot[3070] exited with preempt_count 2
+
+Cc: Borislav Petkov <bp@suse.de>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Ingo Molnar <mingo@kernel.org>
+Fixes: f5967101e9de ("x86/hweight: Get rid of the special calling convention")
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/lib/hweight.S |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/x86/lib/hweight.S
++++ b/arch/x86/lib/hweight.S
+@@ -35,6 +35,7 @@ ENDPROC(__sw_hweight32)
+ ENTRY(__sw_hweight64)
+ #ifdef CONFIG_X86_64
++      pushq   %rdi
+       pushq   %rdx
+       movq    %rdi, %rdx                      # w -> t
+@@ -60,6 +61,7 @@ ENTRY(__sw_hweight64)
+       shrq    $56, %rax                       # w = w_tmp >> 56
+       popq    %rdx
++      popq    %rdi
+       ret
+ #else /* CONFIG_X86_32 */
+       /* We're getting an u64 arg in (%eax,%edx): unsigned long hweight64(__u64 w) */
diff --git a/queue-4.4/x86-hweight-get-rid-of-the-special-calling-convention.patch b/queue-4.4/x86-hweight-get-rid-of-the-special-calling-convention.patch
new file mode 100644 (file)
index 0000000..ff61f05
--- /dev/null
@@ -0,0 +1,268 @@
+From f5967101e9de12addcda4510dfbac66d7c5779c3 Mon Sep 17 00:00:00 2001
+From: Borislav Petkov <bp@suse.de>
+Date: Mon, 30 May 2016 12:56:27 +0200
+Subject: x86/hweight: Get rid of the special calling convention
+
+From: Borislav Petkov <bp@suse.de>
+
+commit f5967101e9de12addcda4510dfbac66d7c5779c3 upstream.
+
+People complained about ARCH_HWEIGHT_CFLAGS and how it throws a wrench
+into kcov, lto, etc, experimentations.
+
+Add asm versions for __sw_hweight{32,64}() and do explicit saving and
+restoring of clobbered registers. This gets rid of the special calling
+convention. We get to call those functions on !X86_FEATURE_POPCNT CPUs.
+
+We still need to hardcode POPCNT and register operands as some old gas
+versions which we support, do not know about POPCNT.
+
+Btw, remove redundant REX prefix from 32-bit POPCNT because alternatives
+can do padding now.
+
+Suggested-by: H. Peter Anvin <hpa@zytor.com>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brian Gerst <brgerst@gmail.com>
+Cc: Denys Vlasenko <dvlasenk@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/1464605787-20603-1-git-send-email-bp@alien8.de
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/Kconfig                    |    5 --
+ arch/x86/include/asm/arch_hweight.h |   24 ++++-------
+ arch/x86/kernel/i386_ksyms_32.c     |    2 
+ arch/x86/kernel/x8664_ksyms_64.c    |    3 +
+ arch/x86/lib/Makefile               |    2 
+ arch/x86/lib/hweight.S              |   77 ++++++++++++++++++++++++++++++++++++
+ lib/Makefile                        |    2 
+ lib/hweight.c                       |    4 +
+ 8 files changed, 97 insertions(+), 22 deletions(-)
+
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -280,11 +280,6 @@ config X86_32_LAZY_GS
+       def_bool y
+       depends on X86_32 && !CC_STACKPROTECTOR
+-config ARCH_HWEIGHT_CFLAGS
+-      string
+-      default "-fcall-saved-ecx -fcall-saved-edx" if X86_32
+-      default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64
+-
+ config ARCH_SUPPORTS_UPROBES
+       def_bool y
+--- a/arch/x86/include/asm/arch_hweight.h
++++ b/arch/x86/include/asm/arch_hweight.h
+@@ -2,8 +2,8 @@
+ #define _ASM_X86_HWEIGHT_H
+ #ifdef CONFIG_64BIT
+-/* popcnt %edi, %eax -- redundant REX prefix for alignment */
+-#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
++/* popcnt %edi, %eax */
++#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc7"
+ /* popcnt %rdi, %rax */
+ #define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"
+ #define REG_IN "D"
+@@ -15,19 +15,15 @@
+ #define REG_OUT "a"
+ #endif
+-/*
+- * __sw_hweightXX are called from within the alternatives below
+- * and callee-clobbered registers need to be taken care of. See
+- * ARCH_HWEIGHT_CFLAGS in <arch/x86/Kconfig> for the respective
+- * compiler switches.
+- */
++#define __HAVE_ARCH_SW_HWEIGHT
++
+ static __always_inline unsigned int __arch_hweight32(unsigned int w)
+ {
+-      unsigned int res = 0;
++      unsigned int res;
+       asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT)
+-                   : "="REG_OUT (res)
+-                   : REG_IN (w));
++                       : "="REG_OUT (res)
++                       : REG_IN (w));
+       return res;
+ }
+@@ -51,11 +47,11 @@ static inline unsigned long __arch_hweig
+ #else
+ static __always_inline unsigned long __arch_hweight64(__u64 w)
+ {
+-      unsigned long res = 0;
++      unsigned long res;
+       asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT)
+-                   : "="REG_OUT (res)
+-                   : REG_IN (w));
++                       : "="REG_OUT (res)
++                       : REG_IN (w));
+       return res;
+ }
+--- a/arch/x86/kernel/i386_ksyms_32.c
++++ b/arch/x86/kernel/i386_ksyms_32.c
+@@ -42,3 +42,5 @@ EXPORT_SYMBOL(empty_zero_page);
+ EXPORT_SYMBOL(___preempt_schedule);
+ EXPORT_SYMBOL(___preempt_schedule_notrace);
+ #endif
++
++EXPORT_SYMBOL(__sw_hweight32);
+--- a/arch/x86/kernel/x8664_ksyms_64.c
++++ b/arch/x86/kernel/x8664_ksyms_64.c
+@@ -42,6 +42,9 @@ EXPORT_SYMBOL(clear_page);
+ EXPORT_SYMBOL(csum_partial);
++EXPORT_SYMBOL(__sw_hweight32);
++EXPORT_SYMBOL(__sw_hweight64);
++
+ /*
+  * Export string functions. We normally rely on gcc builtin for most of these,
+  * but gcc sometimes decides not to inline them.
+--- a/arch/x86/lib/Makefile
++++ b/arch/x86/lib/Makefile
+@@ -23,7 +23,7 @@ lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) +=
+ lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o
+ lib-$(CONFIG_RETPOLINE) += retpoline.o
+-obj-y += msr.o msr-reg.o msr-reg-export.o
++obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o
+ ifeq ($(CONFIG_X86_32),y)
+         obj-y += atomic64_32.o
+--- /dev/null
++++ b/arch/x86/lib/hweight.S
+@@ -0,0 +1,77 @@
++#include <linux/linkage.h>
++
++#include <asm/asm.h>
++
++/*
++ * unsigned int __sw_hweight32(unsigned int w)
++ * %rdi: w
++ */
++ENTRY(__sw_hweight32)
++
++#ifdef CONFIG_X86_64
++      movl %edi, %eax                         # w
++#endif
++      __ASM_SIZE(push,) %__ASM_REG(dx)
++      movl %eax, %edx                         # w -> t
++      shrl %edx                               # t >>= 1
++      andl $0x55555555, %edx                  # t &= 0x55555555
++      subl %edx, %eax                         # w -= t
++
++      movl %eax, %edx                         # w -> t
++      shrl $2, %eax                           # w_tmp >>= 2
++      andl $0x33333333, %edx                  # t     &= 0x33333333
++      andl $0x33333333, %eax                  # w_tmp &= 0x33333333
++      addl %edx, %eax                         # w = w_tmp + t
++
++      movl %eax, %edx                         # w -> t
++      shrl $4, %edx                           # t >>= 4
++      addl %edx, %eax                         # w_tmp += t
++      andl  $0x0f0f0f0f, %eax                 # w_tmp &= 0x0f0f0f0f
++      imull $0x01010101, %eax, %eax           # w_tmp *= 0x01010101
++      shrl $24, %eax                          # w = w_tmp >> 24
++      __ASM_SIZE(pop,) %__ASM_REG(dx)
++      ret
++ENDPROC(__sw_hweight32)
++
++ENTRY(__sw_hweight64)
++#ifdef CONFIG_X86_64
++      pushq   %rdx
++
++      movq    %rdi, %rdx                      # w -> t
++      movabsq $0x5555555555555555, %rax
++      shrq    %rdx                            # t >>= 1
++      andq    %rdx, %rax                      # t &= 0x5555555555555555
++      movabsq $0x3333333333333333, %rdx
++      subq    %rax, %rdi                      # w -= t
++
++      movq    %rdi, %rax                      # w -> t
++      shrq    $2, %rdi                        # w_tmp >>= 2
++      andq    %rdx, %rax                      # t     &= 0x3333333333333333
++      andq    %rdi, %rdx                      # w_tmp &= 0x3333333333333333
++      addq    %rdx, %rax                      # w = w_tmp + t
++
++      movq    %rax, %rdx                      # w -> t
++      shrq    $4, %rdx                        # t >>= 4
++      addq    %rdx, %rax                      # w_tmp += t
++      movabsq $0x0f0f0f0f0f0f0f0f, %rdx
++      andq    %rdx, %rax                      # w_tmp &= 0x0f0f0f0f0f0f0f0f
++      movabsq $0x0101010101010101, %rdx
++      imulq   %rdx, %rax                      # w_tmp *= 0x0101010101010101
++      shrq    $56, %rax                       # w = w_tmp >> 56
++
++      popq    %rdx
++      ret
++#else /* CONFIG_X86_32 */
++      /* We're getting an u64 arg in (%eax,%edx): unsigned long hweight64(__u64 w) */
++      pushl   %ecx
++
++      call    __sw_hweight32
++      movl    %eax, %ecx                      # stash away result
++      movl    %edx, %eax                      # second part of input
++      call    __sw_hweight32
++      addl    %ecx, %eax                      # result
++
++      popl    %ecx
++      ret
++#endif
++ENDPROC(__sw_hweight64)
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -58,8 +58,6 @@ obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o
+ obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o
+ obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o
+-GCOV_PROFILE_hweight.o := n
+-CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS))
+ obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
+ obj-$(CONFIG_BTREE) += btree.o
+--- a/lib/hweight.c
++++ b/lib/hweight.c
+@@ -9,6 +9,7 @@
+  * The Hamming Weight of a number is the total number of bits set in it.
+  */
++#ifndef __HAVE_ARCH_SW_HWEIGHT
+ unsigned int __sw_hweight32(unsigned int w)
+ {
+ #ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
+@@ -25,6 +26,7 @@ unsigned int __sw_hweight32(unsigned int
+ #endif
+ }
+ EXPORT_SYMBOL(__sw_hweight32);
++#endif
+ unsigned int __sw_hweight16(unsigned int w)
+ {
+@@ -43,6 +45,7 @@ unsigned int __sw_hweight8(unsigned int
+ }
+ EXPORT_SYMBOL(__sw_hweight8);
++#ifndef __HAVE_ARCH_SW_HWEIGHT
+ unsigned long __sw_hweight64(__u64 w)
+ {
+ #if BITS_PER_LONG == 32
+@@ -65,3 +68,4 @@ unsigned long __sw_hweight64(__u64 w)
+ #endif
+ }
+ EXPORT_SYMBOL(__sw_hweight64);
++#endif