qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues
@ 2014-05-02 13:45 Peter Maydell
  2014-05-02 13:45 ` [Qemu-devel] [PATCH 1/4] linux-user/elfload.c: Fix incorrect ARM HWCAP bits Peter Maydell
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Peter Maydell @ 2014-05-02 13:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, patches

This patchset fixes a number of issues in the ARM elfload.c, mostly
relating to the AT_HWCAP bits:
 * off-by-one error for some of the existing ARM bits
 * update to include bits defined in newer kernels, and fix
   some bugs in how we were handling existing bits
 * properly separate out 64-bit from 32-bit code, so that we
   get the right 64-bit HWCAP and core-dump behaviour
 * support HWCAP2, which 32-bit ARM uses for some of the crypto
   feature bits

I've cc'd the first 3 for stable because they seemed
safe enough, and the 3rd patch in particular looks worth
having in stable since we're supposed to support A64 binaries
there.

thanks
-- PMM

Peter Maydell (4):
  linux-user/elfload.c: Fix incorrect ARM HWCAP bits
  linux-user/elfload.c: Update ARM HWCAP bits
  linux-user/elfload.c: Fix A64 code which was incorrectly acting like
    A32
  linux-user/elfload.c: Support ARM HWCAP2 flags

 include/elf.h        |   1 +
 linux-user/elfload.c | 145 ++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 127 insertions(+), 19 deletions(-)

-- 
1.9.2

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Qemu-devel] [PATCH 1/4] linux-user/elfload.c: Fix incorrect ARM HWCAP bits
  2014-05-02 13:45 [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues Peter Maydell
@ 2014-05-02 13:45 ` Peter Maydell
  2014-05-02 13:45 ` [Qemu-devel] [PATCH 2/4] linux-user/elfload.c: Update " Peter Maydell
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2014-05-02 13:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, patches

The ELF HWCAP bits for ARM features THUMBEE, NEON, VFPv3 and VFPv3D16 are
all off by one compared to the kernel definitions. Fix this discrepancy
and add in the missing CRUNCH bit which was the cause of the off-by-one
error. (We don't emulate any of the CPUs which have that weird hardware,
so it's otherwise uninteresting to us.)

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 linux-user/elfload.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index d2380b6..6cfaa3a 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -346,10 +346,11 @@ enum
     ARM_HWCAP_ARM_EDSP      = 1 << 7,
     ARM_HWCAP_ARM_JAVA      = 1 << 8,
     ARM_HWCAP_ARM_IWMMXT    = 1 << 9,
-    ARM_HWCAP_ARM_THUMBEE   = 1 << 10,
-    ARM_HWCAP_ARM_NEON      = 1 << 11,
-    ARM_HWCAP_ARM_VFPv3     = 1 << 12,
-    ARM_HWCAP_ARM_VFPv3D16  = 1 << 13,
+    ARM_HWCAP_ARM_CRUNCH    = 1 << 10,
+    ARM_HWCAP_ARM_THUMBEE   = 1 << 11,
+    ARM_HWCAP_ARM_NEON      = 1 << 12,
+    ARM_HWCAP_ARM_VFPv3     = 1 << 13,
+    ARM_HWCAP_ARM_VFPv3D16  = 1 << 14,
 };
 
 #ifndef TARGET_AARCH64
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Qemu-devel] [PATCH 2/4] linux-user/elfload.c: Update ARM HWCAP bits
  2014-05-02 13:45 [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues Peter Maydell
  2014-05-02 13:45 ` [Qemu-devel] [PATCH 1/4] linux-user/elfload.c: Fix incorrect ARM HWCAP bits Peter Maydell
