hv: vlapic: remove vcpu/vm structure pointer from vlapic

We could use container_of to get vcpu/vm structure pointer from vlapic. So vcpu/vm
structure pointer is no need in vlapic structure.

Tracked-On: #4550
Signed-off-by: Li Fei1 <fei1.li@intel.com>
This commit is contained in:
Li Fei1 2020-03-30 11:45:31 +08:00 committed by wenlingz
parent 7f342bf62f
commit a7768fdb6a
2 changed files with 61 additions and 60 deletions

View File

@ -64,6 +64,11 @@ static inline uint32_t prio(uint32_t x)
#define DBG_LEVEL_VLAPIC 6U #define DBG_LEVEL_VLAPIC 6U
static inline struct acrn_vcpu *vlapic2vcpu(const struct acrn_vlapic *vlapic)
{
return container_of(container_of(vlapic, struct acrn_vcpu_arch, vlapic), struct acrn_vcpu, arch);
}
#if VLAPIC_VERBOS #if VLAPIC_VERBOS
static inline void vlapic_dump_irr(const struct acrn_vlapic *vlapic, const char *msg) static inline void vlapic_dump_irr(const struct acrn_vlapic *vlapic, const char *msg)
{ {
@ -165,7 +170,7 @@ vlapic_get_apicid(const struct acrn_vlapic *vlapic)
static inline uint32_t static inline uint32_t
vlapic_build_id(const struct acrn_vlapic *vlapic) vlapic_build_id(const struct acrn_vlapic *vlapic)
{ {
const struct acrn_vcpu *vcpu = vlapic->vcpu; const struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic);
uint32_t vlapic_id, lapic_regs_id; uint32_t vlapic_id, lapic_regs_id;
if (is_sos_vm(vcpu->vm)) { if (is_sos_vm(vcpu->vm)) {
@ -299,7 +304,7 @@ static void vlapic_init_timer(struct acrn_vlapic *vlapic)
(void)memset(vtimer, 0U, sizeof(struct vlapic_timer)); (void)memset(vtimer, 0U, sizeof(struct vlapic_timer));
initialize_timer(&vtimer->timer, initialize_timer(&vtimer->timer,
vlapic_timer_expired, vlapic->vcpu, vlapic_timer_expired, vlapic2vcpu(vlapic),
0UL, 0, 0UL); 0UL, 0, 0UL);
} }
@ -427,23 +432,24 @@ static void vlapic_write_icrtmr(struct acrn_vlapic *vlapic)
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; uint64_t ret;
struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic);
if (is_lapic_pt_enabled(vlapic->vcpu)) { if (is_lapic_pt_enabled(vcpu)) {
/* If physical TSC_DEADLINE is zero which means it's not armed (automatically disarmed /* If physical TSC_DEADLINE is zero which means it's not armed (automatically disarmed
* after timer triggered), return 0 and reset the virtual TSC_DEADLINE; * after timer triggered), return 0 and reset the virtual TSC_DEADLINE;
* If physical TSC_DEADLINE is not zero, return the virtual TSC_DEADLINE value. * If physical TSC_DEADLINE is not zero, return the virtual TSC_DEADLINE value.
*/ */
if (msr_read(MSR_IA32_TSC_DEADLINE) == 0UL) { if (msr_read(MSR_IA32_TSC_DEADLINE) == 0UL) {
vcpu_set_guest_msr(vlapic->vcpu, MSR_IA32_TSC_DEADLINE, 0UL); vcpu_set_guest_msr(vcpu, MSR_IA32_TSC_DEADLINE, 0UL);
ret = 0UL; ret = 0UL;
} else { } else {
ret = vcpu_get_guest_msr(vlapic->vcpu, MSR_IA32_TSC_DEADLINE); ret = vcpu_get_guest_msr(vcpu, MSR_IA32_TSC_DEADLINE);
} }
} else if (!vlapic_lvtt_tsc_deadline(vlapic)) { } else if (!vlapic_lvtt_tsc_deadline(vlapic)) {
ret = 0UL; ret = 0UL;
} else { } else {
ret = (vlapic->vtimer.timer.fire_tsc == 0UL) ? 0UL : ret = (vlapic->vtimer.timer.fire_tsc == 0UL) ? 0UL :
vcpu_get_guest_msr(vlapic->vcpu, MSR_IA32_TSC_DEADLINE); vcpu_get_guest_msr(vcpu, MSR_IA32_TSC_DEADLINE);
} }
return ret; return ret;
@ -453,9 +459,10 @@ void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, uint64_t val_arg)
{ {
struct hv_timer *timer; struct hv_timer *timer;
uint64_t val = val_arg; uint64_t val = val_arg;
struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic);
if (is_lapic_pt_enabled(vlapic->vcpu)) { if (is_lapic_pt_enabled(vcpu)) {
vcpu_set_guest_msr(vlapic->vcpu, MSR_IA32_TSC_DEADLINE, val); vcpu_set_guest_msr(vcpu, MSR_IA32_TSC_DEADLINE, val);
/* If val is not zero, which mean guest intends to arm the tsc_deadline timer, /* If val is not zero, which mean guest intends to arm the tsc_deadline timer,
* if the calculated value to write to the physical TSC_DEADLINE msr is zero, * if the calculated value to write to the physical TSC_DEADLINE msr is zero,
* we plus 1 to not disarm the physcial timer falsely; * we plus 1 to not disarm the physcial timer falsely;
@ -472,7 +479,7 @@ void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, uint64_t val_arg)
msr_write(MSR_IA32_TSC_DEADLINE, 0); msr_write(MSR_IA32_TSC_DEADLINE, 0);
} }
} else if (vlapic_lvtt_tsc_deadline(vlapic)) { } else if (vlapic_lvtt_tsc_deadline(vlapic)) {
vcpu_set_guest_msr(vlapic->vcpu, MSR_IA32_TSC_DEADLINE, val); vcpu_set_guest_msr(vcpu, MSR_IA32_TSC_DEADLINE, val);
timer = &vlapic->vtimer.timer; timer = &vlapic->vtimer.timer;
del_timer(timer); del_timer(timer);
@ -510,11 +517,11 @@ vlapic_set_tmr(struct acrn_vlapic *vlapic, uint32_t vector, bool level)
struct lapic_reg *tmrptr = &(vlapic->apic_page.tmr[0]); struct lapic_reg *tmrptr = &(vlapic->apic_page.tmr[0]);
if (level) { if (level) {
if (!bitmap32_test_and_set_lock((uint16_t)(vector & 0x1fU), &tmrptr[(vector & 0xffU) >> 5U].v)) { if (!bitmap32_test_and_set_lock((uint16_t)(vector & 0x1fU), &tmrptr[(vector & 0xffU) >> 5U].v)) {
vcpu_set_eoi_exit_bitmap(vlapic->vcpu, vector); vcpu_set_eoi_exit_bitmap(vlapic2vcpu(vlapic), vector);
} }
} else { } else {
if (bitmap32_test_and_clear_lock((uint16_t)(vector & 0x1fU), &tmrptr[(vector & 0xffU) >> 5U].v)) { if (bitmap32_test_and_clear_lock((uint16_t)(vector & 0x1fU), &tmrptr[(vector & 0xffU) >> 5U].v)) {
vcpu_clear_eoi_exit_bitmap(vlapic->vcpu, vector); vcpu_clear_eoi_exit_bitmap(vlapic2vcpu(vlapic), vector);
} }
} }
} }
@ -533,7 +540,7 @@ vlapic_reset_tmr(struct acrn_vlapic *vlapic)
lapic->tmr[i].v = 0U; lapic->tmr[i].v = 0U;
} }
vcpu_reset_eoi_exit_bitmaps(vlapic->vcpu); vcpu_reset_eoi_exit_bitmaps(vlapic2vcpu(vlapic));
} }
static void apicv_basic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, bool level) static void apicv_basic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, bool level)
@ -550,7 +557,7 @@ static void apicv_basic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector,
if (!bitmap32_test_and_set_lock((uint16_t)(vector & 0x1fU), &irrptr[idx].v)) { if (!bitmap32_test_and_set_lock((uint16_t)(vector & 0x1fU), &irrptr[idx].v)) {
/* update TMR if interrupt trigger mode has changed */ /* update TMR if interrupt trigger mode has changed */
vlapic_set_tmr(vlapic, vector, level); vlapic_set_tmr(vlapic, vector, level);
vcpu_make_request(vlapic->vcpu, ACRN_REQUEST_EVENT); vcpu_make_request(vlapic2vcpu(vlapic), ACRN_REQUEST_EVENT);
} }
} }
@ -560,6 +567,7 @@ static void apicv_advanced_accept_intr(struct acrn_vlapic *vlapic, uint32_t vect
vlapic_set_tmr(vlapic, vector, level); vlapic_set_tmr(vlapic, vector, level);
if (apicv_set_intr_ready(vlapic, vector)) { if (apicv_set_intr_ready(vlapic, vector)) {
struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic);
/* /*
* Send interrupt to vCPU via posted interrupt way: * Send interrupt to vCPU via posted interrupt way:
* 1. If target vCPU is in root mode(isn't running), * 1. If target vCPU is in root mode(isn't running),
@ -570,10 +578,10 @@ static void apicv_advanced_accept_intr(struct acrn_vlapic *vlapic, uint32_t vect
* send PI notification to vCPU and hardware will * send PI notification to vCPU and hardware will
* sync PIR to vIRR automatically. * sync PIR to vIRR automatically.
*/ */
bitmap_set_lock(ACRN_REQUEST_EVENT, &vlapic->vcpu->arch.pending_req); bitmap_set_lock(ACRN_REQUEST_EVENT, &vcpu->arch.pending_req);
if (get_pcpu_id() != pcpuid_from_vcpu(vlapic->vcpu)) { if (get_pcpu_id() != pcpuid_from_vcpu(vcpu)) {
apicv_post_intr(pcpuid_from_vcpu(vlapic->vcpu)); apicv_post_intr(pcpuid_from_vcpu(vcpu));
} }
} }
} }
@ -590,7 +598,7 @@ static void vlapic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, bool
if ((lapic->svr.v & APIC_SVR_ENABLE) == 0U) { if ((lapic->svr.v & APIC_SVR_ENABLE) == 0U) {
dev_dbg(DBG_LEVEL_VLAPIC, "vlapic is software disabled, ignoring interrupt %u", vector); dev_dbg(DBG_LEVEL_VLAPIC, "vlapic is software disabled, ignoring interrupt %u", vector);
} else { } else {
signal_event(&vlapic->vcpu->events[VCPU_EVENT_VIRTUAL_INTERRUPT]); signal_event(&vlapic2vcpu(vlapic)->events[VCPU_EVENT_VIRTUAL_INTERRUPT]);
vlapic->ops->accept_intr(vlapic, vector, level); vlapic->ops->accept_intr(vlapic, vector, level);
} }
} }
@ -738,12 +746,13 @@ vlapic_write_lvt(struct acrn_vlapic *vlapic, uint32_t offset)
if ((offset == APIC_OFFSET_LINT0_LVT) && if ((offset == APIC_OFFSET_LINT0_LVT) &&
((val & APIC_LVT_DM) == APIC_LVT_DM_EXTINT)) { ((val & APIC_LVT_DM) == APIC_LVT_DM_EXTINT)) {
uint32_t last = vlapic_get_lvt(vlapic, offset); uint32_t last = vlapic_get_lvt(vlapic, offset);
struct acrn_vm *vm = vlapic2vcpu(vlapic)->vm;
/* mask -> unmask: may from every vlapic in the vm */ /* mask -> unmask: may from every vlapic in the vm */
if (((last & APIC_LVT_M) != 0U) && ((val & APIC_LVT_M) == 0U)) { if (((last & APIC_LVT_M) != 0U) && ((val & APIC_LVT_M) == 0U)) {
if ((vlapic->vm->wire_mode == VPIC_WIRE_INTR) || if ((vm->wire_mode == VPIC_WIRE_INTR) ||
(vlapic->vm->wire_mode == VPIC_WIRE_NULL)) { (vm->wire_mode == VPIC_WIRE_NULL)) {
vlapic->vm->wire_mode = VPIC_WIRE_LAPIC; vm->wire_mode = VPIC_WIRE_LAPIC;
dev_dbg(DBG_LEVEL_VLAPIC, dev_dbg(DBG_LEVEL_VLAPIC,
"vpic wire mode -> LAPIC"); "vpic wire mode -> LAPIC");
} else { } else {
@ -752,8 +761,8 @@ vlapic_write_lvt(struct acrn_vlapic *vlapic, uint32_t offset)
} }
/* unmask -> mask: only from the vlapic LINT0-ExtINT enabled */ /* unmask -> mask: only from the vlapic LINT0-ExtINT enabled */
} else if (((last & APIC_LVT_M) == 0U) && ((val & APIC_LVT_M) != 0U)) { } else if (((last & APIC_LVT_M) == 0U) && ((val & APIC_LVT_M) != 0U)) {
if (vlapic->vm->wire_mode == VPIC_WIRE_LAPIC) { if (vm->wire_mode == VPIC_WIRE_LAPIC) {
vlapic->vm->wire_mode = VPIC_WIRE_NULL; vm->wire_mode = VPIC_WIRE_NULL;
dev_dbg(DBG_LEVEL_VLAPIC, dev_dbg(DBG_LEVEL_VLAPIC,
"vpic wire mode -> NULL"); "vpic wire mode -> NULL");
} }
@ -806,13 +815,10 @@ vlapic_mask_lvts(struct acrn_vlapic *vlapic)
static void static void
vlapic_fire_lvt(struct acrn_vlapic *vlapic, uint32_t lvt) vlapic_fire_lvt(struct acrn_vlapic *vlapic, uint32_t lvt)
{ {
uint32_t vec, mode;
struct acrn_vcpu *vcpu = vlapic->vcpu;
if ((lvt & APIC_LVT_M) == 0U) { if ((lvt & APIC_LVT_M) == 0U) {
struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic);
vec = lvt & APIC_LVT_VECTOR; uint32_t vec = lvt & APIC_LVT_VECTOR;
mode = lvt & APIC_LVT_DM; uint32_t mode = lvt & APIC_LVT_DM;
switch (mode) { switch (mode) {
case APIC_LVT_DM_FIXED: case APIC_LVT_DM_FIXED:
@ -884,10 +890,10 @@ vlapic_process_eoi(struct acrn_vlapic *vlapic)
* Register of the LAPIC. * Register of the LAPIC.
* TODO: Check if the bit 12 "Suppress EOI Broadcasts" is set. * TODO: Check if the bit 12 "Suppress EOI Broadcasts" is set.
*/ */
vioapic_broadcast_eoi(vlapic->vm, vector); vioapic_broadcast_eoi(vlapic2vcpu(vlapic)->vm, vector);
} }
vcpu_make_request(vlapic->vcpu, ACRN_REQUEST_EVENT); vcpu_make_request(vlapic2vcpu(vlapic), ACRN_REQUEST_EVENT);
} }
dev_dbg(DBG_LEVEL_VLAPIC, "Gratuitous EOI"); dev_dbg(DBG_LEVEL_VLAPIC, "Gratuitous EOI");
@ -921,9 +927,9 @@ vlapic_trigger_lvt(struct acrn_vlapic *vlapic, uint32_t lvt_index)
{ {
uint32_t lvt; uint32_t lvt;
int32_t ret = 0; int32_t ret = 0;
struct acrn_vcpu *vcpu = vlapic->vcpu;
if (vlapic_enabled(vlapic) == false) { if (vlapic_enabled(vlapic) == false) {
struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic);
/* /*
* When the local APIC is global/hardware disabled, * When the local APIC is global/hardware disabled,
* LINT[1:0] pins are configured as INTR and NMI pins, * LINT[1:0] pins are configured as INTR and NMI pins,
@ -1094,7 +1100,7 @@ vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
} }
if (lowprio && (lowprio_dest != NULL)) { if (lowprio && (lowprio_dest != NULL)) {
bitmap_set_nolock(lowprio_dest->vcpu->vcpu_id, dmask); bitmap_set_nolock(vlapic2vcpu(lowprio_dest)->vcpu_id, dmask);
} }
} }
} }
@ -1220,6 +1226,7 @@ static void vlapic_write_icrlo(struct acrn_vlapic *vlapic)
|| (mode == APIC_DELMODE_STARTUP))) { || (mode == APIC_DELMODE_STARTUP))) {
dev_dbg(DBG_LEVEL_VLAPIC, "Invalid ICR value"); dev_dbg(DBG_LEVEL_VLAPIC, "Invalid ICR value");
} else { } else {
struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic);
dev_dbg(DBG_LEVEL_VLAPIC, dev_dbg(DBG_LEVEL_VLAPIC,
"icrlo 0x%08x icrhi 0x%08x triggered ipi %u", "icrlo 0x%08x icrhi 0x%08x triggered ipi %u",
@ -1227,17 +1234,17 @@ static void vlapic_write_icrlo(struct acrn_vlapic *vlapic)
switch (shorthand) { switch (shorthand) {
case APIC_DEST_DESTFLD: case APIC_DEST_DESTFLD:
vlapic_calc_dest(vlapic->vm, &dmask, is_broadcast, dest, phys, false); vlapic_calc_dest(vcpu->vm, &dmask, is_broadcast, dest, phys, false);
break; break;
case APIC_DEST_SELF: case APIC_DEST_SELF:
bitmap_set_nolock(vlapic->vcpu->vcpu_id, &dmask); bitmap_set_nolock(vcpu->vcpu_id, &dmask);
break; break;
case APIC_DEST_ALLISELF: case APIC_DEST_ALLISELF:
dmask = vm_active_cpus(vlapic->vm); dmask = vm_active_cpus(vcpu->vm);
break; break;
case APIC_DEST_ALLESELF: case APIC_DEST_ALLESELF:
dmask = vm_active_cpus(vlapic->vm); dmask = vm_active_cpus(vcpu->vm);
bitmap_clear_nolock(vlapic->vcpu->vcpu_id, &dmask); bitmap_clear_nolock(vlapic2vcpu(vlapic)->vcpu_id, &dmask);
break; break;
default: default:
/* /*
@ -1247,9 +1254,9 @@ static void vlapic_write_icrlo(struct acrn_vlapic *vlapic)
break; break;
} }
for (vcpu_id = 0U; vcpu_id < vlapic->vm->hw.created_vcpus; vcpu_id++) { for (vcpu_id = 0U; vcpu_id < vcpu->vm->hw.created_vcpus; vcpu_id++) {
if ((dmask & (1UL << vcpu_id)) != 0UL) { if ((dmask & (1UL << vcpu_id)) != 0UL) {
target_vcpu = vcpu_from_vid(vlapic->vm, vcpu_id); target_vcpu = vcpu_from_vid(vcpu->vm, vcpu_id);
if (mode == APIC_DELMODE_FIXED) { if (mode == APIC_DELMODE_FIXED) {
vlapic_set_intr(target_vcpu, vec, LAPIC_TRIG_EDGE); vlapic_set_intr(target_vcpu, vec, LAPIC_TRIG_EDGE);
@ -1385,6 +1392,7 @@ vlapic_write_svr(struct acrn_vlapic *vlapic)
changed = old ^ new; changed = old ^ new;
if ((changed & APIC_SVR_ENABLE) != 0U) { if ((changed & APIC_SVR_ENABLE) != 0U) {
if ((new & APIC_SVR_ENABLE) == 0U) { if ((new & APIC_SVR_ENABLE) == 0U) {
struct acrn_vm *vm = vlapic2vcpu(vlapic)->vm;
/* /*
* The apic is now disabled so stop the apic timer * The apic is now disabled so stop the apic timer
* and mask all the LVT entries. * and mask all the LVT entries.
@ -1394,8 +1402,8 @@ vlapic_write_svr(struct acrn_vlapic *vlapic)
vlapic_mask_lvts(vlapic); vlapic_mask_lvts(vlapic);
/* the only one enabled LINT0-ExtINT vlapic disabled */ /* the only one enabled LINT0-ExtINT vlapic disabled */
if (vlapic->vm->wire_mode == VPIC_WIRE_NULL) { if (vm->wire_mode == VPIC_WIRE_NULL) {
vlapic->vm->wire_mode = VPIC_WIRE_INTR; vm->wire_mode = VPIC_WIRE_INTR;
dev_dbg(DBG_LEVEL_VLAPIC, dev_dbg(DBG_LEVEL_VLAPIC,
"vpic wire mode -> INTR"); "vpic wire mode -> INTR");
} }
@ -1637,7 +1645,7 @@ vlapic_reset(struct acrn_vlapic *vlapic, const struct acrn_apicv_ops *ops, enum
vlapic->msr_apicbase = DEFAULT_APIC_BASE; vlapic->msr_apicbase = DEFAULT_APIC_BASE;
if (vlapic->vcpu->vcpu_id == BSP_CPU_ID) { if (vlapic2vcpu(vlapic)->vcpu_id == BSP_CPU_ID) {
vlapic->msr_apicbase |= APICBASE_BSP; vlapic->msr_apicbase |= APICBASE_BSP;
} }
if (mode == INIT_RESET) { if (mode == INIT_RESET) {
@ -1681,8 +1689,8 @@ vlapic_reset(struct acrn_vlapic *vlapic, const struct acrn_apicv_ops *ops, enum
} }
/** /**
* @pre vlapic->vm != NULL * @pre vlapic-...->vm != NULL
* @pre vlapic->vcpu->vcpu_id < MAX_VCPUS_PER_VM * @pre vlapic-...->vcpu->vcpu_id < MAX_VCPUS_PER_VM
*/ */
void void
vlapic_init(struct acrn_vlapic *vlapic) vlapic_init(struct acrn_vlapic *vlapic)
@ -1725,13 +1733,13 @@ uint64_t vlapic_get_apicbase(const struct acrn_vlapic *vlapic)
static void ptapic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, __unused bool level) static void ptapic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, __unused bool level)
{ {
pr_err("Invalid op %s, VM%u, vCPU%u, vector %u", __func__, pr_err("Invalid op %s, VM%u, vCPU%u, vector %u", __func__,
vlapic->vm->vm_id, vlapic->vcpu->vcpu_id, vector); vlapic2vcpu(vlapic)->vm->vm_id, vlapic2vcpu(vlapic)->vcpu_id, vector);
} }
static bool ptapic_inject_intr(struct acrn_vlapic *vlapic, static bool ptapic_inject_intr(struct acrn_vlapic *vlapic,
__unused bool guest_irq_enabled, __unused bool injected) __unused bool guest_irq_enabled, __unused bool injected)
{ {
pr_err("Invalid op %s, VM%u, vCPU%u", __func__, vlapic->vm->vm_id, vlapic->vcpu->vcpu_id); pr_err("Invalid op %s, VM%u, vCPU%u", __func__, vlapic2vcpu(vlapic)->vm->vm_id, vlapic2vcpu(vlapic)->vcpu_id);
return injected; return injected;
} }
@ -1766,8 +1774,6 @@ int32_t vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new)
int32_t ret = 0; int32_t ret = 0;
uint64_t changed; uint64_t changed;
bool change_in_vlapic_mode = false; bool change_in_vlapic_mode = false;
struct acrn_vcpu *vcpu = vlapic->vcpu;
if (vlapic->msr_apicbase != new) { if (vlapic->msr_apicbase != new) {
changed = vlapic->msr_apicbase ^ new; changed = vlapic->msr_apicbase ^ new;
@ -1777,20 +1783,21 @@ int32_t vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new)
* TODO: Logic to check for change in Reserved Bits and Inject GP * TODO: Logic to check for change in Reserved Bits and Inject GP
*/ */
/* /*
* Logic to check for change in Bits 11:10 for vLAPIC mode switch * Logic to check for change in Bits 11:10 for vLAPIC mode switch
*/ */
if (change_in_vlapic_mode) { if (change_in_vlapic_mode) {
if ((new & APICBASE_LAPIC_MODE) == if ((new & APICBASE_LAPIC_MODE) ==
(APICBASE_XAPIC | APICBASE_X2APIC)) { (APICBASE_XAPIC | APICBASE_X2APIC)) {
struct acrn_vcpu *vcpu = vlapic2vcpu(vlapic);
if (is_lapic_pt_configured(vcpu->vm)) { if (is_lapic_pt_configured(vcpu->vm)) {
/* vlapic need to be reset to make sure it is in correct state */ /* vlapic need to be reset to make sure it is in correct state */
vlapic_reset(vlapic, &ptapic_ops, SOFTWARE_RESET); vlapic_reset(vlapic, &ptapic_ops, SOFTWARE_RESET);
} }
vlapic->msr_apicbase = new; vlapic->msr_apicbase = new;
vlapic_build_x2apic_id(vlapic); vlapic_build_x2apic_id(vlapic);
switch_apicv_mode_x2apic(vlapic->vcpu); switch_apicv_mode_x2apic(vcpu);
update_vm_vlapic_state(vcpu->vm); update_vm_vlapic_state(vcpu->vm);
} else { } else {
/* /*
@ -2170,9 +2177,6 @@ int32_t vlapic_x2apic_write(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val)
void vlapic_create(struct acrn_vcpu *vcpu) void vlapic_create(struct acrn_vcpu *vcpu)
{ {
vcpu->arch.vlapic.vm = vcpu->vm;
vcpu->arch.vlapic.vcpu = vcpu;
if (is_vcpu_bsp(vcpu)) { if (is_vcpu_bsp(vcpu)) {
uint64_t *pml4_page = uint64_t *pml4_page =
(uint64_t *)vcpu->vm->arch_vm.nworld_eptp; (uint64_t *)vcpu->vm->arch_vm.nworld_eptp;
@ -2497,7 +2501,7 @@ int32_t veoi_vmexit_handler(struct acrn_vcpu *vcpu)
if (bitmap32_test((uint16_t)(vector & 0x1fU), &tmrptr[idx].v)) { if (bitmap32_test((uint16_t)(vector & 0x1fU), &tmrptr[idx].v)) {
/* hook to vIOAPIC */ /* hook to vIOAPIC */
vioapic_broadcast_eoi(vlapic->vm, vector); vioapic_broadcast_eoi(vcpu->vm, vector);
} }
TRACE_2L(TRACE_VMEXIT_APICV_VIRT_EOI, vector, 0UL); TRACE_2L(TRACE_VMEXIT_APICV_VIRT_EOI, vector, 0UL);
@ -2509,16 +2513,14 @@ static void vlapic_x2apic_self_ipi_handler(struct acrn_vlapic *vlapic)
{ {
struct lapic_regs *lapic; struct lapic_regs *lapic;
uint32_t vector; uint32_t vector;
struct acrn_vcpu *target_vcpu;
lapic = &(vlapic->apic_page); lapic = &(vlapic->apic_page);
vector = lapic->self_ipi.v & APIC_VECTOR_MASK; vector = lapic->self_ipi.v & APIC_VECTOR_MASK;
target_vcpu = vlapic->vcpu;
if (vector < 16U) { if (vector < 16U) {
vlapic_set_error(vlapic, APIC_ESR_SEND_ILLEGAL_VECTOR); vlapic_set_error(vlapic, APIC_ESR_SEND_ILLEGAL_VECTOR);
dev_dbg(DBG_LEVEL_VLAPIC, "Ignoring invalid IPI %u", vector); dev_dbg(DBG_LEVEL_VLAPIC, "Ignoring invalid IPI %u", vector);
} else { } else {
vlapic_set_intr(target_vcpu, vector, LAPIC_TRIG_EDGE); vlapic_set_intr(vlapic2vcpu(vlapic), vector, LAPIC_TRIG_EDGE);
} }
} }

View File

@ -61,9 +61,6 @@ struct acrn_vlapic {
*/ */
struct lapic_regs apic_page; struct lapic_regs apic_page;
struct acrn_vm *vm;
struct acrn_vcpu *vcpu;
uint32_t esr_pending; uint32_t esr_pending;
int32_t esr_firing; int32_t esr_firing;
@ -88,6 +85,8 @@ struct acrn_vlapic {
uint32_t lvt_last[VLAPIC_MAXLVT_INDEX + 1]; uint32_t lvt_last[VLAPIC_MAXLVT_INDEX + 1];
} __aligned(PAGE_SIZE); } __aligned(PAGE_SIZE);
struct acrn_vcpu;
struct acrn_apicv_ops { struct acrn_apicv_ops {
void (*accept_intr)(struct acrn_vlapic *vlapic, uint32_t vector, bool level); void (*accept_intr)(struct acrn_vlapic *vlapic, uint32_t vector, bool level);
bool (*inject_intr)(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected); bool (*inject_intr)(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected);