All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/6] Improve getauxval support
@ 2013-08-17 22:38 Richard Henderson
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 1/6] osdep: Create qemu_getauxval and qemu_init_auxval Richard Henderson
                   ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Richard Henderson @ 2013-08-17 22:38 UTC (permalink / raw)
  To: qemu-devel

The getauxval routine was added to glibc for 2.16.  In order to 
better support qemu on systems prior to 2.16, add a qemu_getauxval
entry point, and add the relevant defines to our own elf.h.


r~


Richard Henderson (6):
  osdep: Create qemu_getauxval and qemu_init_auxval
  tcg-ppc64: Use qemu_getauxval
  tcg-arm: Use qemu_getauxval
  tcg-s390: Use qemu_getauxval in query_facilities
  util: Provide fallback hwcap and platform for powerpc
  util: Use qemu_getauxval in linux qemu_cache_utils_init

 include/elf.h              |  70 ++++++++++++++++++++++
 include/qemu/cache-utils.h |   4 +-
 include/qemu/osdep.h       |  20 +++++++
 linux-user/main.c          |   3 +-
 tcg/arm/tcg-target.c       |  15 ++---
 tcg/ppc64/tcg-target.c     |  11 +---
 tcg/s390/tcg-target.c      |  95 ++++--------------------------
 util/Makefile.objs         |   1 +
 util/cache-utils.c         |  51 +++++++---------
 util/getauxval.c           | 143 +++++++++++++++++++++++++++++++++++++++++++++
 vl.c                       |   3 +-
 11 files changed, 280 insertions(+), 136 deletions(-)
 create mode 100644 util/getauxval.c

-- 
1.8.1.4

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

* [Qemu-devel] [PATCH 1/6] osdep: Create qemu_getauxval and qemu_init_auxval
  2013-08-17 22:38 [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
@ 2013-08-17 22:38 ` Richard Henderson
  2013-08-29 21:17   ` Aurelien Jarno
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 2/6] tcg-ppc64: Use qemu_getauxval Richard Henderson
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 9+ messages in thread
From: Richard Henderson @ 2013-08-17 22:38 UTC (permalink / raw)
  To: qemu-devel

Abstract away dependence on a system implementation of getauxval.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/qemu/osdep.h | 20 ++++++++++++
 linux-user/main.c    |  1 +
 util/Makefile.objs   |  1 +
 util/getauxval.c     | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 vl.c                 |  1 +
 5 files changed, 114 insertions(+)
 create mode 100644 util/getauxval.c

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 26136f1..8d1948b 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -215,4 +215,24 @@ bool fips_get_state(void);
  */
 char *qemu_get_local_state_pathname(const char *relative_pathname);
 
+/* Return a value for an AT_* type in the auxiliary vector.  Return 0 if the
+ * key is not present.  We attempt to emulate AT_HWCAP and AT_PLATFORM as
+ * best we can when real host support is not present.
+ */
+#ifdef _WIN32
+static inline unsigned long qemu_getauxval(unsigned long type) { return 0; }
+#else
+unsigned long qemu_getauxval(unsigned long type);
+#endif
+
+/* If supported and required, locate the auxiliary vector at program startup.
+ *
+ * @envp must be the third argument to main.
+ */
+#if defined(CONFIG_GETAUXVAL) || defined(_WIN32)
+static inline void qemu_init_auxval(char **envp) { }
+#else
+void qemu_init_auxval(char **envp);
+#endif
+
 #endif
diff --git a/linux-user/main.c b/linux-user/main.c
index 03859bc..fae102a 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3549,6 +3549,7 @@ int main(int argc, char **argv, char **envp)
 
     module_call_init(MODULE_INIT_QOM);
 
