aboutsummaryrefslogtreecommitdiff
path: root/target/i386
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-02-05 19:39:22 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-02-05 19:39:22 +0000
commit3e29da9fd81002a0c03041aaa26dea6d9dd9bd65 (patch)
treeacd21f31ace26a41b261fe462ae26c782ffb42d2 /target/i386
parent47994e16b1d66411953623e7c0bf0cdcd50bd507 (diff)
parent5ed76a4c63db9295c6c5d67895925810050d4a46 (diff)
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* cpu-exec fixes (Emilio, Laurent) * TCG bugfix in queue.h (Paolo) * high address load for linuxboot (Zhijian) * PVH support (Liam, Stefano) * misc i386 changes (Paolo, Robert, Doug) * configure tweak for openpty (Thomas) * elf2dmp port to Windows (Viktor) * initial improvements to Makefile infrastructure (Yang + GSoC 2013) # gpg: Signature made Tue 05 Feb 2019 17:34:42 GMT # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # 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 * remotes/bonzini/tags/for-upstream: (76 commits) queue: fix QTAILQ_FOREACH_REVERSE_SAFE scsi-generic: Convert from DPRINTF() macro to trace events scsi-disk: Convert from DPRINTF() macro to trace events pc: Use hotplug_handler_(plug|unplug|unplug_request) i386: hvf: Fix smp boot hangs hw/vfio/Makefile.objs: Create new CONFIG_* variables for VFIO core and PCI hw/i2c/Makefile.objs: Create new CONFIG_* variables for EEPROM and ACPI controller hw/tricore/Makefile.objs: Create CONFIG_* for tricore hw/openrisc/Makefile.objs: Create CONFIG_* for openrisc hw/moxie/Makefile.objs: Conditionally build moxie hw/hppa/Makefile.objs: Create CONFIG_* for hppa hw/cris/Makefile.objs: Create CONFIG_* for cris hw/alpha/Makefile.objs: Create CONFIG_* for alpha hw/sparc64/Makefile.objs: Create CONFIG_* for sparc64 hw/riscv/Makefile.objs: Create CONFIG_* for riscv boards hw/nios2/Makefile.objs: Conditionally build nios2 hw/xtensa/Makefile.objs: Build xtensa_sim and xtensa_fpga conditionally hw/lm32/Makefile.objs: Conditionally build lm32 and milkmyst hw/sparc/Makefile.objs: CONFIG_* for sun4m and leon3 created hw/s390/Makefile.objs: Create new CONFIG_* variables for s390x boards and devices ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # qemu-deprecated.texi
Diffstat (limited to 'target/i386')
-rw-r--r--target/i386/cpu.c17
-rw-r--r--target/i386/cpu.h1
-rw-r--r--target/i386/gdbstub.c193
-rw-r--r--target/i386/hvf/hvf.c5
-rw-r--r--target/i386/hvf/x86_cpuid.c18
-rw-r--r--target/i386/hvf/x86_decode.c2
6 files changed, 198 insertions, 38 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 7483daef58..b077196611 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1077,7 +1077,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
- NULL, NULL, "pconfig", NULL,
+ NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, "spec-ctrl", "stibp",
NULL, "arch-capabilities", NULL, "ssbd",
@@ -2530,8 +2530,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB |
CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
- CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
- CPUID_7_0_EBX_INTEL_PT,
+ CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
.features[FEAT_7_0_ECX] =
CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE |
CPUID_7_0_ECX_AVX512VNNI,
@@ -2583,7 +2582,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
- CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_INTEL_PT,
+ CPUID_7_0_EBX_SMAP,
.features[FEAT_7_0_ECX] =
CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
@@ -2641,8 +2640,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB |
CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
- CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
- CPUID_7_0_EBX_INTEL_PT,
+ CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
.features[FEAT_7_0_ECX] =
CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
@@ -2650,8 +2648,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
.features[FEAT_7_0_EDX] =
- CPUID_7_0_EDX_PCONFIG | CPUID_7_0_EDX_SPEC_CTRL |
- CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+ CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
/* Missing: XSAVES (not supported by some Linux versions,
* including v4.1 to v4.12).
* KVM doesn't yet expose any XSAVES state save component,
@@ -5873,10 +5870,10 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->gdb_arch_name = x86_gdb_arch_name;
#ifdef TARGET_X86_64
cc->gdb_core_xml_file = "i386-64bit.xml";
- cc->gdb_num_core_regs = 57;
+ cc->gdb_num_core_regs = 66;
#else
cc->gdb_core_xml_file = "i386-32bit.xml";
- cc->gdb_num_core_regs = 41;
+ cc->gdb_num_core_regs = 50;
#endif
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
cc->debug_excp_handler = breakpoint_handler;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 59656a70e6..95112b9118 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -694,7 +694,6 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
#define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network Instructions */
#define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation Single Precision */
-#define CPUID_7_0_EDX_PCONFIG (1U << 18) /* Platform Configuration */
#define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */
#define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29) /*Arch Capabilities*/
#define CPUID_7_0_EDX_SPEC_CTRL_SSBD (1U << 31) /* Speculative Store Bypass Disable */
diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c
index 9b94ab852c..1221433bc7 100644
--- a/target/i386/gdbstub.c
+++ b/target/i386/gdbstub.c
@@ -32,18 +32,61 @@ static const int gpr_map[16] = {
#endif
static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+/*
+ * Keep these in sync with assignment to
+ * gdb_num_core_regs in target/i386/cpu.c
+ * and with the machine description
+ */
+
+/*
+ * SEG: 6 segments, plus fs_base, gs_base, kernel_gs_base
+ */
+
+/*
+ * general regs -----> 8 or 16
+ */
+#define IDX_NB_IP 1
+#define IDX_NB_FLAGS 1
+#define IDX_NB_SEG (6 + 3)
+#define IDX_NB_CTL 6
+#define IDX_NB_FP 16
+/*
+ * fpu regs ----------> 8 or 16
+ */
+#define IDX_NB_MXCSR 1
+/*
+ * total ----> 8+1+1+9+6+16+8+1=50 or 16+1+1+9+6+16+16+1=66
+ */
+
#define IDX_IP_REG CPU_NB_REGS
-#define IDX_FLAGS_REG (IDX_IP_REG + 1)
-#define IDX_SEG_REGS (IDX_FLAGS_REG + 1)
-#define IDX_FP_REGS (IDX_SEG_REGS + 6)
-#define IDX_XMM_REGS (IDX_FP_REGS + 16)
+#define IDX_FLAGS_REG (IDX_IP_REG + IDX_NB_IP)
+#define IDX_SEG_REGS (IDX_FLAGS_REG + IDX_NB_FLAGS)
+#define IDX_CTL_REGS (IDX_SEG_REGS + IDX_NB_SEG)
+#define IDX_FP_REGS (IDX_CTL_REGS + IDX_NB_CTL)
+#define IDX_XMM_REGS (IDX_FP_REGS + IDX_NB_FP)
#define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS)
+#define IDX_CTL_CR0_REG (IDX_CTL_REGS + 0)
+#define IDX_CTL_CR2_REG (IDX_CTL_REGS + 1)
+#define IDX_CTL_CR3_REG (IDX_CTL_REGS + 2)
+#define IDX_CTL_CR4_REG (IDX_CTL_REGS + 3)
+#define IDX_CTL_CR8_REG (IDX_CTL_REGS + 4)
+#define IDX_CTL_EFER_REG (IDX_CTL_REGS + 5)
+
+#ifdef TARGET_X86_64
+#define GDB_FORCE_64 1
+#else
+#define GDB_FORCE_64 0
+#endif
+
+
int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
{
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
+ uint64_t tpr;
+
/* N.B. GDB can't deal with changes in registers or sizes in the middle
of a session. So if we're in 32-bit mode on a 64-bit cpu, still act
as if we're on a 64-bit cpu. */
@@ -105,6 +148,28 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
case IDX_SEG_REGS + 5:
return gdb_get_reg32(mem_buf, env->segs[R_GS].selector);
+ case IDX_SEG_REGS + 6:
+ if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
+ return gdb_get_reg64(mem_buf, env->segs[R_FS].base);
+ }
+ return gdb_get_reg32(mem_buf, env->segs[R_FS].base);
+
+ case IDX_SEG_REGS + 7:
+ if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
+ return gdb_get_reg64(mem_buf, env->segs[R_GS].base);
+ }
+ return gdb_get_reg32(mem_buf, env->segs[R_GS].base);
+
+ case IDX_SEG_REGS + 8:
+#ifdef TARGET_X86_64
+ if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
+ return gdb_get_reg64(mem_buf, env->kernelgsbase);
+ }
+ return gdb_get_reg32(mem_buf, env->kernelgsbase);
+#else
+ return gdb_get_reg32(mem_buf, 0);
+#endif
+
case IDX_FP_REGS + 8:
return gdb_get_reg32(mem_buf, env->fpuc);
case IDX_FP_REGS + 9:
@@ -125,6 +190,47 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
case IDX_MXCSR_REG:
return gdb_get_reg32(mem_buf, env->mxcsr);
+
+ case IDX_CTL_CR0_REG:
+ if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
+ return gdb_get_reg64(mem_buf, env->cr[0]);
+ }
+ return gdb_get_reg32(mem_buf, env->cr[0]);
+
+ case IDX_CTL_CR2_REG:
+ if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
+ return gdb_get_reg64(mem_buf, env->cr[2]);
+ }
+ return gdb_get_reg32(mem_buf, env->cr[2]);
+
+ case IDX_CTL_CR3_REG:
+ if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
+ return gdb_get_reg64(mem_buf, env->cr[3]);
+ }
+ return gdb_get_reg32(mem_buf, env->cr[3]);
+
+ case IDX_CTL_CR4_REG:
+ if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
+ return gdb_get_reg64(mem_buf, env->cr[4]);
+ }
+ return gdb_get_reg32(mem_buf, env->cr[4]);
+
+ case IDX_CTL_CR8_REG:
+#ifdef CONFIG_SOFTMMU
+ tpr = cpu_get_apic_tpr(cpu->apic_state);
+#else
+ tpr = 0;
+#endif
+ if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
+ return gdb_get_reg64(mem_buf, tpr);
+ }
+ return gdb_get_reg32(mem_buf, tpr);
+
+ case IDX_CTL_EFER_REG:
+ if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) {
+ return gdb_get_reg64(mem_buf, env->efer);
+ }
+ return gdb_get_reg32(mem_buf, env->efer);
}
}
return 0;
@@ -229,6 +335,32 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
case IDX_SEG_REGS + 5:
return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf);
+ case IDX_SEG_REGS + 6:
+ if (env->hflags & HF_CS64_MASK) {
+ env->segs[R_FS].base = ldq_p(mem_buf);
+ return 8;
+ }
+ env->segs[R_FS].base = ldl_p(mem_buf);
+ return 4;
+
+ case IDX_SEG_REGS + 7:
+ if (env->hflags & HF_CS64_MASK) {
+ env->segs[R_GS].base = ldq_p(mem_buf);
+ return 8;
+ }
+ env->segs[R_GS].base = ldl_p(mem_buf);
+ return 4;
+
+#ifdef TARGET_X86_64
+ case IDX_SEG_REGS + 8:
+ if (env->hflags & HF_CS64_MASK) {
+ env->kernelgsbase = ldq_p(mem_buf);
+ return 8;
+ }
+ env->kernelgsbase = ldl_p(mem_buf);
+ return 4;
+#endif
+
case IDX_FP_REGS + 8:
cpu_set_fpuc(env, ldl_p(mem_buf));
return 4;
@@ -253,6 +385,59 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
case IDX_MXCSR_REG:
cpu_set_mxcsr(env, ldl_p(mem_buf));
return 4;
+
+ case IDX_CTL_CR0_REG:
+ if (env->hflags & HF_CS64_MASK) {
+ cpu_x86_update_cr0(env, ldq_p(mem_buf));
+ return 8;
+ }
+ cpu_x86_update_cr0(env, ldl_p(mem_buf));
+ return 4;
+
+ case IDX_CTL_CR2_REG:
+ if (env->hflags & HF_CS64_MASK) {
+ env->cr[2] = ldq_p(mem_buf);
+ return 8;
+ }
+ env->cr[2] = ldl_p(mem_buf);
+ return 4;
+
+ case IDX_CTL_CR3_REG:
+ if (env->hflags & HF_CS64_MASK) {
+ cpu_x86_update_cr3(env, ldq_p(mem_buf));
+ return 8;
+ }
+ cpu_x86_update_cr3(env, ldl_p(mem_buf));
+ return 4;
+
+ case IDX_CTL_CR4_REG:
+ if (env->hflags & HF_CS64_MASK) {
+ cpu_x86_update_cr4(env, ldq_p(mem_buf));
+ return 8;
+ }
+ cpu_x86_update_cr4(env, ldl_p(mem_buf));
+ return 4;
+
+ case IDX_CTL_CR8_REG:
+ if (env->hflags & HF_CS64_MASK) {
+#ifdef CONFIG_SOFTMMU
+ cpu_set_apic_tpr(cpu->apic_state, ldq_p(mem_buf));
+#endif
+ return 8;
+ }
+#ifdef CONFIG_SOFTMMU
+ cpu_set_apic_tpr(cpu->apic_state, ldl_p(mem_buf));
+#endif
+ return 4;
+
+ case IDX_CTL_EFER_REG:
+ if (env->hflags & HF_CS64_MASK) {
+ cpu_load_efer(env, ldq_p(mem_buf));
+ return 8;
+ }
+ cpu_load_efer(env, ldl_p(mem_buf));
+ return 4;
+
}
}
/* Unrecognised register. */
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 689b585027..42f9447303 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -499,7 +499,6 @@ void hvf_reset_vcpu(CPUState *cpu) {
}
hv_vm_sync_tsc(0);
- cpu->halted = 0;
hv_vcpu_invalidate_tlb(cpu->hvf_fd);
hv_vcpu_flush(cpu->hvf_fd);
}
@@ -582,8 +581,6 @@ int hvf_init_vcpu(CPUState *cpu)
wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
- hvf_reset_vcpu(cpu);
-
x86cpu = X86_CPU(cpu);
x86cpu->env.xsave_buf = qemu_memalign(4096, 4096);
@@ -659,8 +656,6 @@ int hvf_vcpu_exec(CPUState *cpu)
int ret = 0;
uint64_t rip = 0;
- cpu->halted = 0;
-
if (hvf_process_events(cpu)) {
return EXCP_HLT;
}
diff --git a/target/i386/hvf/x86_cpuid.c b/target/i386/hvf/x86_cpuid.c
index 9874a46e92..4d957fe896 100644
--- a/target/i386/hvf/x86_cpuid.c
+++ b/target/i386/hvf/x86_cpuid.c
@@ -38,16 +38,6 @@ static uint64_t xgetbv(uint32_t xcr)
return (((uint64_t)edx) << 32) | eax;
}
-static bool vmx_mpx_supported()
-{
- uint64_t cap_exit, cap_entry;
-
- hv_vmx_read_capability(HV_VMX_CAP_ENTRY, &cap_entry);
- hv_vmx_read_capability(HV_VMX_CAP_EXIT, &cap_exit);
-
- return ((cap_exit & (1 << 23)) && (cap_entry & (1 << 16)));
-}
-
uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
int reg)
{
@@ -92,11 +82,8 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_CLWB |
CPUID_7_0_EBX_AVX512DQ | CPUID_7_0_EBX_SHA_NI |
CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL |
- CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_MPX;
+ CPUID_7_0_EBX_INVPCID;
- if (!vmx_mpx_supported()) {
- ebx &= ~CPUID_7_0_EBX_MPX;
- }
hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap);
if (!(cap & CPU_BASED2_INVPCID)) {
ebx &= ~CPUID_7_0_EBX_INVPCID;
@@ -119,9 +106,6 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
XSTATE_BNDCSR_MASK | XSTATE_OPMASK_MASK |
XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK);
eax &= supp_xcr0;
- if (!vmx_mpx_supported()) {
- eax &= ~(XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK);
- }
} else if (idx == 1) {
hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap);
eax &= CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1;
diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c
index 5f513c5563..9ef7d7513f 100644
--- a/target/i386/hvf/x86_decode.c
+++ b/target/i386/hvf/x86_decode.c
@@ -1642,7 +1642,7 @@ void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode,
X86Seg seg = R_DS;
if (!decode->modrm.mod && 6 == decode->modrm.rm) {
- op->ptr = (uint16_t)decode->displacement;
+ ptr = decode->displacement;
goto calc_addr;
}