i386/hvf: Integrates x2APIC support with hvf accel
Support for x2APIC mode was recently introduced in the software emulated APIC implementation for TCG. Enabling it when using macOS’s hvf accelerator is useful and significantly helps performance, as Qemu currently uses the emulated APIC when running on hvf as well. This change wires up the read & write operations for the MSR VM exits and allow-lists the CPUID flag in the x86 hvf runtime. Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu> Link: https://lore.kernel.org/r/20241105155800.5461-2-phil@philjordan.eu Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
b7e55bd9d0
commit
0e27f3a5d0
@ -77,7 +77,7 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
|
|||||||
ecx &= CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 |
|
ecx &= CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 |
|
||||||
CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID |
|
CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID |
|
||||||
CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_MOVBE |
|
CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_MOVBE |
|
||||||
CPUID_EXT_POPCNT | CPUID_EXT_AES |
|
CPUID_EXT_POPCNT | CPUID_EXT_AES | CPUID_EXT_X2APIC |
|
||||||
(supported_xcr0 ? CPUID_EXT_XSAVE : 0) |
|
(supported_xcr0 ? CPUID_EXT_XSAVE : 0) |
|
||||||
CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND;
|
CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND;
|
||||||
ecx |= CPUID_EXT_HYPERVISOR;
|
ecx |= CPUID_EXT_HYPERVISOR;
|
||||||
|
@ -663,6 +663,15 @@ static void exec_lods(CPUX86State *env, struct x86_decode *decode)
|
|||||||
env->eip += decode->len;
|
env->eip += decode->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void raise_exception(CPUX86State *env, int exception_index,
|
||||||
|
int error_code)
|
||||||
|
{
|
||||||
|
env->exception_nr = exception_index;
|
||||||
|
env->error_code = error_code;
|
||||||
|
env->has_error_code = true;
|
||||||
|
env->exception_injected = 1;
|
||||||
|
}
|
||||||
|
|
||||||
void simulate_rdmsr(CPUX86State *env)
|
void simulate_rdmsr(CPUX86State *env)
|
||||||
{
|
{
|
||||||
X86CPU *cpu = env_archcpu(env);
|
X86CPU *cpu = env_archcpu(env);
|
||||||
@ -677,6 +686,17 @@ void simulate_rdmsr(CPUX86State *env)
|
|||||||
case MSR_IA32_APICBASE:
|
case MSR_IA32_APICBASE:
|
||||||
val = cpu_get_apic_base(cpu->apic_state);
|
val = cpu_get_apic_base(cpu->apic_state);
|
||||||
break;
|
break;
|
||||||
|
case MSR_APIC_START ... MSR_APIC_END: {
|
||||||
|
int ret;
|
||||||
|
int index = (uint32_t)env->regs[R_ECX] - MSR_APIC_START;
|
||||||
|
|
||||||
|
ret = apic_msr_read(index, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
raise_exception(env, EXCP0D_GPF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MSR_IA32_UCODE_REV:
|
case MSR_IA32_UCODE_REV:
|
||||||
val = cpu->ucode_rev;
|
val = cpu->ucode_rev;
|
||||||
break;
|
break;
|
||||||
@ -777,6 +797,17 @@ void simulate_wrmsr(CPUX86State *env)
|
|||||||
case MSR_IA32_APICBASE:
|
case MSR_IA32_APICBASE:
|
||||||
cpu_set_apic_base(cpu->apic_state, data);
|
cpu_set_apic_base(cpu->apic_state, data);
|
||||||
break;
|
break;
|
||||||
|
case MSR_APIC_START ... MSR_APIC_END: {
|
||||||
|
int ret;
|
||||||
|
int index = (uint32_t)env->regs[R_ECX] - MSR_APIC_START;
|
||||||
|
|
||||||
|
ret = apic_msr_write(index, data);
|
||||||
|
if (ret < 0) {
|
||||||
|
raise_exception(env, EXCP0D_GPF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MSR_FSBASE:
|
case MSR_FSBASE:
|
||||||
wvmcs(cs->accel->fd, VMCS_GUEST_FS_BASE, data);
|
wvmcs(cs->accel->fd, VMCS_GUEST_FS_BASE, data);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user