aboutsummaryrefslogtreecommitdiffstats
path: root/extras
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-01-18 15:22:42 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-01-18 15:22:42 +0000
commit4eb8e8dc041e4525c561553a970a4c7adf6bba30 (patch)
tree03bf759c23e8eff141e5a0f0960183eb68bf53b1 /extras
parentc1ea56152af43af8fa0d6ead7ab22ebd065e63ae (diff)
downloadxen-4eb8e8dc041e4525c561553a970a4c7adf6bba30.tar.gz
xen-4eb8e8dc041e4525c561553a970a4c7adf6bba30.tar.bz2
xen-4eb8e8dc041e4525c561553a970a4c7adf6bba30.zip
minios: extend map_frames into being able to map a series of
contiguous frames, or the same frame several times, aligned, from another domain, with specific protection, and with potential failures. Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'extras')
-rw-r--r--extras/mini-os/arch/ia64/mm.c9
-rw-r--r--extras/mini-os/arch/x86/mm.c62
-rw-r--r--extras/mini-os/include/ia64/arch_mm.h2
-rw-r--r--extras/mini-os/include/mm.h5
-rw-r--r--extras/mini-os/include/x86/arch_mm.h1
5 files changed, 56 insertions, 23 deletions
diff --git a/extras/mini-os/arch/ia64/mm.c b/extras/mini-os/arch/ia64/mm.c
index cb1699a9ab..f557730257 100644
--- a/extras/mini-os/arch/ia64/mm.c
+++ b/extras/mini-os/arch/ia64/mm.c
@@ -124,9 +124,14 @@ arch_init_demand_mapping_area(unsigned long max_pfn)
/* Helper function used in gnttab.c. */
void*
-map_frames(unsigned long* frames, unsigned long n)
+map_frames_ex(unsigned long* frames, unsigned long n, unsigned long stride,
+ unsigned long increment, unsigned long alignment, domid_t id,
+ int may_fail, unsigned long prot)
{
- n = n;
+ /* TODO: incomplete! */
+ ASSERT(n == 1 || (stride == 0 && increment == 1));
+ ASSERT(id == DOMID_SELF);
+ ASSERT(prot == 0);
return (void*) __va(SWAP(frames[0]) << PAGE_SHIFT);
}
diff --git a/extras/mini-os/arch/x86/mm.c b/extras/mini-os/arch/x86/mm.c
index 78e6c7638b..53becda146 100644
--- a/extras/mini-os/arch/x86/mm.c
+++ b/extras/mini-os/arch/x86/mm.c
@@ -367,6 +367,7 @@ void mem_test(unsigned long *start_add, unsigned long *end_add)
static pgentry_t *demand_map_pgt;
static void *demand_map_area_start;
+#define DEMAND_MAP_PAGES 1024
void arch_init_demand_mapping_area(unsigned long max_pfn)
{
@@ -426,20 +427,19 @@ void arch_init_demand_mapping_area(unsigned long max_pfn)
printk("Initialised demand area.\n");
}
-void *map_frames(unsigned long *f, unsigned long n)
+#define MAP_BATCH ((STACK_SIZE / 2) / sizeof(mmu_update_t))
+
+void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride,
+ unsigned long increment, unsigned long alignment, domid_t id,
+ int may_fail, unsigned long prot)
{
unsigned long x;
unsigned long y = 0;
- mmu_update_t mmu_updates[16];
int rc;
-
- if (n > 16) {
- printk("Tried to map too many (%ld) frames at once.\n", n);
- return NULL;
- }
+ unsigned long done = 0;
/* Find a run of n contiguous frames */
- for (x = 0; x <= 1024 - n; x += y + 1) {
+ for (x = 0; x <= DEMAND_MAP_PAGES - n; x = (x + y + 1 + alignment - 1) & ~(alignment - 1)) {
for (y = 0; y < n; y++)
if (demand_map_pgt[x+y] & _PAGE_PRESENT)
break;
@@ -447,24 +447,46 @@ void *map_frames(unsigned long *f, unsigned long n)
break;
}
if (y != n) {
- printk("Failed to map %ld frames!\n", n);
+ printk("Failed to find %ld frames!\n", n);
return NULL;
}
/* Found it at x. Map it in. */
- for (y = 0; y < n; y++) {
- mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + y]);
- mmu_updates[y].val = (f[y] << PAGE_SHIFT) | L1_PROT;
- }
- rc = HYPERVISOR_mmu_update(mmu_updates, n, NULL, DOMID_SELF);
- if (rc < 0) {
- printk("Map %ld failed: %d.\n", n, rc);
- return NULL;
- } else {
- return (void *)(unsigned long)((unsigned long)demand_map_area_start +
- x * PAGE_SIZE);
+ while (done < n) {
+ unsigned long todo;
+
+ if (may_fail)
+ todo = 1;
+ else
+ todo = n - done;
+
+ if (todo > MAP_BATCH)
+ todo = MAP_BATCH;
+
+ {
+ mmu_update_t mmu_updates[todo];
+
+ for (y = 0; y < todo; y++) {
+ mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + done + y]);
+ mmu_updates[y].val = ((f[(done + y) * stride] + (done + y) * increment) << PAGE_SHIFT) | prot;
+ }
+
+ rc = HYPERVISOR_mmu_update(mmu_updates, todo, NULL, id);
+ if (rc < 0) {
+ if (may_fail)
+ f[done * stride] |= 0xF0000000;
+ else {
+ printk("Map %ld (%lx, ...) failed: %d.\n", todo, f[done * stride], rc);
+ return NULL;
+ }
+ }
+ }
+
+ done += todo;
}
+ return (void *)(unsigned long)((unsigned long)demand_map_area_start +
+ x * PAGE_SIZE);
}
static void clear_bootstrap(void)
diff --git a/extras/mini-os/include/ia64/arch_mm.h b/extras/mini-os/include/ia64/arch_mm.h
index 9c18e00378..c1506ac988 100644
--- a/extras/mini-os/include/ia64/arch_mm.h
+++ b/extras/mini-os/include/ia64/arch_mm.h
@@ -36,4 +36,6 @@
#define STACK_SIZE_PAGE_ORDER 1
#define STACK_SIZE (PAGE_SIZE * (1 << STACK_SIZE_PAGE_ORDER))
+#define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, 0, 0)
+
#endif /* __ARCH_MM_H__ */
diff --git a/extras/mini-os/include/mm.h b/extras/mini-os/include/mm.h
index a9c0f2c181..4319fa2640 100644
--- a/extras/mini-os/include/mm.h
+++ b/extras/mini-os/include/mm.h
@@ -57,6 +57,9 @@ void arch_init_demand_mapping_area(unsigned long max_pfn);
void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p);
void arch_init_p2m(unsigned long max_pfn_p);
-void *map_frames(unsigned long *f, unsigned long n);
+/* map f[i*stride]+i*increment for i in 0..n-1, aligned on alignment pages */
+void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride,
+ unsigned long increment, unsigned long alignment, domid_t id,
+ int may_fail, unsigned long prot);
#endif /* _MM_H_ */
diff --git a/extras/mini-os/include/x86/arch_mm.h b/extras/mini-os/include/x86/arch_mm.h
index 5c7f061471..8ae845131a 100644
--- a/extras/mini-os/include/x86/arch_mm.h
+++ b/extras/mini-os/include/x86/arch_mm.h
@@ -223,5 +223,6 @@ static __inline__ paddr_t machine_to_phys(maddr_t machine)
#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
#define pte_to_virt(_pte) to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT)
+#define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, 0, L1_PROT)
#endif /* _ARCH_MM_H_ */