mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
x86: make CPU state flush requests explicit
Having this be an implied side effect of a TLB flush is not very nice: It could (at least in theory) lead to unintended state flushes (see e.g. https://lists.xenproject.org/archives/html/xen-devel/2017-11/msg00187.html for context). Introduce a flag to be used in the two places actually wanting the state flushed, and conditionalize the __sync_local_execstate() invocation in the IPI handler accordingly. At the same time also conditionalize the flush_area_local() invocations, to short-circuit the function ending up as a no-op anyway. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
1 parent
3e635d02d7
commit
c64bf2d2a6
3 files changed
+9
-5
No files matched your search
@@ -1697,7 +1697,7 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
|
||||
!cpumask_empty(&dirty_mask)) )
|
||||
{
|
||||
/* Other cpus call __sync_local_execstate from flush ipi handler. */
|
||||
flush_tlb_mask(&dirty_mask);
|
||||
flush_mask(&dirty_mask, FLUSH_TLB | FLUSH_VCPU_STATE);
|
||||
}
|
||||
|
||||
if ( prev != next )
|
||||
@@ -1806,7 +1806,7 @@ void sync_vcpu_execstate(struct vcpu *v)
|
||||
sync_local_execstate();
|
||||
|
||||
/* Other cpus call __sync_local_execstate from flush ipi handler. */
|
||||
flush_tlb_mask(v->vcpu_dirty_cpumask);
|
||||
flush_mask(v->vcpu_dirty_cpumask, FLUSH_TLB | FLUSH_VCPU_STATE);
|
||||
}
|
||||
|
||||
static int relinquish_memory(
|
||||
|
||||
+5
-3
@@ -207,9 +207,10 @@ void invalidate_interrupt(struct cpu_user_regs *regs)
|
||||
unsigned int flags = flush_flags;
|
||||
ack_APIC_irq();
|
||||
perfc_incr(ipis);
|
||||
if ( __sync_local_execstate() )
|
||||
if ( (flags & FLUSH_VCPU_STATE) && __sync_local_execstate() )
|
||||
flags &= ~(FLUSH_TLB | FLUSH_TLB_GLOBAL);
|
||||
flush_area_local(flush_va, flags);
|
||||
if ( flags & ~(FLUSH_VCPU_STATE | FLUSH_ORDER_MASK) )
|
||||
flush_area_local(flush_va, flags);
|
||||
cpumask_clear_cpu(smp_processor_id(), &flush_cpumask);
|
||||
}
|
||||
|
||||
@@ -219,7 +220,8 @@ void flush_area_mask(const cpumask_t *mask, const void *va, unsigned int flags)
|
||||
|
||||
ASSERT(local_irq_is_enabled());
|
||||
|
||||
if ( cpumask_test_cpu(cpu, mask) )
|
||||
if ( (flags & ~(FLUSH_VCPU_STATE | FLUSH_ORDER_MASK)) &&
|
||||
cpumask_test_cpu(cpu, mask) )
|
||||
flags = flush_area_local(va, flags);
|
||||
|
||||
if ( (flags & ~FLUSH_ORDER_MASK) &&
|
||||
|
||||
@@ -101,6 +101,8 @@ void write_cr3(unsigned long cr3);
|
||||
#define FLUSH_CACHE 0x400
|
||||
/* VA for the flush has a valid mapping */
|
||||
#define FLUSH_VA_VALID 0x800
|
||||
/* Flush CPU state */
|
||||
#define FLUSH_VCPU_STATE 0x1000
|
||||
|
||||
/* Flush local TLBs/caches. */
|
||||
unsigned int flush_area_local(const void *va, unsigned int flags);
|
||||
|
||||