+    qemu_init_auxval(envp);
     qemu_cache_utils_init(envp);
 
     if ((envlist = envlist_create()) == NULL) {
diff --git a/util/Makefile.objs b/util/Makefile.objs
index dc72ab0..8e0c929 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -11,3 +11,4 @@ util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o uri.o notify.o
 util-obj-y += qemu-option.o qemu-progress.o
 util-obj-y += hexdump.o
 util-obj-y += crc32c.o
+util-obj-y += getauxval.o
diff --git a/util/getauxval.c b/util/getauxval.c
new file mode 100644
index 0000000..55b639c
--- /dev/null
+++ b/util/getauxval.c
@@ -0,0 +1,91 @@
+/*
+ * QEMU access to the auxiliary vector
+ *
+ * Copyright (C) 2013 Red Hat, Inc
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu-common.h"
+#include "qemu/osdep.h"
+
+#ifdef CONFIG_GETAUXVAL
+/* Don't inline this in qemu/osdep.h, because pulling in <sys/auxv.h> for
+   the system declaration of getauxval pulls in the system <elf.h>, which
+   conflicts with qemu's version.  */
+
+#include <sys/auxv.h>
+
+unsigned long qemu_getauxval(unsigned long key)
+{
+    return getauxval(key);
+}
+#elif !defined(_WIN32)
+#include "elf.h"
+
+/* Our elf.h doesn't contain Elf32_auxv_t and Elf64_auxv_t, which is ok because
+   that just makes it easier to define it properly for the host here.  */
+typedef struct {
+    unsigned long a_type;
+    unsigned long a_val;
+} ElfW_auxv_t;
+
+static const ElfW_auxv_t *auxv;
+
+void qemu_init_auxval(char **envp)
+{
+#ifdef __linux__
+    /* The auxiliary vector is located just beyond the initial environment.  */
+    while (*envp != NULL)
+        continue;
+    auxv = (const ElfW_auxv_t *)envp;
+#endif
+}
+
+static const char *default_platform(void)
+{
+    return NULL;
+}
+
+static unsigned long default_hwcap(void)
+{
+    return 0;
+}
+
+unsigned long qemu_getauxval(unsigned long type)
+{
+    /* If we were able to find the auxiliary vector, use it.  */
+    if (auxv) {
+        const ElfW_auxv_t *a;
+        for (a = auxv; a->a_type != 0; a++) {
+            if (a->a_type == type) {
+                return a->a_val;
+            }
+        }
+    }
+
+    /* Otherwise, guess defaults for the host based on compiler flags.  */
+    if (type == AT_HWCAP) {
+        return default_hwcap();
+    } else if (type == AT_PLATFORM) {
+        return (unsigned long)default_platform();
+    }
+    return 0;
+}
+#endif
diff --git a/vl.c b/vl.c
index f422a1c..c539fd3 100644
--- a/vl.c
+++ b/vl.c
@@ -2967,6 +2967,7 @@ int main(int argc, char **argv, char **envp)
     init_clocks();
     rtc_clock = host_clock;
 
+    qemu_init_auxval(envp);
     qemu_cache_utils_init(envp);
 
     QLIST_INIT (&vm_change_state_head);
-- 
1.8.1.4

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

* [Qemu-devel] [PATCH 2/6] tcg-ppc64: Use qemu_getauxval
  2013-08-17 22:38 [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 1/6] osdep: Create qemu_getauxval and qemu_init_auxval Richard Henderson
@ 2013-08-17 22:38 ` Richard Henderson
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 3/6] tcg-arm: " Richard Henderson
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2013-08-17 22:38 UTC (permalink / raw)
  To: qemu-devel

Allow host detection on linux systems without glibc 2.16 or later.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/elf.h          | 34 ++++++++++++++++++++++++++++++++++
 tcg/ppc64/tcg-target.c | 11 ++---------
 2 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/include/elf.h b/include/elf.h
index 58bfbf8..7fdd3df 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -411,6 +411,40 @@ typedef struct {
 #define R_SPARC_5		44
 #define R_SPARC_6		45
 
+/* Bits present in AT_HWCAP for PowerPC.  */
+
+#define PPC_FEATURE_32                  0x80000000
+#define PPC_FEATURE_64                  0x40000000
+#define PPC_FEATURE_601_INSTR           0x20000000
+#define PPC_FEATURE_HAS_ALTIVEC         0x10000000
+#define PPC_FEATURE_HAS_FPU             0x08000000
+#define PPC_FEATURE_HAS_MMU             0x04000000
+#define PPC_FEATURE_HAS_4xxMAC          0x02000000
+#define PPC_FEATURE_UNIFIED_CACHE       0x01000000
+#define PPC_FEATURE_HAS_SPE             0x00800000
+#define PPC_FEATURE_HAS_EFP_SINGLE      0x00400000
+#define PPC_FEATURE_HAS_EFP_DOUBLE      0x00200000
+#define PPC_FEATURE_NO_TB               0x00100000
+#define PPC_FEATURE_POWER4              0x00080000
+#define PPC_FEATURE_POWER5              0x00040000
+#define PPC_FEATURE_POWER5_PLUS         0x00020000
+#define PPC_FEATURE_CELL                0x00010000
+#define PPC_FEATURE_BOOKE               0x00008000
+#define PPC_FEATURE_SMT                 0x00004000
+#define PPC_FEATURE_ICACHE_SNOOP        0x00002000
+#define PPC_FEATURE_ARCH_2_05           0x00001000
+#define PPC_FEATURE_PA6T                0x00000800
+#define PPC_FEATURE_HAS_DFP             0x00000400
+#define PPC_FEATURE_POWER6_EXT          0x00000200
+#define PPC_FEATURE_ARCH_2_06           0x00000100
+#define PPC_FEATURE_HAS_VSX             0x00000080
+
+#define PPC_FEATURE_PSERIES_PERFMON_COMPAT \
+                                        0x00000040
+
+#define PPC_FEATURE_TRUE_LE             0x00000002
+#define PPC_FEATURE_PPC_LE              0x00000001
+
 /* Bits present in AT_HWCAP, primarily for Sparc32.  */
 
 #define HWCAP_SPARC_FLUSH       1    /* CPU supports flush instruction. */
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 0678de2..a53f32a 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -45,15 +45,10 @@ static uint8_t *tb_ret_addr;
 #define GUEST_BASE 0
 #endif
 
-#ifdef CONFIG_GETAUXVAL
-#include <sys/auxv.h>
+#include "elf.h"
 static bool have_isa_2_06;
 #define HAVE_ISA_2_06  have_isa_2_06
 #define HAVE_ISEL      have_isa_2_06
-#else
-#define HAVE_ISA_2_06  0
-#define HAVE_ISEL      0
-#endif
 
 #ifdef CONFIG_USE_GUEST_BASE
 #define TCG_GUEST_BASE_REG 30
@@ -2132,12 +2127,10 @@ static const TCGTargetOpDef ppc_op_defs[] = {
 
 static void tcg_target_init (TCGContext *s)
 {
-#ifdef CONFIG_GETAUXVAL
-    unsigned long hwcap = getauxval(AT_HWCAP);
+    unsigned long hwcap = qemu_getauxval(AT_HWCAP);
     if (hwcap & PPC_FEATURE_ARCH_2_06) {
         have_isa_2_06 = true;
     }
-#endif
 
     tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffffffff);
     tcg_regset_set32 (tcg_target_available_regs[TCG_TYPE_I64], 0, 0xffffffff);
-- 
1.8.1.4

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

* [Qemu-devel] [PATCH 3/6] tcg-arm: Use qemu_getauxval
  2013-08-17 22:38 [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 1/6] osdep: Create qemu_getauxval and qemu_init_auxval Richard Henderson
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 2/6] tcg-ppc64: Use qemu_getauxval Richard Henderson
@ 2013-08-17 22:38 ` Richard Henderson
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 4/6] tcg-s390: Use qemu_getauxval in query_facilities Richard Henderson
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2013-08-17 22:38 UTC (permalink / raw)
  To: qemu-devel

Allow host detection on linux systems without glibc 2.16 or later.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/elf.h        | 22 ++++++++++++++++++++++
 tcg/arm/tcg-target.c | 15 ++++++---------
 2 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/include/elf.h b/include/elf.h
index 7fdd3df..e95fa95 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -411,6 +411,28 @@ typedef struct {
 #define R_SPARC_5		44
 #define R_SPARC_6		45
 
+/* Bits present in AT_HWCAP for ARM.  */
+
+#define HWCAP_ARM_SWP		1
+#define HWCAP_ARM_HALF		2
+#define HWCAP_ARM_THUMB		4
+#define HWCAP_ARM_26BIT		8
+#define HWCAP_ARM_FAST_MULT	16
+#define HWCAP_ARM_FPA		32
+#define HWCAP_ARM_VFP		64
+#define HWCAP_ARM_EDSP		128
+#define HWCAP_ARM_JAVA		256
+#define HWCAP_ARM_IWMMXT	512
+#define HWCAP_ARM_CRUNCH	1024
+#define HWCAP_ARM_THUMBEE	2048
+#define HWCAP_ARM_NEON		4096
+#define HWCAP_ARM_VFPv3		8192
+#define HWCAP_ARM_VFPv3D16	16384
+#define HWCAP_ARM_TLS		32768
+#define HWCAP_ARM_VFPv4		65536
+#define HWCAP_ARM_IDIVA		131072
+#define HWCAP_ARM_IDIVT		262144
+
 /* Bits present in AT_HWCAP for PowerPC.  */
 
 #define PPC_FEATURE_32                  0x80000000
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 6c4854d..f56666c 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -22,6 +22,8 @@
  * THE SOFTWARE.
  */
 
+#include "elf.h"
+
 /* The __ARM_ARCH define is provided by gcc 4.8.  Construct it otherwise.  */
 #ifndef __ARM_ARCH
 # if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
@@ -56,9 +58,6 @@ static int arm_arch = __ARM_ARCH;
 #ifndef use_idiv_instructions
 bool use_idiv_instructions;
 #endif
-#ifdef CONFIG_GETAUXVAL
-# include <sys/auxv.h>
-#endif
 
 #ifndef NDEBUG
 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
@@ -2030,22 +2029,20 @@ static const TCGTargetOpDef arm_op_defs[] = {
 
 static void tcg_target_init(TCGContext *s)
 {
-#if defined(CONFIG_GETAUXVAL)
     /* Only probe for the platform and capabilities if we havn't already
        determined maximum values at compile time.  */
-# if !defined(use_idiv_instructions)
+#ifndef use_idiv_instructions
     {
-        unsigned long hwcap = getauxval(AT_HWCAP);
+        unsigned long hwcap = qemu_getauxval(AT_HWCAP);
         use_idiv_instructions = (hwcap & HWCAP_ARM_IDIVA) != 0;
     }
-# endif
+#endif
     if (__ARM_ARCH < 7) {
-        const char *pl = (const char *)getauxval(AT_PLATFORM);
+        const char *pl = (const char *)qemu_getauxval(AT_PLATFORM);
         if (pl != NULL && pl[0] == 'v' && pl[1] >= '4' && pl[1] <= '9') {
             arm_arch = pl[1] - '0';
         }
     }
-#endif /* GETAUXVAL */
 
     tcg_regset_set32(tcg_target_available_regs[TCG_TYPE_I32], 0, 0xffff);
     tcg_regset_set32(tcg_target_call_clobber_regs, 0,
-- 
1.8.1.4

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

* [Qemu-devel] [PATCH 4/6] tcg-s390: Use qemu_getauxval in query_facilities
  2013-08-17 22:38 [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
                   ` (2 preceding siblings ...)
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 3/6] tcg-arm: " Richard Henderson
@ 2013-08-17 22:38 ` Richard Henderson
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 5/6] util: Provide fallback hwcap and platform for powerpc Richard Henderson
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2013-08-17 22:38 UTC (permalink / raw)
  To: qemu-devel

No need to set up a SIGILL signal handler for detection anymore.

Remove a ton of sanity checks that must be true, given that we're
requiring a 64-bit build (the note about 31-bit KVM is satisfied
by configuring with TCI).

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/elf.h         | 14 ++++++++
 tcg/s390/tcg-target.c | 95 +++++++--------------------------------------------
 2 files changed, 26 insertions(+), 83 deletions(-)

diff --git a/include/elf.h b/include/elf.h
index e95fa95..354ff1a 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -476,6 +476,20 @@ typedef struct {
 #define HWCAP_SPARC_V9		16
 #define HWCAP_SPARC_ULTRA3	32
 
+/* Bits present in AT_HWCAP for s390.  */
+
+#define HWCAP_S390_ESAN3        1
+#define HWCAP_S390_ZARCH        2
+#define HWCAP_S390_STFLE        4
+#define HWCAP_S390_MSA          8
+#define HWCAP_S390_LDISP        16
+#define HWCAP_S390_EIMM         32
+#define HWCAP_S390_DFP          64
+#define HWCAP_S390_HPAGE        128
+#define HWCAP_S390_ETF3EH       256
+#define HWCAP_S390_HIGH_GPRS    512
+#define HWCAP_S390_TE           1024
+
 /*
  * 68k ELF relocation types
  */
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index f229f1c..6862e2f 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -29,6 +29,8 @@
 #error "unsupported code generation mode"
 #endif
 
+#include "elf.h"
+
 /* ??? The translation blocks produced by TCG are generally small enough to
    be entirely reachable with a 16-bit displacement.  Leaving the option for
    a 32-bit displacement here Just In Case.  */
@@ -2234,91 +2236,18 @@ static void sigill_handler(int sig)
 
 static void query_facilities(void)
 {
-    struct sigaction sa_old, sa_new;
-    register int r0 __asm__("0");
-    register void *r1 __asm__("1");
-    int fail;
-
-    memset(&sa_new, 0, sizeof(sa_new));
-    sa_new.sa_handler = sigill_handler;
-    sigaction(SIGILL, &sa_new, &sa_old);
-
-    /* First, try STORE FACILITY LIST EXTENDED.  If this is present, then
-       we need not do any more probing.  Unfortunately, this itself is an
-       extension and the original STORE FACILITY LIST instruction is
-       kernel-only, storing its results at absolute address 200.  */
-    /* stfle 0(%r1) */
-    r1 = &facilities;
-    asm volatile(".word 0xb2b0,0x1000"
-                 : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
-
-    if (got_sigill) {
-        /* STORE FACILITY EXTENDED is not available.  Probe for one of each
-           kind of instruction that we're interested in.  */
-        /* ??? Possibly some of these are in practice never present unless
-           the store-facility-extended facility is also present.  But since
-           that isn't documented it's just better to probe for each.  */
-
-        /* Test for z/Architecture.  Required even in 31-bit mode.  */
-        got_sigill = 0;
-        /* agr %r0,%r0 */
-        asm volatile(".word 0xb908,0x0000" : "=r"(r0) : : "cc");
-        if (!got_sigill) {
-            facilities |= FACILITY_ZARCH_ACTIVE;
-        }
-
-        /* Test for long displacement.  */
-        got_sigill = 0;
-        /* ly %r0,0(%r1) */
-        r1 = &facilities;
-        asm volatile(".word 0xe300,0x1000,0x0058"
-                     : "=r"(r0) : "r"(r1) : "cc");
-        if (!got_sigill) {
-            facilities |= FACILITY_LONG_DISP;
-        }
-
-        /* Test for extended immediates.  */
-        got_sigill = 0;
-        /* afi %r0,0 */
-        asm volatile(".word 0xc209,0x0000,0x0000" : : : "cc");
-        if (!got_sigill) {
-            facilities |= FACILITY_EXT_IMM;
-        }
-
-        /* Test for general-instructions-extension.  */
-        got_sigill = 0;
-        /* msfi %r0,1 */
-        asm volatile(".word 0xc201,0x0000,0x0001");
-        if (!got_sigill) {
-            facilities |= FACILITY_GEN_INST_EXT;
-        }
-    }
-
-    sigaction(SIGILL, &sa_old, NULL);
+    unsigned long hwcap = qemu_getauxval(AT_HWCAP);
 
-    /* The translator currently uses these extensions unconditionally.
-       Pruning this back to the base ESA/390 architecture doesn't seem
-       worthwhile, since even the KVM target requires z/Arch.  */
-    fail = 0;
-    if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
-        fprintf(stderr, "TCG: z/Arch facility is required.\n");
-        fprintf(stderr, "TCG: Boot with a 64-bit enabled kernel.\n");
-        fail = 1;
-    }
-    if ((facilities & FACILITY_LONG_DISP) == 0) {
-        fprintf(stderr, "TCG: long-displacement facility is required.\n");
-        fail = 1;
-    }
+    /* Is STORE FACILITY LIST EXTENDED available?  Honestly, I believe this
+       is present on all 64-bit systems, but let's check for it anyway.  */
+    if (hwcap & HWCAP_S390_STFLE) {
+        register int r0 __asm__("0");
+        register void *r1 __asm__("1");
 
-    /* So far there's just enough support for 31-bit mode to let the
-       compile succeed.  This is good enough to run QEMU with KVM.  */
-    if (sizeof(void *) != 8) {
-        fprintf(stderr, "TCG: 31-bit mode is not supported.\n");
-        fail = 1;
-    }
-
-    if (fail) {
-        exit(-1);
+        /* stfle 0(%r1) */
+        r1 = &facilities;
+        asm volatile(".word 0xb2b0,0x1000"
+                     : "=r"(r0) : "0"(0), "r"(r1) : "memory", "cc");
     }
 }
 
-- 
1.8.1.4

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

* [Qemu-devel] [PATCH 5/6] util: Provide fallback hwcap and platform for powerpc
  2013-08-17 22:38 [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
                   ` (3 preceding siblings ...)
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 4/6] tcg-s390: Use qemu_getauxval in query_facilities Richard Henderson
@ 2013-08-17 22:38 ` Richard Henderson
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 6/6] util: Use qemu_getauxval in linux qemu_cache_utils_init Richard Henderson
  2013-08-26 20:26 ` [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
  6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2013-08-17 22:38 UTC (permalink / raw)
  To: qemu-devel

Allow host "detection" on non-linux hosts.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 util/getauxval.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 2 deletions(-)

diff --git a/util/getauxval.c b/util/getauxval.c
index 55b639c..2e93a14 100644
--- a/util/getauxval.c
+++ b/util/getauxval.c
@@ -60,12 +60,64 @@ void qemu_init_auxval(char **envp)
 
 static const char *default_platform(void)
 {
-    return NULL;
+    const char *ret = NULL;
+
+#ifdef _ARCH_PPC
+# if defined(_ARCH_PWR8)
+    ret = "power8";
+# elif defined(_ARCH_PWR7)
+    ret = "power7";
+# elif defined(_ARCH_PWR6X) || defined(_ARCH_PWR6)
+    ret = "power6";
+# elif defined(_ARCH_PWR5X)
+    ret = "power5+";
+# elif defined(_ARCH_PWR5)
+    ret = "power5";
+# elif defined(_ARCH_PWR4)
+    ret = "power4";
+# else
+    ret = "power3";
+# endif
+#endif /* _ARCH_PPC */
+
+    return ret;
 }
 
 static unsigned long default_hwcap(void)
 {
-    return 0;
+    unsigned long ret = 0;
+
+#ifdef _ARCH_PPC
+# if defined(_ARCH_PWR8) || defined(_ARCH_PWR7)
+    ret |= PPC_FEATURE_ARCH_2_06;
+# elif defined(_ARCH_PWR6X) || defined(_ARCH_PWR6)
+    ret |= PPC_FEATURE_ARCH_2_05;
+# elif defined(_ARCH_PWR5X)
+    ret |= PPC_FEATURE_POWER5_PLUS;
+# elif defined(_ARCH_PWR5)
+    ret |= PPC_FEATURE_POWER5;
+# elif defined(_ARCH_PWR4)
+    ret |= PPC_FEATURE_POWER4;
+# endif
+# if defined(_ARCH_PWR6) /* and later */
+    ret |= PPC_FEATURE_TRUE_LE | PPC_FEATURE_PSERIES_PERFMON_COMPAT;
+# endif
+# if defined(_ARCH_PWR5) /* and later */
+    ret |= PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP;
+# endif
+# if defined(_ARCH_PPC64)
+    ret |= PPC_FEATURE_64;
+# endif
+# if defined(__VSX__)
+    ret |= PPC_FEATURE_HAS_VSX;
+# endif
+# if defined(__ALTIVEC__)
+    ret |= PPC_FEATURE_HAS_ALTIVEC;
+# endif
+    ret |= PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | PPC_FEATURE_HAS_MMU;
+#endif /* _ARCH_PPC */
+
+    return ret;
 }
 
 unsigned long qemu_getauxval(unsigned long type)
-- 
1.8.1.4

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

* [Qemu-devel] [PATCH 6/6] util: Use qemu_getauxval in linux qemu_cache_utils_init
  2013-08-17 22:38 [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
                   ` (4 preceding siblings ...)
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 5/6] util: Provide fallback hwcap and platform for powerpc Richard Henderson
@ 2013-08-17 22:38 ` Richard Henderson
  2013-08-26 20:26 ` [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
  6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2013-08-17 22:38 UTC (permalink / raw)
  To: qemu-devel

With this we no longer pass down envp, and thus all systems can have
the same void prototype.  So also eliminate a useless thunk.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 include/qemu/cache-utils.h |  4 ++--
 linux-user/main.c          |  2 +-
 util/cache-utils.c         | 51 ++++++++++++++++++----------------------------
 vl.c                       |  2 +-
 4 files changed, 24 insertions(+), 35 deletions(-)

diff --git a/include/qemu/cache-utils.h b/include/qemu/cache-utils.h
index 2c57f78..211245b 100644
--- a/include/qemu/cache-utils.h
+++ b/include/qemu/cache-utils.h
@@ -12,7 +12,7 @@ struct qemu_cache_conf {
 
 extern struct qemu_cache_conf qemu_cache_conf;
 
-void qemu_cache_utils_init(char **envp);
+void qemu_cache_utils_init(void);
 
 /* mildly adjusted code from tcg-dyngen.c */
 static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
@@ -38,7 +38,7 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 }
 
 #else
-#define qemu_cache_utils_init(envp) do { (void) (envp); } while (0)
+#define qemu_cache_utils_init() do { } while (0)
 #endif
 
 #endif /* QEMU_CACHE_UTILS_H */
diff --git a/linux-user/main.c b/linux-user/main.c
index fae102a..b1200ef 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3550,7 +3550,7 @@ int main(int argc, char **argv, char **envp)
     module_call_init(MODULE_INIT_QOM);
 
     qemu_init_auxval(envp);
-    qemu_cache_utils_init(envp);
+    qemu_cache_utils_init();
 
     if ((envlist = envlist_create()) == NULL) {
         (void) fprintf(stderr, "Unable to allocate envlist\n");
diff --git a/util/cache-utils.c b/util/cache-utils.c
index b94013a..0470030 100644
--- a/util/cache-utils.c
+++ b/util/cache-utils.c
@@ -1,3 +1,4 @@
+#include "qemu-common.h"
 #include "qemu/cache-utils.h"
 
 #if defined(_ARCH_PPC)
@@ -9,31 +10,33 @@ struct qemu_cache_conf qemu_cache_conf = {
 #if defined _AIX
 #include <sys/systemcfg.h>
 
-static void ppc_init_cacheline_sizes(void)
+void qemu_cache_utils_init(void)
 {
     qemu_cache_conf.icache_bsize = _system_configuration.icache_line;
     qemu_cache_conf.dcache_bsize = _system_configuration.dcache_line;
 }
 
 #elif defined __linux__
+#include "qemu/osdep.h"
+#include "elf.h"
 
-#define QEMU_AT_NULL        0
-#define QEMU_AT_DCACHEBSIZE 19
-#define QEMU_AT_ICACHEBSIZE 20
-
-static void ppc_init_cacheline_sizes(char **envp)
+void qemu_cache_utils_init(void)
 {
-    unsigned long *auxv;
-
-    while (*envp++);
+    unsigned long dsize = qemu_getauxval(AT_DCACHEBSIZE);
+    unsigned long isize = qemu_getauxval(AT_ICACHEBSIZE);
 
-    for (auxv = (unsigned long *) envp; *auxv != QEMU_AT_NULL; auxv += 2) {
-        switch (*auxv) {
-        case QEMU_AT_DCACHEBSIZE: qemu_cache_conf.dcache_bsize = auxv[1]; break;
-        case QEMU_AT_ICACHEBSIZE: qemu_cache_conf.icache_bsize = auxv[1]; break;
-        default: break;
+    if (dsize == 0 || isize == 0) {
+        if (dsize == 0) {
+            fprintf(stderr, "getauxval AT_DCACHEBSIZE failed\n");
+        }
+        if (isize == 0) {
+            fprintf(stderr, "getauxval AT_ICACHEBSIZE failed\n");
         }
+        exit(1);
+
     }
+    qemu_cache_conf.dcache_bsize = dsize;
+    qemu_cache_conf.icache_bsize = isize;
 }
 
 #elif defined __APPLE__
@@ -41,7 +44,7 @@ static void ppc_init_cacheline_sizes(char **envp)
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
-static void ppc_init_cacheline_sizes(void)
+void qemu_cache_utils_init(void)
 {
     size_t len;
     unsigned cacheline;
@@ -55,9 +58,8 @@ static void ppc_init_cacheline_sizes(void)
         qemu_cache_conf.icache_bsize = cacheline;
     }
 }
-#endif
 
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -65,7 +67,7 @@ static void ppc_init_cacheline_sizes(void)
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
-static void ppc_init_cacheline_sizes(void)
+void qemu_cache_utils_init(void)
 {
     size_t len = 4;
     unsigned cacheline;
@@ -81,17 +83,4 @@ static void ppc_init_cacheline_sizes(void)
 }
 #endif
 
-#ifdef __linux__
-void qemu_cache_utils_init(char **envp)
-{
-    ppc_init_cacheline_sizes(envp);
-}
-#else
-void qemu_cache_utils_init(char **envp)
-{
-    (void) envp;
-    ppc_init_cacheline_sizes();
-}
-#endif
-
 #endif /* _ARCH_PPC */
diff --git a/vl.c b/vl.c
index c539fd3..51d2c18 100644
--- a/vl.c
+++ b/vl.c
@@ -2968,7 +2968,7 @@ int main(int argc, char **argv, char **envp)
     rtc_clock = host_clock;
 
     qemu_init_auxval(envp);
-    qemu_cache_utils_init(envp);
+    qemu_cache_utils_init();
 
     QLIST_INIT (&vm_change_state_head);
     os_setup_early_signal_handling();
-- 
1.8.1.4

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

* Re: [Qemu-devel] [PATCH 0/6] Improve getauxval support
  2013-08-17 22:38 [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
                   ` (5 preceding siblings ...)
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 6/6] util: Use qemu_getauxval in linux qemu_cache_utils_init Richard Henderson
@ 2013-08-26 20:26 ` Richard Henderson
  6 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2013-08-26 20:26 UTC (permalink / raw)
  To: qemu-devel

Ping.

r~

On 08/17/2013 03:38 PM, Richard Henderson wrote:
> The getauxval routine was added to glibc for 2.16.  In order to 
> better support qemu on systems prior to 2.16, add a qemu_getauxval
> entry point, and add the relevant defines to our own elf.h.
> 
> 
> r~
> 
> 
> Richard Henderson (6):
>   osdep: Create qemu_getauxval and qemu_init_auxval
>   tcg-ppc64: Use qemu_getauxval
>   tcg-arm: Use qemu_getauxval
>   tcg-s390: Use qemu_getauxval in query_facilities
>   util: Provide fallback hwcap and platform for powerpc
>   util: Use qemu_getauxval in linux qemu_cache_utils_init
> 
>  include/elf.h              |  70 ++++++++++++++++++++++
>  include/qemu/cache-utils.h |   4 +-
>  include/qemu/osdep.h       |  20 +++++++
>  linux-user/main.c          |   3 +-
>  tcg/arm/tcg-target.c       |  15 ++---
>  tcg/ppc64/tcg-target.c     |  11 +---
>  tcg/s390/tcg-target.c      |  95 ++++--------------------------
>  util/Makefile.objs         |   1 +
>  util/cache-utils.c         |  51 +++++++---------
>  util/getauxval.c           | 143 +++++++++++++++++++++++++++++++++++++++++++++
>  vl.c                       |   3 +-
>  11 files changed, 280 insertions(+), 136 deletions(-)
>  create mode 100644 util/getauxval.c
> 

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

* Re: [Qemu-devel] [PATCH 1/6] osdep: Create qemu_getauxval and qemu_init_auxval
  2013-08-17 22:38 ` [Qemu-devel] [PATCH 1/6] osdep: Create qemu_getauxval and qemu_init_auxval Richard Henderson
@ 2013-08-29 21:17   ` Aurelien Jarno
  0 siblings, 0 replies; 9+ messages in thread
From: Aurelien Jarno @ 2013-08-29 21:17 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel

On Sat, Aug 17, 2013 at 03:38:03PM -0700, Richard Henderson wrote:
> Abstract away dependence on a system implementation of getauxval.
> 
> Signed-off-by: Richard Henderson <rth@twiddle.net>
> ---
>  include/qemu/osdep.h | 20 ++++++++++++
>  linux-user/main.c    |  1 +
>  util/Makefile.objs   |  1 +
>  util/getauxval.c     | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  vl.c                 |  1 +
>  5 files changed, 114 insertions(+)
>  create mode 100644 util/getauxval.c
> 
> diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
> index 26136f1..8d1948b 100644
> --- a/include/qemu/osdep.h
> +++ b/include/qemu/osdep.h
> @@ -215,4 +215,24 @@ bool fips_get_state(void);
>   */
>  char *qemu_get_local_state_pathname(const char *relative_pathname);
>  
> +/* Return a value for an AT_* type in the auxiliary vector.  Return 0 if the
> + * key is not present.  We attempt to emulate AT_HWCAP and AT_PLATFORM as
> + * best we can when real host support is not present.
> + */
> +#ifdef _WIN32
> +static inline unsigned long qemu_getauxval(unsigned long type) { return 0; }
> +#else
> +unsigned long qemu_getauxval(unsigned long type);
> +#endif
> +
> +/* If supported and required, locate the auxiliary vector at program startup.
> + *
> + * @envp must be the third argument to main.
> + */
> +#if defined(CONFIG_GETAUXVAL) || defined(_WIN32)
> +static inline void qemu_init_auxval(char **envp) { }
> +#else
> +void qemu_init_auxval(char **envp);
> +#endif
> +
>  #endif
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 03859bc..fae102a 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -3549,6 +3549,7 @@ int main(int argc, char **argv, char **envp)
>  
>      module_call_init(MODULE_INIT_QOM);
>  
> +    qemu_init_auxval(envp);
>      qemu_cache_utils_init(envp);
>  
>      if ((envlist = envlist_create()) == NULL) {
> diff --git a/util/Makefile.objs b/util/Makefile.objs
> index dc72ab0..8e0c929 100644
> --- a/util/Makefile.objs
> +++ b/util/Makefile.objs
> @@ -11,3 +11,4 @@ util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o uri.o notify.o
>  util-obj-y += qemu-option.o qemu-progress.o
>  util-obj-y += hexdump.o
>  util-obj-y += crc32c.o
> +util-obj-y += getauxval.o
> diff --git a/util/getauxval.c b/util/getauxval.c
> new file mode 100644
> index 0000000..55b639c
> --- /dev/null
> +++ b/util/getauxval.c
> @@ -0,0 +1,91 @@
> +/*
> + * QEMU access to the auxiliary vector
> + *
> + * Copyright (C) 2013 Red Hat, Inc
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + */
> +
> +#include "qemu-common.h"
> +#include "qemu/osdep.h"
> +
> +#ifdef CONFIG_GETAUXVAL
> +/* Don't inline this in qemu/osdep.h, because pulling in <sys/auxv.h> for
> +   the system declaration of getauxval pulls in the system <elf.h>, which
> +   conflicts with qemu's version.  */
> +
> +#include <sys/auxv.h>
> +
> +unsigned long qemu_getauxval(unsigned long key)
> +{
> +    return getauxval(key);
> +}
> +#elif !defined(_WIN32)
> +#include "elf.h"
> +
> +/* Our elf.h doesn't contain Elf32_auxv_t and Elf64_auxv_t, which is ok because
> +   that just makes it easier to define it properly for the host here.  */
> +typedef struct {
> +    unsigned long a_type;
> +    unsigned long a_val;
> +} ElfW_auxv_t;
> +
> +static const ElfW_auxv_t *auxv;
> +
> +void qemu_init_auxval(char **envp)
> +{
> +#ifdef __linux__
> +    /* The auxiliary vector is located just beyond the initial environment.  */
> +    while (*envp != NULL)
> +        continue;

This is basically an endless loop, so QEMU doesn't start on a system
without getauxval support.

> +    auxv = (const ElfW_auxv_t *)envp;
> +#endif
> +}
> +
> +static const char *default_platform(void)
> +{
> +    return NULL;
> +}
> +
> +static unsigned long default_hwcap(void)
> +{
> +    return 0;
> +}
> +
> +unsigned long qemu_getauxval(unsigned long type)
> +{
> +    /* If we were able to find the auxiliary vector, use it.  */
> +    if (auxv) {
> +        const ElfW_auxv_t *a;
> +        for (a = auxv; a->a_type != 0; a++) {
> +            if (a->a_type == type) {
> +                return a->a_val;
> +            }
> +        }
> +    }
> +
> +    /* Otherwise, guess defaults for the host based on compiler flags.  */
> +    if (type == AT_HWCAP) {
> +        return default_hwcap();
> +    } else if (type == AT_PLATFORM) {
> +        return (unsigned long)default_platform();
> +    }
> +    return 0;
> +}
> +#endif
> diff --git a/vl.c b/vl.c
> index f422a1c..c539fd3 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -2967,6 +2967,7 @@ int main(int argc, char **argv, char **envp)
>      init_clocks();
>      rtc_clock = host_clock;
>  
> +    qemu_init_auxval(envp);
>      qemu_cache_utils_init(envp);
>  
>      QLIST_INIT (&vm_change_state_head);
> -- 
> 1.8.1.4
> 
> 
> 

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net

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

end of thread, other threads:[~2013-08-29 21:17 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-17 22:38 [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson
2013-08-17 22:38 ` [Qemu-devel] [PATCH 1/6] osdep: Create qemu_getauxval and qemu_init_auxval Richard Henderson
2013-08-29 21:17   ` Aurelien Jarno
2013-08-17 22:38 ` [Qemu-devel] [PATCH 2/6] tcg-ppc64: Use qemu_getauxval Richard Henderson
2013-08-17 22:38 ` [Qemu-devel] [PATCH 3/6] tcg-arm: " Richard Henderson
2013-08-17 22:38 ` [Qemu-devel] [PATCH 4/6] tcg-s390: Use qemu_getauxval in query_facilities Richard Henderson
2013-08-17 22:38 ` [Qemu-devel] [PATCH 5/6] util: Provide fallback hwcap and platform for powerpc Richard Henderson
2013-08-17 22:38 ` [Qemu-devel] [PATCH 6/6] util: Use qemu_getauxval in linux qemu_cache_utils_init Richard Henderson
2013-08-26 20:26 ` [Qemu-devel] [PATCH 0/6] Improve getauxval support Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.