@@ -341,6 +341,17 @@ int hvf_arch_init_vcpu(CPUState *cpu)
void hvf_vcpu_before_first_run(CPUState *cpu)
{
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ hv_vcpuid_t vcpu = cpu->accel->fd;
+ uint64_t apic_base;
+ hv_return_t apicbase_result;
+
+ if (cpu_is_apic_enabled(x86_cpu->apic_state)
+ && !is_x2apic_mode(x86_cpu->apic_state)) {
+ apic_base = MSR_IA32_APICBASE_BASE & cpu_get_apic_base(x86_cpu->apic_state);
+ apicbase_result = hv_vmx_vcpu_set_apic_address(vcpu, apic_base);
+ assert_hvf_ok(apicbase_result);
+ }
}
static void hvf_store_events(CPUState *cpu, uint32_t ins_len, uint64_t idtvec_info)
@@ -797,10 +797,28 @@ void simulate_wrmsr(CPUX86State *env)
break;
case MSR_IA32_APICBASE: {
int r;
+ hv_return_t res;
r = cpu_set_apic_base(cpu->apic_state, data);
if (r < 0) {
raise_exception(env, EXCP0D_GPF, 0);
+ } else {
+ uint64_t pbc = rvmcs(cs->accel->fd, VMCS_SEC_PROC_BASED_CTLS);
+ uint64_t new_pbc;
+ if (cpu_is_apic_enabled(cpu->apic_state)
+ && !is_x2apic_mode(cpu->apic_state)) {
+ res = hv_vmx_vcpu_set_apic_address(cs->accel->fd,
+ data & MSR_IA32_APICBASE_BASE);
+ assert_hvf_ok(res);
+
+ new_pbc = pbc | VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES;
+ } else {
+ new_pbc = pbc & ~VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES;
+ }
+ if (new_pbc != pbc) {
+ wvmcs(cs->accel->fd, VMCS_SEC_PROC_BASED_CTLS,
+ cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased2, new_pbc));
+ }
}
break;