Skip to content

Commit bfecf30

Browse files
jsun26intelwenlingz
authored andcommitted
HV: do not offline pcpu when lapic pt disabled
In current code, wait_pcpus_offline() and make_pcpu_offline() are called by both shutdown_vm() and reset_vm(), but this is not needed when lapic_pt is not enabled for the vcpus of the VM. The patch merged offline pcpus part code into a common offline_lapic_pt_enabled_pcpus() api for shutdown_vm() and reset_vm() use and called only when lapic_pt is enabled. Tracked-On: #4325 Signed-off-by: Victor Sun <victor.sun@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent c59f12d commit bfecf30

File tree

1 file changed

+47
-45
lines changed
  • hypervisor/arch/x86/guest

1 file changed

+47
-45
lines changed

hypervisor/arch/x86/guest/vm.c

Lines changed: 47 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ static uint64_t lapic_pt_enabled_pcpu_bitmap(struct acrn_vm *vm)
464464

465465
if (is_lapic_pt_configured(vm)) {
466466
foreach_vcpu(i, vm, vcpu) {
467-
if (is_lapic_pt_enabled(vcpu)) {
467+
if (is_x2apic_enabled(vcpu_vlapic(vcpu))) {
468468
bitmap_set_nolock(pcpuid_from_vcpu(vcpu), &bitmap);
469469
}
470470
}
@@ -619,13 +619,53 @@ static bool is_ready_for_system_shutdown(void)
619619
return ret;
620620
}
621621

622+
static int32_t offline_lapic_pt_enabled_pcpus(const struct acrn_vm *vm, uint64_t pcpu_mask)
623+
{
624+
int32_t ret = 0;
625+
uint16_t i;
626+
uint64_t mask = pcpu_mask;
627+
const struct acrn_vcpu *vcpu = NULL;
628+
uint16_t this_pcpu_id = get_pcpu_id();
629+
630+
if (bitmap_test(this_pcpu_id, &mask)) {
631+
bitmap_clear_nolock(this_pcpu_id, &mask);
632+
if (vm->state == VM_POWERED_OFF) {
633+
/*
634+
* If the current pcpu needs to offline itself,
635+
* it will be done after shutdown_vm() completes
636+
* in the idle thread.
637+
*/
638+
make_pcpu_offline(this_pcpu_id);
639+
} else {
640+
/*
641+
* The current pcpu can't reset itself
642+
*/
643+
pr_warn("%s: cannot offline self(%u)",
644+
__func__, this_pcpu_id);
645+
ret = -EINVAL;
646+
}
647+
}
648+
649+
foreach_vcpu(i, vm, vcpu) {
650+
if (bitmap_test(pcpuid_from_vcpu(vcpu), &mask)) {
651+
make_pcpu_offline(pcpuid_from_vcpu(vcpu));
652+
}
653+
}
654+
655+
wait_pcpus_offline(mask);
656+
if (!start_pcpus(mask)) {
657+
pr_fatal("Failed to start all cpus in mask(0x%lx)", mask);
658+
ret = -ETIMEDOUT;
659+
}
660+
return ret;
661+
}
662+
622663
/*
623664
* @pre vm != NULL
624665
*/
625666
int32_t shutdown_vm(struct acrn_vm *vm)
626667
{
627668
uint16_t i;
628-
uint16_t this_pcpu_id;
629669
uint64_t mask;
630670
struct acrn_vcpu *vcpu = NULL;
631671
struct acrn_vm_config *vm_config = NULL;
@@ -636,32 +676,14 @@ int32_t shutdown_vm(struct acrn_vm *vm)
636676
/* Only allow shutdown paused vm */
637677
if (vm->state == VM_PAUSED) {
638678
vm->state = VM_POWERED_OFF;
639-
this_pcpu_id = get_pcpu_id();
640-
mask = lapic_pt_enabled_pcpu_bitmap(vm);
641679

642-
/*
643-
* If the current pcpu needs to offline itself,
644-
* it will be done after shutdown_vm() completes
645-
* in the idle thread.
646-
*/
647-
if (bitmap_test(this_pcpu_id, &mask)) {
648-
bitmap_clear_nolock(this_pcpu_id, &mask);
649-
make_pcpu_offline(this_pcpu_id);
680+
mask = lapic_pt_enabled_pcpu_bitmap(vm);
681+
if (mask != 0UL) {
682+
ret = offline_lapic_pt_enabled_pcpus(vm, mask);
650683
}
651684

652685
foreach_vcpu(i, vm, vcpu) {
653686
offline_vcpu(vcpu);
654-
655-
if (bitmap_test(pcpuid_from_vcpu(vcpu), &mask)) {
656-
make_pcpu_offline(pcpuid_from_vcpu(vcpu));
657-
}
658-
}
659-
660-
wait_pcpus_offline(mask);
661-
662-
if ((mask != 0UL) && (!start_pcpus(mask))) {
663-
pr_fatal("Failed to start all cpus in mask(0x%lx)", mask);
664-
ret = -ETIMEDOUT;
665687
}
666688

667689
vm_config = get_vm_config(vm->vm_id);
@@ -716,38 +738,18 @@ void start_vm(struct acrn_vm *vm)
716738
int32_t reset_vm(struct acrn_vm *vm)
717739
{
718740
uint16_t i;
719-
uint16_t this_pcpu_id;
720741
uint64_t mask;
721742
struct acrn_vcpu *vcpu = NULL;
722743
int32_t ret = 0;
723744

724745
if (vm->state == VM_PAUSED) {
725-
this_pcpu_id = get_pcpu_id();
726746
mask = lapic_pt_enabled_pcpu_bitmap(vm);
727-
728-
/*
729-
* The current pcpu can't reset itself
730-
*/
731-
if (bitmap_test(this_pcpu_id, &mask)) {
732-
pr_warn("%s: cannot offline self(%u)",
733-
__func__, this_pcpu_id);
734-
bitmap_clear_nolock(this_pcpu_id, &mask);
735-
ret = -EINVAL;
747+
if (mask != 0UL) {
748+
ret = offline_lapic_pt_enabled_pcpus(vm, mask);
736749
}
737750

738751
foreach_vcpu(i, vm, vcpu) {
739752
reset_vcpu(vcpu, COLD_RESET);
740-
741-
if (bitmap_test(pcpuid_from_vcpu(vcpu), &mask)) {
742-
make_pcpu_offline(pcpuid_from_vcpu(vcpu));
743-
}
744-
}
745-
746-
wait_pcpus_offline(mask);
747-
748-
if ((mask != 0UL) && (!start_pcpus(mask))) {
749-
pr_fatal("Failed to start all cpus in mask(0x%lx)", mask);
750-
ret = -ETIMEDOUT;
751753
}
752754

753755
/*

0 commit comments

Comments
 (0)