]> xenbits.xensource.com Git - xen.git/commit
x86/mm: properly flush TLB in switch_cr3_cr4()
authorJan Beulich <jbeulich@suse.com>
Tue, 5 Mar 2019 12:52:44 +0000 (13:52 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 5 Mar 2019 12:52:44 +0000 (13:52 +0100)
commit6e5f22ba437d78c0a84b9673f7e2cfefdbc62f4b
tree2cabb3676e088d3d5f6006782a3fef2ab9116c00
parentfad0de986220c46e70be2f83279961aad7394af0
x86/mm: properly flush TLB in switch_cr3_cr4()

The CR3 values used for contexts run with PCID enabled uniformly have
CR3.NOFLUSH set, resulting in the CR3 write itself to not cause any
flushing at all. When the second CR4 write is skipped or doesn't do any
flushing, there's nothing so far which would purge TLB entries which may
have accumulated again if the PCID doesn't change; the "just in case"
flush only affects the case where the PCID actually changes. (There may
be particularly many TLB entries re-accumulated in case of a watchdog
NMI kicking in during the critical time window.)

Suppress the no-flush behavior of the CR3 write in this particular case.

Similarly the second CR4 write may not cause any flushing of TLB entries
established again while the original PCID was still in use - it may get
performed because of unrelated bits changing. The flush of the old PCID
needs to happen nevertheless.

At the same time also eliminate a possible race with lazy context
switch: Just like for CR4, CR3 may change at any time while interrupts
are enabled, due to the __sync_local_execstate() invocation from the
flush IPI handler. It is for that reason that the CR3 read, just like
the CR4 one, must happen only after interrupts have been turned off.

This is XSA-292.

Reported-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Tested-by: Sergey Dyasli <sergey.dyasli@citrix.com>
xen/arch/x86/flushtlb.c