* Make named CPU models usable for qemu-{i386,x86_64}

* Fix backwards time with -icount auto
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmSdRiQUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroOqcwf9FGAqZ+0V34Y8XeXMu8Es3bFjEKG8
 t3BpVNhTBOYDPvpshnPVx2I29nRT2opc1C4YkjMAv5/1nivj1kDM7hDObOSJQvqy
 5FgTsJYqRtGj+J7uVBrspWZsP8BYeykKmXR6deBOPvCuw5nnLdDQ3dLV2F26lKUu
 lsFyEVbi4dzf8+TVuNIXEg7mVBYytjBQwBmmHgeOofeikjq9WEudr49mwJMCHyzl
 iXCatnctXGKZYSnp+eHIBiFRdSzjqdgrDRa0ysSqABoBI1pmkhyQKSay6cSjfG4n
 gFlqPF/i9RqAWpsQrM1IMGgPK39SrT2dYlHDJV2P/NEQrS6kLh2HoW/ArQ==
 =oj3B
 -----END PGP SIGNATURE-----

Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging

* Make named CPU models usable for qemu-{i386,x86_64}
* Fix backwards time with -icount auto

# -----BEGIN PGP SIGNATURE-----
#
# iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmSdRiQUHHBib256aW5p
# QHJlZGhhdC5jb20ACgkQv/vSX3jHroOqcwf9FGAqZ+0V34Y8XeXMu8Es3bFjEKG8
# t3BpVNhTBOYDPvpshnPVx2I29nRT2opc1C4YkjMAv5/1nivj1kDM7hDObOSJQvqy
# 5FgTsJYqRtGj+J7uVBrspWZsP8BYeykKmXR6deBOPvCuw5nnLdDQ3dLV2F26lKUu
# lsFyEVbi4dzf8+TVuNIXEg7mVBYytjBQwBmmHgeOofeikjq9WEudr49mwJMCHyzl
# iXCatnctXGKZYSnp+eHIBiFRdSzjqdgrDRa0ysSqABoBI1pmkhyQKSay6cSjfG4n
# gFlqPF/i9RqAWpsQrM1IMGgPK39SrT2dYlHDJV2P/NEQrS6kLh2HoW/ArQ==
# =oj3B
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 29 Jun 2023 10:51:48 AM CEST
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [undefined]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* tag 'for-upstream' of https://gitlab.com/bonzini/qemu:
  target/i386: emulate 64-bit ring 0 for linux-user if LM feature is set
  target/i386: ignore CPL0-specific features in user mode emulation
  target/i386: ignore ARCH_CAPABILITIES features in user mode emulation
  target/i386: Export MSR_ARCH_CAPABILITIES bits to guests
  icount: don't adjust virtual time backwards after warp

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-06-29 13:16:06 +02:00
commit 4d541f63e9
4 changed files with 135 additions and 44 deletions

View File

