Skip to content

Commit cc5bc34

Browse files
donshengwenlingz
authored andcommitted
hv: extend struct pi_desc to support VT-d posted interrupts
For CPU side posted interrupts, it only uses bit 0 (ON) of the PI's 64-bit control , other bits are don't care. This is not the case for VT-d posted interrupts, define more bit fields for the PI's 64-bit control. Use bitmap functions to manipulate the bit fields atomically. Some MISRA-C violation and coding style fixes Tracked-On: #4506 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com> Reviewed-by: Eddie Dong <eddie.dong@Intel.com>
1 parent b7a126c commit cc5bc34

File tree

3 files changed

+44
-15
lines changed

3 files changed

+44
-15
lines changed

hypervisor/arch/x86/guest/vcpu.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ static void init_xsave(struct acrn_vcpu *vcpu)
270270
(void)memset((void *)area, 0U, XSAVE_STATE_AREA_SIZE);
271271

272272
/* xsaves only support compacted format, so set it in xcomp_bv[63],
273-
* keep the reset area in header area as zero. */
273+
* keep the reset area in header area as zero.
274+
*/
274275
ectx->xs_area.xsave_hdr.hdr.xcomp_bv |= XSAVE_COMPACTED_FORMAT;
275276
}
276277

@@ -402,7 +403,7 @@ void init_vcpu_protect_mode_regs(struct acrn_vcpu *vcpu, uint64_t vgdt_base_gpa)
402403
{
403404
struct acrn_vcpu_regs vcpu_regs;
404405

405-
(void)memcpy_s((void*)&vcpu_regs, sizeof(struct acrn_vcpu_regs),
406+
(void)memcpy_s((void *)&vcpu_regs, sizeof(struct acrn_vcpu_regs),
406407
(void *)&protect_mode_init_vregs, sizeof(struct acrn_vcpu_regs));
407408

408409
vcpu_regs.gdt.base = vgdt_base_gpa;
@@ -472,6 +473,12 @@ int32_t create_vcpu(uint16_t pcpu_id, struct acrn_vm *vm, struct acrn_vcpu **rtn
472473
*/
473474
vcpu->arch.vpid = 1U + (vm->vm_id * MAX_VCPUS_PER_VM) + vcpu->vcpu_id;
474475

476+
vcpu->arch.pid.control.bits.nv = POSTED_INTR_VECTOR;
477+
/* ACRN does not support vCPU migration, one vCPU always runs on
478+
* the same pCPU, so PI's ndst is never changed after startup.
479+
*/
480+
vcpu->arch.pid.control.bits.ndst = per_cpu(lapic_id, pcpu_id);
481+
475482
/* Create per vcpu vlapic */
476483
vlapic_create(vcpu);
477484

@@ -644,8 +651,8 @@ void kick_vcpu(const struct acrn_vcpu *vcpu)
644651
}
645652

646653
/*
647-
* @pre (&vcpu->stack[CONFIG_STACK_SIZE] & (CPU_STACK_ALIGN - 1UL)) == 0
648-
*/
654+
* @pre (&vcpu->stack[CONFIG_STACK_SIZE] & (CPU_STACK_ALIGN - 1UL)) == 0
655+
*/
649656
static uint64_t build_stack_frame(struct acrn_vcpu *vcpu)
650657
{
651658
uint64_t stacktop = (uint64_t)&vcpu->stack[CONFIG_STACK_SIZE];
@@ -846,8 +853,8 @@ uint64_t vcpumask2pcpumask(struct acrn_vm *vm, uint64_t vdmask)
846853
*
847854
* @pre vcpu != NULL
848855
*
849-
* @return true, if vCPU LAPIC is in x2APIC mode and VM, vCPU belongs to, is configured for
850-
* LAPIC Pass-through
856+
* @return true, if vCPU LAPIC is in x2APIC mode and VM, vCPU belongs to, is configured for
857+
* LAPIC Pass-through
851858
*/
852859
bool is_lapic_pt_enabled(struct acrn_vcpu *vcpu)
853860
{

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,8 +1957,8 @@ vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg)
19571957
phys = (address.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS);
19581958
rh = (address.bits.rh == MSI_ADDR_RH);
19591959

1960-
delmode = data.bits.delivery_mode;
1961-
vec = data.bits.vector;
1960+
delmode = (uint32_t)(data.bits.delivery_mode);
1961+
vec = (uint32_t)(data.bits.vector);
19621962

19631963
dev_dbg(DBG_LEVEL_VLAPIC, "lapic MSI %s dest %#x, vec %u",
19641964
phys ? "physical" : "logical", dest, vec);
@@ -2214,11 +2214,9 @@ apicv_set_intr_ready(struct acrn_vlapic *vlapic, uint32_t vector)
22142214
bool notify = false;
22152215

22162216
pid = get_pi_desc(vlapic->vcpu);
2217-
22182217
idx = vector >> 6U;
2219-
22202218
if (!bitmap_test_and_set_lock((uint16_t)(vector & 0x3fU), &pid->pir[idx])) {
2221-
notify = (atomic_cmpxchg64(&pid->pending, 0UL, 1UL) == 0UL);
2219+
notify = (bitmap_test_and_set_lock(POSTED_INTR_ON, &pid->control.value) == false);
22222220
}
22232221
return notify;
22242222
}
@@ -2278,7 +2276,7 @@ static void vlapic_apicv_inject_pir(struct acrn_vlapic *vlapic)
22782276
struct lapic_reg *irr = NULL;
22792277

22802278
pid = get_pi_desc(vlapic->vcpu);
2281-
if (atomic_cmpxchg64(&pid->pending, 1UL, 0UL) == 1UL) {
2279+
if (bitmap_test_and_clear_lock(POSTED_INTR_ON, &pid->control.value)) {
22822280
pirval = 0UL;
22832281
lapic = &(vlapic->apic_page);
22842282
irr = &lapic->irr[0];
@@ -2445,7 +2443,7 @@ int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu)
24452443
* 2 = linear access for an instruction fetch
24462444
* c) we suppose the guest goes wrong when it will access the APIC-access page
24472445
* when process event-delivery. According chap 26.5.1.2 VM Exits During Event Injection,
2448-
* vol 3, sdm: If the "virtualize APIC accesses" VM-execution control is 1 and
2446+
* vol 3, sdm: If the "virtualize APIC accesses" VM-execution control is 1 and
24492447
* event delivery generates an access to the APIC-access page, that access is treated as
24502448
* described in Section 29.4 and may cause a VM exit.
24512449
* 3 = linear access (read or write) during event delivery

hypervisor/include/arch/x86/vmx.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,10 +378,33 @@
378378
struct pi_desc {
379379
/* Posted Interrupt Requests, one bit per requested vector */
380380
uint64_t pir[4];
381-
uint64_t pending;
382-
uint32_t unused[3];
381+
382+
union {
383+
struct {
384+
/* Outstanding Notification */
385+
uint16_t on:1;
386+
387+
/* Suppress Notification, of non-urgent interrupts */
388+
uint16_t sn:1;
389+
390+
uint16_t rsvd_1:14;
391+
392+
/* Notification Vector */
393+
uint8_t nv;
394+
395+
uint8_t rsvd_2;
396+
397+
/* Notification destination, a physical LAPIC ID */
398+
uint32_t ndst;
399+
} bits;
400+
401+
uint64_t value;
402+
} control;
403+
404+
uint32_t rsvd[6];
383405
} __aligned(64);
384406

407+
385408
/* External Interfaces */
386409
void vmx_on(void);
387410
void vmx_off(void);
@@ -408,4 +431,5 @@ void exec_vmwrite64(uint32_t field_full, uint64_t value);
408431
void exec_vmclear(void *addr);
409432
void exec_vmptrld(void *addr);
410433

434+
#define POSTED_INTR_ON 0U
411435
#endif /* VMX_H_ */

0 commit comments

Comments
 (0)