hv: fix SOS vapic_id assignment issue

Currently vlapic_build_id() uses vcpu_id to retrieve the lapic_id
per_cpu variable:

  vlapic_id = per_cpu(lapic_id, vcpu->vcpu_id);

SOS vcpu_id may not equal to pcpu_id, and in that case it runs into
problems. For example, if any pre-launched VMs are launched on PCPUs
whose IDs are smaller than any PCPU IDs that are used by SOS.

This patch fixes the issue and simplify the code to create or get
vapic_id by:

- assign vapic_id in create_vlapic(), which now takes pcpu_id as input
  argument, and save it in the new field: vlapic->vapic_id, which will
  never be changed.
- simplify vlapic_get_apicid() by returning te saved vapid_id directly.
- remove vlapic_build_id().
- vlapic_init() is only called once, merge it into vlapic_create().

Tracked-On: #4268
Signed-off-by: Zide Chen <zide.chen@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Zide Chen
2020-04-02 13:57:41 -07:00
committed by wenlingz
parent 00ad3863a1
commit 6040d8f6a2
3 changed files with 38 additions and 68 deletions

View File

@@ -61,6 +61,7 @@ struct acrn_vlapic {
*/
struct lapic_regs apic_page;
uint32_t vapic_id;
uint32_t esr_pending;
int32_t esr_firing;
@@ -163,17 +164,20 @@ int32_t vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg);
void vlapic_receive_intr(struct acrn_vm *vm, bool level, uint32_t dest,
bool phys, uint32_t delmode, uint32_t vec, bool rh);
uint32_t vlapic_get_apicid(const struct acrn_vlapic *vlapic);
void vlapic_create(struct acrn_vcpu *vcpu);
/**
* @pre vlapic != NULL
*/
static inline uint32_t vlapic_get_apicid(const struct acrn_vlapic *vlapic)
{
return vlapic->vapic_id;
}
void vlapic_create(struct acrn_vcpu *vcpu, uint16_t pcpu_id);
/*
* @pre vcpu != NULL
*/
void vlapic_free(struct acrn_vcpu *vcpu);
/**
* @pre vlapic->vm != NULL
* @pre vlapic->vcpu->vcpu_id < MAX_VCPUS_PER_VM
*/
void vlapic_init(struct acrn_vlapic *vlapic);
void vlapic_reset(struct acrn_vlapic *vlapic, const struct acrn_apicv_ops *ops, enum reset_mode mode);
void vlapic_restore(struct acrn_vlapic *vlapic, const struct lapic_regs *regs);
uint64_t vlapic_apicv_get_apic_access_addr(void);