9a05aa7fc4
22707-x2apic-preenabled-check.patch - bnc#641419 - L3: Xen: qemu-dm reports "xc_map_foreign_batch: mmap failed: Cannot allocate memory" 7434-qemu-rlimit-as.patch - Additional or upstream patches from Jan 22693-fam10-mmio-conf-base-protect.patch 22694-x86_64-no-weak.patch 22708-xenctx-misc.patch 21432-4.0-cpu-boot-failure.patch 22645-amd-flush-filter.patch qemu-fix-7433.patch - Maintain compatibility with the extid flag even though it is deprecated for both legacy and sxp config files. hv_extid_compatibility.patch - bnc#649209-improve suspend eventchn lock suspend_evtchn_lock.patch - Removed the hyper-v shim patches in favor of using the upstream version. - bnc#641419 - L3: Xen: qemu-dm reports "xc_map_foreign_batch: mmap failed: Cannot allocate memory" qemu-rlimit-as.patch - Upstream c/s 7433 to replace qemu_altgr_more.patch 7433-qemu-altgr.patch OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=90
190 lines
6.8 KiB
Diff
190 lines
6.8 KiB
Diff
Subject: xenpaging: drop paged pages in guest_remove_page
|
|
|
|
Simply drop paged-pages in guest_remove_page(), and notify xenpaging to
|
|
drop reference to the gfn.
|
|
|
|
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
|
---
|
|
v2:
|
|
resume dropped page to unpause vcpus
|
|
|
|
tools/xenpaging/xenpaging.c | 17 +++++++---
|
|
xen/arch/x86/mm/p2m.c | 65 +++++++++++++++++++++++++++++++----------
|
|
xen/common/memory.c | 6 +++
|
|
xen/include/asm-x86/p2m.h | 4 ++
|
|
xen/include/public/mem_event.h | 1
|
|
5 files changed, 73 insertions(+), 20 deletions(-)
|
|
|
|
Index: xen-4.0.1-testing/tools/xenpaging/xenpaging.c
|
|
===================================================================
|
|
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
|
|
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
|
|
@@ -600,12 +600,19 @@ int main(int argc, char *argv[])
|
|
goto out;
|
|
}
|
|
|
|
- /* Populate the page */
|
|
- rc = xenpaging_populate_page(paging, &req.gfn, fd, i);
|
|
- if ( rc != 0 )
|
|
+ if ( req.flags & MEM_EVENT_FLAG_DROP_PAGE )
|
|
{
|
|
- ERROR("Error populating page");
|
|
- goto out;
|
|
+ DPRINTF("Dropping page %"PRIx64" p2mt %x\n", req.gfn, req.p2mt);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ /* Populate the page */
|
|
+ rc = xenpaging_populate_page(paging, &req.gfn, fd, i);
|
|
+ if ( rc != 0 )
|
|
+ {
|
|
+ ERROR("Error populating page");
|
|
+ goto out;
|
|
+ }
|
|
}
|
|
|
|
/* Prepare the response */
|
|
Index: xen-4.0.1-testing/xen/arch/x86/mm/p2m.c
|
|
===================================================================
|
|
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c
|
|
+++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c
|
|
@@ -2000,12 +2000,15 @@ p2m_remove_page(struct domain *d, unsign
|
|
|
|
P2M_DEBUG("removing gfn=%#lx mfn=%#lx\n", gfn, mfn);
|
|
|
|
- for ( i = 0; i < (1UL << page_order); i++ )
|
|
+ if ( mfn_valid(_mfn(mfn)) )
|
|
{
|
|
- mfn_return = d->arch.p2m->get_entry(d, gfn + i, &t, p2m_query);
|
|
- if ( !p2m_is_grant(t) )
|
|
- set_gpfn_from_mfn(mfn+i, INVALID_M2P_ENTRY);
|
|
- ASSERT( !p2m_is_valid(t) || mfn + i == mfn_x(mfn_return) );
|
|
+ for ( i = 0; i < (1UL << page_order); i++ )
|
|
+ {
|
|
+ mfn_return = d->arch.p2m->get_entry(d, gfn + i, &t, p2m_query);
|
|
+ if ( !p2m_is_grant(t) )
|
|
+ set_gpfn_from_mfn(mfn+i, INVALID_M2P_ENTRY);
|
|
+ ASSERT( !p2m_is_valid(t) || mfn + i == mfn_x(mfn_return) );
|
|
+ }
|
|
}
|
|
set_p2m_entry(d, gfn, _mfn(INVALID_MFN), page_order, p2m_invalid);
|
|
}
|
|
@@ -2529,6 +2532,35 @@ int p2m_mem_paging_evict(struct domain *
|
|
return 0;
|
|
}
|
|
|
|
+void p2m_mem_paging_drop_page(struct domain *d, unsigned long gfn)
|
|
+{
|
|
+ struct vcpu *v = current;
|
|
+ mem_event_request_t req;
|
|
+ p2m_type_t p2mt;
|
|
+
|
|
+ memset(&req, 0, sizeof(req));
|
|
+
|
|
+ /* Check that there's space on the ring for this request */
|
|
+ if ( mem_event_check_ring(d) )
|
|
+ return;
|
|
+
|
|
+ gfn_to_mfn(d, gfn, &p2mt);
|
|
+ /* Pause domain */
|
|
+ if ( v->domain->domain_id == d->domain_id )
|
|
+ {
|
|
+ vcpu_pause_nosync(v);
|
|
+ req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED;
|
|
+ }
|
|
+
|
|
+ /* Send request to pager */
|
|
+ req.flags |= MEM_EVENT_FLAG_DROP_PAGE;
|
|
+ req.gfn = gfn;
|
|
+ req.p2mt = p2mt;
|
|
+ req.vcpu_id = v->vcpu_id;
|
|
+
|
|
+ mem_event_put_request(d, &req);
|
|
+}
|
|
+
|
|
void p2m_mem_paging_populate(struct domain *d, unsigned long gfn)
|
|
{
|
|
struct vcpu *v = current;
|
|
@@ -2593,17 +2625,20 @@ void p2m_mem_paging_resume(struct domain
|
|
/* Pull the response off the ring */
|
|
mem_event_get_response(d, &rsp);
|
|
|
|
- /* Fix p2m entry */
|
|
- mfn = gfn_to_mfn(d, rsp.gfn, &p2mt);
|
|
- if ( mfn_valid(mfn) )
|
|
+ if ( !( rsp.flags & MEM_EVENT_FLAG_DROP_PAGE ) )
|
|
{
|
|
- p2m_lock(d->arch.p2m);
|
|
- set_p2m_entry(d, rsp.gfn, mfn, 0, p2m_ram_rw);
|
|
- set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn);
|
|
- p2m_unlock(d->arch.p2m);
|
|
- } else {
|
|
- gdprintk(XENLOG_ERR, "invalid mfn %lx for gfn %lx p2mt %x flags %lx\n",
|
|
- mfn_x(mfn), rsp.gfn, p2mt, (unsigned long)rsp.flags);
|
|
+ /* Fix p2m entry */
|
|
+ mfn = gfn_to_mfn(d, rsp.gfn, &p2mt);
|
|
+ if ( mfn_valid(mfn) )
|
|
+ {
|
|
+ p2m_lock(d->arch.p2m);
|
|
+ set_p2m_entry(d, rsp.gfn, mfn, 0, p2m_ram_rw);
|
|
+ set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn);
|
|
+ p2m_unlock(d->arch.p2m);
|
|
+ } else {
|
|
+ gdprintk(XENLOG_ERR, "invalid mfn %lx for gfn %lx p2mt %x flags %lx\n",
|
|
+ mfn_x(mfn), rsp.gfn, p2mt, (unsigned long)rsp.flags);
|
|
+ }
|
|
}
|
|
|
|
/* Unpause domain */
|
|
Index: xen-4.0.1-testing/xen/common/memory.c
|
|
===================================================================
|
|
--- xen-4.0.1-testing.orig/xen/common/memory.c
|
|
+++ xen-4.0.1-testing/xen/common/memory.c
|
|
@@ -162,6 +162,12 @@ int guest_remove_page(struct domain *d,
|
|
|
|
#ifdef CONFIG_X86
|
|
mfn = mfn_x(gfn_to_mfn(d, gmfn, &p2mt));
|
|
+ if ( unlikely(p2m_is_paging(p2mt)) )
|
|
+ {
|
|
+ guest_physmap_remove_page(d, gmfn, mfn, 0);
|
|
+ p2m_mem_paging_drop_page(d, gmfn);
|
|
+ return 1;
|
|
+ }
|
|
#else
|
|
mfn = gmfn_to_mfn(d, gmfn);
|
|
#endif
|
|
Index: xen-4.0.1-testing/xen/include/asm-x86/p2m.h
|
|
===================================================================
|
|
--- xen-4.0.1-testing.orig/xen/include/asm-x86/p2m.h
|
|
+++ xen-4.0.1-testing/xen/include/asm-x86/p2m.h
|
|
@@ -441,6 +441,8 @@ int set_shared_p2m_entry(struct domain *
|
|
int p2m_mem_paging_nominate(struct domain *d, unsigned long gfn);
|
|
/* Evict a frame */
|
|
int p2m_mem_paging_evict(struct domain *d, unsigned long gfn);
|
|
+/* Tell xenpaging to drop a paged out frame */
|
|
+void p2m_mem_paging_drop_page(struct domain *d, unsigned long gfn);
|
|
/* Start populating a paged out frame */
|
|
void p2m_mem_paging_populate(struct domain *d, unsigned long gfn);
|
|
/* Prepare the p2m for paging a frame in */
|
|
@@ -448,6 +450,8 @@ int p2m_mem_paging_prep(struct domain *d
|
|
/* Resume normal operation (in case a domain was paused) */
|
|
void p2m_mem_paging_resume(struct domain *d);
|
|
#else
|
|
+static inline void p2m_mem_paging_drop_page(struct domain *d, unsigned long gfn)
|
|
+{ }
|
|
static inline void p2m_mem_paging_populate(struct domain *d, unsigned long gfn)
|
|
{ }
|
|
#endif
|
|
Index: xen-4.0.1-testing/xen/include/public/mem_event.h
|
|
===================================================================
|
|
--- xen-4.0.1-testing.orig/xen/include/public/mem_event.h
|
|
+++ xen-4.0.1-testing/xen/include/public/mem_event.h
|
|
@@ -37,6 +37,7 @@
|
|
#define MEM_EVENT_FLAG_VCPU_PAUSED (1 << 0)
|
|
#define MEM_EVENT_FLAG_DOM_PAUSED (1 << 1)
|
|
#define MEM_EVENT_FLAG_OUT_OF_MEM (1 << 2)
|
|
+#define MEM_EVENT_FLAG_DROP_PAGE (1 << 3)
|
|
|
|
|
|
typedef struct mem_event_shared_page {
|