ia64/xen-unstable

changeset 14725:2bbd28891160

Initial check-in to support PV balloon driver within HVM guests.
Still todo:

- fix mapcache invalidation (should happen in Xen)
- support 32-on-64 mode correctly

Signed-off-by: Steven Hand <steven@xensource.com>
author Steven Hand <steven@xensource.com>
date Wed Apr 04 19:59:10 2007 +0100 (2007-04-04)
parents b3c75956303b
children f4318c89291a
files linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c linux-2.6-xen-sparse/drivers/xen/core/gnttab.c linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c unmodified_drivers/linux-2.6/Makefile unmodified_drivers/linux-2.6/balloon/Kbuild unmodified_drivers/linux-2.6/balloon/Makefile unmodified_drivers/linux-2.6/mkbuildtree unmodified_drivers/linux-2.6/platform-pci/xen_support.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/irq.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/common/memory.c xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/support.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Wed Apr 04 19:17:39 2007 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c	Wed Apr 04 19:59:10 2007 +0100
     1.3 @@ -48,14 +48,21 @@
     1.4  #include <asm/hypervisor.h>
     1.5  #include <xen/balloon.h>
     1.6  #include <xen/interface/memory.h>
     1.7 +#include <asm/maddr.h>
     1.8 +#include <asm/page.h>
     1.9  #include <asm/pgalloc.h>
    1.10  #include <asm/pgtable.h>
    1.11  #include <asm/uaccess.h>
    1.12  #include <asm/tlb.h>
    1.13 +#include <linux/highmem.h>
    1.14  #include <linux/list.h>
    1.15  #include <xen/xenbus.h>
    1.16  #include "common.h"
    1.17  
    1.18 +#ifndef CONFIG_XEN 
    1.19 +#define scrub_pages(_p,_n)
    1.20 +#endif
    1.21 +
    1.22  #ifdef CONFIG_PROC_FS
    1.23  static struct proc_dir_entry *balloon_pde;
    1.24  #endif
    1.25 @@ -217,6 +224,7 @@ static int increase_reservation(unsigned
    1.26  
    1.27  		set_phys_to_machine(pfn, frame_list[i]);
    1.28  
    1.29 +#ifdef CONFIG_XEN
    1.30  		/* Link back into the page tables if not highmem. */
    1.31  		if (pfn < max_low_pfn) {
    1.32  			int ret;
    1.33 @@ -226,6 +234,7 @@ static int increase_reservation(unsigned
    1.34  				0);
    1.35  			BUG_ON(ret);
    1.36  		}
    1.37 +#endif
    1.38  
    1.39  		/* Relinquish the page back to the allocator. */
    1.40  		ClearPageReserved(page);
    1.41 @@ -242,6 +251,8 @@ static int increase_reservation(unsigned
    1.42  	return 0;
    1.43  }
    1.44  
    1.45 +extern void xen_invalidate_foreign_mappings(void);
    1.46 +
    1.47  static int decrease_reservation(unsigned long nr_pages)
    1.48  {
    1.49  	unsigned long  pfn, i, flags;
    1.50 @@ -275,7 +286,7 @@ static int decrease_reservation(unsigned
    1.51  				(unsigned long)v, __pte_ma(0), 0);
    1.52  			BUG_ON(ret);
    1.53  		}
    1.54 -#ifdef CONFIG_XEN_SCRUB_PAGES
    1.55 +#ifdef CONFIG_XEN
    1.56  		else {
    1.57  			v = kmap(page);
    1.58  			scrub_pages(v, 1);
    1.59 @@ -284,19 +295,24 @@ static int decrease_reservation(unsigned
    1.60  #endif
    1.61  	}
    1.62  
    1.63 +#ifdef CONFIG_XEN
    1.64  	/* Ensure that ballooned highmem pages don't have kmaps. */
    1.65  	kmap_flush_unused();
    1.66  	flush_tlb_all();
    1.67 +#endif
    1.68  
    1.69  	balloon_lock(flags);
    1.70  
    1.71  	/* No more mappings: invalidate P2M and add to balloon. */
    1.72  	for (i = 0; i < nr_pages; i++) {
    1.73  		pfn = mfn_to_pfn(frame_list[i]);
    1.74 +#ifdef CONFIG_XEN
    1.75  		set_phys_to_machine(pfn, INVALID_P2M_ENTRY);
    1.76 +#endif
    1.77  		balloon_append(pfn_to_page(pfn));
    1.78  	}
    1.79  
    1.80 +        xen_invalidate_foreign_mappings(); 
    1.81  	set_xen_guest_handle(reservation.extent_start, frame_list);
    1.82  	reservation.nr_extents   = nr_pages;
    1.83  	ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation);
    1.84 @@ -446,7 +462,7 @@ static struct notifier_block xenstore_no
    1.85  
    1.86  static int __init balloon_init(void)
    1.87  {
    1.88 -#ifdef CONFIG_X86
    1.89 +#if defined(CONFIG_X86) && defined(CONFIG_XEN) 
    1.90  	unsigned long pfn;
    1.91  	struct page *page;
    1.92  #endif
    1.93 @@ -456,8 +472,12 @@ static int __init balloon_init(void)
    1.94  
    1.95  	IPRINTK("Initialising balloon driver.\n");
    1.96  
    1.97 +#ifdef CONFIG_XEN
    1.98  	bs.current_pages = min(xen_start_info->nr_pages, max_pfn);
    1.99  	totalram_pages   = bs.current_pages;
   1.100 +#else 
   1.101 +        bs.current_pages = totalram_pages; 
   1.102 +#endif
   1.103  	bs.target_pages  = bs.current_pages;
   1.104  	bs.balloon_low   = 0;
   1.105  	bs.balloon_high  = 0;
   1.106 @@ -479,7 +499,7 @@ static int __init balloon_init(void)
   1.107  #endif
   1.108  	balloon_sysfs_init();
   1.109  
   1.110 -#ifdef CONFIG_X86
   1.111 +#if defined(CONFIG_X86) && defined(CONFIG_XEN) 
   1.112  	/* Initialise the balloon with excess memory space. */
   1.113  	for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) {
   1.114  		page = pfn_to_page(pfn);
   1.115 @@ -498,6 +518,14 @@ static int __init balloon_init(void)
   1.116  
   1.117  subsys_initcall(balloon_init);
   1.118  
   1.119 +static void balloon_exit(void) 
   1.120 +{
   1.121 +    /* XXX - release balloon here */
   1.122 +    return; 
   1.123 +}
   1.124 +
   1.125 +module_exit(balloon_exit); 
   1.126 +
   1.127  void balloon_update_driver_allowance(long delta)
   1.128  {
   1.129  	unsigned long flags;
   1.130 @@ -507,6 +535,7 @@ void balloon_update_driver_allowance(lon
   1.131  	balloon_unlock(flags);
   1.132  }
   1.133  
   1.134 +#ifdef CONFIG_XEN
   1.135  static int dealloc_pte_fn(
   1.136  	pte_t *pte, struct page *pmd_page, unsigned long addr, void *data)
   1.137  {
   1.138 @@ -524,6 +553,7 @@ static int dealloc_pte_fn(
   1.139  	BUG_ON(ret != 1);
   1.140  	return 0;
   1.141  }
   1.142 +#endif
   1.143  
   1.144  struct page **alloc_empty_pages_and_pagevec(int nr_pages)
   1.145  {
   1.146 @@ -559,8 +589,13 @@ struct page **alloc_empty_pages_and_page
   1.147  			if (ret == 1)
   1.148  				ret = 0; /* success */
   1.149  		} else {
   1.150 +#ifdef CONFIG_XEN
   1.151  			ret = apply_to_page_range(&init_mm, vaddr, PAGE_SIZE,
   1.152  						  dealloc_pte_fn, NULL);
   1.153 +#else 
   1.154 +                        /* cannot handle non-auto translate mode */
   1.155 +                        ret = 1; 
   1.156 +#endif
   1.157  		}
   1.158  
   1.159  		if (ret != 0) {
   1.160 @@ -576,7 +611,9 @@ struct page **alloc_empty_pages_and_page
   1.161  
   1.162   out:
   1.163  	schedule_work(&balloon_worker);
   1.164 +#ifdef CONFIG_XEN
   1.165  	flush_tlb_all();
   1.166 +#endif
   1.167  	return pagevec;
   1.168  
   1.169   err:
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c	Wed Apr 04 19:17:39 2007 +0100
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/sysfs.c	Wed Apr 04 19:59:10 2007 +0100
     2.3 @@ -29,6 +29,7 @@
     2.4   */
     2.5  
     2.6  #include <linux/capability.h>
     2.7 +#include <linux/errno.h>
     2.8  #include <linux/stat.h>
     2.9  #include <linux/sysdev.h>
    2.10  #include "common.h"
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Wed Apr 04 19:17:39 2007 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c	Wed Apr 04 19:59:10 2007 +0100
     3.3 @@ -407,11 +407,13 @@ grow_nomem:
     3.4  static unsigned int __max_nr_grant_frames(void)
     3.5  {
     3.6  	struct gnttab_query_size query;
     3.7 -	int rc;
     3.8 +	int rc = -1;
     3.9  
    3.10  	query.dom = DOMID_SELF;
    3.11  
    3.12 +#ifdef CONFIG_XEN
    3.13  	rc = HYPERVISOR_grant_table_op(GNTTABOP_query_size, &query, 1);
    3.14 +#endif
    3.15  	if ((rc < 0) || (query.status != GNTST_okay))
    3.16  		return 4; /* Legacy max supported number of frames */
    3.17  
     4.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c	Wed Apr 04 19:17:39 2007 +0100
     4.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/xen_proc.c	Wed Apr 04 19:59:10 2007 +0100
     4.3 @@ -1,4 +1,5 @@
     4.4  
     4.5 +#include <linux/module.h>
     4.6  #include <linux/proc_fs.h>
     4.7  #include <xen/xen_proc.h>
     4.8  
     4.9 @@ -12,7 +13,11 @@ struct proc_dir_entry *create_xen_proc_e
    4.10  	return create_proc_entry(name, mode, xen_base);
    4.11  }
    4.12  
    4.13 +EXPORT_SYMBOL_GPL(create_xen_proc_entry); 
    4.14 +
    4.15  void remove_xen_proc_entry(const char *name)
    4.16  {
    4.17  	remove_proc_entry(name, xen_base);
    4.18  }
    4.19 +
    4.20 +EXPORT_SYMBOL_GPL(remove_xen_proc_entry); 
     5.1 --- a/unmodified_drivers/linux-2.6/Makefile	Wed Apr 04 19:17:39 2007 +0100
     5.2 +++ b/unmodified_drivers/linux-2.6/Makefile	Wed Apr 04 19:59:10 2007 +0100
     5.3 @@ -2,6 +2,7 @@ include $(M)/overrides.mk
     5.4  
     5.5  obj-m += platform-pci/
     5.6  obj-m += xenbus/
     5.7 +obj-m += balloon/
     5.8  obj-m += blkfront/
     5.9  obj-m += netfront/
    5.10  obj-m += util/
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/unmodified_drivers/linux-2.6/balloon/Kbuild	Wed Apr 04 19:59:10 2007 +0100
     6.3 @@ -0,0 +1,9 @@
     6.4 +include $(M)/overrides.mk
     6.5 +
     6.6 +obj-m  = xen-balloon.o
     6.7 +
     6.8 +EXTRA_CFLAGS += -I$(M)/platform-pci
     6.9 +
    6.10 +xen-balloon-objs =
    6.11 +xen-balloon-objs += balloon.o
    6.12 +xen-balloon-objs += sysfs.o
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/unmodified_drivers/linux-2.6/balloon/Makefile	Wed Apr 04 19:59:10 2007 +0100
     7.3 @@ -0,0 +1,3 @@
     7.4 +ifneq ($(KERNELRELEASE),)
     7.5 +include $(src)/Kbuild
     7.6 +endif
     8.1 --- a/unmodified_drivers/linux-2.6/mkbuildtree	Wed Apr 04 19:17:39 2007 +0100
     8.2 +++ b/unmodified_drivers/linux-2.6/mkbuildtree	Wed Apr 04 19:59:10 2007 +0100
     8.3 @@ -17,6 +17,9 @@ for d in $(find ${XL}/drivers/xen/ -maxd
     8.4      if ! echo $d | egrep -q back; then
     8.5          lndir $d $(basename $d) > /dev/null 2>&1
     8.6      fi
     8.7 +    if ! echo $d | egrep -q ball; then
     8.8 +        lndir $d $(basename $d) > /dev/null 2>&1
     8.9 +    fi
    8.10  done
    8.11  
    8.12  ln -sf ${XL}/drivers/xen/core/gnttab.c platform-pci
    8.13 @@ -47,6 +50,7 @@ i[34567]86)
    8.14      ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypercall.h include/asm
    8.15      ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm
    8.16      ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm
    8.17 +    ln -sf ${XL}/include/asm-i386/mach-xen/asm/page.h include/asm
    8.18    ;;
    8.19  "ia64")
    8.20      ln -sf ${XL}/include/asm-ia64/hypervisor.h include/asm
     9.1 --- a/unmodified_drivers/linux-2.6/platform-pci/xen_support.c	Wed Apr 04 19:17:39 2007 +0100
     9.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/xen_support.c	Wed Apr 04 19:59:10 2007 +0100
     9.3 @@ -59,12 +59,3 @@ void xen_machphys_update(unsigned long m
     9.4  }
     9.5  EXPORT_SYMBOL(xen_machphys_update);
     9.6  
     9.7 -void balloon_update_driver_allowance(long delta)
     9.8 -{
     9.9 -}
    9.10 -EXPORT_SYMBOL(balloon_update_driver_allowance);
    9.11 -
    9.12 -void balloon_release_driver_page(struct page *page)
    9.13 -{
    9.14 -}
    9.15 -EXPORT_SYMBOL(balloon_release_driver_page);
    10.1 --- a/xen/arch/x86/hvm/hvm.c	Wed Apr 04 19:17:39 2007 +0100
    10.2 +++ b/xen/arch/x86/hvm/hvm.c	Wed Apr 04 19:59:10 2007 +0100
    10.3 @@ -521,12 +521,12 @@ static hvm_hypercall_t *hvm_hypercall_ta
    10.4      HYPERCALL(hvm_op)
    10.5  };
    10.6  
    10.7 -void hvm_do_hypercall(struct cpu_user_regs *pregs)
    10.8 +int hvm_do_hypercall(struct cpu_user_regs *pregs)
    10.9  {
   10.10      if ( unlikely(ring_3(pregs)) )
   10.11      {
   10.12          pregs->eax = -EPERM;
   10.13 -        return;
   10.14 +        return 0;
   10.15      }
   10.16  
   10.17      if ( (pregs->eax >= NR_hypercalls) || !hvm_hypercall_table[pregs->eax] )
   10.18 @@ -535,11 +535,21 @@ void hvm_do_hypercall(struct cpu_user_re
   10.19                  current->domain->domain_id, current->vcpu_id,
   10.20                  pregs->eax);
   10.21          pregs->eax = -ENOSYS;
   10.22 -        return;
   10.23 +        return 0;
   10.24      }
   10.25  
   10.26 +    /* Install a canary value in regs->eip so can check for continuation */
   10.27 +    pregs->eip |= 0xF; 
   10.28 +
   10.29      pregs->eax = hvm_hypercall_table[pregs->eax](
   10.30          pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi);
   10.31 +
   10.32 +    /* XXX: pot fake IO instr here to inform the emulator to flush mapcache */
   10.33 +
   10.34 +    if( (pregs->eip & 0xF) == 0 ) /* preempted */
   10.35 +        return 1; 
   10.36 +
   10.37 +    return 0; 
   10.38  }
   10.39  
   10.40  #else /* defined(__x86_64__) */
   10.41 @@ -599,12 +609,12 @@ static hvm_hypercall_t *hvm_hypercall32_
   10.42      HYPERCALL(event_channel_op)
   10.43  };
   10.44  
   10.45 -void hvm_do_hypercall(struct cpu_user_regs *pregs)
   10.46 +int hvm_do_hypercall(struct cpu_user_regs *pregs)
   10.47  {
   10.48      if ( unlikely(ring_3(pregs)) )
   10.49      {
   10.50          pregs->rax = -EPERM;
   10.51 -        return;
   10.52 +        return 0;
   10.53      }
   10.54  
   10.55      pregs->rax = (uint32_t)pregs->eax; /* mask in case compat32 caller */
   10.56 @@ -614,7 +624,7 @@ void hvm_do_hypercall(struct cpu_user_re
   10.57                  current->domain->domain_id, current->vcpu_id,
   10.58                  pregs->rax);
   10.59          pregs->rax = -ENOSYS;
   10.60 -        return;
   10.61 +        return 0;
   10.62      }
   10.63  
   10.64      if ( current->arch.paging.mode->guest_levels == 4 )
   10.65 @@ -633,6 +643,7 @@ void hvm_do_hypercall(struct cpu_user_re
   10.66                                                         (uint32_t)pregs->esi,
   10.67                                                         (uint32_t)pregs->edi);
   10.68      }
   10.69 +    return 0; /* XXX SMH: fix for preempt here */
   10.70  }
   10.71  
   10.72  #endif /* defined(__x86_64__) */
    11.1 --- a/xen/arch/x86/hvm/irq.c	Wed Apr 04 19:17:39 2007 +0100
    11.2 +++ b/xen/arch/x86/hvm/irq.c	Wed Apr 04 19:59:10 2007 +0100
    11.3 @@ -347,11 +347,7 @@ int hvm_local_events_need_delivery(struc
    11.4  
    11.5      pending = (vcpu_info(v, evtchn_upcall_pending) || cpu_has_pending_irq(v));
    11.6      if ( unlikely(pending) )
    11.7 -    {
    11.8 -        struct cpu_user_regs regs;
    11.9 -        hvm_store_cpu_guest_regs(v, &regs, NULL);
   11.10 -        pending = !irq_masked(regs.eflags);
   11.11 -    }
   11.12 +        pending = hvm_interrupts_enabled(v); 
   11.13  
   11.14      return pending;
   11.15  }
    12.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Apr 04 19:17:39 2007 +0100
    12.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Wed Apr 04 19:59:10 2007 +0100
    12.3 @@ -498,6 +498,12 @@ static int svm_realmode(struct vcpu *v)
    12.4      return (eflags & X86_EFLAGS_VM) || !(cr0 & X86_CR0_PE);
    12.5  }
    12.6  
    12.7 +static int svm_interrupts_enabled(struct vcpu *v)
    12.8 +{
    12.9 +    unsigned long eflags = v->arch.hvm_svm.vmcb->rflags;
   12.10 +    return !irq_masked(eflags); 
   12.11 +}
   12.12 +
   12.13  static int svm_guest_x86_mode(struct vcpu *v)
   12.14  {
   12.15      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   12.16 @@ -800,6 +806,7 @@ static struct hvm_function_table svm_fun
   12.17      .paging_enabled       = svm_paging_enabled,
   12.18      .long_mode_enabled    = svm_long_mode_enabled,
   12.19      .pae_enabled          = svm_pae_enabled,
   12.20 +    .interrupts_enabled   = svm_interrupts_enabled,
   12.21      .guest_x86_mode       = svm_guest_x86_mode,
   12.22      .get_guest_ctrl_reg   = svm_get_ctrl_reg,
   12.23      .get_segment_base     = svm_get_segment_base,
   12.24 @@ -2268,8 +2275,8 @@ asmlinkage void svm_vmexit_handler(struc
   12.25          inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
   12.26          ASSERT(inst_len > 0);
   12.27          HVMTRACE_1D(VMMCALL, v, regs->eax);
   12.28 -        __update_guest_eip(vmcb, inst_len);
   12.29 -        hvm_do_hypercall(regs);
   12.30 +        if(hvm_do_hypercall(regs) == 0) /* not preempted */
   12.31 +            __update_guest_eip(vmcb, inst_len);
   12.32          break;
   12.33  
   12.34      case VMEXIT_CR0_READ:
    13.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Wed Apr 04 19:17:39 2007 +0100
    13.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Wed Apr 04 19:59:10 2007 +0100
    13.3 @@ -957,6 +957,13 @@ static int vmx_pae_enabled(struct vcpu *
    13.4      return (vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE));
    13.5  }
    13.6  
    13.7 +static int vmx_interrupts_enabled(struct vcpu *v) 
    13.8 +{
    13.9 +    unsigned long eflags = __vmread(GUEST_RFLAGS); 
   13.10 +    return !irq_masked(eflags); 
   13.11 +}
   13.12 +
   13.13 +
   13.14  static void vmx_update_host_cr3(struct vcpu *v)
   13.15  {
   13.16      ASSERT( (v == current) || !vcpu_runnable(v) );
   13.17 @@ -1030,6 +1037,7 @@ static struct hvm_function_table vmx_fun
   13.18      .paging_enabled       = vmx_paging_enabled,
   13.19      .long_mode_enabled    = vmx_long_mode_enabled,
   13.20      .pae_enabled          = vmx_pae_enabled,
   13.21 +    .interrupts_enabled   = vmx_interrupts_enabled,
   13.22      .guest_x86_mode       = vmx_guest_x86_mode,
   13.23      .get_guest_ctrl_reg   = vmx_get_ctrl_reg,
   13.24      .get_segment_base     = vmx_get_segment_base,
   13.25 @@ -2620,8 +2628,8 @@ asmlinkage void vmx_vmexit_handler(struc
   13.26      {
   13.27          HVMTRACE_1D(VMMCALL, v, regs->eax);
   13.28          inst_len = __get_instruction_length(); /* Safe: VMCALL */
   13.29 -        __update_guest_eip(inst_len);
   13.30 -        hvm_do_hypercall(regs);
   13.31 +        if(hvm_do_hypercall(regs) == 0)        /* not preempted */
   13.32 +            __update_guest_eip(inst_len);
   13.33          break;
   13.34      }
   13.35      case EXIT_REASON_CR_ACCESS:
    14.1 --- a/xen/common/memory.c	Wed Apr 04 19:17:39 2007 +0100
    14.2 +++ b/xen/common/memory.c	Wed Apr 04 19:59:10 2007 +0100
    14.3 @@ -176,12 +176,7 @@ int guest_remove_page(struct domain *d, 
    14.4      if ( unlikely((page->count_info & PGC_count_mask) != 1) )
    14.5      {
    14.6          shadow_drop_references(d, page);
    14.7 -        /* We'll make this a guest-visible error in future, so take heed! */
    14.8 -        if ( (page->count_info & PGC_count_mask) != 1 )
    14.9 -            gdprintk(XENLOG_INFO, "Dom%d freeing in-use page %lx "
   14.10 -                     "(pseudophys %lx): count=%lx type=%lx\n",
   14.11 -                     d->domain_id, mfn, get_gpfn_from_mfn(mfn),
   14.12 -                     (unsigned long)page->count_info, page->u.inuse.type_info);
   14.13 +        /* NB: still may have foreign references to the page at this stage */
   14.14      }
   14.15  
   14.16      guest_physmap_remove_page(d, gmfn, mfn);
    15.1 --- a/xen/include/asm-x86/hvm/hvm.h	Wed Apr 04 19:17:39 2007 +0100
    15.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Wed Apr 04 19:59:10 2007 +0100
    15.3 @@ -93,13 +93,15 @@ struct hvm_function_table {
    15.4       * 1) determine whether paging is enabled,
    15.5       * 2) determine whether long mode is enabled,
    15.6       * 3) determine whether PAE paging is enabled,
    15.7 -     * 4) determine the mode the guest is running in,
    15.8 -     * 5) return the current guest control-register value
    15.9 -     * 6) return the current guest segment descriptor base
   15.10 +     * 4) determine whether interrupts are enabled or not,
   15.11 +     * 5) determine the mode the guest is running in,
   15.12 +     * 6) return the current guest control-register value
   15.13 +     * 7) return the current guest segment descriptor base
   15.14       */
   15.15      int (*paging_enabled)(struct vcpu *v);
   15.16      int (*long_mode_enabled)(struct vcpu *v);
   15.17      int (*pae_enabled)(struct vcpu *v);
   15.18 +    int (*interrupts_enabled)(struct vcpu *v);
   15.19      int (*guest_x86_mode)(struct vcpu *v);
   15.20      unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);
   15.21      unsigned long (*get_segment_base)(struct vcpu *v, enum x86_segment seg);
   15.22 @@ -190,6 +192,12 @@ hvm_pae_enabled(struct vcpu *v)
   15.23  }
   15.24  
   15.25  static inline int
   15.26 +hvm_interrupts_enabled(struct vcpu *v)
   15.27 +{
   15.28 +    return hvm_funcs.interrupts_enabled(v);
   15.29 +}
   15.30 +
   15.31 +static inline int
   15.32  hvm_guest_x86_mode(struct vcpu *v)
   15.33  {
   15.34      return hvm_funcs.guest_x86_mode(v);
    16.1 --- a/xen/include/asm-x86/hvm/support.h	Wed Apr 04 19:17:39 2007 +0100
    16.2 +++ b/xen/include/asm-x86/hvm/support.h	Wed Apr 04 19:59:10 2007 +0100
    16.3 @@ -228,7 +228,7 @@ int hvm_copy_from_guest_virt(void *buf, 
    16.4  void hvm_print_line(struct vcpu *v, const char c);
    16.5  void hlt_timer_fn(void *data);
    16.6  
    16.7 -void hvm_do_hypercall(struct cpu_user_regs *pregs);
    16.8 +int hvm_do_hypercall(struct cpu_user_regs *pregs);
    16.9  
   16.10  void hvm_hlt(unsigned long rflags);
   16.11  void hvm_triple_fault(void);