diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 4df61e00f..4adb52ae5 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -401,7 +401,7 @@ static void vlapic_icrtmr_write_handler(struct acrn_vlapic *vlapic) } } -static uint64_t vlapic_get_tsc_deadline_msr(const struct acrn_vlapic *vlapic) +uint64_t vlapic_get_tsc_deadline_msr(const struct acrn_vlapic *vlapic) { uint64_t ret; if (!vlapic_lvtt_tsc_deadline(vlapic)) { @@ -415,8 +415,7 @@ static uint64_t vlapic_get_tsc_deadline_msr(const struct acrn_vlapic *vlapic) } -static void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, - uint64_t val_arg) +void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, uint64_t val_arg) { struct hv_timer *timer; uint64_t val = val_arg; @@ -1754,17 +1753,13 @@ void vlapic_restore(struct acrn_vlapic *vlapic, const struct lapic_regs *regs) vlapic_dcr_write_handler(vlapic); } -static uint64_t -vlapic_get_apicbase(const struct acrn_vlapic *vlapic) +uint64_t vlapic_get_apicbase(const struct acrn_vlapic *vlapic) { - return vlapic->msr_apicbase; } -static int32_t -vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new) +int32_t vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new) { - int32_t ret = 0; uint64_t changed; changed = vlapic->msr_apicbase ^ new; @@ -2046,8 +2041,7 @@ vlapic_x2apic_pt_icr_access(struct acrn_vm *vm, uint64_t val) return ret; } -static int32_t vlapic_x2apic_access(struct acrn_vcpu *vcpu, uint32_t msr, bool write, - uint64_t *val) +int32_t vlapic_x2apic_read(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val) { struct acrn_vlapic *vlapic; uint32_t offset; @@ -2061,30 +2055,19 @@ static int32_t vlapic_x2apic_access(struct acrn_vcpu *vcpu, uint32_t msr, bool w if (is_x2apic_enabled(vlapic)) { if (is_lapic_pt(vcpu->vm)) { switch (msr) { - case MSR_IA32_EXT_APIC_ICR: - error = vlapic_x2apic_pt_icr_access(vcpu->vm, *val); - break; - case MSR_IA32_EXT_APIC_LDR: - case MSR_IA32_EXT_XAPICID: - if (!write) { - offset = x2apic_msr_to_regoff(msr); - error = vlapic_read(vlapic, offset, val); - } - break; - default: - pr_err("%s: unexpected MSR[0x%x] access with lapic_pt", __func__, msr); - break; + case MSR_IA32_EXT_APIC_LDR: + case MSR_IA32_EXT_XAPICID: + offset = x2apic_msr_to_regoff(msr); + error = vlapic_read(vlapic, offset, val); + break; + default: + pr_err("%s: unexpected MSR[0x%x] read with lapic_pt", __func__, msr); + break; } } else { - offset = x2apic_msr_to_regoff(msr); - if (write) { - if (!is_x2apic_read_only_msr(msr)) { - error = vlapic_write(vlapic, offset, *val); - } - } else { - if (!is_x2apic_write_only_msr(msr)) { - error = vlapic_read(vlapic, offset, val); - } + if (!is_x2apic_write_only_msr(msr)) { + offset = x2apic_msr_to_regoff(msr); + error = vlapic_read(vlapic, offset, val); } } } @@ -2092,71 +2075,38 @@ static int32_t vlapic_x2apic_access(struct acrn_vcpu *vcpu, uint32_t msr, bool w return error; } -int32_t -vlapic_rdmsr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *rval) +int32_t vlapic_x2apic_write(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val) { - int32_t error = 0; struct acrn_vlapic *vlapic; + uint32_t offset; + int32_t error = -1; - dev_dbg(ACRN_DBG_LAPIC, "cpu[%hu] rdmsr: %x", vcpu->vcpu_id, msr); + /* + * If vLAPIC is in xAPIC mode and guest tries to access x2APIC MSRs + * inject a GP to guest + */ vlapic = vcpu_vlapic(vcpu); - - switch (msr) { - case MSR_IA32_APIC_BASE: - *rval = vlapic_get_apicbase(vlapic); - break; - - case MSR_IA32_TSC_DEADLINE: - *rval = vlapic_get_tsc_deadline_msr(vlapic); - break; - - default: - if (is_x2apic_msr(msr)) { - error = vlapic_x2apic_access(vcpu, msr, false, rval); + if (is_x2apic_enabled(vlapic)) { + if (is_lapic_pt(vcpu->vm)) { + switch (msr) { + case MSR_IA32_EXT_APIC_ICR: + error = vlapic_x2apic_pt_icr_access(vcpu->vm, val); + break; + default: + pr_err("%s: unexpected MSR[0x%x] write with lapic_pt", __func__, msr); + break; + } } else { - error = -1; - dev_dbg(ACRN_DBG_LAPIC, - "Invalid vlapic msr 0x%x access\n", msr); + if (!is_x2apic_read_only_msr(msr)) { + offset = x2apic_msr_to_regoff(msr); + error = vlapic_write(vlapic, offset, val); + } } - break; } return error; } -int32_t -vlapic_wrmsr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t wval) -{ - int32_t error = 0; - struct acrn_vlapic *vlapic; - - vlapic = vcpu_vlapic(vcpu); - - switch (msr) { - case MSR_IA32_APIC_BASE: - error = vlapic_set_apicbase(vlapic, wval); - break; - - case MSR_IA32_TSC_DEADLINE: - vlapic_set_tsc_deadline_msr(vlapic, wval); - break; - - default: - if (is_x2apic_msr(msr)) { - error = vlapic_x2apic_access(vcpu, msr, true, &wval); - } else { - error = -1; - dev_dbg(ACRN_DBG_LAPIC, - "Invalid vlapic msr 0x%x access\n", msr); - } - break; - } - - dev_dbg(ACRN_DBG_LAPIC, "cpu[%hu] wrmsr: %x wval=%#x", - vcpu->vcpu_id, msr, wval); - return error; -} - int32_t vlapic_create(struct acrn_vcpu *vcpu) { vcpu->arch.vlapic.vm = vcpu->vm; diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index 942adc402..49b444c41 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -388,7 +388,7 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu) switch (msr) { case MSR_IA32_TSC_DEADLINE: { - err = vlapic_rdmsr(vcpu, msr, &v); + v = vlapic_get_tsc_deadline_msr(vcpu_vlapic(vcpu)); break; } case MSR_IA32_TSC_ADJUST: @@ -435,7 +435,7 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu) case MSR_IA32_APIC_BASE: { /* Read APIC base */ - err = vlapic_rdmsr(vcpu, msr, &v); + v = vlapic_get_apicbase(vcpu_vlapic(vcpu)); break; } case MSR_IA32_FEATURE_CONTROL: @@ -446,7 +446,7 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu) default: { if (is_x2apic_msr(msr)) { - err = vlapic_rdmsr(vcpu, msr, &v); + err = vlapic_x2apic_read(vcpu, msr, &v); } else { pr_warn("%s(): vm%d vcpu%d reading MSR %lx not supported", __func__, vcpu->vm->vm_id, vcpu->vcpu_id, msr); @@ -526,7 +526,7 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu) switch (msr) { case MSR_IA32_TSC_DEADLINE: { - err = vlapic_wrmsr(vcpu, msr, v); + vlapic_set_tsc_deadline_msr(vcpu_vlapic(vcpu), v); break; } case MSR_IA32_TSC_ADJUST: @@ -586,7 +586,7 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu) } case MSR_IA32_APIC_BASE: { - err = vlapic_wrmsr(vcpu, msr, v); + err = vlapic_set_apicbase(vcpu_vlapic(vcpu), v); break; } case MSR_IA32_FEATURE_CONTROL: @@ -597,7 +597,7 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu) default: { if (is_x2apic_msr(msr)) { - err = vlapic_wrmsr(vcpu, msr, v); + err = vlapic_x2apic_write(vcpu, msr, v); } else { pr_warn("%s(): vm%d vcpu%d writing MSR %lx not supported", __func__, vcpu->vm->vm_id, vcpu->vcpu_id, msr); diff --git a/hypervisor/include/arch/x86/guest/vlapic.h b/hypervisor/include/arch/x86/guest/vlapic.h index 04ace61ac..b90ad72e0 100644 --- a/hypervisor/include/arch/x86/guest/vlapic.h +++ b/hypervisor/include/arch/x86/guest/vlapic.h @@ -165,8 +165,12 @@ void vlapic_get_deliverable_intr(struct acrn_vlapic *vlapic, uint32_t vector); */ uint64_t apicv_get_pir_desc_paddr(struct acrn_vcpu *vcpu); -int32_t vlapic_rdmsr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *rval); -int32_t vlapic_wrmsr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t wval); +uint64_t vlapic_get_tsc_deadline_msr(const struct acrn_vlapic *vlapic); +void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, uint64_t val_arg); +uint64_t vlapic_get_apicbase(const struct acrn_vlapic *vlapic); +int32_t vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new); +int32_t vlapic_x2apic_read(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val); +int32_t vlapic_x2apic_write(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val); /* * Signals to the LAPIC that an interrupt at 'vector' needs to be generated