diff options
Diffstat (limited to 'system/xen/xsa/xsa255-2.patch')
-rw-r--r-- | system/xen/xsa/xsa255-2.patch | 167 |
1 files changed, 0 insertions, 167 deletions
diff --git a/system/xen/xsa/xsa255-2.patch b/system/xen/xsa/xsa255-2.patch deleted file mode 100644 index 402b6efe98c26..0000000000000 --- a/system/xen/xsa/xsa255-2.patch +++ /dev/null @@ -1,167 +0,0 @@ -From: Jan Beulich <jbeulich@suse.com> -Subject: gnttab: don't blindly free status pages upon version change - -There may still be active mappings, which would trigger the respective -BUG_ON(). Split the loop into one dealing with the page attributes and -the second (when the first fully passed) freeing the pages. Return an -error if any pages still have pending references. - -This is part of XSA-255. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> -Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> ---- -v4: Add gprintk(XENLOG_ERR, ...) to domain_crash() invocations. -v3: Call guest_physmap_remove_page() from gnttab_map_frame(), making the - code unconditional at the same time. Re-base over changes to first - patch. -v2: Also deal with translated guests. - ---- a/xen/common/grant_table.c -+++ b/xen/common/grant_table.c -@@ -1636,23 +1636,74 @@ status_alloc_failed: - return -ENOMEM; - } - --static void -+static int - gnttab_unpopulate_status_frames(struct domain *d, struct grant_table *gt) - { -- int i; -+ unsigned int i; - - for ( i = 0; i < nr_status_frames(gt); i++ ) - { - struct page_info *pg = virt_to_page(gt->status[i]); -+ gfn_t gfn = gnttab_get_frame_gfn(gt, true, i); -+ -+ /* -+ * For translated domains, recovering from failure after partial -+ * changes were made is more complicated than it seems worth -+ * implementing at this time. Hence respective error paths below -+ * crash the domain in such a case. -+ */ -+ if ( paging_mode_translate(d) ) -+ { -+ int rc = gfn_eq(gfn, INVALID_GFN) -+ ? 0 -+ : guest_physmap_remove_page(d, gfn, -+ _mfn(page_to_mfn(pg)), 0); -+ -+ if ( rc ) -+ { -+ gprintk(XENLOG_ERR, -+ "Could not remove status frame %u (GFN %#lx) from P2M\n", -+ i, gfn_x(gfn)); -+ domain_crash(d); -+ return rc; -+ } -+ gnttab_set_frame_gfn(gt, true, i, INVALID_GFN); -+ } - - BUG_ON(page_get_owner(pg) != d); - if ( test_and_clear_bit(_PGC_allocated, &pg->count_info) ) - put_page(pg); -- BUG_ON(pg->count_info & ~PGC_xen_heap); -+ -+ if ( pg->count_info & ~PGC_xen_heap ) -+ { -+ if ( paging_mode_translate(d) ) -+ { -+ gprintk(XENLOG_ERR, -+ "Wrong page state %#lx of status frame %u (GFN %#lx)\n", -+ pg->count_info, i, gfn_x(gfn)); -+ domain_crash(d); -+ } -+ else -+ { -+ if ( get_page(pg, d) ) -+ set_bit(_PGC_allocated, &pg->count_info); -+ while ( i-- ) -+ gnttab_create_status_page(d, gt, i); -+ } -+ return -EBUSY; -+ } -+ -+ page_set_owner(pg, NULL); -+ } -+ -+ for ( i = 0; i < nr_status_frames(gt); i++ ) -+ { - free_xenheap_page(gt->status[i]); - gt->status[i] = NULL; - } - gt->nr_status_frames = 0; -+ -+ return 0; - } - - /* -@@ -2962,8 +3013,9 @@ gnttab_set_version(XEN_GUEST_HANDLE_PARA - break; - } - -- if ( op.version < 2 && gt->gt_version == 2 ) -- gnttab_unpopulate_status_frames(currd, gt); -+ if ( op.version < 2 && gt->gt_version == 2 && -+ (res = gnttab_unpopulate_status_frames(currd, gt)) != 0 ) -+ goto out_unlock; - - /* Make sure there's no crud left over from the old version. */ - for ( i = 0; i < nr_grant_frames(gt); i++ ) -@@ -3803,6 +3855,11 @@ int gnttab_map_frame(struct domain *d, u - rc = -EINVAL; - } - -+ if ( !rc && paging_mode_translate(d) && -+ !gfn_eq(gnttab_get_frame_gfn(gt, status, idx), INVALID_GFN) ) -+ rc = guest_physmap_remove_page(d, gnttab_get_frame_gfn(gt, status, idx), -+ *mfn, 0); -+ - if ( !rc ) - gnttab_set_frame_gfn(gt, status, idx, gfn); - ---- a/xen/include/asm-arm/grant_table.h -+++ b/xen/include/asm-arm/grant_table.h -@@ -73,6 +73,11 @@ static inline unsigned int gnttab_dom0_m - (gfn); \ - } while ( 0 ) - -+#define gnttab_get_frame_gfn(gt, st, idx) ({ \ -+ _gfn((st) ? gnttab_status_gmfn(NULL, gt, idx) \ -+ : gnttab_shared_gmfn(NULL, gt, idx)); \ -+}) -+ - #define gnttab_create_shared_page(d, t, i) \ - do { \ - share_xen_page_with_guest( \ ---- a/xen/include/asm-x86/grant_table.h -+++ b/xen/include/asm-x86/grant_table.h -@@ -47,6 +47,12 @@ static inline unsigned int gnttab_dom0_m - #define gnttab_init_arch(gt) 0 - #define gnttab_destroy_arch(gt) do {} while ( 0 ) - #define gnttab_set_frame_gfn(gt, st, idx, gfn) do {} while ( 0 ) -+#define gnttab_get_frame_gfn(gt, st, idx) ({ \ -+ unsigned long mfn_ = (st) ? gnttab_status_mfn(gt, idx) \ -+ : gnttab_shared_mfn(gt, idx); \ -+ unsigned long gpfn_ = get_gpfn_from_mfn(mfn_); \ -+ VALID_M2P(gpfn_) ? _gfn(gpfn_) : INVALID_GFN; \ -+}) - - #define gnttab_create_shared_page(d, t, i) \ - do { \ -@@ -63,11 +69,11 @@ static inline unsigned int gnttab_dom0_m - } while ( 0 ) - - --#define gnttab_shared_mfn(d, t, i) \ -+#define gnttab_shared_mfn(t, i) \ - ((virt_to_maddr((t)->shared_raw[i]) >> PAGE_SHIFT)) - - #define gnttab_shared_gmfn(d, t, i) \ -- (mfn_to_gmfn(d, gnttab_shared_mfn(d, t, i))) -+ (mfn_to_gmfn(d, gnttab_shared_mfn(t, i))) - - - #define gnttab_status_mfn(t, i) \ |