HV:refine 'apic_page' & 'pir_desc' in 'struct acrn_vlapic'

- update 'apic_page' field in 'struct acrn_vlapic',
   from pointer type to 'struct lapic_regs' type.

 - delete 'pir' and update 'pir_desc' to 'vlapic_pir_desc'
   type.

 - fix potential memory leak in 'vlapic_create()'
   should free allocated memory in case of registering
   mmio handler failure.

Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
This commit is contained in:
Yonghua Huang 2018-08-20 18:25:48 +08:00 committed by lijinxia
parent 17ef5076a4
commit e0d40feaa8
4 changed files with 68 additions and 77 deletions

View File

@ -52,7 +52,7 @@
static inline void vlapic_dump_irr(struct acrn_vlapic *vlapic, char *msg) static inline void vlapic_dump_irr(struct acrn_vlapic *vlapic, char *msg)
{ {
uint32_t i; uint32_t i;
struct lapic_reg *irrptr = &(vlapic)->apic_page->irr[0]; struct lapic_reg *irrptr = &(vlapic->apic_page.irr[0]);
for (i = 0U; i < 8U; i++) for (i = 0U; i < 8U; i++)
dev_dbg(ACRN_DBG_LAPIC, "%s irr%u 0x%08x", dev_dbg(ACRN_DBG_LAPIC, "%s irr%u 0x%08x",
@ -62,7 +62,7 @@ static inline void vlapic_dump_irr(struct acrn_vlapic *vlapic, char *msg)
static inline void vlapic_dump_isr(struct acrn_vlapic *vlapic, char *msg) static inline void vlapic_dump_isr(struct acrn_vlapic *vlapic, char *msg)
{ {
uint32_t i; uint32_t i;
struct lapic_reg *isrptr = &(vlapic)->apic_page->isr[0]; struct lapic_reg *isrptr = &(vlapic->apic_page.isr[0]);
for (i = 0U; i < 8U; i++) { for (i = 0U; i < 8U; i++) {
dev_dbg(ACRN_DBG_LAPIC, "%s isr%u 0x%08x", dev_dbg(ACRN_DBG_LAPIC, "%s isr%u 0x%08x",
@ -155,14 +155,14 @@ vm_active_cpus(struct vm *vm)
uint32_t uint32_t
vlapic_get_id(struct acrn_vlapic *vlapic) vlapic_get_id(struct acrn_vlapic *vlapic)
{ {
uint32_t id = vlapic->apic_page->id; uint32_t id = vlapic->apic_page.id;
return id; return id;
} }
uint8_t uint8_t
vlapic_get_apicid(struct acrn_vlapic *vlapic) vlapic_get_apicid(struct acrn_vlapic *vlapic)
{ {
uint32_t apicid = vlapic->apic_page->id >> APIC_ID_SHIFT; uint32_t apicid = (vlapic->apic_page.id) >> APIC_ID_SHIFT;
return (uint8_t)apicid; return (uint8_t)apicid;
} }
@ -192,7 +192,7 @@ vlapic_dfr_write_handler(struct acrn_vlapic *vlapic)
{ {
struct lapic_regs *lapic; struct lapic_regs *lapic;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
lapic->dfr &= APIC_DFR_MODEL_MASK; lapic->dfr &= APIC_DFR_MODEL_MASK;
lapic->dfr |= APIC_DFR_RESERVED; lapic->dfr |= APIC_DFR_RESERVED;
@ -210,7 +210,7 @@ vlapic_ldr_write_handler(struct acrn_vlapic *vlapic)
{ {
struct lapic_regs *lapic; struct lapic_regs *lapic;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
lapic->ldr &= ~APIC_LDR_RESERVED; lapic->ldr &= ~APIC_LDR_RESERVED;
dev_dbg(ACRN_DBG_LAPIC, "vlapic LDR set to %#x", lapic->ldr); dev_dbg(ACRN_DBG_LAPIC, "vlapic LDR set to %#x", lapic->ldr);
} }
@ -224,7 +224,7 @@ vlapic_id_write_handler(struct acrn_vlapic *vlapic)
* We don't allow the ID register to be modified so reset it back to * We don't allow the ID register to be modified so reset it back to
* its default value. * its default value.
*/ */
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
lapic->id = vlapic_get_id(vlapic); lapic->id = vlapic_get_id(vlapic);
} }
@ -240,28 +240,29 @@ vlapic_timer_divisor_shift(uint32_t dcr)
static inline bool static inline bool
vlapic_lvtt_oneshot(struct acrn_vlapic *vlapic) vlapic_lvtt_oneshot(struct acrn_vlapic *vlapic)
{ {
return ((vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_TM) return (((vlapic->apic_page.lvt[APIC_LVT_TIMER].val) & APIC_LVTT_TM)
== APIC_LVTT_TM_ONE_SHOT); == APIC_LVTT_TM_ONE_SHOT);
} }
static inline bool static inline bool
vlapic_lvtt_period(struct acrn_vlapic *vlapic) vlapic_lvtt_period(struct acrn_vlapic *vlapic)
{ {
return ((vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_TM) return (((vlapic->apic_page.lvt[APIC_LVT_TIMER].val) & APIC_LVTT_TM)
== APIC_LVTT_TM_PERIODIC); == APIC_LVTT_TM_PERIODIC);
} }
static inline bool static inline bool
vlapic_lvtt_tsc_deadline(struct acrn_vlapic *vlapic) vlapic_lvtt_tsc_deadline(struct acrn_vlapic *vlapic)
{ {
return ((vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_TM) return (((vlapic->apic_page.lvt[APIC_LVT_TIMER].val) & APIC_LVTT_TM)
== APIC_LVTT_TM_TSCDLT); == APIC_LVTT_TM_TSCDLT);
} }
static inline bool static inline bool
vlapic_lvtt_masked(struct acrn_vlapic *vlapic) vlapic_lvtt_masked(struct acrn_vlapic *vlapic)
{ {
return (vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_M) != 0U; return ((vlapic->apic_page.lvt[APIC_LVT_TIMER].val) & APIC_LVTT_M)
!= 0U;
} }
static void vlapic_create_timer(struct acrn_vlapic *vlapic) static void vlapic_create_timer(struct acrn_vlapic *vlapic)
@ -372,7 +373,7 @@ static void vlapic_dcr_write_handler(struct acrn_vlapic *vlapic)
{ {
uint32_t divisor_shift; uint32_t divisor_shift;
struct vlapic_timer *vtimer; struct vlapic_timer *vtimer;
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
vtimer = &vlapic->vtimer; vtimer = &vlapic->vtimer;
divisor_shift = vlapic_timer_divisor_shift(lapic->dcr_timer); divisor_shift = vlapic_timer_divisor_shift(lapic->dcr_timer);
@ -389,7 +390,7 @@ static void vlapic_icrtmr_write_handler(struct acrn_vlapic *vlapic)
return; return;
} }
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
vtimer = &vlapic->vtimer; vtimer = &vlapic->vtimer;
vtimer->tmicr = lapic->icr_timer; vtimer->tmicr = lapic->icr_timer;
@ -448,7 +449,7 @@ vlapic_esr_write_handler(struct acrn_vlapic *vlapic)
{ {
struct lapic_regs *lapic; struct lapic_regs *lapic;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
lapic->esr = vlapic->esr_pending; lapic->esr = vlapic->esr_pending;
vlapic->esr_pending = 0U; vlapic->esr_pending = 0U;
} }
@ -467,7 +468,7 @@ vlapic_set_intr_ready(struct acrn_vlapic *vlapic, uint32_t vector, bool level)
ASSERT(vector <= NR_MAX_VECTOR, ASSERT(vector <= NR_MAX_VECTOR,
"invalid vector %u", vector); "invalid vector %u", vector);
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
if ((lapic->svr & APIC_SVR_ENABLE) == 0U) { if ((lapic->svr & APIC_SVR_ENABLE) == 0U) {
dev_dbg(ACRN_DBG_LAPIC, dev_dbg(ACRN_DBG_LAPIC,
"vlapic is software disabled, ignoring interrupt %u", "vlapic is software disabled, ignoring interrupt %u",
@ -557,7 +558,7 @@ lvt_off_to_idx(uint32_t offset)
static inline uint32_t * static inline uint32_t *
vlapic_get_lvtptr(struct acrn_vlapic *vlapic, uint32_t offset) vlapic_get_lvtptr(struct acrn_vlapic *vlapic, uint32_t offset)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
uint32_t i; uint32_t i;
switch (offset) { switch (offset) {
@ -592,7 +593,7 @@ vlapic_lvt_write_handler(struct acrn_vlapic *vlapic, uint32_t offset)
uint32_t *lvtptr, mask, val, idx; uint32_t *lvtptr, mask, val, idx;
struct lapic_regs *lapic; struct lapic_regs *lapic;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
lvtptr = vlapic_get_lvtptr(vlapic, offset); lvtptr = vlapic_get_lvtptr(vlapic, offset);
val = *lvtptr; val = *lvtptr;
idx = lvt_off_to_idx(offset); idx = lvt_off_to_idx(offset);
@ -656,7 +657,7 @@ vlapic_lvt_write_handler(struct acrn_vlapic *vlapic, uint32_t offset)
static void static void
vlapic_mask_lvts(struct acrn_vlapic *vlapic) vlapic_mask_lvts(struct acrn_vlapic *vlapic)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
lapic->lvt_cmci |= APIC_LVT_M; lapic->lvt_cmci |= APIC_LVT_M;
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_CMCI_LVT); vlapic_lvt_write_handler(vlapic, APIC_OFFSET_CMCI_LVT);
@ -722,7 +723,7 @@ dump_isrvec_stk(struct acrn_vlapic *vlapic)
uint32_t i; uint32_t i;
struct lapic_reg *isrptr; struct lapic_reg *isrptr;
isrptr = &vlapic->apic_page->isr[0]; isrptr = &(vlapic->apic_page.isr[0]);
for (i = 0U; i < 8U; i++) { for (i = 0U; i < 8U; i++) {
printf("ISR%u 0x%08x\n", i, isrptr[i].val); printf("ISR%u 0x%08x\n", i, isrptr[i].val);
} }
@ -749,7 +750,7 @@ vlapic_update_ppr(struct acrn_vlapic *vlapic)
* bits is set in the ISRx registers. * bits is set in the ISRx registers.
*/ */
top_isrvec = (uint32_t)vlapic->isrvec_stk[vlapic->isrvec_stk_top]; top_isrvec = (uint32_t)vlapic->isrvec_stk[vlapic->isrvec_stk_top];
tpr = vlapic->apic_page->tpr; tpr = vlapic->apic_page.tpr;
/* update ppr */ /* update ppr */
{ {
@ -782,7 +783,7 @@ vlapic_update_ppr(struct acrn_vlapic *vlapic)
* corresponding entry on the isrvec stack. * corresponding entry on the isrvec stack.
*/ */
i = 1U; i = 1U;
isrptr = &vlapic->apic_page->isr[0]; isrptr = &(vlapic->apic_page.isr[0]);
for (vector = 0U; vector < 256U; vector++) { for (vector = 0U; vector < 256U; vector++) {
idx = vector / 32U; idx = vector / 32U;
if ((isrptr[idx].val & (1U << (vector % 32U))) != 0U) { if ((isrptr[idx].val & (1U << (vector % 32U))) != 0U) {
@ -804,14 +805,14 @@ vlapic_update_ppr(struct acrn_vlapic *vlapic)
ppr = top_isrvec & 0xf0U; ppr = top_isrvec & 0xf0U;
} }
vlapic->apic_page->ppr = ppr; vlapic->apic_page.ppr = ppr;
dev_dbg(ACRN_DBG_LAPIC, "%s 0x%02x", __func__, ppr); dev_dbg(ACRN_DBG_LAPIC, "%s 0x%02x", __func__, ppr);
} }
static void static void
vlapic_process_eoi(struct acrn_vlapic *vlapic) vlapic_process_eoi(struct acrn_vlapic *vlapic)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
struct lapic_reg *isrptr, *tmrptr; struct lapic_reg *isrptr, *tmrptr;
uint32_t i, vector, bitpos; uint32_t i, vector, bitpos;
@ -979,8 +980,8 @@ vlapic_calcdest(struct vm *vm, uint64_t *dmask, uint32_t dest,
bitmap_clear_lock(vcpu_id, &amask); bitmap_clear_lock(vcpu_id, &amask);
vlapic = vm_lapic_from_vcpu_id(vm, vcpu_id); vlapic = vm_lapic_from_vcpu_id(vm, vcpu_id);
dfr = vlapic->apic_page->dfr; dfr = vlapic->apic_page.dfr;
ldr = vlapic->apic_page->ldr; ldr = vlapic->apic_page.ldr;
if ((dfr & APIC_DFR_MODEL_MASK) == if ((dfr & APIC_DFR_MODEL_MASK) ==
APIC_DFR_MODEL_FLAT) { APIC_DFR_MODEL_FLAT) {
@ -1012,8 +1013,8 @@ vlapic_calcdest(struct vm *vm, uint64_t *dmask, uint32_t dest,
if (lowprio) { if (lowprio) {
if (target == NULL) { if (target == NULL) {
target = vlapic; target = vlapic;
} else if (target->apic_page->ppr > } else if (target->apic_page.ppr >
vlapic->apic_page->ppr) { vlapic->apic_page.ppr) {
target = vlapic; target = vlapic;
} else { } else {
/* target is the dest */ /* target is the dest */
@ -1039,7 +1040,7 @@ calcvdest(struct vm *vm, uint64_t *dmask, uint32_t dest, bool phys)
static void static void
vlapic_set_tpr(struct acrn_vlapic *vlapic, uint32_t val) vlapic_set_tpr(struct acrn_vlapic *vlapic, uint32_t val)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
if (lapic->tpr != val) { if (lapic->tpr != val) {
dev_dbg(ACRN_DBG_LAPIC, dev_dbg(ACRN_DBG_LAPIC,
@ -1052,7 +1053,7 @@ vlapic_set_tpr(struct acrn_vlapic *vlapic, uint32_t val)
static uint32_t static uint32_t
vlapic_get_tpr(struct acrn_vlapic *vlapic) vlapic_get_tpr(struct acrn_vlapic *vlapic)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
return lapic->tpr; return lapic->tpr;
} }
@ -1093,7 +1094,7 @@ vlapic_icrlo_write_handler(struct acrn_vlapic *vlapic)
struct lapic_regs *lapic; struct lapic_regs *lapic;
struct vcpu *target_vcpu; struct vcpu *target_vcpu;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
lapic->icr_lo &= ~APIC_DELSTAT_PEND; lapic->icr_lo &= ~APIC_DELSTAT_PEND;
icr_low = lapic->icr_lo; icr_low = lapic->icr_lo;
@ -1213,7 +1214,7 @@ vlapic_icrlo_write_handler(struct acrn_vlapic *vlapic)
int int
vlapic_pending_intr(struct acrn_vlapic *vlapic, uint32_t *vecptr) vlapic_pending_intr(struct acrn_vlapic *vlapic, uint32_t *vecptr)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
uint32_t i, vector, val, bitpos; uint32_t i, vector, val, bitpos;
struct lapic_reg *irrptr; struct lapic_reg *irrptr;
@ -1245,7 +1246,7 @@ vlapic_pending_intr(struct acrn_vlapic *vlapic, uint32_t *vecptr)
void void
vlapic_intr_accepted(struct acrn_vlapic *vlapic, uint32_t vector) vlapic_intr_accepted(struct acrn_vlapic *vlapic, uint32_t vector)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
struct lapic_reg *irrptr, *isrptr; struct lapic_reg *irrptr, *isrptr;
uint32_t idx, stk_top; uint32_t idx, stk_top;
@ -1288,7 +1289,7 @@ vlapic_svr_write_handler(struct acrn_vlapic *vlapic)
struct lapic_regs *lapic; struct lapic_regs *lapic;
uint32_t old, new, changed; uint32_t old, new, changed;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
new = lapic->svr; new = lapic->svr;
old = vlapic->svr_last; old = vlapic->svr_last;
@ -1334,7 +1335,7 @@ static int
vlapic_read(struct acrn_vlapic *vlapic, uint32_t offset_arg, vlapic_read(struct acrn_vlapic *vlapic, uint32_t offset_arg,
uint64_t *data) uint64_t *data)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
uint32_t i; uint32_t i;
uint32_t offset = offset_arg; uint32_t offset = offset_arg;
@ -1458,7 +1459,7 @@ static int
vlapic_write(struct acrn_vlapic *vlapic, uint32_t offset, vlapic_write(struct acrn_vlapic *vlapic, uint32_t offset,
uint64_t data) uint64_t data)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
uint32_t *regptr; uint32_t *regptr;
uint32_t data32 = (uint32_t)data; uint32_t data32 = (uint32_t)data;
int retval; int retval;
@ -1558,14 +1559,10 @@ vlapic_reset(struct acrn_vlapic *vlapic)
{ {
uint32_t i; uint32_t i;
struct lapic_regs *lapic; struct lapic_regs *lapic;
void *apic_page;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
apic_page = (void *)vlapic->apic_page; (void)memset((void *)lapic, 0U, CPU_PAGE_SIZE);
(void)memset(apic_page, 0U, CPU_PAGE_SIZE); (void)memset((void *)&(vlapic->pir_desc), 0U, sizeof(vlapic->pir_desc));
if (vlapic->pir_desc) {
(void)memset(vlapic->pir_desc, 0U, sizeof(struct vlapic_pir_desc));
}
lapic->id = vlapic_build_id(vlapic); lapic->id = vlapic_build_id(vlapic);
lapic->version = VLAPIC_VERSION; lapic->version = VLAPIC_VERSION;
@ -1598,8 +1595,6 @@ vlapic_init(struct acrn_vlapic *vlapic)
ASSERT(vlapic->vm != NULL, "%s: vm is not initialized", __func__); ASSERT(vlapic->vm != NULL, "%s: vm is not initialized", __func__);
ASSERT(vlapic->vcpu->vcpu_id < phys_cpu_num, ASSERT(vlapic->vcpu->vcpu_id < phys_cpu_num,
"%s: vcpu_id is not initialized", __func__); "%s: vcpu_id is not initialized", __func__);
ASSERT(vlapic->apic_page != NULL,
"%s: apic_page is not initialized", __func__);
/* /*
* If the vlapic is configured in x2apic mode then it will be * If the vlapic is configured in x2apic mode then it will be
@ -1621,7 +1616,7 @@ void vlapic_restore(struct acrn_vlapic *vlapic, struct lapic_regs *regs)
struct lapic_regs *lapic; struct lapic_regs *lapic;
int i; int i;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
lapic->tpr = regs->tpr; lapic->tpr = regs->tpr;
lapic->apr = regs->apr; lapic->apr = regs->apr;
@ -1712,7 +1707,7 @@ vlapic_deliver_intr(struct vm *vm, bool level, uint32_t dest, bool phys,
bool bool
vlapic_enabled(struct acrn_vlapic *vlapic) vlapic_enabled(struct acrn_vlapic *vlapic)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
if (((vlapic->msr_apicbase & APICBASE_ENABLED) != 0U) && if (((vlapic->msr_apicbase & APICBASE_ENABLED) != 0U) &&
((lapic->svr & APIC_SVR_ENABLE) != 0U)) { ((lapic->svr & APIC_SVR_ENABLE) != 0U)) {
@ -1729,7 +1724,7 @@ vlapic_set_tmr(struct acrn_vlapic *vlapic, uint32_t vector, bool level)
struct lapic_reg *tmrptr; struct lapic_reg *tmrptr;
uint32_t mask, idx; uint32_t mask, idx;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
tmrptr = &lapic->tmr[0]; tmrptr = &lapic->tmr[0];
idx = vector / 32U; idx = vector / 32U;
mask = 1U << (vector % 32U); mask = 1U << (vector % 32U);
@ -1902,7 +1897,7 @@ static void vlapic_timer_expired(void *data)
struct lapic_regs *lapic; struct lapic_regs *lapic;
vlapic = vcpu->arch_vcpu.vlapic; vlapic = vcpu->arch_vcpu.vlapic;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
/* inject vcpu timer interrupt if not masked */ /* inject vcpu timer interrupt if not masked */
if (!vlapic_lvtt_masked(vlapic)) { if (!vlapic_lvtt_masked(vlapic)) {
@ -2046,17 +2041,11 @@ int vlapic_mmio_access_handler(struct vcpu *vcpu, struct io_request *io_req,
int vlapic_create(struct vcpu *vcpu) int vlapic_create(struct vcpu *vcpu)
{ {
void *apic_page = alloc_page();
struct acrn_vlapic *vlapic = calloc(1U, sizeof(struct acrn_vlapic)); struct acrn_vlapic *vlapic = calloc(1U, sizeof(struct acrn_vlapic));
ASSERT(vlapic != NULL, "vlapic allocate failed"); ASSERT(vlapic != NULL, "vlapic allocate failed");
ASSERT(apic_page != NULL, "apic reg page allocate failed");
(void)memset((void *)apic_page, 0U, CPU_PAGE_SIZE);
vlapic->vm = vcpu->vm; vlapic->vm = vcpu->vm;
vlapic->vcpu = vcpu; vlapic->vcpu = vcpu;
vlapic->apic_page = (struct lapic_regs *)apic_page;
if (is_vapic_supported()) { if (is_vapic_supported()) {
if (is_vapic_intr_delivery_supported()) { if (is_vapic_intr_delivery_supported()) {
vlapic->ops.apicv_set_intr_ready_fn = vlapic->ops.apicv_set_intr_ready_fn =
@ -2068,8 +2057,6 @@ int vlapic_create(struct vcpu *vcpu)
vlapic->ops.apicv_set_tmr_fn = apicv_set_tmr; vlapic->ops.apicv_set_tmr_fn = apicv_set_tmr;
vlapic->ops.apicv_batch_set_tmr_fn = vlapic->ops.apicv_batch_set_tmr_fn =
apicv_batch_set_tmr; apicv_batch_set_tmr;
vlapic->pir_desc = (struct vlapic_pir_desc *)(&(vlapic->pir));
} }
if (is_vcpu_bsp(vcpu)) { if (is_vcpu_bsp(vcpu)) {
@ -2087,6 +2074,7 @@ int vlapic_create(struct vcpu *vcpu)
(uint64_t)DEFAULT_APIC_BASE + (uint64_t)DEFAULT_APIC_BASE +
CPU_PAGE_SIZE, CPU_PAGE_SIZE,
(void *) 0) != 0) { (void *) 0) != 0) {
free(vlapic);
return -1; return -1;
} }
} }
@ -2100,7 +2088,6 @@ int vlapic_create(struct vcpu *vcpu)
void vlapic_free(struct vcpu *vcpu) void vlapic_free(struct vcpu *vcpu)
{ {
struct acrn_vlapic *vlapic = NULL; struct acrn_vlapic *vlapic = NULL;
void *apic_page = NULL;
if (vcpu == NULL) { if (vcpu == NULL) {
return; return;
@ -2119,13 +2106,6 @@ void vlapic_free(struct vcpu *vcpu)
(uint64_t)DEFAULT_APIC_BASE + CPU_PAGE_SIZE); (uint64_t)DEFAULT_APIC_BASE + CPU_PAGE_SIZE);
} }
apic_page = vlapic->apic_page;
if (apic_page == NULL) {
free(vlapic);
return;
}
free(apic_page);
free(vlapic); free(vlapic);
} }
@ -2141,7 +2121,7 @@ apicv_set_intr_ready(struct acrn_vlapic *vlapic, uint32_t vector,
uint32_t idx; uint32_t idx;
int32_t notify; int32_t notify;
pir_desc = vlapic->pir_desc; pir_desc = &(vlapic->pir_desc);
idx = vector / 64U; idx = vector / 64U;
mask = 1UL << (vector % 64U); mask = 1UL << (vector % 64U);
@ -2159,14 +2139,14 @@ apicv_pending_intr(struct acrn_vlapic *vlapic, __unused uint32_t *vecptr)
uint64_t pending, pirval; uint64_t pending, pirval;
uint32_t i, ppr, vpr; uint32_t i, ppr, vpr;
pir_desc = vlapic->pir_desc; pir_desc = &(vlapic->pir_desc);
pending = atomic_load64(&pir_desc->pending); pending = atomic_load64(&pir_desc->pending);
if (pending == 0U) { if (pending == 0U) {
return 0; return 0;
} }
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
ppr = lapic->ppr & 0xF0U; ppr = lapic->ppr & 0xF0U;
if (ppr == 0U) { if (ppr == 0U) {
@ -2211,7 +2191,7 @@ apicv_set_tmr(__unused struct acrn_vlapic *vlapic, uint32_t vector, bool level)
static void static void
apicv_batch_set_tmr(struct acrn_vlapic *vlapic) apicv_batch_set_tmr(struct acrn_vlapic *vlapic)
{ {
struct lapic_regs *lapic = vlapic->apic_page; struct lapic_regs *lapic = &(vlapic->apic_page);
uint64_t val; uint64_t val;
struct lapic_reg *ptr; struct lapic_reg *ptr;
uint32_t s, e; uint32_t s, e;
@ -2252,7 +2232,7 @@ apicv_get_apic_access_addr(__unused struct vm *vm)
uint64_t uint64_t
apicv_get_apic_page_addr(struct acrn_vlapic *vlapic) apicv_get_apic_page_addr(struct acrn_vlapic *vlapic)
{ {
return HVA2HPA(vlapic->apic_page); return HVA2HPA(&(vlapic->apic_page));
} }
/* /*
@ -2270,13 +2250,13 @@ apicv_inject_pir(struct acrn_vlapic *vlapic)
uint16_t intr_status_old, intr_status_new; uint16_t intr_status_old, intr_status_new;
struct lapic_reg *irr = NULL; struct lapic_reg *irr = NULL;
pir_desc = vlapic->pir_desc; pir_desc = &(vlapic->pir_desc);
if (atomic_cmpxchg64(&pir_desc->pending, 1UL, 0UL) != 1UL) { if (atomic_cmpxchg64(&pir_desc->pending, 1UL, 0UL) != 1UL) {
return; return;
} }
pirval = 0UL; pirval = 0UL;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
irr = &lapic->irr[0]; irr = &lapic->irr[0];
for (i = 0U; i < 4U; i++) { for (i = 0U; i < 4U; i++) {
@ -2382,7 +2362,7 @@ int veoi_vmexit_handler(struct vcpu *vcpu)
vcpu_retain_rip(vcpu); vcpu_retain_rip(vcpu);
vlapic = vcpu->arch_vcpu.vlapic; vlapic = vcpu->arch_vcpu.vlapic;
lapic = vlapic->apic_page; lapic = &(vlapic->apic_page);
vector = (uint32_t)(vcpu->arch_vcpu.exit_qualification & 0xFFUL); vector = (uint32_t)(vcpu->arch_vcpu.exit_qualification & 0xFFUL);
tmrptr = &lapic->tmr[0]; tmrptr = &lapic->tmr[0];

View File

@ -115,10 +115,18 @@ struct vlapic_timer {
}; };
struct acrn_vlapic { struct acrn_vlapic {
/*
* Please keep 'apic_page' and 'pir_desc' be the first two fields in
* current structure, as below alignment restrictions are mandatory
* to support APICv features:
* - 'apic_page' MUST be 4KB aligned.
* - 'pir_desc' MUST be 64 bytes aligned.
*/
struct lapic_regs apic_page;
struct vlapic_pir_desc pir_desc;
struct vm *vm; struct vm *vm;
struct vcpu *vcpu; struct vcpu *vcpu;
struct lapic_regs *apic_page;
struct vlapic_pir_desc *pir_desc;
struct vlapic_ops ops; struct vlapic_ops ops;
uint32_t esr_pending; uint32_t esr_pending;
@ -153,7 +161,6 @@ struct acrn_vlapic {
*/ */
uint32_t svr_last; uint32_t svr_last;
uint32_t lvt_last[VLAPIC_MAXLVT_INDEX + 1]; uint32_t lvt_last[VLAPIC_MAXLVT_INDEX + 1];
struct vlapic_pir_desc pir; } __aligned(CPU_PAGE_SIZE);
};
#endif /* _VLAPIC_PRIV_H_ */ #endif /* _VLAPIC_PRIV_H_ */

View File

@ -167,7 +167,7 @@ struct lapic_regs {
/* reserved */ PAD4; /* reserved */ PAD4;
uint32_t dcr_timer; PAD3; uint32_t dcr_timer; PAD3;
/* reserved */ PAD4; /* reserved */ PAD4;
}; } __aligned(CPU_PAGE_SIZE);
enum LAPIC_REGISTERS { enum LAPIC_REGISTERS {
LAPIC_ID = 0x2, LAPIC_ID = 0x2,

View File

@ -233,6 +233,10 @@ static void deallocate_mem(struct mem_pool *pool, void *ptr)
} }
} }
/*
* The return address will be CPU_PAGE_SIZE aligned if 'num_bytes' is greater
* than CPU_PAGE_SIZE.
*/
void *malloc(unsigned int num_bytes) void *malloc(unsigned int num_bytes)
{ {
void *memory = NULL; void *memory = NULL;