qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation
@ 2023-06-26  8:33 Paolo Bonzini
  2023-06-26  8:33 ` [PATCH v2 1/3] target/i386: ignore ARCH_CAPABILITIES features in " Paolo Bonzini
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Paolo Bonzini @ 2023-06-26  8:33 UTC (permalink / raw)
  To: qemu-devel

When running qemu-i386 even with -cpu Nehalem (aka x86_64-v2), it raises the
warning

  TCG doesn't support requested feature: CPUID.80000001H:EDX.lm [bit 29]

Likewise using qemu-x86_64 with -cpu Haswell, it raises warnings for

  TCG doesn't support requested feature: CPUID.01H:ECX.pcid [bit 17]
  TCG doesn't support requested feature: CPUID.01H:ECX.x2apic [bit 21]
  TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
  TCG doesn't support requested feature: CPUID.07H:EBX.invpcid [bit 10]

Even though x86_64-v3 is the level that qemu-user is supposed to provide.
These are two related problems:

- for Haswell, the 4 missing features are only relevant to code running
  in kernel mode; we can ignore them and mark them as supported even
  though they are not.  The supported features are only used to print
  the warnings

- for qemu-i386, the issue is that this emulator is restricted to running
  programs on a 32-bit processor, even though it is actually emulating
  programs that use the 32-bit kernel ABI on any processor.  The behavior
  the processor in compatibility (32-bit CS, EFER.LMA=1) mode is mostly
  the same as when EFER.LMA=0 and the little code that is needed to handle
  64-bit ring-0 is even present in the qemu-i386 binary, just hidden
  behind checks for HF_LMA_MASK.  So, LM can also be treated as a feature
  that is only relevant in kernel mode; not entirely, so this cannot yet
  be extended to bsd-user, but the required changes are minimal.

Other CPU models have warnings for the ARCH_CAPABILITIES MSR; hide
them as well in a similar manner.

Based-on: <20230623131711.96775-1-pbonzini@redhat.com>

Paolo Bonzini (3):
  target/i386: ignore ARCH_CAPABILITIES features in user mode emulation
  target/i386: ignore CPL0-specific features in user mode emulation
  target/i386: emulate 64-bit ring 0 for linux-user if LM feature is set

 linux-user/i386/cpu_loop.c  |  57 ++++++++++----------
 target/i386/cpu.c           | 103 +++++++++++++++++++++++++++++++++---
 target/i386/tcg/translate.c |   6 ++-
 3 files changed, 126 insertions(+), 40 deletions(-)

-- 
2.41.0



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

* [PATCH v2 1/3] target/i386: ignore ARCH_CAPABILITIES features in user mode emulation
  2023-06-26  8:33 [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation Paolo Bonzini
@ 2023-06-26  8:33 ` Paolo Bonzini
  2023-06-26 10:04   ` Richard Henderson
  2023-06-26  8:33 ` [PATCH v2 2/3] target/i386: ignore CPL0-specific " Paolo Bonzini
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Paolo Bonzini @ 2023-06-26  8:33 UTC (permalink / raw)
  To: qemu-devel

ARCH_CAPABILITIES is only accessible through a read-only MSR, so it has
no impact on any user-mode operation (user-mode cannot read the MSR).
So do not bother printing warnings about it in user mode emulation.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c0fb6b3ad92..8387843c4d9 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1069,6 +1069,13 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
         .msr = {
             .index = MSR_IA32_ARCH_CAPABILITIES,
         },
