direct-io.hg

changeset 10377:3f8523ce8895

[IA64] check memory descriptor over lap in dom_fw_init()

check memory descriptor over lap in dom_fw_init() and
assign page to dom0 precisely.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author awilliam@xenbuild.aw
date Sat Jun 03 16:06:23 2006 -0600 (2006-06-03)
parents 8771f539663a
children e32ddb4a90e6
files xen/arch/ia64/xen/dom_fw.c xen/arch/ia64/xen/domain.c
line diff
     1.1 --- a/xen/arch/ia64/xen/dom_fw.c	Sat Jun 03 15:34:07 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/dom_fw.c	Sat Jun 03 16:06:23 2006 -0600
     1.3 @@ -3,6 +3,9 @@
     1.4   *  Copyright (C) 2004 Hewlett-Packard Co.
     1.5   *       Dan Magenheimer (dan.magenheimer@hp.com)
     1.6   *
     1.7 + * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
     1.8 + *                    VA Linux Systems Japan K.K.
     1.9 + *                    dom0 vp model support
    1.10   */
    1.11  
    1.12  #include <xen/config.h>
    1.13 @@ -766,6 +769,13 @@ efi_mdt_cmp(const void *a, const void *b
    1.14  		return 1;
    1.15  	if (x->phys_addr < y->phys_addr)
    1.16  		return -1;
    1.17 +
    1.18 +	// num_pages == 0 is allowed.
    1.19 +	if (x->num_pages > y->num_pages)
    1.20 +		return 1;
    1.21 +	if (x->num_pages < y->num_pages)
    1.22 +		return -1;
    1.23 +
    1.24  	return 0;
    1.25  }
    1.26  
    1.27 @@ -1002,11 +1012,15 @@ dom_fw_init (struct domain *d, const cha
    1.28  
    1.29  		/* simulate 1MB free memory at physical address zero */
    1.30  		MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 0);//XXX
    1.31 +#else
    1.32 +		int num_mds;
    1.33 +		int j;
    1.34  #endif
    1.35  		/* hypercall patches live here, masquerade as reserved PAL memory */
    1.36  		MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END, 0);
    1.37 +
    1.38 +#ifndef CONFIG_XEN_IA64_DOM0_VP
    1.39   		MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem-IA64_GRANULE_SIZE, 0);//XXX make sure this doesn't overlap on i/o, runtime area.
    1.40 -#ifndef CONFIG_XEN_IA64_DOM0_VP
    1.41  /* hack */	MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,last_start,last_end,1);
    1.42  #endif
    1.43  
    1.44 @@ -1039,6 +1053,51 @@ dom_fw_init (struct domain *d, const cha
    1.45  			                     dom_fw_dom0_passthrough, &arg);
    1.46  		}
    1.47  		else MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
    1.48 +
    1.49 +#ifdef CONFIG_XEN_IA64_DOM0_VP
    1.50 +		// simple
    1.51 +		// MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
    1.52 +		//         HYPERCALL_END, maxmem, 0);
    1.53 +		// is not good. Check overlap.
    1.54 +		sort(efi_memmap, i, sizeof(efi_memory_desc_t),
    1.55 +		     efi_mdt_cmp, NULL);
    1.56 +
    1.57 +		// find gap and fill it with conventional memory
    1.58 +		num_mds = i;
    1.59 +		for (j = 0; j < num_mds; j++) {
    1.60 +			unsigned long end;
    1.61 +			unsigned long next_start;
    1.62 +
    1.63 +			md = &efi_memmap[j];
    1.64 +			end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
    1.65 +
    1.66 +			next_start = maxmem;
    1.67 +			if (j + 1 < num_mds) {
    1.68 +				efi_memory_desc_t* next_md = &efi_memmap[j + 1];
    1.69 +				next_start = next_md->phys_addr;
    1.70 +				BUG_ON(end > next_start);
    1.71 +				if (end == next_md->phys_addr)
    1.72 +					continue;
    1.73 +			}
    1.74 +
    1.75 +			// clip the range and align to PAGE_SIZE
    1.76 +			// Avoid "legacy" low memory addresses and the
    1.77 +			// HYPERCALL patch area.      
    1.78 +			if (end < HYPERCALL_END)
    1.79 +				end = HYPERCALL_END;
    1.80 +			if (next_start > maxmem)
    1.81 +				next_start = maxmem;
    1.82 +			end = PAGE_ALIGN(end);
    1.83 +			next_start = next_start & PAGE_MASK;
    1.84 +			if (end >= next_start)
    1.85 +				continue;
    1.86 +
    1.87 +			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
    1.88 +			        end, next_start, 0);
    1.89 +			if (next_start >= maxmem)
    1.90 +				break;
    1.91 +		}
    1.92 +#endif        
    1.93  	}
    1.94  	else {
    1.95  #ifndef CONFIG_XEN_IA64_DOM0_VP
    1.96 @@ -1069,11 +1128,47 @@ dom_fw_init (struct domain *d, const cha
    1.97  	bp->console_info.orig_y = 24;
    1.98  	bp->fpswa = dom_pa((unsigned long) fpswa_inf);
    1.99  	if (d == dom0) {
   1.100 +		int j;
   1.101 +		u64 addr;
   1.102 +
   1.103  		// XXX CONFIG_XEN_IA64_DOM0_VP
   1.104 -		// initrd_start address is hard coded in start_kernel()
   1.105 +		// initrd_start address is hard coded in construct_dom0()
   1.106  		bp->initrd_start = (dom0_start+dom0_size) -
   1.107  		  (PAGE_ALIGN(ia64_boot_param->initrd_size) + 4*1024*1024);
   1.108  		bp->initrd_size = ia64_boot_param->initrd_size;
   1.109 +
   1.110 +		// dom0 doesn't need build_physmap_table()
   1.111 +		// see arch_set_info_guest()
   1.112 +		// instead we allocate pages manually.
   1.113 +		for (j = 0; j < i; j++) {
   1.114 +			md = &efi_memmap[j];
   1.115 +			if (md->phys_addr > maxmem)
   1.116 +				break;
   1.117 +
   1.118 +			if (md->type == EFI_LOADER_DATA ||
   1.119 +			    md->type == EFI_PAL_CODE ||
   1.120 +			    md->type == EFI_CONVENTIONAL_MEMORY) {
   1.121 +				unsigned long start = md->phys_addr & PAGE_MASK;
   1.122 +				unsigned long end = md->phys_addr +
   1.123 +				              (md->num_pages << EFI_PAGE_SHIFT);
   1.124 +
   1.125 +				if (end == start) {
   1.126 +					// md->num_pages = 0 is allowed.
   1.127 +					end += PAGE_SIZE;
   1.128 +				}
   1.129 +				if (end > (max_page << PAGE_SHIFT))
   1.130 +					end = (max_page << PAGE_SHIFT);
   1.131 +
   1.132 +				for (addr = start; addr < end; addr += PAGE_SIZE) {
   1.133 +					assign_new_domain0_page(d, addr);
   1.134 +				}
   1.135 +			}
   1.136 +		}
   1.137 +		// work around for legacy device driver.
   1.138 +		for (addr = 0; addr < 1 * MB; addr += PAGE_SIZE) {
   1.139 +			assign_new_domain0_page(d, addr);
   1.140 +		}
   1.141 +		d->arch.physmap_built = 1;
   1.142  	}
   1.143  	else {
   1.144  		bp->initrd_start = d->arch.initrd_start;
     2.1 --- a/xen/arch/ia64/xen/domain.c	Sat Jun 03 15:34:07 2006 -0600
     2.2 +++ b/xen/arch/ia64/xen/domain.c	Sat Jun 03 16:06:23 2006 -0600
     2.3 @@ -790,14 +790,6 @@ int construct_dom0(struct domain *d,
     2.4  
     2.5  	physdev_init_dom0(d);
     2.6  
     2.7 -	// dom0 doesn't need build_physmap_table()
     2.8 -	// see arch_set_info_guest()
     2.9 -	// instead we allocate pages manually.
    2.10 -	for (i = 0; i < max_pages; i++) {
    2.11 -		assign_new_domain0_page(d, i << PAGE_SHIFT);
    2.12 -	}
    2.13 -	d->arch.physmap_built = 1;
    2.14 -
    2.15  	// FIXME: Hack for keyboard input
    2.16  	//serial_input_init();
    2.17