Skip to content

Commit fa583f7

Browse files
fyin1rafaeljw
authored andcommitted
ACPI: processor_idle: Skip dummy wait if kernel is in guest
In function acpi_idle_do_entry(), an ioport access is used for dummy wait to guarantee hardware behavior. But it could trigger unnecessary VMexit if kernel is running as guest in virtualization environment. If it's in virtualization environment, the deeper C state enter operation (inb()) will trap to hypervisor. It's not needed to do dummy wait after the inb() call. So we could just remove the dummy io port access to avoid unnecessary VMexit. And keep dummy io port access to maintain timing for native environment. Signed-off-by: Yin Fengwei <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 918c1fe commit fa583f7

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

drivers/acpi/processor_idle.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,19 @@ static int acpi_idle_bm_check(void)
642642
return bm_status;
643643
}
644644

645+
static void wait_for_freeze(void)
646+
{
647+
#ifdef CONFIG_X86
648+
/* No delay is needed if we are in guest */
649+
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
650+
return;
651+
#endif
652+
/* Dummy wait op - must do something useless after P_LVL2 read
653+
because chipsets cannot guarantee that STPCLK# signal
654+
gets asserted in time to freeze execution properly. */
655+
inl(acpi_gbl_FADT.xpm_timer_block.address);
656+
}
657+
645658
/**
646659
* acpi_idle_do_entry - enter idle state using the appropriate method
647660
* @cx: cstate data
@@ -658,10 +671,7 @@ static void __cpuidle acpi_idle_do_entry(struct acpi_processor_cx *cx)
658671
} else {
659672
/* IO port based C-state */
660673
inb(cx->address);
661-
/* Dummy wait op - must do something useless after P_LVL2 read
662-
because chipsets cannot guarantee that STPCLK# signal
663-
gets asserted in time to freeze execution properly. */
664-
inl(acpi_gbl_FADT.xpm_timer_block.address);
674+
wait_for_freeze();
665675
}
666676
}
667677

@@ -682,8 +692,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
682692
safe_halt();
683693
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
684694
inb(cx->address);
685-
/* See comment in acpi_idle_do_entry() */
686-
inl(acpi_gbl_FADT.xpm_timer_block.address);
695+
wait_for_freeze();
687696
} else
688697
return -ENODEV;
689698
}

0 commit comments

Comments
 (0)