@ 2014-05-02 13:45 ` Peter Maydell
  2014-05-02 13:45 ` [Qemu-devel] [PATCH 3/4] linux-user/elfload.c: Fix A64 code which was incorrectly acting like A32 Peter Maydell
  2014-05-02 13:45 ` [Qemu-devel] [PATCH 4/4] linux-user/elfload.c: Support ARM HWCAP2 flags Peter Maydell
  3 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2014-05-02 13:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, patches

The kernel has added support for a number of new ARM HWCAP bits;
add them to QEMU, including support for setting them where we have
a corresponding CPU feature bit.

We were also incorrectly setting the VFPv3D16 HWCAP -- this means
"only 16 D registers", not "supports 16-bit floating point format";
since QEMU always has 32 D registers for VFPv3, we can just remove
the line that incorrectly set this bit.

The kernel does not set the HWCAP_FPA even if it is providing FPA
emulation via nwfpe, so don't set this bit in QEMU either.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
---
 linux-user/elfload.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 6cfaa3a..0449b29 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -351,6 +351,13 @@ enum
     ARM_HWCAP_ARM_NEON      = 1 << 12,
     ARM_HWCAP_ARM_VFPv3     = 1 << 13,
     ARM_HWCAP_ARM_VFPv3D16  = 1 << 14,
+    ARM_HWCAP_ARM_TLS       = 1 << 15,
+    ARM_HWCAP_ARM_VFPv4     = 1 << 16,
+    ARM_HWCAP_ARM_IDIVA     = 1 << 17,
+    ARM_HWCAP_ARM_IDIVT     = 1 << 18,
+    ARM_HWCAP_ARM_VFPD32    = 1 << 19,
+    ARM_HWCAP_ARM_LPAE      = 1 << 20,
+    ARM_HWCAP_ARM_EVTSTRM   = 1 << 21,
 };
 
 #ifndef TARGET_AARCH64
@@ -428,17 +435,28 @@ static uint32_t get_elf_hwcap(void)
     hwcaps |= ARM_HWCAP_ARM_HALF;
     hwcaps |= ARM_HWCAP_ARM_THUMB;
     hwcaps |= ARM_HWCAP_ARM_FAST_MULT;
-    hwcaps |= ARM_HWCAP_ARM_FPA;
 
     /* probe for the extra features */
 #define GET_FEATURE(feat, hwcap) \
     do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+    /* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */
+    GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
     GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
     GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
     GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
     GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
     GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
-    GET_FEATURE(ARM_FEATURE_VFP_FP16, ARM_HWCAP_ARM_VFPv3D16);
+    GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
+    GET_FEATURE(ARM_FEATURE_VFP4, ARM_HWCAP_ARM_VFPv4);
+    GET_FEATURE(ARM_FEATURE_ARM_DIV, ARM_HWCAP_ARM_IDIVA);
+    GET_FEATURE(ARM_FEATURE_THUMB_DIV, ARM_HWCAP_ARM_IDIVT);
+    /* All QEMU's VFPv3 CPUs have 32 registers, see VFP_DREG in translate.c.
+     * Note that the ARM_HWCAP_ARM_VFPv3D16 bit is always the inverse of
+     * ARM_HWCAP_ARM_VFPD32 (and so always clear for QEMU); it is unrelated
+     * to our VFP_FP16 feature bit.
+     */
+    GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPD32);
+    GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
 #undef GET_FEATURE
 
     return hwcaps;
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Qemu-devel] [PATCH 3/4] linux-user/elfload.c: Fix A64 code which was incorrectly acting like A32
  2014-05-02 13:45 [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues Peter Maydell
  2014-05-02 13:45 ` [Qemu-devel] [PATCH 1/4] linux-user/elfload.c: Fix incorrect ARM HWCAP bits Peter Maydell
  2014-05-02 13:45 ` [Qemu-devel] [PATCH 2/4] linux-user/elfload.c: Update " Peter Maydell
@ 2014-05-02 13:45 ` Peter Maydell
  2014-05-02 13:45 ` [Qemu-devel] [PATCH 4/4] linux-user/elfload.c: Support ARM HWCAP2 flags Peter Maydell
  3 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2014-05-02 13:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, patches

The ARM target-specific code in elfload.c was incorrectly allowing
the 64-bit ARM target to use most of the existing 32-bit definitions:
most noticably this meant that our HWCAP bits passed to the guest
were wrong, and register handling when dumping core was totally
broken. Fix this by properly separating the 64 and 32 bit code,
since they have more differences than similarities.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Cc: qemu-stable@nongnu.org
---
 linux-user/elfload.c | 86 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 73 insertions(+), 13 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 0449b29..e1ff346 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -267,17 +267,15 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
 
 #ifdef TARGET_ARM
 
+#ifndef TARGET_AARCH64
+/* 32 bit ARM definitions */
+
 #define ELF_START_MMAP 0x80000000
 
 #define elf_check_arch(x) ((x) == ELF_MACHINE)
 
 #define ELF_ARCH        ELF_MACHINE
-
-#ifdef TARGET_AARCH64
-#define ELF_CLASS       ELFCLASS64
-#else
 #define ELF_CLASS       ELFCLASS32
-#endif
 
 static inline void init_thread(struct target_pt_regs *regs,
                                struct image_info *infop)
@@ -285,10 +283,6 @@ static inline void init_thread(struct target_pt_regs *regs,
     abi_long stack = infop->start_stack;
     memset(regs, 0, sizeof(*regs));
 
-#ifdef TARGET_AARCH64
-    regs->pc = infop->entry & ~0x3ULL;
-    regs->sp = stack;
-#else
     regs->ARM_cpsr = 0x10;
     if (infop->entry & 1)
         regs->ARM_cpsr |= CPSR_T;
@@ -302,7 +296,6 @@ static inline void init_thread(struct target_pt_regs *regs,
     /* For uClinux PIC binaries.  */
     /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
     regs->ARM_r10 = infop->start_data;
-#endif
 }
 
 #define ELF_NREG    18
@@ -360,7 +353,6 @@ enum
     ARM_HWCAP_ARM_EVTSTRM   = 1 << 21,
 };
 
-#ifndef TARGET_AARCH64
 /* The commpage only exists for 32 bit kernels */
 
 #define TARGET_HAS_VALIDATE_GUEST_SPACE
@@ -422,7 +414,6 @@ static int validate_guest_space(unsigned long guest_base,
 
     return 1; /* All good */
 }
-#endif
 
 #define ELF_HWCAP get_elf_hwcap()
 
@@ -462,7 +453,76 @@ static uint32_t get_elf_hwcap(void)
     return hwcaps;
 }
 
-#endif
+#else
+/* 64 bit ARM definitions */
+#define ELF_START_MMAP 0x80000000
+
+#define elf_check_arch(x) ((x) == ELF_MACHINE)
+
+#define ELF_ARCH        ELF_MACHINE
+#define ELF_CLASS       ELFCLASS64
+#define ELF_PLATFORM    "aarch64"
+
+static inline void init_thread(struct target_pt_regs *regs,
+                               struct image_info *infop)
+{
+    abi_long stack = infop->start_stack;
+    memset(regs, 0, sizeof(*regs));
+
+    regs->pc = infop->entry & ~0x3ULL;
+    regs->sp = stack;
+}
+
+#define ELF_NREG    34
+typedef target_elf_greg_t  target_elf_gregset_t[ELF_NREG];
+
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+                               const CPUARMState *env)
+{
+    int i;
+
+    for (i = 0; i < 32; i++) {
+        (*regs)[i] = tswapreg(env->xregs[i]);
+    }
+    (*regs)[32] = tswapreg(env->pc);
+    (*regs)[33] = tswapreg(pstate_read((CPUARMState *)env));
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE       4096
+
+enum {
+    ARM_HWCAP_A64_FP            = 1 << 0,
+    ARM_HWCAP_A64_ASIMD         = 1 << 1,
+    ARM_HWCAP_A64_EVTSTRM       = 1 << 2,
+    ARM_HWCAP_A64_AES           = 1 << 3,
+    ARM_HWCAP_A64_PMULL         = 1 << 4,
+    ARM_HWCAP_A64_SHA1          = 1 << 5,
+    ARM_HWCAP_A64_SHA2          = 1 << 6,
+    ARM_HWCAP_A64_CRC32         = 1 << 7,
+};
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+    ARMCPU *cpu = ARM_CPU(thread_cpu);
+    uint32_t hwcaps = 0;
+
+    hwcaps |= ARM_HWCAP_A64_FP;
+    hwcaps |= ARM_HWCAP_A64_ASIMD;
+
+    /* probe for the extra features */
+#define GET_FEATURE(feat, hwcap) \
+    do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+    GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP_A64_PMULL);
+#undef GET_FEATURE
+
+    return hwcaps;
+}
+
+#endif /* not TARGET_AARCH64 */
+#endif /* TARGET_ARM */
 
 #ifdef TARGET_UNICORE32
 
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Qemu-devel] [PATCH 4/4] linux-user/elfload.c: Support ARM HWCAP2 flags
  2014-05-02 13:45 [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues Peter Maydell
                   ` (2 preceding siblings ...)
  2014-05-02 13:45 ` [Qemu-devel] [PATCH 3/4] linux-user/elfload.c: Fix A64 code which was incorrectly acting like A32 Peter Maydell
@ 2014-05-02 13:45 ` Peter Maydell
  3 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2014-05-02 13:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Riku Voipio, patches