+        /*
+         * FEAT_ARCH_CAPABILITIES only affects a read-only MSR, which
+         * cannot be read from user mode.  Therefore, it has no impact
+         > on any user-mode operation, and warnings about unsupported
+         * features do not matter.
+         */
+        .tcg_features = ~0U,
     },
     [FEAT_CORE_CAPABILITY] = {
         .type = MSR_FEATURE_WORD,
-- 
2.41.0



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

* [PATCH v2 2/3] target/i386: ignore CPL0-specific features in user mode emulation
  2023-06-26  8:33 [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation Paolo Bonzini
  2023-06-26  8:33 ` [PATCH v2 1/3] target/i386: ignore ARCH_CAPABILITIES features in " Paolo Bonzini
@ 2023-06-26  8:33 ` Paolo Bonzini
  2023-06-26 10:04   ` Richard Henderson
  2023-06-26  8:33 ` [PATCH v2 3/3] target/i386: emulate 64-bit ring 0 for linux-user if LM feature is set Paolo Bonzini
  2023-06-26  9:20 ` [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation Daniel P. Berrangé
  3 siblings, 1 reply; 11+ messages in thread
From: Paolo Bonzini @ 2023-06-26  8:33 UTC (permalink / raw)
  To: qemu-devel

Features such as PCID are only accessible through privileged operations,
and therefore have no impact on any user-mode operation.  Allow reporting
them to programs running under user mode emulation, so that "-cpu" can be
used with more named CPU models.

XSAVES would be similar, but it doesn't make sense to provide it until
XSAVEC is implemented.

With this change, all CPUs up to Broadwell-v4 can be emulate.  Skylake-Client
requires XSAVEC, while EPYC also requires SHA-NI, MISALIGNSSE and TOPOEXT.
MISALIGNSSE is not hard to implement, but I am not sure it is worth using
a precious hflags bit for it.

Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1534
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 target/i386/cpu.c | 83 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 76 insertions(+), 7 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 8387843c4d9..69a1f2f805b 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -623,13 +623,25 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
           CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */
           /* missing:
           CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
+
+/*
+ * Kernel-only features that can be shown to usermode programs even if
+ * they aren't actually supported by TCG, because qemu-user only runs
+ * in CPL=3; remove them if they are ever implemented for system emulation.
+ */
+#if defined CONFIG_USER_ONLY
+#define CPUID_EXT_KERNEL_FEATURES (CPUID_EXT_PCID | CPUID_EXT_TSC_DEADLINE_TIMER | \
+                                 CPUID_EXT_X2APIC)
+#else
+#define CPUID_EXT_KERNEL_FEATURES 0
+#endif
 #define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
           CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
           CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
           CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */   \
           CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \
           CPUID_EXT_RDRAND | CPUID_EXT_AVX | CPUID_EXT_F16C | \
-          CPUID_EXT_FMA)
+          CPUID_EXT_FMA | CPUID_EXT_KERNEL_FEATURES)
           /* missing:
           CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
           CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID,
@@ -642,22 +654,63 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
 #define TCG_EXT2_X86_64_FEATURES 0
 #endif
 
+/*
+ * CPUID_*_KERNEL_FEATURES denotes bits and features that are not usable
+ * in usermode or by 32-bit programs.  Those are added to supported
+ * TCG features unconditionally in user-mode emulation mode.  This may
+ * indeed seem strange or incorrect, but it works because code running
+ * under usermode emulation cannot access them.
+ *
+ * Even for long mode, qemu-i386 is not running "a userspace program on a
+ * 32-bit CPU"; it's running "a userspace program with a 32-bit code segment"
+ * and therefore using the 32-bit ABI; the CPU itself might be 64-bit
+ * but again the difference is only visible in kernel mode.
+ */
+#if defined CONFIG_USER_ONLY
+#define CPUID_EXT2_KERNEL_FEATURES CPUID_EXT2_FFXSR
+#else
+#define CPUID_EXT2_KERNEL_FEATURES 0
+#endif
+
 #define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
           CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
           CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \
-          CPUID_EXT2_SYSCALL | TCG_EXT2_X86_64_FEATURES)
+          CPUID_EXT2_SYSCALL | TCG_EXT2_X86_64_FEATURES | \
+          CPUID_EXT2_KERNEL_FEATURES)
+
+#if defined CONFIG_USER_ONLY
+#define CPUID_EXT3_KERNEL_FEATURES CPUID_EXT3_OSVW
+#else
+#define CPUID_EXT3_KERNEL_FEATURES 0
+#endif
+
 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
           CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A | \
-          CPUID_EXT3_3DNOWPREFETCH)
+          CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_KERNEL_FEATURES)
+
 #define TCG_EXT4_FEATURES 0
+
+#if defined CONFIG_USER_ONLY
+#define CPUID_SVM_KERNEL_FEATURES (CPUID_SVM_NRIPSAVE | CPUID_SVM_VNMI)
+#else
+#define CPUID_SVM_KERNEL_FEATURES 0
+#endif
 #define TCG_SVM_FEATURES (CPUID_SVM_NPT | CPUID_SVM_VGIF | \
-          CPUID_SVM_SVME_ADDR_CHK)
+          CPUID_SVM_SVME_ADDR_CHK | CPUID_SVM_KERNEL_FEATURES)
+
 #define TCG_KVM_FEATURES 0
+
+#if defined CONFIG_USER_ONLY
+#define CPUID_7_0_EBX_KERNEL_FEATURES CPUID_7_0_EBX_INVPCID
+#else
+#define CPUID_7_0_EBX_KERNEL_FEATURES 0
+#endif
 #define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
           CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
           CPUID_7_0_EBX_PCOMMIT | CPUID_7_0_EBX_CLFLUSHOPT |            \
           CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_FSGSBASE | \
-          CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_RDSEED)
+          CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_RDSEED | \
+          CPUID_7_0_EBX_KERNEL_FEATURES)
           /* missing:
           CPUID_7_0_EBX_HLE
           CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM */
@@ -672,7 +725,14 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
           CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS | CPUID_7_0_ECX_VAES | \
           TCG_7_0_ECX_RDPID)
 
-#define TCG_7_0_EDX_FEATURES CPUID_7_0_EDX_FSRM
+#if defined CONFIG_USER_ONLY
+#define CPUID_7_0_EDX_KERNEL_FEATURES (CPUID_7_0_EDX_SPEC_CTRL | \
+          CPUID_7_0_EDX_ARCH_CAPABILITIES | CPUID_7_0_EDX_SPEC_CTRL_SSBD)
+#else
+#define CPUID_7_0_EDX_KERNEL_FEATURES 0
+#endif
+#define TCG_7_0_EDX_FEATURES (CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_KERNEL_FEATURES)
+
 #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \
           CPUID_7_1_EAX_FSRC)
 #define TCG_7_1_EDX_FEATURES 0
@@ -686,8 +746,17 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
 #define TCG_SGX_12_0_EBX_FEATURES 0
 #define TCG_SGX_12_1_EAX_FEATURES 0
 
+#if defined CONFIG_USER_ONLY
+#define CPUID_8000_0008_EBX_KERNEL_FEATURES (CPUID_8000_0008_EBX_IBPB | \
+          CPUID_8000_0008_EBX_IBRS | CPUID_8000_0008_EBX_STIBP | \
+          CPUID_8000_0008_EBX_STIBP_ALWAYS_ON | CPUID_8000_0008_EBX_AMD_SSBD | \
+          CPUID_8000_0008_EBX_AMD_PSFD)
+#else
+#define CPUID_8000_0008_EBX_KERNEL_FEATURES 0
+#endif
+
 #define TCG_8000_0008_EBX  (CPUID_8000_0008_EBX_XSAVEERPTR | \
-          CPUID_8000_0008_EBX_WBNOINVD)
+          CPUID_8000_0008_EBX_WBNOINVD | CPUID_8000_0008_EBX_KERNEL_FEATURES)
 
 FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
     [FEAT_1_EDX] = {
-- 
2.41.0



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

* [PATCH v2 3/3] target/i386: emulate 64-bit ring 0 for linux-user if LM feature is set
  2023-06-26  8:33 [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation Paolo Bonzini
  2023-06-26  8:33 ` [PATCH v2 1/3] target/i386: ignore ARCH_CAPABILITIES features in " Paolo Bonzini
  2023-06-26  8:33 ` [PATCH v2 2/3] target/i386: ignore CPL0-specific " Paolo Bonzini
@ 2023-06-26  8:33 ` Paolo Bonzini
  2023-06-26  9:20 ` [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation Daniel P. Berrangé
  3 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2023-06-26  8:33 UTC (permalink / raw)
  To: qemu-devel

32-bit binaries can run on a long mode processor even if the kernel
is 64-bit, of course, and this can have slightly different behavior;
for example, SYSCALL is allowed on Intel processors.

Allow reporting LM to programs running under user mode emulation,
so that "-cpu" can be used with named CPU models even for qemu-i386
and even without disabling LM by hand.

Fortunately, most of the runtime code in QEMU has to depend on HF_LMA_MASK
or on HF_CS64_MASK (which is anyway false for qemu-i386's 32-bit code
segment) rather than TARGET_X86_64, therefore all that is needed is an
update of linux-user's ring 0 setup.

Fixes: https://gitlab.com/qemu-project/qemu/-/issues/1534
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 linux-user/i386/cpu_loop.c  | 57 ++++++++++++++++++-------------------
 target/i386/cpu.c           | 15 ++++++++--
 target/i386/tcg/translate.c |  6 ++--
 3 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index 9eeda551eaf..ef2dcb3d767 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -47,7 +47,7 @@ static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
 }
 
 static uint64_t *idt_table;
-#ifdef TARGET_X86_64
+
 static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
                        uint64_t addr, unsigned int sel)
 {
@@ -60,8 +60,10 @@ static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
     p[2] = tswap32(addr >> 32);
     p[3] = 0;
 }
+
+#ifdef TARGET_X86_64
 /* only dpl matters as we do only user space emulation */
-static void set_idt(int n, unsigned int dpl)
+static void set_idt(int n, unsigned int dpl, bool is64)
 {
     set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
 }
@@ -78,9 +80,13 @@ static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
 }
 
 /* only dpl matters as we do only user space emulation */
-static void set_idt(int n, unsigned int dpl)
+static void set_idt(int n, unsigned int dpl, bool is64)
 {
-    set_gate(idt_table + n, 0, dpl, 0, 0);
+    if (is64) {
+        set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
+    } else {
+        set_gate(idt_table + n, 0, dpl, 0, 0);
+    }
 }
 #endif
 
@@ -325,6 +331,9 @@ static void target_cpu_free(void *obj)
 void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
 {
     CPUState *cpu = env_cpu(env);
+    bool is64 = (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) != 0;
+    int i;
+
     OBJECT(cpu)->free = target_cpu_free;
     env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
     env->hflags |= HF_PE_MASK | HF_CPL_MASK;
@@ -332,15 +341,18 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
         env->cr[4] |= CR4_OSFXSR_MASK;
         env->hflags |= HF_OSFXSR_MASK;
     }
-#ifndef TARGET_ABI32
+
     /* enable 64 bit mode if possible */
-    if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
+    if (is64) {
+        env->cr[4] |= CR4_PAE_MASK;
+        env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
+        env->hflags |= HF_LMA_MASK;
+    }
+#ifndef TARGET_ABI32
+    else {
         fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
         exit(EXIT_FAILURE);
     }
-    env->cr[4] |= CR4_PAE_MASK;
-    env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
-    env->hflags |= HF_LMA_MASK;
 #endif
 
     /* flags setup : we activate the IRQs by default as in user mode */
@@ -379,27 +391,12 @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
                                 PROT_READ|PROT_WRITE,
                                 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
     idt_table = g2h_untagged(env->idt.base);
-    set_idt(0, 0);
-    set_idt(1, 0);
-    set_idt(2, 0);
-    set_idt(3, 3);
-    set_idt(4, 3);
-    set_idt(5, 0);
-    set_idt(6, 0);
-    set_idt(7, 0);
-    set_idt(8, 0);
-    set_idt(9, 0);
-    set_idt(10, 0);
-    set_idt(11, 0);
-    set_idt(12, 0);
-    set_idt(13, 0);
-    set_idt(14, 0);
-    set_idt(15, 0);
-    set_idt(16, 0);
-    set_idt(17, 0);
-    set_idt(18, 0);
-    set_idt(19, 0);
-    set_idt(0x80, 3);
+    for (i = 0; i < 20; i++) {
+        set_idt(i, 0, is64);
+    }
+    set_idt(3, 3, is64);
+    set_idt(4, 3, is64);
+    set_idt(0x80, 3, is64);
 
     /* linux segment setup */
     {
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 69a1f2f805b..958878f6064 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -666,7 +666,10 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
  * and therefore using the 32-bit ABI; the CPU itself might be 64-bit
  * but again the difference is only visible in kernel mode.
  */
-#if defined CONFIG_USER_ONLY
+#if defined CONFIG_LINUX_USER
+#define CPUID_EXT2_KERNEL_FEATURES (CPUID_EXT2_LM | CPUID_EXT2_FFXSR)
+#elif defined CONFIG_USER_ONLY
+/* FIXME: Long mode not yet supported for i386 bsd-user */
 #define CPUID_EXT2_KERNEL_FEATURES CPUID_EXT2_FFXSR
 #else
 #define CPUID_EXT2_KERNEL_FEATURES 0
@@ -5539,7 +5542,15 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
     }
 #ifndef TARGET_X86_64
     if (w == FEAT_8000_0001_EDX) {
-        r &= ~CPUID_EXT2_LM;
+        /*
+         * 32-bit TCG can emulate 64-bit compatibility mode.  If there is no
+         * way for userspace to get out of its 32-bit jail, we can leave
+         * the LM bit set.
+         */
+        uint32_t unavail = tcg_enabled()
+            ? CPUID_EXT2_LM & ~CPUID_EXT2_KERNEL_FEATURES
+            : CPUID_EXT2_LM;
+        r &= ~unavail;
     }
 #endif
     if (migratable_only) {
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 28cb3fb7f4b..90c7b32f362 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -173,12 +173,14 @@ typedef struct DisasContext {
 #endif
 #if !defined(TARGET_X86_64)
 #define CODE64(S) false
-#define LMA(S)    false
 #elif defined(CONFIG_USER_ONLY)
 #define CODE64(S) true
-#define LMA(S)    true
 #else
 #define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0)
+#endif
+#if defined(CONFIG_SOFTMMU) && !defined(TARGET_X86_64)
+#define LMA(S)    false
+#else
 #define LMA(S)    (((S)->flags & HF_LMA_MASK) != 0)
 #endif
 
-- 
2.41.0



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

* Re: [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation
  2023-06-26  8:33 [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation Paolo Bonzini
                   ` (2 preceding siblings ...)
  2023-06-26  8:33 ` [PATCH v2 3/3] target/i386: emulate 64-bit ring 0 for linux-user if LM feature is set Paolo Bonzini
@ 2023-06-26  9:20 ` Daniel P. Berrangé
  2023-06-26  9:27   ` Paolo Bonzini
  3 siblings, 1 reply; 11+ messages in thread
From: Daniel P. Berrangé @ 2023-06-26  9:20 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Mon, Jun 26, 2023 at 10:33:14AM +0200, Paolo Bonzini wrote:
> When running qemu-i386 even with -cpu Nehalem (aka x86_64-v2), it raises the
> warning
> 
>   TCG doesn't support requested feature: CPUID.80000001H:EDX.lm [bit 29]
>
> Likewise using qemu-x86_64 with -cpu Haswell, it raises warnings for
> 
>   TCG doesn't support requested feature: CPUID.01H:ECX.pcid [bit 17]
>   TCG doesn't support requested feature: CPUID.01H:ECX.x2apic [bit 21]
>   TCG doesn't support requested feature: CPUID.01H:ECX.tsc-deadline [bit 24]
>   TCG doesn't support requested feature: CPUID.07H:EBX.invpcid [bit 10]
> 
> Even though x86_64-v3 is the level that qemu-user is supposed to provide.

> These are two related problems:
> 
> - for Haswell, the 4 missing features are only relevant to code running
>   in kernel mode; we can ignore them and mark them as supported even
>   though they are not.  The supported features are only used to print
>   the warnings
> 
> - for qemu-i386, the issue is that this emulator is restricted to running
>   programs on a 32-bit processor, even though it is actually emulating
>   programs that use the 32-bit kernel ABI on any processor.  The behavior
>   the processor in compatibility (32-bit CS, EFER.LMA=1) mode is mostly
>   the same as when EFER.LMA=0 and the little code that is needed to handle
>   64-bit ring-0 is even present in the qemu-i386 binary, just hidden
>   behind checks for HF_LMA_MASK.  So, LM can also be treated as a feature
>   that is only relevant in kernel mode; not entirely, so this cannot yet
>   be extended to bsd-user, but the required changes are minimal.

IMHO in this case we should hard block all named CPUs with
'lm' set from qemu-i386. It only makes sense to use named CPU
models that were actually from the 32-bit era with qemu-i386.

If someone wants Nehalem then they should be using qemu-x86_64.
If someone wants qemu-i386 then they should be using an older
named CPU model predating 'lm'.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation
  2023-06-26  9:20 ` [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation Daniel P. Berrangé
@ 2023-06-26  9:27   ` Paolo Bonzini
  2023-06-26  9:36     ` Daniel P. Berrangé
  0 siblings, 1 reply; 11+ messages in thread
From: Paolo Bonzini @ 2023-06-26  9:27 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: qemu-devel

On Mon, Jun 26, 2023 at 11:20 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
> > - for qemu-i386, the issue is that this emulator is restricted to running
> >   programs on a 32-bit processor, even though it is actually emulating
> >   programs that use the 32-bit kernel ABI on any processor.  The behavior
> >   the processor in compatibility (32-bit CS, EFER.LMA=1) mode is mostly
> >   the same as when EFER.LMA=0 and the little code that is needed to handle
> >   64-bit ring-0 is even present in the qemu-i386 binary, just hidden
> >   behind checks for HF_LMA_MASK.  So, LM can also be treated as a feature
> >   that is only relevant in kernel mode; not entirely, so this cannot yet
> >   be extended to bsd-user, but the required changes are minimal.
>
> IMHO in this case we should hard block all named CPUs with
> 'lm' set from qemu-i386. It only makes sense to use named CPU
> models that were actually from the 32-bit era with qemu-i386.
>
> If someone wants Nehalem then they should be using qemu-x86_64.
> If someone wants qemu-i386 then they should be using an older
> named CPU model predating 'lm'.

What you write is true for qemu-system-*, but the problem is that
qemu-user binaries are only able to run one ELF target. qemu-x86_64 is
not able to run i386 binaries, unlike a 64-bit kernel; and that's
really intrinsic in the design of qemu-user because implementing
multiple ABIs (including multiple definitions of structs and syscall
numbers) would require compiling the same files multiple times.

Also, when using qemu-i386 on a (non-x86) 32-bit host you really do
not need the performance penalty of 64-on-32 emulation to run 32-bit
binaries.

Paolo



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

* Re: [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation
  2023-06-26  9:27   ` Paolo Bonzini
@ 2023-06-26  9:36     ` Daniel P. Berrangé
  2023-06-26  9:37       ` Paolo Bonzini
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel P. Berrangé @ 2023-06-26  9:36 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: qemu-devel

On Mon, Jun 26, 2023 at 11:27:54AM +0200, Paolo Bonzini wrote:
> On Mon, Jun 26, 2023 at 11:20 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
> > > - for qemu-i386, the issue is that this emulator is restricted to running
> > >   programs on a 32-bit processor, even though it is actually emulating
> > >   programs that use the 32-bit kernel ABI on any processor.  The behavior
> > >   the processor in compatibility (32-bit CS, EFER.LMA=1) mode is mostly
> > >   the same as when EFER.LMA=0 and the little code that is needed to handle
> > >   64-bit ring-0 is even present in the qemu-i386 binary, just hidden
> > >   behind checks for HF_LMA_MASK.  So, LM can also be treated as a feature
> > >   that is only relevant in kernel mode; not entirely, so this cannot yet
> > >   be extended to bsd-user, but the required changes are minimal.
> >
> > IMHO in this case we should hard block all named CPUs with
> > 'lm' set from qemu-i386. It only makes sense to use named CPU
> > models that were actually from the 32-bit era with qemu-i386.
> >
> > If someone wants Nehalem then they should be using qemu-x86_64.
> > If someone wants qemu-i386 then they should be using an older
> > named CPU model predating 'lm'.
> 
> What you write is true for qemu-system-*, but the problem is that
> qemu-user binaries are only able to run one ELF target. qemu-x86_64 is
> not able to run i386 binaries, unlike a 64-bit kernel; and that's
> really intrinsic in the design of qemu-user because implementing
> multiple ABIs (including multiple definitions of structs and syscall
> numbers) would require compiling the same files multiple times.

Oh, right, yes, ignore my comment.


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



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

* Re: [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation
  2023-06-26  9:36     ` Daniel P. Berrangé
@ 2023-06-26  9:37       ` Paolo Bonzini
  2023-06-26 10:06         ` Richard Henderson
  0 siblings, 1 reply; 11+ messages in thread
From: Paolo Bonzini @ 2023-06-26  9:37 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: qemu-devel

On Mon, Jun 26, 2023 at 11:36 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
> > > If someone wants Nehalem then they should be using qemu-x86_64.
> > > If someone wants qemu-i386 then they should be using an older
> > > named CPU model predating 'lm'.
> >
> > What you write is true for qemu-system-*, but the problem is that
> > qemu-user binaries are only able to run one ELF target. qemu-x86_64 is
> > not able to run i386 binaries, unlike a 64-bit kernel; and that's
> > really intrinsic in the design of qemu-user because implementing
> > multiple ABIs (including multiple definitions of structs and syscall
> > numbers) would require compiling the same files multiple times.
>
> Oh, right, yes, ignore my comment.

By the way it's possible that the above comment would not be true
anymore with the "one binary" work that is going on (though I'm not
sure if that applies to system emulation only). However, the effect on
speed for 32-bit hosts remains true until we ditch them altogether.

Paolo



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

* Re: [PATCH v2 2/3] target/i386: ignore CPL0-specific features in user mode emulation
  2023-06-26  8:33 ` [PATCH v2 2/3] target/i386: ignore CPL0-specific " Paolo Bonzini
@ 2023-06-26 10:04   ` Richard Henderson
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2023-06-26 10:04 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel

On 6/26/23 10:33, Paolo Bonzini wrote:
> Features such as PCID are only accessible through privileged operations,
> and therefore have no impact on any user-mode operation.  Allow reporting
> them to programs running under user mode emulation, so that "-cpu" can be
> used with more named CPU models.
> 
> XSAVES would be similar, but it doesn't make sense to provide it until
> XSAVEC is implemented.
> 
> With this change, all CPUs up to Broadwell-v4 can be emulate.  Skylake-Client
> requires XSAVEC, while EPYC also requires SHA-NI, MISALIGNSSE and TOPOEXT.
> MISALIGNSSE is not hard to implement, but I am not sure it is worth using
> a precious hflags bit for it.
> 
> Fixes:https://gitlab.com/qemu-project/qemu/-/issues/1534
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
>   target/i386/cpu.c | 83 +++++++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 76 insertions(+), 7 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


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

* Re: [PATCH v2 1/3] target/i386: ignore ARCH_CAPABILITIES features in user mode emulation
  2023-06-26  8:33 ` [PATCH v2 1/3] target/i386: ignore ARCH_CAPABILITIES features in " Paolo Bonzini
@ 2023-06-26 10:04   ` Richard Henderson
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2023-06-26 10:04 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel

On 6/26/23 10:33, Paolo Bonzini wrote:
> ARCH_CAPABILITIES is only accessible through a read-only MSR, so it has
> no impact on any user-mode operation (user-mode cannot read the MSR).
> So do not bother printing warnings about it in user mode emulation.
> 
> Signed-off-by: Paolo Bonzini<pbonzini@redhat.com>
> ---
>   target/i386/cpu.c | 7 +++++++
>   1 file changed, 7 insertions(+)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~


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

* Re: [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation
  2023-06-26  9:37       ` Paolo Bonzini
@ 2023-06-26 10:06         ` Richard Henderson
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Henderson @ 2023-06-26 10:06 UTC (permalink / raw)
  To: Paolo Bonzini, Daniel P. Berrangé; +Cc: qemu-devel

On 6/26/23 11:37, Paolo Bonzini wrote:
> On Mon, Jun 26, 2023 at 11:36 AM Daniel P. Berrangé <berrange@redhat.com> wrote:
>>>> If someone wants Nehalem then they should be using qemu-x86_64.
>>>> If someone wants qemu-i386 then they should be using an older
>>>> named CPU model predating 'lm'.
>>>
>>> What you write is true for qemu-system-*, but the problem is that
>>> qemu-user binaries are only able to run one ELF target. qemu-x86_64 is
>>> not able to run i386 binaries, unlike a 64-bit kernel; and that's
>>> really intrinsic in the design of qemu-user because implementing
>>> multiple ABIs (including multiple definitions of structs and syscall
>>> numbers) would require compiling the same files multiple times.
>>
>> Oh, right, yes, ignore my comment.
> 
> By the way it's possible that the above comment would not be true
> anymore with the "one binary" work that is going on (though I'm not
> sure if that applies to system emulation only). However, the effect on
> speed for 32-bit hosts remains true until we ditch them altogether.

Yes, one binary work is system-mode only.
Primarily because of the ABI issues you describe.


r~


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

end of thread, other threads:[~2023-06-26 10:06 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-26  8:33 [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation Paolo Bonzini
2023-06-26  8:33 ` [PATCH v2 1/3] target/i386: ignore ARCH_CAPABILITIES features in " Paolo Bonzini
2023-06-26 10:04   ` Richard Henderson
2023-06-26  8:33 ` [PATCH v2 2/3] target/i386: ignore CPL0-specific " Paolo Bonzini
2023-06-26 10:04   ` Richard Henderson
2023-06-26  8:33 ` [PATCH v2 3/3] target/i386: emulate 64-bit ring 0 for linux-user if LM feature is set Paolo Bonzini
2023-06-26  9:20 ` [PATCH v2 0/3] target/i386: allow using named CPU modeles with user mode emulation Daniel P. Berrangé
2023-06-26  9:27   ` Paolo Bonzini
2023-06-26  9:36     ` Daniel P. Berrangé
2023-06-26  9:37       ` Paolo Bonzini
2023-06-26 10:06         ` Richard Henderson

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).