Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.1:Update
xen
19161-pv-ldt-handling.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 19161-pv-ldt-handling.patch of Package xen
# HG changeset patch # User Keir Fraser <keir.fraser@citrix.com> # Date 1233760126 0 # Node ID 13a0272c8c024fca83bc991c7e2da992d07bc8eb # Parent 271697e6d9b2b85ce348548f99166be450d1cf5a x86: Clean up PV guest LDT handling. 1. Do not touch deferred_ops in invalidate_shadow_ldt(), as we may not always be in a context where deferred_ops is valid. 2. Protected the shadow LDT with a lock, now that mmu updates are not protected by the per-domain lock. Signed-off-by: Keir Fraser <keir.fraser@citrix.com> --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -319,6 +319,8 @@ int vcpu_initialise(struct vcpu *v) v->arch.perdomain_ptes = d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT); + spin_lock_init(&v->arch.shadow_ldt_lock); + return (is_pv_32on64_vcpu(v) ? setup_compat_l4(v) : 0); } --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -460,14 +460,18 @@ void update_cr3(struct vcpu *v) } -static void invalidate_shadow_ldt(struct vcpu *v) +static void invalidate_shadow_ldt(struct vcpu *v, int flush) { int i; unsigned long pfn; struct page_info *page; + BUG_ON(unlikely(in_irq())); + + spin_lock(&v->arch.shadow_ldt_lock); + if ( v->arch.shadow_ldt_mapcnt == 0 ) - return; + goto out; v->arch.shadow_ldt_mapcnt = 0; @@ -482,11 +486,12 @@ static void invalidate_shadow_ldt(struct put_page_and_type(page); } - /* Dispose of the (now possibly invalid) mappings from the TLB. */ - if ( v == current ) - queue_deferred_ops(v->domain, DOP_FLUSH_TLB | DOP_RELOAD_LDT); - else - flush_tlb_mask(v->domain->domain_dirty_cpumask); + /* Rid TLBs of stale mappings (guest mappings and shadow mappings). */ + if ( flush ) + flush_tlb_mask(v->vcpu_dirty_cpumask); + + out: + spin_unlock(&v->arch.shadow_ldt_lock); } @@ -537,8 +542,10 @@ int map_ldt_shadow_page(unsigned int off nl1e = l1e_from_pfn(mfn, l1e_get_flags(l1e) | _PAGE_RW); + spin_lock(&v->arch.shadow_ldt_lock); l1e_write(&v->arch.perdomain_ptes[off + 16], nl1e); v->arch.shadow_ldt_mapcnt++; + spin_unlock(&v->arch.shadow_ldt_lock); return 1; } @@ -936,7 +943,7 @@ void put_page_from_l1e(l1_pgentry_t l1e, (d == e) ) { for_each_vcpu ( d, v ) - invalidate_shadow_ldt(v); + invalidate_shadow_ldt(v, 1); } put_page(page); } @@ -2347,7 +2354,7 @@ int new_guest_cr3(unsigned long mfn) return 0; } - invalidate_shadow_ldt(v); + invalidate_shadow_ldt(v, 0); write_ptbase(v); return 1; @@ -2362,7 +2369,7 @@ int new_guest_cr3(unsigned long mfn) return 0; } - invalidate_shadow_ldt(v); + invalidate_shadow_ldt(v, 0); old_base_mfn = pagetable_get_pfn(v->arch.guest_table); @@ -2399,6 +2406,10 @@ static void process_deferred_ops(void) flush_tlb_local(); } + /* + * Do this after flushing TLBs, to ensure we see fresh LDT mappings + * via the linear pagetable mapping. + */ if ( deferred_ops & DOP_RELOAD_LDT ) (void)map_ldt_shadow_page(0); @@ -2771,7 +2782,7 @@ int do_mmuext_op( else if ( (v->arch.guest_context.ldt_ents != ents) || (v->arch.guest_context.ldt_base != ptr) ) { - invalidate_shadow_ldt(v); + invalidate_shadow_ldt(v, 0); v->arch.guest_context.ldt_base = ptr; v->arch.guest_context.ldt_ents = ents; load_LDT(v); --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -353,6 +353,7 @@ struct arch_vcpu /* Current LDT details. */ unsigned long shadow_ldt_mapcnt; + spinlock_t shadow_ldt_lock; struct paging_vcpu paging;
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