diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2013-06-26 17:22:45 +0100 |
---|---|---|
committer | Ian Campbell <ian.campbell@citrix.com> | 2013-06-26 17:22:45 +0100 |
commit | 47a1d0b48ce3010c1b119541353cb1a7b5ed5de9 (patch) | |
tree | 68788b39608c9179c8c8847f29172a71e73b32e7 | |
parent | b53f25e319d2d862b889260ccff6c8baea664a21 (diff) | |
parent | d0f535e9af564642250badf1fa300725ef996616 (diff) | |
download | xen-47a1d0b48ce3010c1b119541353cb1a7b5ed5de9.tar.gz xen-47a1d0b48ce3010c1b119541353cb1a7b5ed5de9.tar.bz2 xen-47a1d0b48ce3010c1b119541353cb1a7b5ed5de9.zip |
Merge branch 'staging' of ssh://xenbits.xen.org/home/xen/git/xen into staging
-rw-r--r-- | tools/hotplug/Linux/xen-hotplug-common.sh | 1 | ||||
-rw-r--r-- | xen/arch/x86/domain.c | 27 | ||||
-rw-r--r-- | xen/arch/x86/mm.c | 9 | ||||
-rw-r--r-- | xen/include/asm-x86/mm.h | 1 |
4 files changed, 29 insertions, 9 deletions
diff --git a/tools/hotplug/Linux/xen-hotplug-common.sh b/tools/hotplug/Linux/xen-hotplug-common.sh index 4a7bc7349f..7af468836e 100644 --- a/tools/hotplug/Linux/xen-hotplug-common.sh +++ b/tools/hotplug/Linux/xen-hotplug-common.sh @@ -31,6 +31,7 @@ dir=$(dirname "$0") exec 2>>/var/log/xen/xen-hotplug.log export PATH="${BINDIR}:${SBINDIR}:${LIBEXEC}:${PRIVATE_BINDIR}:/sbin:/bin:/usr/bin:/usr/sbin:$PATH" +export LD_LIBRARY_PATH="${LIBDIR}${LD_LIBRARY_PATH+:}$LD_LIBRARY_PATH" export LANG="POSIX" unset $(set | grep ^LC_ | cut -d= -f1) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 48f3487102..52c9040f59 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -829,6 +829,10 @@ int arch_set_info_guest( if ( v->vcpu_id == 0 ) d->vm_assist = c(vm_assist); + rc = put_old_guest_table(current); + if ( rc ) + return rc; + if ( !compat ) rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents); else @@ -864,18 +868,24 @@ int arch_set_info_guest( } else { - /* - * Since v->arch.guest_table{,_user} are both NULL, this effectively - * is just a call to put_old_guest_table(). - */ if ( !compat ) - rc = vcpu_destroy_pagetables(v); + rc = put_old_guest_table(v); if ( !rc ) rc = get_page_type_preemptible(cr3_page, !compat ? PGT_root_page_table : PGT_l3_page_table); - if ( rc == -EINTR ) + switch ( rc ) + { + case -EINTR: rc = -EAGAIN; + case -EAGAIN: + case 0: + break; + default: + if ( cr3_page == current->arch.old_guest_table ) + cr3_page = NULL; + break; + } } if ( rc ) /* handled below */; @@ -901,6 +911,11 @@ int arch_set_info_guest( pagetable_get_page(v->arch.guest_table); v->arch.guest_table = pagetable_null(); break; + default: + if ( cr3_page == current->arch.old_guest_table ) + cr3_page = NULL; + case 0: + break; } } if ( !rc ) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 5123860ffd..77dcafc261 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -640,7 +640,8 @@ static int get_page_and_type_from_pagenr(unsigned long page_nr, get_page_type_preemptible(page, type) : (get_page_type(page, type) ? 0 : -EINVAL)); - if ( unlikely(rc) && partial >= 0 ) + if ( unlikely(rc) && partial >= 0 && + (!preemptible || page != current->arch.old_guest_table) ) put_page(page); return rc; @@ -2427,6 +2428,7 @@ int put_page_type_preemptible(struct page_info *page) int get_page_type_preemptible(struct page_info *page, unsigned long type) { + ASSERT(!current->arch.old_guest_table); return __get_page_type(page, type, 1); } @@ -2617,7 +2619,7 @@ static void put_superpage(unsigned long mfn) return; } -static int put_old_guest_table(struct vcpu *v) +int put_old_guest_table(struct vcpu *v) { int rc; @@ -2988,7 +2990,8 @@ long do_mmuext_op( rc = -EAGAIN; else if ( rc != -EAGAIN ) MEM_LOG("Error while pinning mfn %lx", page_to_mfn(page)); - put_page(page); + if ( page != curr->arch.old_guest_table ) + put_page(page); break; } diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 6b367c0fee..213fc9cb37 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -354,6 +354,7 @@ void put_page_type(struct page_info *page); int get_page_type(struct page_info *page, unsigned long type); int put_page_type_preemptible(struct page_info *page); int get_page_type_preemptible(struct page_info *page, unsigned long type); +int put_old_guest_table(struct vcpu *); int get_page_from_l1e( l1_pgentry_t l1e, struct domain *l1e_owner, struct domain *pg_owner); void put_page_from_l1e(l1_pgentry_t l1e, struct domain *l1e_owner); |