From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp.tuxdriver.com (charlotte.tuxdriver.com [70.61.120.58]) by dpdk.org (Postfix) with ESMTP id D342F5916 for ; Tue, 18 Mar 2014 21:42:26 +0100 (CET) Received: from hmsreliant.think-freely.org ([2001:470:8:a08:7aac:c0ff:fec2:933b] helo=localhost) by smtp.tuxdriver.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.63) (envelope-from ) id 1WQ0rM-0001Xr-Fi; Tue, 18 Mar 2014 16:43:57 -0400 From: Neil Horman To: dev@dpdk.org Date: Tue, 18 Mar 2014 16:43:34 -0400 Message-Id: <1395175414-25232-1-git-send-email-nhorman@tuxdriver.com> X-Mailer: git-send-email 1.8.3.1 X-Spam-Score: -2.9 (--) X-Spam-Status: No Subject: [dpdk-dev] [PATCH] eal: fix up bad asm in rte_cpu_get_features X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Mar 2014 20:42:27 -0000 The recent conversion to build dpdk as a DSO has an error in rte_cpu_get_features. When being build with -fpie, %ebx gets clobbered by the cpuid instruction which is also the pic register. Therefore the inline asm tries to save off %ebx, but does so incorrectly. It starts by loading params.ebx to "D" which is %edi, but then the first instruction moves %ebx to %edi, clobbering the input value. Then after the operation is complete, "D" (%edi) is stored to the local ebx variable, but only after the xchgl instruction has happened, which means ebx holds only the PIC pointer. This behavior was causing strange segfults for me when running the cpuid instruction. The fix is pretty easy, split the asm into two separate directives, the first saving ebx, and using it to grab the appropriate cpuid info (and correctly listing %edi as a clobbered register in the process, and then a subsequent asm directive preforming the reverse exchange (again, listing %edi as being clobbered). Signed-off-by: Neil Horman --- lib/librte_eal/common/eal_common_cpuflags.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c index 1ebf78c..2072a0c 100644 --- a/lib/librte_eal/common/eal_common_cpuflags.c +++ b/lib/librte_eal/common/eal_common_cpuflags.c @@ -208,16 +208,19 @@ rte_cpu_get_features(struct cpuid_parameters_t params) asm volatile ( "mov %%ebx, %%edi\n" "cpuid\n" - "xchgl %%ebx, %%edi;\n" : "=a" (eax), - "=D" (ebx), + "=b" (ebx), "=c" (ecx), "=d" (edx) /* input */ : "a" (params.eax), - "D" (params.ebx), + "b" (params.ebx), "c" (params.ecx), - "d" (params.edx)); + "d" (params.edx) + : "%edi"); + + asm volatile ("xchgl %%ebx, %%edi;\n" + : :); #endif switch (params.return_register) { -- 1.8.3.1