mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 14:12:07 +02:00
x86/core changes for v6.8:
- Add comments about the magic behind the shadow STI
before MWAIT in __sti_mwait().
- Fix possible unintended timer delays caused by a race in
mwait_idle_with_hints().
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-----BEGIN PGP SIGNATURE-----
iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmWb210RHG1pbmdvQGtl
cm5lbC5vcmcACgkQEnMQ0APhK1g5ZA/9FaL7/wVdnZkEXhi8hQclS3J8v+7ZmY+P
WaPW+dJkWHRjy88tgpqjIyP72gskMelUs3YaV1b5o/pmkuGv3vCouz6V6jkZkkUM
ZTjNJ0TrAC69y77q4XFUDqsnuYRjsmmsJWwlUSSd48w1Az8NRrTPKRLs6zbaC/gA
+RwJ5+s+SNNuf66JO81TSAj8wx3JbgzBEwZnSHDKpGxHi0xrB1ttOAptVZAvOa7D
b07rlgu1KbYKFZpDuReXcxiZSnfheVgRGP+a1fcVpWq+Ggk5z6RoVHHZhNgCEXqr
sR4grFnIi3hJSMfwEsfs7Of/fUGHwMxJLm7UmlorhrcQxaB/xOgnwNuHqFza7sVn
XMB0NMZlNf2YN93jNOm5WGi9dDaP3aaP2QG4mRtbnLabV7S8Vr0SYQV0h2oHom3Z
qJ8WeB62Vf1dLr1mxgQJhWgJNXMwfLvGBGMA3QsKkAiTNqkZSIALo60QxYEJijoj
x6Ej9CNyLXLcZb7UaYuzsHqc+M3elWz8icuVa0mguhaTsJaSL3u5K/OPeMs1obFq
76NK+8ws5NYbhg+7Lb219HA0Q1zf2N3bk3Q5vKgIVcPiihRbjpH0W4Q9bQ36m+s4
EyJjCsCaLxIoqcUhsei3OlVoSKJC+owKj0U4oo1s8qsDhjcIvSCnav76eLSmp5YC
yf1DobA2s5I=
=GTHR
-----END PGP SIGNATURE-----
Merge tag 'x86-core-2024-01-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 core updates from Ingo Molnar:
- Add comments about the magic behind the shadow STI
before MWAIT in __sti_mwait().
- Fix possible unintended timer delays caused by a race
in mwait_idle_with_hints().
* tag 'x86-core-2024-01-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86: Fix CPUIDLE_FLAG_IRQ_ENABLE leaking timer reprogram
x86: Add a comment about the "magic" behind shadow sti before mwait
This commit is contained in:
commit
33677aef32
|
|
@ -87,6 +87,15 @@ static __always_inline void __mwaitx(unsigned long eax, unsigned long ebx,
|
|||
:: "a" (eax), "b" (ebx), "c" (ecx));
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-enable interrupts right upon calling mwait in such a way that
|
||||
* no interrupt can fire _before_ the execution of mwait, ie: no
|
||||
* instruction must be placed between "sti" and "mwait".
|
||||
*
|
||||
* This is necessary because if an interrupt queues a timer before
|
||||
* executing mwait, it would otherwise go unnoticed and the next tick
|
||||
* would not be reprogrammed accordingly before mwait ever wakes up.
|
||||
*/
|
||||
static __always_inline void __sti_mwait(unsigned long eax, unsigned long ecx)
|
||||
{
|
||||
mds_idle_clear_cpu_buffers();
|
||||
|
|
@ -115,8 +124,15 @@ static __always_inline void mwait_idle_with_hints(unsigned long eax, unsigned lo
|
|||
}
|
||||
|
||||
__monitor((void *)¤t_thread_info()->flags, 0, 0);
|
||||
if (!need_resched())
|
||||
__mwait(eax, ecx);
|
||||
|
||||
if (!need_resched()) {
|
||||
if (ecx & 1) {
|
||||
__mwait(eax, ecx);
|
||||
} else {
|
||||
__sti_mwait(eax, ecx);
|
||||
raw_local_irq_disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
current_clr_polling();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,11 +131,12 @@ static unsigned int mwait_substates __initdata;
|
|||
#define MWAIT2flg(eax) ((eax & 0xFF) << 24)
|
||||
|
||||
static __always_inline int __intel_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
struct cpuidle_driver *drv,
|
||||
int index, bool irqoff)
|
||||
{
|
||||
struct cpuidle_state *state = &drv->states[index];
|
||||
unsigned long eax = flg2MWAIT(state->flags);
|
||||
unsigned long ecx = 1; /* break on interrupt flag */
|
||||
unsigned long ecx = 1*irqoff; /* break on interrupt flag */
|
||||
|
||||
mwait_idle_with_hints(eax, ecx);
|
||||
|
||||
|
|
@ -159,19 +160,13 @@ static __always_inline int __intel_idle(struct cpuidle_device *dev,
|
|||
static __cpuidle int intel_idle(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
return __intel_idle(dev, drv, index);
|
||||
return __intel_idle(dev, drv, index, true);
|
||||
}
|
||||
|
||||
static __cpuidle int intel_idle_irq(struct cpuidle_device *dev,
|
||||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
int ret;
|
||||
|
||||
raw_local_irq_enable();
|
||||
ret = __intel_idle(dev, drv, index);
|
||||
raw_local_irq_disable();
|
||||
|
||||
return ret;
|
||||
return __intel_idle(dev, drv, index, false);
|
||||
}
|
||||
|
||||
static __cpuidle int intel_idle_ibrs(struct cpuidle_device *dev,
|
||||
|
|
@ -184,7 +179,7 @@ static __cpuidle int intel_idle_ibrs(struct cpuidle_device *dev,
|
|||
if (smt_active)
|
||||
__update_spec_ctrl(0);
|
||||
|
||||
ret = __intel_idle(dev, drv, index);
|
||||
ret = __intel_idle(dev, drv, index, true);
|
||||
|
||||
if (smt_active)
|
||||
__update_spec_ctrl(spec_ctrl);
|
||||
|
|
@ -196,7 +191,7 @@ static __cpuidle int intel_idle_xstate(struct cpuidle_device *dev,
|
|||
struct cpuidle_driver *drv, int index)
|
||||
{
|
||||
fpu_idle_fpregs();
|
||||
return __intel_idle(dev, drv, index);
|
||||
return __intel_idle(dev, drv, index, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user