|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.1] x86: make MMUEXT_NEW_USER_BASEPTR preemptible
commit 210e61b80c29ef824f5fdc5946d6d876b8875fe3
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu May 2 17:24:02 2013 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu May 2 17:24:02 2013 +0200
x86: make MMUEXT_NEW_USER_BASEPTR preemptible
... as it may take significant amounts of time.
This is part of CVE-2013-1918 / XSA-45.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Acked-by: Tim Deegan <tim@xxxxxxx>
master commit: 918a5f17b447072b40780f4d03a3adc99ff0073b
master date: 2013-05-02 16:36:44 +0200
---
xen/arch/x86/mm.c | 38 ++++++++++++++++++++++++++++++++------
1 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index cc6242e..b561a6f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -3200,29 +3200,55 @@ long do_mmuext_op(
unsigned long old_mfn, mfn;
mfn = gmfn_to_mfn(d, op.arg1.mfn);
+ old_mfn = pagetable_get_pfn(curr->arch.guest_table_user);
+ /*
+ * This is particularly important when getting restarted after the
+ * previous attempt got preempted in the put-old-MFN phase.
+ */
+ if ( old_mfn == mfn )
+ break;
+
if ( mfn != 0 )
{
if ( paging_mode_refcounts(d) )
okay = get_page_from_pagenr(mfn, d);
else
- okay = !get_page_and_type_from_pagenr(
- mfn, PGT_root_page_table, d, 0, 0);
+ {
+ rc = get_page_and_type_from_pagenr(
+ mfn, PGT_root_page_table, d, 0, 1);
+ okay = !rc;
+ }
if ( unlikely(!okay) )
{
- MEM_LOG("Error while installing new mfn %lx", mfn);
+ if ( rc == -EINTR )
+ rc = -EAGAIN;
+ else if ( rc != -EAGAIN )
+ MEM_LOG("Error while installing new mfn %lx", mfn);
break;
}
}
- old_mfn = pagetable_get_pfn(curr->arch.guest_table_user);
curr->arch.guest_table_user = pagetable_from_pfn(mfn);
if ( old_mfn != 0 )
{
+ struct page_info *page = mfn_to_page(old_mfn);
+
if ( paging_mode_refcounts(d) )
- put_page(mfn_to_page(old_mfn));
+ put_page(page);
else
- put_page_and_type(mfn_to_page(old_mfn));
+ switch ( rc = put_page_and_type_preemptible(page, 1) )
+ {
+ case -EINTR:
+ rc = -EAGAIN;
+ case -EAGAIN:
+ curr->arch.old_guest_table = page;
+ okay = 0;
+ break;
+ default:
+ BUG_ON(rc);
+ break;
+ }
}
break;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.1
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |