Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
xen.7653
xsa241.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa241.patch of Package xen.7653
From: Jan Beulich <jbeulich@suse.com> Subject: x86: don't store possibly stale TLB flush time stamp While the timing window is extremely narrow, it is theoretically possible for an update to the TLB flush clock and a subsequent flush IPI to happen between the read and write parts of the update of the per-page stamp. Exclude this possibility by disabling interrupts across the update, preventing the IPI to be serviced in the middle. This is XSA-241. Suggested-by: George Dunlap <george.dunlap@citrix.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: George Dunlap <george.dunlap@citrix.com> Index: xen-4.5.5-testing/xen/arch/x86/mm.c =================================================================== --- xen-4.5.5-testing.orig/xen/arch/x86/mm.c +++ xen-4.5.5-testing/xen/arch/x86/mm.c @@ -2381,7 +2381,7 @@ static int _put_final_page_type(struct p */ if ( !(shadow_mode_enabled(page_get_owner(page)) && (page->count_info & PGC_page_table)) ) - page->tlbflush_timestamp = tlbflush_current_time(); + page_set_tlbflush_timestamp(page); wmb(); page->u.inuse.type_info--; } @@ -2454,7 +2454,7 @@ static int _put_page_type(struct page_in if ( (!ptpg || !PGT_type_equal(x, ptpg->u.inuse.type_info)) && !(shadow_mode_enabled(page_get_owner(page)) && (page->count_info & PGC_page_table)) ) - page->tlbflush_timestamp = tlbflush_current_time(); + page_set_tlbflush_timestamp(page); } if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) ) Index: xen-4.5.5-testing/xen/arch/x86/mm/shadow/common.c =================================================================== --- xen-4.5.5-testing.orig/xen/arch/x86/mm/shadow/common.c +++ xen-4.5.5-testing/xen/arch/x86/mm/shadow/common.c @@ -1583,7 +1583,7 @@ void shadow_free(struct domain *d, mfn_t * TLBs when we reuse the page. Because the destructors leave the * contents of the pages in place, we can delay TLB flushes until * just before the allocator hands the page out again. */ - sp->tlbflush_timestamp = tlbflush_current_time(); + page_set_tlbflush_timestamp(sp); perfc_decr(shadow_alloc_count); page_list_add_tail(sp, &d->arch.paging.shadow.freelist); sp = next; Index: xen-4.5.5-testing/xen/common/page_alloc.c =================================================================== --- xen-4.5.5-testing.orig/xen/common/page_alloc.c +++ xen-4.5.5-testing/xen/common/page_alloc.c @@ -877,7 +877,7 @@ static void free_heap_pages( /* If a page has no owner it will need no safety TLB flush. */ pg[i].u.free.need_tlbflush = (page_get_owner(&pg[i]) != NULL); if ( pg[i].u.free.need_tlbflush ) - pg[i].tlbflush_timestamp = tlbflush_current_time(); + page_set_tlbflush_timestamp(&pg[i]); /* This page is not a guest frame any more. */ page_set_owner(&pg[i], NULL); /* set_gpfn_from_mfn snoops pg owner */ Index: xen-4.5.5-testing/xen/include/asm-arm/flushtlb.h =================================================================== --- xen-4.5.5-testing.orig/xen/include/asm-arm/flushtlb.h +++ xen-4.5.5-testing/xen/include/asm-arm/flushtlb.h @@ -2,6 +2,7 @@ #define __ASM_ARM_FLUSHTLB_H__ #include <xen/cpumask.h> +#include <xen/mm.h> /* * Filter the given set of CPUs, removing those that definitely flushed their @@ -14,6 +15,11 @@ do { #define tlbflush_current_time() (0) +static inline void page_set_tlbflush_timestamp(struct page_info *page) +{ + page->tlbflush_timestamp = tlbflush_current_time(); +} + #if defined(CONFIG_ARM_32) # include <asm/arm32/flushtlb.h> #elif defined(CONFIG_ARM_64) Index: xen-4.5.5-testing/xen/include/asm-x86/flushtlb.h =================================================================== --- xen-4.5.5-testing.orig/xen/include/asm-x86/flushtlb.h +++ xen-4.5.5-testing/xen/include/asm-x86/flushtlb.h @@ -24,6 +24,20 @@ DECLARE_PER_CPU(u32, tlbflush_time); #define tlbflush_current_time() tlbflush_clock +static inline void page_set_tlbflush_timestamp(struct page_info *page) +{ + /* + * Prevent storing a stale time stamp, which could happen if an update + * to tlbflush_clock plus a subsequent flush IPI happen between the + * reading of tlbflush_clock and the writing of the struct page_info + * field. + */ + ASSERT(local_irq_is_enabled()); + local_irq_disable(); + page->tlbflush_timestamp = tlbflush_current_time(); + local_irq_enable(); +} + /* * @cpu_stamp is the timestamp at last TLB flush for the CPU we are testing. * @lastuse_stamp is a timestamp taken when the PFN we are testing was last
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor