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 <fengwei.yin@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
918c1fe9fb
commit
fa583f71a9
@ -642,6 +642,19 @@ static int acpi_idle_bm_check(void)
|
|||||||
return bm_status;
|
return bm_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wait_for_freeze(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_X86
|
||||||
|
/* No delay is needed if we are in guest */
|
||||||
|
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
/* Dummy wait op - must do something useless after P_LVL2 read
|
||||||
|
because chipsets cannot guarantee that STPCLK# signal
|
||||||
|
gets asserted in time to freeze execution properly. */
|
||||||
|
inl(acpi_gbl_FADT.xpm_timer_block.address);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* acpi_idle_do_entry - enter idle state using the appropriate method
|
* acpi_idle_do_entry - enter idle state using the appropriate method
|
||||||
* @cx: cstate data
|
* @cx: cstate data
|
||||||
@ -658,10 +671,7 @@ static void __cpuidle acpi_idle_do_entry(struct acpi_processor_cx *cx)
|
|||||||
} else {
|
} else {
|
||||||
/* IO port based C-state */
|
/* IO port based C-state */
|
||||||
inb(cx->address);
|
inb(cx->address);
|
||||||
/* Dummy wait op - must do something useless after P_LVL2 read
|
wait_for_freeze();
|
||||||
because chipsets cannot guarantee that STPCLK# signal
|
|
||||||
gets asserted in time to freeze execution properly. */
|
|
||||||
inl(acpi_gbl_FADT.xpm_timer_block.address);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,8 +692,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
|
|||||||
safe_halt();
|
safe_halt();
|
||||||
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
|
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
|
||||||
inb(cx->address);
|
inb(cx->address);
|
||||||
/* See comment in acpi_idle_do_entry() */
|
wait_for_freeze();
|
||||||
inl(acpi_gbl_FADT.xpm_timer_block.address);
|
|
||||||
} else
|
} else
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user