summaryrefslogtreecommitdiffstats
path: root/target/i386/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/i386/cpu.c')
-rw-r--r--target/i386/cpu.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 97e250e876..6b029f1bdf 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -631,7 +631,8 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
#define TCG_EXT4_FEATURES 0
-#define TCG_SVM_FEATURES CPUID_SVM_NPT
+#define TCG_SVM_FEATURES (CPUID_SVM_NPT | CPUID_SVM_VGIF | \
+ CPUID_SVM_SVME_ADDR_CHK)
#define TCG_KVM_FEATURES 0
#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 | \
@@ -5115,6 +5116,15 @@ static void x86_register_cpudef_types(const X86CPUDefinition *def)
}
+uint32_t cpu_x86_virtual_addr_width(CPUX86State *env)
+{
+ if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57) {
+ return 57; /* 57 bits virtual */
+ } else {
+ return 48; /* 48 bits virtual */
+ }
+}
+
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
@@ -5517,16 +5527,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break;
case 0x80000008:
/* virtual & phys address size in low 2 bytes. */
+ *eax = cpu->phys_bits;
if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
/* 64 bit processor */
- *eax = cpu->phys_bits; /* configurable physical bits */
- if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57) {
- *eax |= 0x00003900; /* 57 bits virtual */
- } else {
- *eax |= 0x00003000; /* 48 bits virtual */
- }
- } else {
- *eax = cpu->phys_bits;
+ *eax |= (cpu_x86_virtual_addr_width(env) << 8);
}
*ebx = env->features[FEAT_8000_0008_EBX];
if (cs->nr_cores * cs->nr_threads > 1) {
@@ -5651,8 +5655,9 @@ static void x86_cpu_reset(DeviceState *dev)
env->old_exception = -1;
/* init to reset state */
-
+ env->int_ctl = 0;
env->hflags2 |= HF2_GIF_MASK;
+ env->hflags2 |= HF2_VGIF_MASK;
env->hflags &= ~HF_GUEST_MASK;
cpu_x86_update_cr0(env, 0x60000010);
@@ -6536,10 +6541,12 @@ int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request)
!(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
return CPU_INTERRUPT_HARD;
#if !defined(CONFIG_USER_ONLY)
- } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
+ } else if (env->hflags2 & HF2_VGIF_MASK) {
+ if((interrupt_request & CPU_INTERRUPT_VIRQ) &&
(env->eflags & IF_MASK) &&
!(env->hflags & HF_INHIBIT_IRQ_MASK)) {
- return CPU_INTERRUPT_VIRQ;
+ return CPU_INTERRUPT_VIRQ;
+ }
#endif
}
}