aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@citrix.com>2013-06-26 17:22:45 +0100
committerIan Campbell <ian.campbell@citrix.com>2013-06-26 17:22:45 +0100
commit47a1d0b48ce3010c1b119541353cb1a7b5ed5de9 (patch)
tree68788b39608c9179c8c8847f29172a71e73b32e7
parentb53f25e319d2d862b889260ccff6c8baea664a21 (diff)
parentd0f535e9af564642250badf1fa300725ef996616 (diff)
downloadxen-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.sh1
-rw-r--r--xen/arch/x86/domain.c27
-rw-r--r--xen/arch/x86/mm.c9
-rw-r--r--xen/include/asm-x86/mm.h1
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);