ia64/xen-unstable

changeset 8070:b9181b1c576f

Merged.
author emellor@leeni.uk.xensource.com
date Sat Nov 26 01:21:55 2005 +0000 (2005-11-26)
parents 3c21a174e8fc c3cfc4ff3b08
children 5d95ab80f290 895a9ca1b0a6
files
line diff
     1.1 --- a/install.sh	Sat Nov 26 01:13:51 2005 +0000
     1.2 +++ b/install.sh	Sat Nov 26 01:21:55 2005 +0000
     1.3 @@ -28,7 +28,7 @@ cp -fdRL $src/etc/init.d/* $dst/etc/init
     1.4  echo "All done."
     1.5  
     1.6  [ -x "$(which udevinfo)" ] && \
     1.7 -  UDEV_VERSION=$(udevinfo -V | sed -e 's/^.*\s\([0-9]\+\)[^0-9]*/\1/')
     1.8 +  UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
     1.9  
    1.10  if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then
    1.11    cp -f $src/etc/udev/rules.d/*.rules $dst/etc/udev/rules.d/
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Sat Nov 26 01:13:51 2005 +0000
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Sat Nov 26 01:21:55 2005 +0000
     2.3 @@ -213,55 +213,6 @@ static int privcmd_ioctl(struct inode *i
     2.4  	break;
     2.5  #endif
     2.6  
     2.7 -#ifndef __ia64__
     2.8 -	case IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS: {
     2.9 -		pgd_t *pgd; 
    2.10 -		pud_t *pud; 
    2.11 -		pmd_t *pmd; 
    2.12 -		unsigned long m2pv, m2p_mfn; 	
    2.13 -		privcmd_m2pmfns_t m; 
    2.14 -		unsigned long __user *p;
    2.15 -		int i; 
    2.16 -
    2.17 -#if defined (__x86_64__)
    2.18 -		/* 
    2.19 -		** XXX SMH: the below procedure won't work for 64 since 
    2.20 -		** we don't have access to the memory which maps the M2P. 
    2.21 -		** A proper fix will probably involve moving this 
    2.22 -		** functionality to Xen - for now just return an error 
    2.23 -		** here rather than GPF'ing in the kernel. 
    2.24 -		*/
    2.25 -		ret = -EINVAL; 
    2.26 -		break; 
    2.27 -#endif
    2.28 -
    2.29 -		if (copy_from_user(&m, udata, sizeof(m)))
    2.30 -			return -EFAULT;
    2.31 -
    2.32 -		m2pv = (unsigned long)machine_to_phys_mapping;
    2.33 -
    2.34 -		p = m.arr; 
    2.35 -
    2.36 -		for (i=0; i < m.num; i++) { 
    2.37 -			pgd = pgd_offset_k(m2pv);
    2.38 -			pud = pud_offset(pgd, m2pv);
    2.39 -			pmd = pmd_offset(pud, m2pv);
    2.40 -			m2p_mfn  = (*(uint64_t *)pmd >> PAGE_SHIFT)&0xFFFFFFFF;
    2.41 -			m2p_mfn += pte_index(m2pv);
    2.42 -
    2.43 -			if (put_user(m2p_mfn, p + i))
    2.44 -				return -EFAULT;
    2.45 -
    2.46 -			m2pv += (1 << 21); 
    2.47 -		}
    2.48 -
    2.49 -		ret = 0; 
    2.50 -		break; 
    2.51 -
    2.52 -	}
    2.53 -	break;
    2.54 -#endif
    2.55 -
    2.56  	default:
    2.57  		ret = -EINVAL;
    2.58  		break;
     3.1 --- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h	Sat Nov 26 01:13:51 2005 +0000
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h	Sat Nov 26 01:21:55 2005 +0000
     3.3 @@ -59,11 +59,6 @@ typedef struct privcmd_mmapbatch {
     3.4  	unsigned long __user *arr; /* array of mfns - top nibble set on err */
     3.5  } privcmd_mmapbatch_t; 
     3.6  
     3.7 -typedef struct privcmd_m2pmfns { 
     3.8 -	int num;    /* max number of mfns to return */
     3.9 -	unsigned long __user *arr; /* array of mfns */
    3.10 -} privcmd_m2pmfns_t; 
    3.11 -
    3.12  typedef struct privcmd_blkmsg
    3.13  {
    3.14  	unsigned long op;
    3.15 @@ -82,8 +77,6 @@ typedef struct privcmd_blkmsg
    3.16  	_IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
    3.17  #define IOCTL_PRIVCMD_MMAPBATCH					\
    3.18  	_IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
    3.19 -#define IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS			\
    3.20 -	_IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
    3.21  
    3.22  #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
    3.23  
     4.1 --- a/tools/check/check_hotplug	Sat Nov 26 01:13:51 2005 +0000
     4.2 +++ b/tools/check/check_hotplug	Sat Nov 26 01:21:55 2005 +0000
     4.3 @@ -7,7 +7,7 @@ function error {
     4.4     exit 1
     4.5  }
     4.6  [ -x "$(which udevinfo)" ] && \
     4.7 -  UDEV_VERSION=$(udevinfo -V | sed -e 's/^.*\s\([0-9]\+\)[^0-9]*/\1/')
     4.8 +  UDEV_VERSION=$(udevinfo -V | sed -e 's/^[^0-9]* \([0-9]\{1,\}\)[^0-9]\{0,\}/\1/')
     4.9  
    4.10  if [ -n "$UDEV_VERSION" ] && [ $UDEV_VERSION -ge 059 ]; then
    4.11    exit 0
     5.1 --- a/tools/libxc/xc_linux_restore.c	Sat Nov 26 01:13:51 2005 +0000
     5.2 +++ b/tools/libxc/xc_linux_restore.c	Sat Nov 26 01:21:55 2005 +0000
     5.3 @@ -78,6 +78,7 @@ int uncanonicalize_pagetable(unsigned lo
     5.4              pfn = (pte >> PAGE_SHIFT) & 0xffffffff;
     5.5              
     5.6              if(pfn >= max_pfn) { 
     5.7 +                /* This "page table page" is probably not one; bail. */
     5.8                  ERR("Frame number in type %lu page table is out of range: "
     5.9                      "i=%d pfn=0x%lx max_pfn=%lu", 
    5.10                      type >> 28, i, pfn, max_pfn);
    5.11 @@ -111,6 +112,7 @@ int xc_linux_restore(int xc_handle, int 
    5.12      unsigned long mfn, pfn; 
    5.13      unsigned int prev_pc, this_pc;
    5.14      int verify = 0;
    5.15 +    int nraces = 0; 
    5.16  
    5.17      /* The new domain's shared-info frame number. */
    5.18      unsigned long shared_info_frame;
    5.19 @@ -344,8 +346,15 @@ int xc_linux_restore(int xc_handle, int 
    5.20                  if(pt_levels != 3 || pagetype != L1TAB) { 
    5.21  
    5.22                      if(!uncanonicalize_pagetable(pagetype, page)) {
    5.23 -                        ERR("failed uncanonicalize pt!\n"); 
    5.24 -                        goto out; 
    5.25 +                        /* 
    5.26 +                        ** Failing to uncanonicalize a page table can be ok
    5.27 +                        ** under live migration since the pages type may have
    5.28 +                        ** changed by now (and we'll get an update later). 
    5.29 +                        */
    5.30 +                        DPRINTF("PT L%ld race on pfn=%08lx mfn=%08lx\n", 
    5.31 +                                pagetype >> 28, pfn, mfn); 
    5.32 +                        nraces++; 
    5.33 +                        continue; 
    5.34                      }
    5.35  
    5.36                  } 
    5.37 @@ -394,7 +403,7 @@ int xc_linux_restore(int xc_handle, int 
    5.38          n+= j; /* crude stats */
    5.39      }
    5.40  
    5.41 -    DPRINTF("Received all pages\n");
    5.42 +    DPRINTF("Received all pages (%d races)\n", nraces);
    5.43  
    5.44      if(pt_levels == 3) { 
    5.45  
     6.1 --- a/tools/libxc/xc_linux_save.c	Sat Nov 26 01:13:51 2005 +0000
     6.2 +++ b/tools/libxc/xc_linux_save.c	Sat Nov 26 01:21:55 2005 +0000
     6.3 @@ -502,7 +502,7 @@ static unsigned long *xc_map_m2p(int xc_
     6.4                                   unsigned long max_mfn, 
     6.5                                   int prot) 
     6.6  { 
     6.7 -    privcmd_m2pmfns_t m2p_mfns; 
     6.8 +    struct xen_machphys_mfn_list xmml;
     6.9      privcmd_mmap_t ioctlx; 
    6.10      privcmd_mmap_entry_t *entries; 
    6.11      unsigned long m2p_chunks, m2p_size; 
    6.12 @@ -512,50 +512,45 @@ static unsigned long *xc_map_m2p(int xc_
    6.13      m2p_size   = M2P_SIZE(max_mfn); 
    6.14      m2p_chunks = M2P_CHUNKS(max_mfn); 
    6.15  
    6.16 -
    6.17 -    m2p_mfns.num = m2p_chunks; 
    6.18 -
    6.19 -    if(!(m2p_mfns.arr = malloc(m2p_chunks * sizeof(unsigned long)))) { 
    6.20 +    xmml.max_extents = m2p_chunks;
    6.21 +    if (!(xmml.extent_start = malloc(m2p_chunks * sizeof(unsigned long)))) { 
    6.22          ERR("failed to allocate space for m2p mfns!\n"); 
    6.23          return NULL; 
    6.24      } 
    6.25  
    6.26 -    if (ioctl(xc_handle, IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS, &m2p_mfns) < 0) {
    6.27 +    if (xc_memory_op(xc_handle, XENMEM_machphys_mfn_list, &xmml) ||
    6.28 +        (xmml.nr_extents != m2p_chunks)) {
    6.29          ERR("xc_get_m2p_mfns:"); 
    6.30          return NULL;
    6.31      }
    6.32  
    6.33 -    if((m2p = mmap(NULL, m2p_size, prot, 
    6.34 -                   MAP_SHARED, xc_handle, 0)) == MAP_FAILED) {
    6.35 +    if ((m2p = mmap(NULL, m2p_size, prot, 
    6.36 +                    MAP_SHARED, xc_handle, 0)) == MAP_FAILED) {
    6.37          ERR("failed to mmap m2p"); 
    6.38          return NULL; 
    6.39      } 
    6.40 -    
    6.41  
    6.42 -    if(!(entries = malloc(m2p_chunks * sizeof(privcmd_mmap_entry_t)))) { 
    6.43 +    if (!(entries = malloc(m2p_chunks * sizeof(privcmd_mmap_entry_t)))) { 
    6.44          ERR("failed to allocate space for mmap entries!\n"); 
    6.45          return NULL; 
    6.46      } 
    6.47  
    6.48 -
    6.49      ioctlx.num   = m2p_chunks;
    6.50      ioctlx.dom   = DOMID_XEN; 
    6.51      ioctlx.entry = entries; 
    6.52      
    6.53 -    for(i=0; i < m2p_chunks; i++) { 
    6.54 -        
    6.55 +    for (i=0; i < m2p_chunks; i++) { 
    6.56          entries[i].va = (unsigned long)(((void *)m2p) + (i * M2P_CHUNK_SIZE)); 
    6.57 -        entries[i].mfn = m2p_mfns.arr[i]; 
    6.58 +        entries[i].mfn = xmml.extent_start[i];
    6.59          entries[i].npages = M2P_CHUNK_SIZE >> PAGE_SHIFT;
    6.60 -
    6.61      }
    6.62  
    6.63 -    if((rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx)) < 0) {
    6.64 +    if ((rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx)) < 0) {
    6.65          ERR("ioctl_mmap failed (rc = %d)", rc); 
    6.66          return NULL; 
    6.67      }
    6.68 -        
    6.69 -    free(m2p_mfns.arr); 
    6.70 +
    6.71 +    free(xmml.extent_start);
    6.72      free(entries); 
    6.73  
    6.74      return m2p; 
     7.1 --- a/tools/libxc/xc_private.c	Sat Nov 26 01:13:51 2005 +0000
     7.2 +++ b/tools/libxc/xc_private.c	Sat Nov 26 01:21:55 2005 +0000
     7.3 @@ -190,6 +190,7 @@ int xc_memory_op(int xc_handle,
     7.4  {
     7.5      DECLARE_HYPERCALL;
     7.6      struct xen_memory_reservation *reservation = arg;
     7.7 +    struct xen_machphys_mfn_list *xmml = arg;
     7.8      long ret = -EINVAL;
     7.9  
    7.10      hypercall.op     = __HYPERVISOR_memory_op;
    7.11 @@ -214,6 +215,20 @@ int xc_memory_op(int xc_handle,
    7.12              goto out1;
    7.13          }
    7.14          break;
    7.15 +    case XENMEM_machphys_mfn_list:
    7.16 +        if ( mlock(xmml, sizeof(*xmml)) != 0 )
    7.17 +        {
    7.18 +            PERROR("Could not mlock");
    7.19 +            goto out1;
    7.20 +        }
    7.21 +        if ( mlock(xmml->extent_start,
    7.22 +                   xmml->max_extents * sizeof(unsigned long)) != 0 )
    7.23 +        {
    7.24 +            PERROR("Could not mlock");
    7.25 +            safe_munlock(xmml, sizeof(*xmml));
    7.26 +            goto out1;
    7.27 +        }
    7.28 +        break;
    7.29      }
    7.30  
    7.31      ret = do_xen_hypercall(xc_handle, &hypercall);
    7.32 @@ -227,6 +242,11 @@ int xc_memory_op(int xc_handle,
    7.33              safe_munlock(reservation->extent_start,
    7.34                           reservation->nr_extents * sizeof(unsigned long));
    7.35          break;
    7.36 +    case XENMEM_machphys_mfn_list:
    7.37 +        safe_munlock(xmml, sizeof(*xmml));
    7.38 +        safe_munlock(xmml->extent_start,
    7.39 +                     xmml->max_extents * sizeof(unsigned long));
    7.40 +        break;
    7.41      }
    7.42  
    7.43   out1:
     8.1 --- a/tools/xm-test/configure.ac	Sat Nov 26 01:13:51 2005 +0000
     8.2 +++ b/tools/xm-test/configure.ac	Sat Nov 26 01:21:55 2005 +0000
     8.3 @@ -35,6 +35,7 @@ AC_CONFIG_FILES([
     8.4      Makefile 
     8.5      ramdisk/Makefile
     8.6      tests/Makefile
     8.7 +    tests/_sanity/Makefile
     8.8      tests/block-list/Makefile
     8.9      tests/block-create/Makefile
    8.10      tests/block-destroy/Makefile
     9.1 --- a/tools/xm-test/runtest.sh	Sat Nov 26 01:13:51 2005 +0000
     9.2 +++ b/tools/xm-test/runtest.sh	Sat Nov 26 01:21:55 2005 +0000
     9.3 @@ -14,6 +14,7 @@ usage() {
     9.4      echo "  -q          : run a quick test set"
     9.5      echo "  -e <email>  : set email address for report"
     9.6      echo "  -s <report> : just submit report <report>"
     9.7 +    echo "  -h | --help : show this help"
     9.8  }
     9.9  
    9.10  # Just submit the report
    9.11 @@ -86,6 +87,15 @@ runnable_tests() {
    9.12  	exit 1
    9.13      fi
    9.14  
    9.15 +    # Run a few sample tests to make sure things are working
    9.16 +    # before we take the plunge
    9.17 +    echo "Running sanity checks..."
    9.18 +    make -C tests/_sanity check 2>&1 | grep REASON
    9.19 +    if [ $? -eq 0 ]; then
    9.20 +	echo "Sanity checks failed"
    9.21 +	exit 1
    9.22 +    fi
    9.23 +
    9.24  }
    9.25  
    9.26  # Get contact info if needed
    9.27 @@ -119,7 +129,7 @@ get_contact_info() {
    9.28  # Run the tests
    9.29  run_tests() {
    9.30      output=$1
    9.31 -    echo Running tests...
    9.32 +    echo Running real tests...
    9.33      TEST_VERBOSE=1 make -k check > $output 2>&1
    9.34  }
    9.35  
    9.36 @@ -209,6 +219,10 @@ while [ $# -gt 0 ]
    9.37        -s)
    9.38  	  run=no
    9.39  	  ;;
    9.40 +      -h|--help)
    9.41 +          usage
    9.42 +          exit 0
    9.43 +          ;;
    9.44        *)
    9.45  	  REPORT=$1
    9.46  	  break
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/xm-test/tests/_sanity/01_domu_proc.py	Sat Nov 26 01:21:55 2005 +0000
    10.3 @@ -0,0 +1,34 @@
    10.4 +#!/usr/bin/python
    10.5 +
    10.6 +# Copyright (C) International Business Machines Corp., 2005
    10.7 +# Author: Dan Smith <danms@us.ibm.com>
    10.8 +
    10.9 +#
   10.10 +# Test that the library and ramdisk are working to the point
   10.11 +# that we can start a DomU and read /proc
   10.12 +#
   10.13 +
   10.14 +from XmTestLib import *
   10.15 +
   10.16 +import re
   10.17 +
   10.18 +domain = XmTestDomain()
   10.19 +
   10.20 +try:
   10.21 +    domain.start()
   10.22 +except DomainError, e:
   10.23 +    FAIL(str(e))
   10.24 +
   10.25 +try:
   10.26 +    console = XmConsole(domain.getName())
   10.27 +    console.sendInput("foo")
   10.28 +    run = console.runCmd("cat /proc/cpuinfo")
   10.29 +except ConsoleError, e:
   10.30 +    FAIL(str(e))
   10.31 +
   10.32 +if run["return"] != 0:
   10.33 +    FAIL("Unable to read /proc/cpuinfo")
   10.34 +
   10.35 +if not re.search("processor", run["output"]):
   10.36 +    print run["output"]
   10.37 +    FAIL("/proc/cpuinfo looks wrong!")
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/xm-test/tests/_sanity/Makefile.am	Sat Nov 26 01:21:55 2005 +0000
    11.3 @@ -0,0 +1,21 @@
    11.4 +
    11.5 +SUBDIRS =
    11.6 +
    11.7 +TESTS = 01_domu_proc.test 
    11.8 +
    11.9 +XFAIL_TESTS = 
   11.10 +
   11.11 +EXTRA_DIST = $(TESTS) $(XFAIL_TESTS)
   11.12 +
   11.13 +TESTS_ENVIRONMENT=@TENV@
   11.14 +
   11.15 +%.test: %.py
   11.16 +	cp $< $@
   11.17 +	chmod +x $@
   11.18 +
   11.19 +clean-local: am_config_clean-local
   11.20 +
   11.21 +am_config_clean-local:
   11.22 +	rm -f *test
   11.23 +	rm -f *log
   11.24 +	rm -f *~
    12.1 --- a/tools/xm-test/tests/network-attach/network_utils.py	Sat Nov 26 01:13:51 2005 +0000
    12.2 +++ b/tools/xm-test/tests/network-attach/network_utils.py	Sat Nov 26 01:21:55 2005 +0000
    12.3 @@ -10,7 +10,7 @@ def count_eth(console):
    12.4          run = console.runCmd("ifconfig -a | grep eth")
    12.5      except ConsoleError, e:
    12.6          FAIL(str(e))
    12.7 -    return = len(run['output'].splitlines())
    12.8 +    return len(run['output'].splitlines())
    12.9  
   12.10  def network_attach(domain_name, console):
   12.11      eths_before = count_eth(console)
    13.1 --- a/xen/arch/x86/shadow32.c	Sat Nov 26 01:13:51 2005 +0000
    13.2 +++ b/xen/arch/x86/shadow32.c	Sat Nov 26 01:21:55 2005 +0000
    13.3 @@ -800,13 +800,10 @@ void free_monitor_pagetable(struct vcpu 
    13.4  
    13.5      /*
    13.6       * Then free monitor_table.
    13.7 -     * Note: for VMX guest, only BSP need do this free.
    13.8       */
    13.9 -    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
   13.10 -        mfn = pagetable_get_pfn(v->arch.monitor_table);
   13.11 -        unmap_domain_page(v->arch.monitor_vtable);
   13.12 -        free_domheap_page(&frame_table[mfn]);
   13.13 -    }
   13.14 +    mfn = pagetable_get_pfn(v->arch.monitor_table);
   13.15 +    unmap_domain_page(v->arch.monitor_vtable);
   13.16 +    free_domheap_page(&frame_table[mfn]);
   13.17  
   13.18      v->arch.monitor_table = mk_pagetable(0);
   13.19      v->arch.monitor_vtable = 0;
    14.1 --- a/xen/arch/x86/shadow_public.c	Sat Nov 26 01:13:51 2005 +0000
    14.2 +++ b/xen/arch/x86/shadow_public.c	Sat Nov 26 01:21:55 2005 +0000
    14.3 @@ -297,13 +297,11 @@ void free_monitor_pagetable(struct vcpu 
    14.4  
    14.5      /*
    14.6       * free monitor_table.
    14.7 -     * Note: for VMX guest, only BSP need do this free.
    14.8       */
    14.9 -    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
   14.10 -        mfn = pagetable_get_pfn(v->arch.monitor_table);
   14.11 -        unmap_domain_page(v->arch.monitor_vtable);
   14.12 -        free_domheap_page(&frame_table[mfn]);
   14.13 -    }
   14.14 +    mfn = pagetable_get_pfn(v->arch.monitor_table);
   14.15 +    unmap_domain_page(v->arch.monitor_vtable);
   14.16 +    free_domheap_page(&frame_table[mfn]);
   14.17 +
   14.18      v->arch.monitor_table = mk_pagetable(0);
   14.19      v->arch.monitor_vtable = 0;
   14.20  }
   14.21 @@ -396,18 +394,15 @@ void free_monitor_pagetable(struct vcpu 
   14.22  
   14.23      /*
   14.24       * Then free monitor_table.
   14.25 -     * Note: for VMX guest, only BSP need do this free.
   14.26       */
   14.27 -    if (!(VMX_DOMAIN(v) && v->vcpu_id)) {
   14.28 -        mfn = pagetable_get_pfn(v->arch.monitor_table);
   14.29 -        unmap_domain_page(v->arch.monitor_vtable);
   14.30 -        free_domheap_page(&frame_table[mfn]);
   14.31 -    }
   14.32 +    mfn = pagetable_get_pfn(v->arch.monitor_table);
   14.33 +    unmap_domain_page(v->arch.monitor_vtable);
   14.34 +    free_domheap_page(&frame_table[mfn]);
   14.35  
   14.36      v->arch.monitor_table = mk_pagetable(0);
   14.37      v->arch.monitor_vtable = 0;
   14.38  }
   14.39 -#endif 
   14.40 +#endif
   14.41  
   14.42  static void
   14.43  shadow_free_snapshot(struct domain *d, struct out_of_sync_entry *entry)
    15.1 --- a/xen/arch/x86/x86_32/mm.c	Sat Nov 26 01:13:51 2005 +0000
    15.2 +++ b/xen/arch/x86/x86_32/mm.c	Sat Nov 26 01:21:55 2005 +0000
    15.3 @@ -27,6 +27,7 @@
    15.4  #include <asm/page.h>
    15.5  #include <asm/flushtlb.h>
    15.6  #include <asm/fixmap.h>
    15.7 +#include <public/memory.h>
    15.8  
    15.9  extern l1_pgentry_t *mapcache;
   15.10  
   15.11 @@ -184,6 +185,41 @@ void subarch_init_memory(struct domain *
   15.12      }
   15.13  }
   15.14  
   15.15 +long arch_memory_op(int op, void *arg)
   15.16 +{
   15.17 +    struct xen_machphys_mfn_list xmml;
   15.18 +    unsigned long mfn;
   15.19 +    unsigned int i, max;
   15.20 +    long rc = 0;
   15.21 +
   15.22 +    switch ( op )
   15.23 +    {
   15.24 +    case XENMEM_machphys_mfn_list:
   15.25 +        if ( copy_from_user(&xmml, arg, sizeof(xmml)) )
   15.26 +            return -EFAULT;
   15.27 +
   15.28 +        max = min_t(unsigned int, xmml.max_extents, mpt_size >> 21);
   15.29 +
   15.30 +        for ( i = 0; i < max; i++ )
   15.31 +        {
   15.32 +            mfn = l2e_get_pfn(idle_pg_table_l2[l2_linear_offset(
   15.33 +                RDWR_MPT_VIRT_START + (i << 21))]) + l1_table_offset(i << 21);
   15.34 +            if ( put_user(mfn, &xmml.extent_start[i]) )
   15.35 +                return -EFAULT;
   15.36 +        }
   15.37 +
   15.38 +        if ( put_user(i, &((struct xen_machphys_mfn_list *)arg)->nr_extents) )
   15.39 +            return -EFAULT;
   15.40 +
   15.41 +        break;
   15.42 +
   15.43 +    default:
   15.44 +        rc = -ENOSYS;
   15.45 +        break;
   15.46 +    }
   15.47 +
   15.48 +    return rc;
   15.49 +}
   15.50  
   15.51  long do_stack_switch(unsigned long ss, unsigned long esp)
   15.52  {
    16.1 --- a/xen/arch/x86/x86_64/mm.c	Sat Nov 26 01:13:51 2005 +0000
    16.2 +++ b/xen/arch/x86/x86_64/mm.c	Sat Nov 26 01:21:55 2005 +0000
    16.3 @@ -28,6 +28,7 @@
    16.4  #include <asm/flushtlb.h>
    16.5  #include <asm/fixmap.h>
    16.6  #include <asm/msr.h>
    16.7 +#include <public/memory.h>
    16.8  
    16.9  struct pfn_info *alloc_xen_pagetable(void)
   16.10  {
   16.11 @@ -174,6 +175,51 @@ void subarch_init_memory(struct domain *
   16.12      }
   16.13  }
   16.14  
   16.15 +long arch_memory_op(int op, void *arg)
   16.16 +{
   16.17 +    struct xen_machphys_mfn_list xmml;
   16.18 +    l3_pgentry_t l3e;
   16.19 +    l2_pgentry_t l2e;
   16.20 +    unsigned long mfn, v;
   16.21 +    unsigned int i;
   16.22 +    long rc = 0;
   16.23 +
   16.24 +    switch ( op )
   16.25 +    {
   16.26 +    case XENMEM_machphys_mfn_list:
   16.27 +        if ( copy_from_user(&xmml, arg, sizeof(xmml)) )
   16.28 +            return -EFAULT;
   16.29 +
   16.30 +        for ( v = RDWR_MPT_VIRT_START; v != RDWR_MPT_VIRT_END; v += 1 << 21 )
   16.31 +        {
   16.32 +            l3e = l4e_to_l3e(idle_pg_table[l4_table_offset(v)])[
   16.33 +                l3_table_offset(v)];
   16.34 +            if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
   16.35 +                break;
   16.36 +            l2e = l3e_to_l2e(l3e)[l2_table_offset(v)];
   16.37 +            if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
   16.38 +                break;
   16.39 +            mfn = l2e_get_pfn(l2e) + l1_table_offset(v);
   16.40 +            if ( i == xmml.max_extents )
   16.41 +                break;
   16.42 +            if ( put_user(mfn, &xmml.extent_start[i]) )
   16.43 +                return -EFAULT;
   16.44 +            i++;
   16.45 +        }
   16.46 +
   16.47 +        if ( put_user(i, &((struct xen_machphys_mfn_list *)arg)->nr_extents) )
   16.48 +            return -EFAULT;
   16.49 +
   16.50 +        break;
   16.51 +
   16.52 +    default:
   16.53 +        rc = -ENOSYS;
   16.54 +        break;
   16.55 +    }
   16.56 +
   16.57 +    return rc;
   16.58 +}
   16.59 +
   16.60  long do_stack_switch(unsigned long ss, unsigned long esp)
   16.61  {
   16.62      if ( (ss & 3) != 3 )
    17.1 --- a/xen/common/memory.c	Sat Nov 26 01:13:51 2005 +0000
    17.2 +++ b/xen/common/memory.c	Sat Nov 26 01:21:55 2005 +0000
    17.3 @@ -215,7 +215,7 @@ long do_memory_op(int cmd, void *arg)
    17.4          break;
    17.5  
    17.6      default:
    17.7 -        rc = -ENOSYS;
    17.8 +        rc = arch_memory_op(op, arg);
    17.9          break;
   17.10      }
   17.11  
    18.1 --- a/xen/include/asm-ia64/mm.h	Sat Nov 26 01:13:51 2005 +0000
    18.2 +++ b/xen/include/asm-ia64/mm.h	Sat Nov 26 01:21:55 2005 +0000
    18.3 @@ -440,4 +440,7 @@ extern unsigned long lookup_domain_mpa(s
    18.4  #define __gpa_to_mpa(_d, gpa)   \
    18.5      ((__gpfn_to_mfn((_d),(gpa)>>PAGE_SHIFT)<<PAGE_SHIFT)|((gpa)&~PAGE_MASK))
    18.6  
    18.7 +/* Arch-specific portion of memory_op hypercall. */
    18.8 +#define arch_memory_op(op, arg) (-ENOSYS)
    18.9 +
   18.10  #endif /* __ASM_IA64_MM_H__ */
    19.1 --- a/xen/include/asm-x86/mm.h	Sat Nov 26 01:13:51 2005 +0000
    19.2 +++ b/xen/include/asm-x86/mm.h	Sat Nov 26 01:21:55 2005 +0000
    19.3 @@ -379,6 +379,9 @@ int new_guest_cr3(unsigned long pfn);
    19.4  
    19.5  void propagate_page_fault(unsigned long addr, u16 error_code);
    19.6  
    19.7 -extern int __sync_lazy_execstate(void);
    19.8 +int __sync_lazy_execstate(void);
    19.9 +
   19.10 +/* Arch-specific portion of memory_op hypercall. */
   19.11 +long arch_memory_op(int op, void *arg);
   19.12  
   19.13  #endif /* __ASM_X86_MM_H__ */
    20.1 --- a/xen/include/public/memory.h	Sat Nov 26 01:13:51 2005 +0000
    20.2 +++ b/xen/include/public/memory.h	Sat Nov 26 01:21:55 2005 +0000
    20.3 @@ -60,6 +60,34 @@ typedef struct xen_memory_reservation {
    20.4  #define XENMEM_current_reservation  3
    20.5  #define XENMEM_maximum_reservation  4
    20.6  
    20.7 +/*
    20.8 + * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
    20.9 + * mapping table. Architectures which do not have a m2p table do not implement
   20.10 + * this command.
   20.11 + * arg == addr of xen_machphys_mfn_list_t.
   20.12 + */
   20.13 +#define XENMEM_machphys_mfn_list    5
   20.14 +typedef struct xen_machphys_mfn_list {
   20.15 +    /*
   20.16 +     * Size of the 'extent_start' array. Fewer entries will be filled if the
   20.17 +     * machphys table is smaller than max_extents * 2MB.
   20.18 +     */
   20.19 +    unsigned int max_extents;
   20.20 +    
   20.21 +    /*
   20.22 +     * Pointer to buffer to fill with list of extent starts. If there are
   20.23 +     * any large discontiguities in the machine address space, 2MB gaps in
   20.24 +     * the machphys table will be represented by an MFN base of zero.
   20.25 +     */
   20.26 +    unsigned long *extent_start;
   20.27 +
   20.28 +    /*
   20.29 +     * Number of extents written to the above array. This will be smaller
   20.30 +     * than 'max_extents' if the machphys table is smaller than max_e * 2MB.
   20.31 +     */
   20.32 +    unsigned int nr_extents;
   20.33 +} xen_machphys_mfn_list_t;
   20.34 +
   20.35  #endif /* __XEN_PUBLIC_MEMORY_H__ */
   20.36  
   20.37  /*