@ -47,7 +47,7 @@ static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
} }
static uint64_t *idt_table; static uint64_t *idt_table;
#ifdef TARGET_X86_64
static void set_gate64(void *ptr, unsigned int type, unsigned int dpl, static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
uint64_t addr, unsigned int sel) 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[2] = tswap32(addr >> 32);
p[3] = 0; p[3] = 0;
} }
#ifdef TARGET_X86_64
/* only dpl matters as we do only user space emulation */ /* 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); 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 */ /* 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 #endif
@ -325,6 +331,9 @@ static void target_cpu_free(void *obj)
void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
{ {
CPUState *cpu = env_cpu(env); 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; OBJECT(cpu)->free = target_cpu_free;
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK; env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
env->hflags |= HF_PE_MASK | HF_CPL_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->cr[4] |= CR4_OSFXSR_MASK;
env->hflags |= HF_OSFXSR_MASK; env->hflags |= HF_OSFXSR_MASK;
} }
#ifndef TARGET_ABI32
/* enable 64 bit mode if possible */ /* 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"); fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
env->cr[4] |= CR4_PAE_MASK;
env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
env->hflags |= HF_LMA_MASK;
#endif #endif
/* flags setup : we activate the IRQs by default as in user mode */ /* 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, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
idt_table = g2h_untagged(env->idt.base); idt_table = g2h_untagged(env->idt.base);
set_idt(0, 0); for (i = 0; i < 20; i++) {
set_idt(1, 0); set_idt(i, 0, is64);
set_idt(2, 0); }
set_idt(3, 3); set_idt(3, 3, is64);
set_idt(4, 3); set_idt(4, 3, is64);
set_idt(5, 0); set_idt(0x80, 3, is64);
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);
/* linux segment setup */ /* linux segment setup */
{ {

View File

@ -259,11 +259,16 @@ static void icount_warp_rt(void)
warp_delta = clock - timers_state.vm_clock_warp_start; warp_delta = clock - timers_state.vm_clock_warp_start;
if (icount_enabled() == 2) { if (icount_enabled() == 2) {
/* /*
* In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too far
* far ahead of real time. * ahead of real time (it might already be ahead so careful not
* to go backwards).
*/ */
int64_t cur_icount = icount_get_locked(); int64_t cur_icount = icount_get_locked();
int64_t delta = clock - cur_icount; int64_t delta = clock - cur_icount;
if (delta < 0) {
delta = 0;
}
warp_delta = MIN(warp_delta, delta); warp_delta = MIN(warp_delta, delta);
} }
qatomic_set_i64(&timers_state.qemu_icount_bias, qatomic_set_i64(&timers_state.qemu_icount_bias,

View File

@ -623,13 +623,25 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */ CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64) */
/* missing: /* missing:
CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */ 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 | \ #define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \ CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \ CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \ CPUID_EXT_XSAVE | /* CPUID_EXT_OSXSAVE is dynamic */ \
CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \ CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR | \
CPUID_EXT_RDRAND | CPUID_EXT_AVX | CPUID_EXT_F16C | \ CPUID_EXT_RDRAND | CPUID_EXT_AVX | CPUID_EXT_F16C | \
CPUID_EXT_FMA) CPUID_EXT_FMA | CPUID_EXT_KERNEL_FEATURES)
/* missing: /* missing:
CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX, CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID,
@ -642,22 +654,66 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
#define TCG_EXT2_X86_64_FEATURES 0 #define TCG_EXT2_X86_64_FEATURES 0
#endif #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_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
#endif
#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \ #define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \ CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_PDPE1GB | \ 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 | \ #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A | \ CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A | \
CPUID_EXT3_3DNOWPREFETCH) CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_KERNEL_FEATURES)
#define TCG_EXT4_FEATURES 0 #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 | \ #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 #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 | \ #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_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_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_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: /* missing:
CPUID_7_0_EBX_HLE CPUID_7_0_EBX_HLE
CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM */ CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM */
@ -672,7 +728,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 | \ CPUID_7_0_ECX_LA57 | CPUID_7_0_ECX_PKS | CPUID_7_0_ECX_VAES | \
TCG_7_0_ECX_RDPID) 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 | \ #define TCG_7_1_EAX_FEATURES (CPUID_7_1_EAX_FZRM | CPUID_7_1_EAX_FSRS | \
CPUID_7_1_EAX_FSRC) CPUID_7_1_EAX_FSRC)
#define TCG_7_1_EDX_FEATURES 0 #define TCG_7_1_EDX_FEATURES 0
@ -686,8 +749,17 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
#define TCG_SGX_12_0_EBX_FEATURES 0 #define TCG_SGX_12_0_EBX_FEATURES 0
#define TCG_SGX_12_1_EAX_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 | \ #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] = { FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
[FEAT_1_EDX] = { [FEAT_1_EDX] = {
@ -1060,15 +1132,22 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry", "rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry",
"ssb-no", "mds-no", "pschange-mc-no", "tsx-ctrl", "ssb-no", "mds-no", "pschange-mc-no", "tsx-ctrl",
"taa-no", NULL, NULL, NULL, "taa-no", NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no",
NULL, "fb-clear", NULL, NULL, NULL, "fb-clear", NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, "pbrsb-no", NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
}, },
.msr = { .msr = {
.index = MSR_IA32_ARCH_CAPABILITIES, .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] = { [FEAT_CORE_CAPABILITY] = {
.type = MSR_FEATURE_WORD, .type = MSR_FEATURE_WORD,
@ -5463,7 +5542,15 @@ uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
} }
#ifndef TARGET_X86_64 #ifndef TARGET_X86_64
if (w == FEAT_8000_0001_EDX) { 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 #endif
if (migratable_only) { if (migratable_only) {

View File

@ -173,12 +173,14 @@ typedef struct DisasContext {
#endif #endif
#if !defined(TARGET_X86_64) #if !defined(TARGET_X86_64)
#define CODE64(S) false #define CODE64(S) false
#define LMA(S) false
#elif defined(CONFIG_USER_ONLY) #elif defined(CONFIG_USER_ONLY)
#define CODE64(S) true #define CODE64(S) true
#define LMA(S) true
#else #else
#define CODE64(S) (((S)->flags & HF_CS64_MASK) != 0) #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) #define LMA(S) (((S)->flags & HF_LMA_MASK) != 0)
#endif #endif