From: Greg Kroah-Hartman Date: Tue, 17 Apr 2018 15:19:44 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.16.3~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66a1896488c6b9482958c7260a8a3b49e5c47f6c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches 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 --- 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 index 00000000000..8de4db14f36 --- /dev/null +++ b/queue-4.4/cdc_ether-flag-the-cinterion-ahs8-modem-by-gemalto-as-wwan.patch @@ -0,0 +1,42 @@ +From foo@baz Tue Apr 17 16:59:41 CEST 2018 +From: Bassem Boubaker +Date: Wed, 11 Apr 2018 13:15:53 +0200 +Subject: cdc_ether: flag the Cinterion AHS8 modem by gemalto as WWAN + +From: Bassem Boubaker + + +[ 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 +Acked-by: Oliver Neukum +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..80365de6dba --- /dev/null +++ b/queue-4.4/lan78xx-correctly-indicate-invalid-otp.patch @@ -0,0 +1,35 @@ +From foo@baz Tue Apr 17 16:59:41 CEST 2018 +From: Phil Elwell +Date: Wed, 11 Apr 2018 10:59:17 +0100 +Subject: lan78xx: Correctly indicate invalid OTP + +From: Phil Elwell + + +[ 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-4.4/series b/queue-4.4/series index 91751703499..a3eb87483e1 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -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 index 00000000000..bd05c7cc504 --- /dev/null +++ b/queue-4.4/slip-check-if-rstate-is-initialized-before-uncompressing.patch @@ -0,0 +1,76 @@ +From foo@baz Tue Apr 17 16:59:41 CEST 2018 +From: Tejaswi Tanikella +Date: Wed, 11 Apr 2018 16:34:47 +0530 +Subject: slip: Check if rstate is initialized before uncompressing + +From: Tejaswi Tanikella + + +[ 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> [] slhc_uncompress+0x464/0x468 +89.666965: <2> [] ppp_receive_nonmp_frame+0x3b4/0x65c +89.666978: <2> [] ppp_receive_frame+0x64/0x7e0 +89.666991: <2> [] ppp_input+0x104/0x198 +89.667005: <2> [] pppopns_recv_core+0x238/0x370 +89.667027: <2> [] __sk_receive_skb+0xdc/0x250 +89.667040: <2> [] pppopns_recv+0x44/0x60 +89.667053: <2> [] __sock_queue_rcv_skb+0x16c/0x24c +89.667065: <2> [] sock_queue_rcv_skb+0x2c/0x38 +89.667085: <2> [] raw_rcv+0x124/0x154 +89.667098: <2> [] raw_local_deliver+0x1e0/0x22c +89.667117: <2> [] ip_local_deliver_finish+0x70/0x24c +89.667131: <2> [] 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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..29d2f97eddc --- /dev/null +++ b/queue-4.4/x86-hweight-don-t-clobber-rdi.patch @@ -0,0 +1,105 @@ +From 65ea11ec6a82b1d44aba62b59e9eb20247e57c6e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +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ä + +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:[] [] 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: + [] x86_pmu_stop+0x59/0xd0 + [] x86_pmu_del+0x43/0x140 + [] event_sched_out.isra.105+0xbd/0x260 + [] __perf_remove_from_context+0x2d/0xb0 + [] __perf_event_exit_context+0x4d/0x70 + [] generic_exec_single+0xb6/0x140 + [] ? __perf_remove_from_context+0xb0/0xb0 + [] ? __perf_remove_from_context+0xb0/0xb0 + [] smp_call_function_single+0xdf/0x140 + [] perf_event_exit_cpu_context+0x87/0xc0 + [] perf_reboot+0x13/0x40 + [] notifier_call_chain+0x4a/0x70 + [] __blocking_notifier_call_chain+0x47/0x60 + [] blocking_notifier_call_chain+0x16/0x20 + [] kernel_restart_prepare+0x1d/0x40 + [] kernel_restart+0x12/0x60 + [] SYSC_reboot+0xf6/0x1b0 + [] ? mntput_no_expire+0x2c/0x1b0 + [] ? mntput+0x24/0x40 + [] ? __fput+0x16c/0x1e0 + [] ? ____fput+0xe/0x10 + [] ? task_work_run+0x83/0xa0 + [] ? exit_to_usermode_loop+0x53/0xc0 + [] ? trace_hardirqs_on_thunk+0x1a/0x1c + [] SyS_reboot+0xe/0x10 + [] 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 [] x86_perf_event_update+0x52/0xc0 + RSP + ---[ end trace 7ec95181faf211be ]--- + note: reboot[3070] exited with preempt_count 2 + +Cc: Borislav Petkov +Cc: H. Peter Anvin +Cc: Andy Lutomirski +Cc: Brian Gerst +Cc: Denys Vlasenko +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Ingo Molnar +Fixes: f5967101e9de ("x86/hweight: Get rid of the special calling convention") +Signed-off-by: Ville Syrjälä +Signed-off-by: Linus Torvalds +Cc: Matthias Kaehlcke +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..ff61f05bdbb --- /dev/null +++ b/queue-4.4/x86-hweight-get-rid-of-the-special-calling-convention.patch @@ -0,0 +1,268 @@ +From f5967101e9de12addcda4510dfbac66d7c5779c3 Mon Sep 17 00:00:00 2001 +From: Borislav Petkov +Date: Mon, 30 May 2016 12:56:27 +0200 +Subject: x86/hweight: Get rid of the special calling convention + +From: Borislav Petkov + +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 +Signed-off-by: Borislav Petkov +Acked-by: Peter Zijlstra (Intel) +Cc: Andy Lutomirski +Cc: Borislav Petkov +Cc: Brian Gerst +Cc: Denys Vlasenko +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Link: http://lkml.kernel.org/r/1464605787-20603-1-git-send-email-bp@alien8.de +Signed-off-by: Ingo Molnar +Signed-off-by: Matthias Kaehlcke +Signed-off-by: Greg Kroah-Hartman + +--- + 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 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 ++ ++#include ++ ++/* ++ * 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