ia64/xen-unstable

changeset 16805:2d6a0ee25f2a

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>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jan 18 15:22:42 2008 +0000 (2008-01-18)
parents 8101b65014e8
children edc95d23493b
files extras/mini-os/arch/ia64/mm.c extras/mini-os/arch/x86/mm.c extras/mini-os/include/ia64/arch_mm.h extras/mini-os/include/mm.h extras/mini-os/include/x86/arch_mm.h
line diff
     1.1 --- a/extras/mini-os/arch/ia64/mm.c	Fri Jan 18 15:22:17 2008 +0000
     1.2 +++ b/extras/mini-os/arch/ia64/mm.c	Fri Jan 18 15:22:42 2008 +0000
     1.3 @@ -124,9 +124,14 @@ arch_init_demand_mapping_area(unsigned l
     1.4  
     1.5  /* Helper function used in gnttab.c. */
     1.6  void*
     1.7 -map_frames(unsigned long* frames, unsigned long n)
     1.8 +map_frames_ex(unsigned long* frames, unsigned long n, unsigned long stride,
     1.9 +	unsigned long increment, unsigned long alignment, domid_t id,
    1.10 +	int may_fail, unsigned long prot)
    1.11  {
    1.12 -	n = n;
    1.13 +        /* TODO: incomplete! */
    1.14 +        ASSERT(n == 1 || (stride == 0 && increment == 1));
    1.15 +        ASSERT(id == DOMID_SELF);
    1.16 +        ASSERT(prot == 0);
    1.17  	return (void*) __va(SWAP(frames[0]) << PAGE_SHIFT);
    1.18  }
    1.19  
     2.1 --- a/extras/mini-os/arch/x86/mm.c	Fri Jan 18 15:22:17 2008 +0000
     2.2 +++ b/extras/mini-os/arch/x86/mm.c	Fri Jan 18 15:22:42 2008 +0000
     2.3 @@ -367,6 +367,7 @@ void mem_test(unsigned long *start_add, 
     2.4  
     2.5  static pgentry_t *demand_map_pgt;
     2.6  static void *demand_map_area_start;
     2.7 +#define DEMAND_MAP_PAGES 1024
     2.8  
     2.9  void arch_init_demand_mapping_area(unsigned long max_pfn)
    2.10  {
    2.11 @@ -426,20 +427,19 @@ void arch_init_demand_mapping_area(unsig
    2.12      printk("Initialised demand area.\n");
    2.13  }
    2.14  
    2.15 -void *map_frames(unsigned long *f, unsigned long n)
    2.16 +#define MAP_BATCH ((STACK_SIZE / 2) / sizeof(mmu_update_t))
    2.17 +
    2.18 +void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride,
    2.19 +	unsigned long increment, unsigned long alignment, domid_t id,
    2.20 +	int may_fail, unsigned long prot)
    2.21  {
    2.22      unsigned long x;
    2.23      unsigned long y = 0;
    2.24 -    mmu_update_t mmu_updates[16];
    2.25      int rc;
    2.26 -
    2.27 -    if (n > 16) {
    2.28 -        printk("Tried to map too many (%ld) frames at once.\n", n);
    2.29 -        return NULL;
    2.30 -    }
    2.31 +    unsigned long done = 0;
    2.32  
    2.33      /* Find a run of n contiguous frames */
    2.34 -    for (x = 0; x <= 1024 - n; x += y + 1) {
    2.35 +    for (x = 0; x <= DEMAND_MAP_PAGES - n; x = (x + y + 1 + alignment - 1) & ~(alignment - 1)) {
    2.36          for (y = 0; y < n; y++)
    2.37              if (demand_map_pgt[x+y] & _PAGE_PRESENT)
    2.38                  break;
    2.39 @@ -447,24 +447,46 @@ void *map_frames(unsigned long *f, unsig
    2.40              break;
    2.41      }
    2.42      if (y != n) {
    2.43 -        printk("Failed to map %ld frames!\n", n);
    2.44 +        printk("Failed to find %ld frames!\n", n);
    2.45          return NULL;
    2.46      }
    2.47  
    2.48      /* Found it at x.  Map it in. */
    2.49 -    for (y = 0; y < n; y++) {
    2.50 -        mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + y]);
    2.51 -        mmu_updates[y].val = (f[y] << PAGE_SHIFT) | L1_PROT;
    2.52 -    }
    2.53  
    2.54 -    rc = HYPERVISOR_mmu_update(mmu_updates, n, NULL, DOMID_SELF);
    2.55 -    if (rc < 0) {
    2.56 -        printk("Map %ld failed: %d.\n", n, rc);
    2.57 -        return NULL;
    2.58 -    } else {
    2.59 -        return (void *)(unsigned long)((unsigned long)demand_map_area_start +
    2.60 -                x * PAGE_SIZE);
    2.61 +    while (done < n) {
    2.62 +	unsigned long todo;
    2.63 +
    2.64 +	if (may_fail)
    2.65 +	    todo = 1;
    2.66 +	else
    2.67 +	    todo = n - done;
    2.68 +
    2.69 +	if (todo > MAP_BATCH)
    2.70 +		todo = MAP_BATCH;
    2.71 +
    2.72 +	{
    2.73 +	    mmu_update_t mmu_updates[todo];
    2.74 +
    2.75 +	    for (y = 0; y < todo; y++) {
    2.76 +		mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + done + y]);
    2.77 +		mmu_updates[y].val = ((f[(done + y) * stride] + (done + y) * increment) << PAGE_SHIFT) | prot;
    2.78 +	    }
    2.79 +
    2.80 +	    rc = HYPERVISOR_mmu_update(mmu_updates, todo, NULL, id);
    2.81 +	    if (rc < 0) {
    2.82 +		if (may_fail)
    2.83 +		    f[done * stride] |= 0xF0000000;
    2.84 +		else {
    2.85 +		    printk("Map %ld (%lx, ...) failed: %d.\n", todo, f[done * stride], rc);
    2.86 +		    return NULL;
    2.87 +		}
    2.88 +	    }
    2.89 +	}
    2.90 +
    2.91 +	done += todo;
    2.92      }
    2.93 +    return (void *)(unsigned long)((unsigned long)demand_map_area_start +
    2.94 +	    x * PAGE_SIZE);
    2.95  }
    2.96  
    2.97  static void clear_bootstrap(void)
     3.1 --- a/extras/mini-os/include/ia64/arch_mm.h	Fri Jan 18 15:22:17 2008 +0000
     3.2 +++ b/extras/mini-os/include/ia64/arch_mm.h	Fri Jan 18 15:22:42 2008 +0000
     3.3 @@ -36,4 +36,6 @@
     3.4  #define STACK_SIZE_PAGE_ORDER   1
     3.5  #define STACK_SIZE              (PAGE_SIZE * (1 << STACK_SIZE_PAGE_ORDER))
     3.6  
     3.7 +#define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, 0, 0)
     3.8 +
     3.9  #endif /* __ARCH_MM_H__ */
     4.1 --- a/extras/mini-os/include/mm.h	Fri Jan 18 15:22:17 2008 +0000
     4.2 +++ b/extras/mini-os/include/mm.h	Fri Jan 18 15:22:42 2008 +0000
     4.3 @@ -57,6 +57,9 @@ void arch_init_demand_mapping_area(unsig
     4.4  void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p);
     4.5  void arch_init_p2m(unsigned long max_pfn_p);
     4.6  
     4.7 -void *map_frames(unsigned long *f, unsigned long n);
     4.8 +/* map f[i*stride]+i*increment for i in 0..n-1, aligned on alignment pages */
     4.9 +void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride,
    4.10 +	unsigned long increment, unsigned long alignment, domid_t id,
    4.11 +	int may_fail, unsigned long prot);
    4.12  
    4.13  #endif /* _MM_H_ */
     5.1 --- a/extras/mini-os/include/x86/arch_mm.h	Fri Jan 18 15:22:17 2008 +0000
     5.2 +++ b/extras/mini-os/include/x86/arch_mm.h	Fri Jan 18 15:22:42 2008 +0000
     5.3 @@ -223,5 +223,6 @@ static __inline__ paddr_t machine_to_phy
     5.4  #define pte_to_mfn(_pte)           (((_pte) & (PADDR_MASK&PAGE_MASK)) >> L1_PAGETABLE_SHIFT)
     5.5  #define pte_to_virt(_pte)          to_virt(mfn_to_pfn(pte_to_mfn(_pte)) << PAGE_SHIFT)
     5.6  
     5.7 +#define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, 0, L1_PROT)
     5.8  
     5.9  #endif /* _ARCH_MM_H_ */