The ARM kernel has chosen to spill into the HWCAP2 ELF feature bit flags
early, even though it hasn't yet exhausted all 32 bits of the HWCAP word.
Add support for setting this in the same way we do for HWCAP.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/elf.h        |  1 +
 linux-user/elfload.c | 30 +++++++++++++++++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/include/elf.h b/include/elf.h
index 667af6f..1599ab2 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -254,6 +254,7 @@ typedef int64_t  Elf64_Sxword;
 #define AT_SECURE	23	/* boolean, was exec suid-like? */
 #define AT_BASE_PLATFORM 24	/* string identifying real platforms */
 #define AT_RANDOM	25	/* address of 16 random bytes */
+#define AT_HWCAP2       26      /* extension of AT_HWCAP */
 #define AT_EXECFN	31	/* filename of the executable */
 #define AT_SYSINFO	32	/* address of kernel entry point */
 #define AT_SYSINFO_EHDR	33	/* address of kernel vdso */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index e1ff346..5db67cf 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -20,6 +20,7 @@
 #undef ARCH_DLINFO
 #undef ELF_PLATFORM
 #undef ELF_HWCAP
+#undef ELF_HWCAP2
 #undef ELF_CLASS
 #undef ELF_DATA
 #undef ELF_ARCH
@@ -353,6 +354,14 @@ enum
     ARM_HWCAP_ARM_EVTSTRM   = 1 << 21,
 };
 
