0c76f22ef1
- bnc#633573 - System fail to boot after running several warm reboot tests 22749-vtd-workarounds.patch - Upstream patches from Jan 22744-ept-pod-locking.patch 22777-vtd-ats-fixes.patch 22781-pod-hap-logdirty.patch 22782-x86-emul-smsw.patch 22789-i386-no-x2apic.patch 22790-svm-resume-migrate-pirqs.patch 22816-x86-pirq-drop-priv-check.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=94
175 lines
5.8 KiB
Diff
175 lines
5.8 KiB
Diff
Subject: xenpaging: page-in granttable entries
|
|
|
|
When converting a gfn to mfn, check if the page is paged-out.
|
|
If it is, request a page-in and return GNTST_eagain to the caller
|
|
to indicate a retry of the hypercall is required.
|
|
This fixes granttable errors when xenpaging is enabled in the guest.
|
|
|
|
(xen-unstable changeset: 22209:50c1cc209f8f)
|
|
|
|
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
|
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
|
|
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>
|
|
|
|
---
|
|
xen/common/grant_table.c | 94 ++++++++++++++++++++++++++++++-----------------
|
|
1 file changed, 60 insertions(+), 34 deletions(-)
|
|
|
|
Index: xen-4.0.2-testing/xen/common/grant_table.c
|
|
===================================================================
|
|
--- xen-4.0.2-testing.orig/xen/common/grant_table.c
|
|
+++ xen-4.0.2-testing/xen/common/grant_table.c
|
|
@@ -139,6 +139,37 @@ shared_entry_header(struct grant_table *
|
|
#define active_entry(t, e) \
|
|
((t)->active[(e)/ACGNT_PER_PAGE][(e)%ACGNT_PER_PAGE])
|
|
|
|
+/* Check if the page has been paged out */
|
|
+static int __get_paged_frame(unsigned long gfn, unsigned long *frame, int readonly, struct domain *rd)
|
|
+{
|
|
+ p2m_type_t p2mt;
|
|
+ mfn_t mfn;
|
|
+ int rc = GNTST_okay;
|
|
+
|
|
+ if ( readonly )
|
|
+ mfn = gfn_to_mfn(rd, gfn, &p2mt);
|
|
+ else
|
|
+ mfn = gfn_to_mfn_unshare(rd, gfn, &p2mt, 1);
|
|
+
|
|
+ if ( p2m_is_valid(p2mt) )
|
|
+ {
|
|
+ *frame = mfn_x(mfn);
|
|
+ if ( p2m_is_paging(p2mt) )
|
|
+ {
|
|
+ if ( p2m_is_paged(p2mt) )
|
|
+ p2m_mem_paging_populate(rd, gfn);
|
|
+ rc = GNTST_eagain;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ *frame = INVALID_MFN;
|
|
+ rc = GNTST_bad_page;
|
|
+ }
|
|
+
|
|
+ return rc;
|
|
+}
|
|
+
|
|
static inline int
|
|
__get_maptrack_handle(
|
|
struct grant_table *t)
|
|
@@ -527,14 +558,16 @@ __gnttab_map_grant_ref(
|
|
|
|
if ( !act->pin )
|
|
{
|
|
+ unsigned long gfn;
|
|
+ unsigned long frame;
|
|
+
|
|
+ gfn = sha1 ? sha1->frame : sha2->full_page.frame;
|
|
+ rc = __get_paged_frame(gfn, &frame, !!(op->flags & GNTMAP_readonly), rd);
|
|
+ if ( rc != GNTST_okay )
|
|
+ goto unlock_out;
|
|
+ act->gfn = gfn;
|
|
act->domid = ld->domain_id;
|
|
- if ( sha1 )
|
|
- act->gfn = sha1->frame;
|
|
- else
|
|
- act->gfn = sha2->full_page.frame;
|
|
- act->frame = (op->flags & GNTMAP_readonly) ?
|
|
- gmfn_to_mfn(rd, act->gfn) :
|
|
- gfn_to_mfn_private(rd, act->gfn);
|
|
+ act->frame = frame;
|
|
act->start = 0;
|
|
act->length = PAGE_SIZE;
|
|
act->is_sub_page = 0;
|
|
@@ -1697,6 +1730,7 @@ __acquire_grant_for_copy(
|
|
domid_t trans_domid;
|
|
grant_ref_t trans_gref;
|
|
struct domain *rrd;
|
|
+ unsigned long gfn;
|
|
unsigned long grant_frame;
|
|
unsigned trans_page_off;
|
|
unsigned trans_length;
|
|
@@ -1814,9 +1848,11 @@ __acquire_grant_for_copy(
|
|
}
|
|
else if ( sha1 )
|
|
{
|
|
- act->gfn = sha1->frame;
|
|
- grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
|
|
- gfn_to_mfn_private(rd, act->gfn);
|
|
+ gfn = sha1->frame;
|
|
+ rc = __get_paged_frame(gfn, &grant_frame, readonly, rd);
|
|
+ if ( rc != GNTST_okay )
|
|
+ goto unlock_out;
|
|
+ act->gfn = gfn;
|
|
is_sub_page = 0;
|
|
trans_page_off = 0;
|
|
trans_length = PAGE_SIZE;
|
|
@@ -1824,9 +1860,11 @@ __acquire_grant_for_copy(
|
|
}
|
|
else if ( !(sha2->hdr.flags & GTF_sub_page) )
|
|
{
|
|
- act->gfn = sha2->full_page.frame;
|
|
- grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
|
|
- gfn_to_mfn_private(rd, act->gfn);
|
|
+ gfn = sha2->full_page.frame;
|
|
+ rc = __get_paged_frame(gfn, &grant_frame, readonly, rd);
|
|
+ if ( rc != GNTST_okay )
|
|
+ goto unlock_out;
|
|
+ act->gfn = gfn;
|
|
is_sub_page = 0;
|
|
trans_page_off = 0;
|
|
trans_length = PAGE_SIZE;
|
|
@@ -1834,9 +1872,11 @@ __acquire_grant_for_copy(
|
|
}
|
|
else
|
|
{
|
|
- act->gfn = sha2->sub_page.frame;
|
|
- grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
|
|
- gfn_to_mfn_private(rd, act->gfn);
|
|
+ gfn = sha2->sub_page.frame;
|
|
+ rc = __get_paged_frame(gfn, &grant_frame, readonly, rd);
|
|
+ if ( rc != GNTST_okay )
|
|
+ goto unlock_out;
|
|
+ act->gfn = gfn;
|
|
is_sub_page = 1;
|
|
trans_page_off = sha2->sub_page.page_off;
|
|
trans_length = sha2->sub_page.length;
|
|
@@ -1932,16 +1972,9 @@ __gnttab_copy(
|
|
else
|
|
{
|
|
#ifdef CONFIG_X86
|
|
- p2m_type_t p2mt;
|
|
- s_frame = mfn_x(gfn_to_mfn(sd, op->source.u.gmfn, &p2mt));
|
|
- if ( !p2m_is_valid(p2mt) )
|
|
- s_frame = INVALID_MFN;
|
|
- if ( p2m_is_paging(p2mt) )
|
|
- {
|
|
- p2m_mem_paging_populate(sd, op->source.u.gmfn);
|
|
- rc = -ENOENT;
|
|
+ rc = __get_paged_frame(op->source.u.gmfn, &s_frame, 1, sd);
|
|
+ if ( rc != GNTST_okay )
|
|
goto error_out;
|
|
- }
|
|
#else
|
|
s_frame = gmfn_to_mfn(sd, op->source.u.gmfn);
|
|
#endif
|
|
@@ -1978,16 +2011,9 @@ __gnttab_copy(
|
|
else
|
|
{
|
|
#ifdef CONFIG_X86
|
|
- p2m_type_t p2mt;
|
|
- d_frame = mfn_x(gfn_to_mfn_unshare(dd, op->dest.u.gmfn, &p2mt, 1));
|
|
- if ( !p2m_is_valid(p2mt) )
|
|
- d_frame = INVALID_MFN;
|
|
- if ( p2m_is_paging(p2mt) )
|
|
- {
|
|
- p2m_mem_paging_populate(dd, op->dest.u.gmfn);
|
|
- rc = -ENOENT;
|
|
+ rc = __get_paged_frame(op->dest.u.gmfn, &d_frame, 0, dd);
|
|
+ if ( rc != GNTST_okay )
|
|
goto error_out;
|
|
- }
|
|
#else
|
|
d_frame = gmfn_to_mfn(dd, op->dest.u.gmfn);
|
|
#endif
|