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:
Jan Beulich committed 2018-01-23 10:44:11 +01:00
1 parent 3e635d02d7
commit c64bf2d2a6
3 files changed
+9 -5

No files matched your search

+2 -2
View File
@@ -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
View File
@@ -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) &&
+2
View File
@@ -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);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.