summaryrefslogtreecommitdiffstats
path: root/sys/i386/xen
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2013-03-17 23:39:52 +0000
committerattilio <attilio@FreeBSD.org>2013-03-17 23:39:52 +0000
commitd500d6361abe652aef27a2c034835bc2a60155ad (patch)
tree660c72c3a1b0cbf41943fa591b5ed5d1f31c50f6 /sys/i386/xen
parenta69d85af8b2642ba2d10b8aa37bc58a3123ec1c6 (diff)
parent960294c20051941b358bdc3d71e05fa682614d6f (diff)
downloadFreeBSD-src-d500d6361abe652aef27a2c034835bc2a60155ad.zip
FreeBSD-src-d500d6361abe652aef27a2c034835bc2a60155ad.tar.gz
MFC
Diffstat (limited to 'sys/i386/xen')
-rw-r--r--sys/i386/xen/pmap.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index 3c7c3f5..0f7a80f 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -3448,6 +3448,46 @@ pmap_copy_page(vm_page_t src, vm_page_t dst)
mtx_unlock(&sysmaps->lock);
}
+void
+pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
+ vm_offset_t b_offset, int xfersize)
+{
+ struct sysmaps *sysmaps;
+ vm_page_t a_pg, b_pg;
+ char *a_cp, *b_cp;
+ vm_offset_t a_pg_offset, b_pg_offset;
+ int cnt;
+
+ sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)];
+ mtx_lock(&sysmaps->lock);
+ if (*sysmaps->CMAP1 != 0)
+ panic("pmap_copy_pages: CMAP1 busy");
+ if (*sysmaps->CMAP2 != 0)
+ panic("pmap_copy_pages: CMAP2 busy");
+ sched_pin();
+ while (xfersize > 0) {
+ a_pg = ma[a_offset >> PAGE_SHIFT];
+ a_pg_offset = a_offset & PAGE_MASK;
+ cnt = min(xfersize, PAGE_SIZE - a_pg_offset);
+ b_pg = mb[b_offset >> PAGE_SHIFT];
+ b_pg_offset = b_offset & PAGE_MASK;
+ cnt = min(cnt, PAGE_SIZE - b_pg_offset);
+ PT_SET_MA(sysmaps->CADDR1, PG_V | VM_PAGE_TO_MACH(a_pg) | PG_A);
+ PT_SET_MA(sysmaps->CADDR2, PG_V | PG_RW |
+ VM_PAGE_TO_MACH(b_pg) | PG_A | PG_M);
+ a_cp = sysmaps->CADDR1 + a_pg_offset;
+ b_cp = sysmaps->CADDR2 + b_pg_offset;
+ bcopy(a_cp, b_cp, cnt);
+ a_offset += cnt;
+ b_offset += cnt;
+ xfersize -= cnt;
+ }
+ PT_SET_MA(sysmaps->CADDR1, 0);
+ PT_SET_MA(sysmaps->CADDR2, 0);
+ sched_unpin();
+ mtx_unlock(&sysmaps->lock);
+}
+
/*
* Returns true if the pmap's pv is one of the first
* 16 pvs linked to from this page. This count may
OpenPOWER on IntegriCloud