+enum {
+    ARM_HWCAP2_ARM_AES      = 1 << 0,
+    ARM_HWCAP2_ARM_PMULL    = 1 << 1,
+    ARM_HWCAP2_ARM_SHA1     = 1 << 2,
+    ARM_HWCAP2_ARM_SHA2     = 1 << 3,
+    ARM_HWCAP2_ARM_CRC32    = 1 << 4,
+};
+
 /* The commpage only exists for 32 bit kernels */
 
 #define TARGET_HAS_VALIDATE_GUEST_SPACE
@@ -416,6 +425,7 @@ static int validate_guest_space(unsigned long guest_base,
 }
 
 #define ELF_HWCAP get_elf_hwcap()
+#define ELF_HWCAP2 get_elf_hwcap2()
 
 static uint32_t get_elf_hwcap(void)
 {
@@ -448,11 +458,22 @@ static uint32_t get_elf_hwcap(void)
      */
     GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPD32);
     GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
-#undef GET_FEATURE
 
     return hwcaps;
 }
 
+static uint32_t get_elf_hwcap2(void)
+{
+    ARMCPU *cpu = ARM_CPU(thread_cpu);
+    uint32_t hwcaps = 0;
+
+    GET_FEATURE(ARM_FEATURE_V8_AES, ARM_HWCAP2_ARM_AES);
+    GET_FEATURE(ARM_FEATURE_CRC, ARM_HWCAP2_ARM_CRC32);
+    return hwcaps;
+}
+
+#undef GET_FEATURE
+
 #else
 /* 64 bit ARM definitions */
 #define ELF_START_MMAP 0x80000000
@@ -1486,6 +1507,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
 #ifdef DLINFO_ARCH_ITEMS
     size += DLINFO_ARCH_ITEMS * 2;
 #endif
+#ifdef ELF_HWCAP2
+    size += 2;
+#endif
     size += envc + argc + 2;
     size += 1;  /* argc itself */
     size *= n;
@@ -1519,6 +1543,10 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
     NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
 
+#ifdef ELF_HWCAP2
+    NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
+#endif
+
     if (k_platform)
         NEW_AUX_ENT(AT_PLATFORM, u_platform);
 #ifdef ARCH_DLINFO
-- 
1.9.2

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-05-02 14:09 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-02 13:45 [Qemu-devel] [PATCH 0/4] linux-user: fix ARM hwcaps related issues Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 1/4] linux-user/elfload.c: Fix incorrect ARM HWCAP bits Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 2/4] linux-user/elfload.c: Update " Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 3/4] linux-user/elfload.c: Fix A64 code which was incorrectly acting like A32 Peter Maydell
2014-05-02 13:45 ` [Qemu-devel] [PATCH 4/4] linux-user/elfload.c: Support ARM HWCAP2 flags Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).