[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg (staging)



# HG changeset patch
# User Alex Williamson <alex.williamson@xxxxxx>
# Date 1194472128 25200
# Node ID a1247c2df2b41d7959c1626833c2a149dd705640
# Parent  ef6415fdaf8a026aa6cba380b01152dc96cac449
# Parent  d4c5a1cdcf2e6e9c98c99d218f8b80f8baca10cd
merge with xen-unstable.hg (staging)
---
 tools/examples/block                   |    5 +
 tools/examples/network-bridge          |    4 -
 tools/ioemu/hw/pass-through.c          |   15 ++--
 tools/ioemu/hw/pass-through.h          |    2 
 tools/ioemu/hw/xen_machine_fv.c        |   45 +++++-------
 xen/arch/ia64/xen/mm.c                 |    8 --
 xen/arch/x86/domain.c                  |   23 +++---
 xen/arch/x86/hvm/irq.c                 |   13 +--
 xen/arch/x86/hvm/vmx/intr.c            |   17 +++-
 xen/arch/x86/hvm/vmx/vtd/intel-iommu.c |    9 +-
 xen/arch/x86/hvm/vmx/vtd/io.c          |  121 ++++++++++++++++++++++-----------
 xen/arch/x86/hvm/vmx/vtd/utils.c       |   15 ++--
 xen/arch/x86/hvm/vpt.c                 |    2 
 xen/arch/x86/mm.c                      |   71 ++++++++++++++++---
 xen/arch/x86/mm/shadow/multi.c         |   12 +--
 xen/arch/x86/traps.c                   |    3 
 xen/common/grant_table.c               |    6 -
 xen/include/asm-ia64/mm.h              |    3 
 xen/include/asm-x86/domain.h           |    7 +
 xen/include/asm-x86/hvm/irq.h          |   29 +++++--
 xen/include/asm-x86/mm.h               |   28 ++++---
 xen/include/asm-x86/page.h             |   10 ++
 22 files changed, 289 insertions(+), 159 deletions(-)

diff -r ef6415fdaf8a -r a1247c2df2b4 tools/examples/block
--- a/tools/examples/block      Wed Nov 07 11:01:23 2007 -0700
+++ b/tools/examples/block      Wed Nov 07 14:48:48 2007 -0700
@@ -326,7 +326,10 @@ mount it read-write in a guest domain."
           fatal 'Failed to find an unused loop device'
         fi
 
-        do_or_die losetup "$loopdev" "$file"
+        status=$(losetup "$loopdev" "$file" || echo "failed")
+        if [ -n "$status" ]; then
+          do_or_die losetup -r "$loopdev" "$file"
+        fi
         xenstore_write "$XENBUS_PATH/node" "$loopdev"
         write_dev "$loopdev"
         release_lock "block"
diff -r ef6415fdaf8a -r a1247c2df2b4 tools/examples/network-bridge
--- a/tools/examples/network-bridge     Wed Nov 07 11:01:23 2007 -0700
+++ b/tools/examples/network-bridge     Wed Nov 07 14:48:48 2007 -0700
@@ -72,8 +72,8 @@ find_alt_device () {
     echo "$ifs"
 }
 
-netdev=${netdev:-$(ip route list | awk '/^default / { print $NF }' |
-                  sed 's/.* dev //')}
+netdev=${netdev:-$(ip route list 0.0.0.0/0  | \
+                   sed 's/.*dev \([a-z]\+[0-9]\+\).*$/\1/')}
 if is_network_root ; then
     altdevs=$(find_alt_device $netdev)
     for netdev in $altdevs; do break; done
diff -r ef6415fdaf8a -r a1247c2df2b4 tools/ioemu/hw/pass-through.c
--- a/tools/ioemu/hw/pass-through.c     Wed Nov 07 11:01:23 2007 -0700
+++ b/tools/ioemu/hw/pass-through.c     Wed Nov 07 14:48:48 2007 -0700
@@ -20,8 +20,8 @@
  * Guy Zana <guy@xxxxxxxxxxxx>
  *
  * This file implements direct PCI assignment to a HVM guest
- *
  */
+
 #include "vl.h"
 #include "pass-through.h"
 #include "pci/header.h"
@@ -127,9 +127,10 @@ void pt_iomem_map(PCIDevice *d, int i, u
     if ( !first_map )
     {
         /* Remove old mapping */
-        ret = xc_domain_memory_mapping(xc_handle, domid, old_ebase >> 12,
-                assigned_device->bases[i].access.maddr >> 12,
-                (e_size+0xFFF) >> 12,
+        ret = xc_domain_memory_mapping(xc_handle, domid,
+                old_ebase >> XC_PAGE_SHIFT,
+                assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT,
+                (e_size+XC_PAGE_MASK) >> XC_PAGE_SHIFT,
                 DPCI_REMOVE_MAPPING);
         if ( ret != 0 )
         {
@@ -140,9 +141,9 @@ void pt_iomem_map(PCIDevice *d, int i, u
 
     /* Create new mapping */
     ret = xc_domain_memory_mapping(xc_handle, domid,
-            assigned_device->bases[i].e_physbase >> 12,
-            assigned_device->bases[i].access.maddr >> 12,
-            (e_size+0xFFF) >> 12,
+            assigned_device->bases[i].e_physbase >> XC_PAGE_SHIFT,
+            assigned_device->bases[i].access.maddr >> XC_PAGE_SHIFT,
+            (e_size+XC_PAGE_MASK) >> XC_PAGE_SHIFT,
             DPCI_ADD_MAPPING);
     if ( ret != 0 )
         PT_LOG("Error: create new mapping failed!\n");
diff -r ef6415fdaf8a -r a1247c2df2b4 tools/ioemu/hw/pass-through.h
--- a/tools/ioemu/hw/pass-through.h     Wed Nov 07 11:01:23 2007 -0700
+++ b/tools/ioemu/hw/pass-through.h     Wed Nov 07 14:48:48 2007 -0700
@@ -40,7 +40,7 @@
 /* Misc PCI constants that should be moved to a separate library :) */
 #define PCI_CONFIG_SIZE         (256)
 #define PCI_EXP_DEVCAP_FLR      (1 << 28)
-#define PCI_EXP_DEVCTL_FLR      (0x1b)
+#define PCI_EXP_DEVCTL_FLR      (1 << 15)
 #define PCI_BAR_ENTRIES         (6)
 
 struct pt_region {
diff -r ef6415fdaf8a -r a1247c2df2b4 tools/ioemu/hw/xen_machine_fv.c
--- a/tools/ioemu/hw/xen_machine_fv.c   Wed Nov 07 11:01:23 2007 -0700
+++ b/tools/ioemu/hw/xen_machine_fv.c   Wed Nov 07 14:48:48 2007 -0700
@@ -27,13 +27,6 @@
 #include <xen/hvm/params.h>
 #include <sys/mman.h>
 
-#ifndef PAGE_SIZE
-#define PAGE_SIZE XC_PAGE_SIZE
-#endif
-#ifndef PAGE_SHIFT
-#define PAGE_SHIFT XC_PAGE_SHIFT
-#endif
-
 #if defined(MAPCACHE)
 
 #if defined(__i386__) 
@@ -57,7 +50,7 @@ struct map_cache {
 struct map_cache {
     unsigned long paddr_index;
     uint8_t      *vaddr_base;
-    DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE>>PAGE_SHIFT);
+    DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE>>XC_PAGE_SHIFT);
 };
 
 static struct map_cache *mapcache_entry;
@@ -71,9 +64,9 @@ static int qemu_map_cache_init(void)
 {
     unsigned long size;
 
-    nr_buckets = (((MAX_MCACHE_SIZE >> PAGE_SHIFT) +
-                   (1UL << (MCACHE_BUCKET_SHIFT - PAGE_SHIFT)) - 1) >>
-                  (MCACHE_BUCKET_SHIFT - PAGE_SHIFT));
+    nr_buckets = (((MAX_MCACHE_SIZE >> XC_PAGE_SHIFT) +
+                   (1UL << (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT)) - 1) >>
+                  (MCACHE_BUCKET_SHIFT - XC_PAGE_SHIFT));
 
     /*
      * Use mmap() directly: lets us allocate a big hash table with no up-front
@@ -81,7 +74,7 @@ static int qemu_map_cache_init(void)
      * that we actually use. All others will contain all zeroes.
      */
     size = nr_buckets * sizeof(struct map_cache);
-    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+    size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
     fprintf(logfile, "qemu_map_cache_init nr_buckets = %lx size %lu\n", 
nr_buckets, size);
     mapcache_entry = mmap(NULL, size, PROT_READ|PROT_WRITE,
                           MAP_SHARED|MAP_ANON, -1, 0);
@@ -97,7 +90,7 @@ static void qemu_remap_bucket(struct map
                               unsigned long address_index)
 {
     uint8_t *vaddr_base;
-    unsigned long pfns[MCACHE_BUCKET_SIZE >> PAGE_SHIFT];
+    unsigned long pfns[MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT];
     unsigned int i, j;
 
     if (entry->vaddr_base != NULL) {
@@ -108,11 +101,11 @@ static void qemu_remap_bucket(struct map
         }
     }
 
-    for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i++)
-        pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-PAGE_SHIFT)) + i;
+    for (i = 0; i < MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT; i++)
+        pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
 
     vaddr_base = xc_map_foreign_batch(xc_handle, domid, PROT_READ|PROT_WRITE,
-                                      pfns, MCACHE_BUCKET_SIZE >> PAGE_SHIFT);
+                                      pfns, MCACHE_BUCKET_SIZE >> 
XC_PAGE_SHIFT);
     if (vaddr_base == NULL) {
         fprintf(logfile, "xc_map_foreign_batch error %d\n", errno);
         exit(-1);
@@ -121,10 +114,10 @@ static void qemu_remap_bucket(struct map
     entry->vaddr_base  = vaddr_base;
     entry->paddr_index = address_index;
 
-    for (i = 0; i < MCACHE_BUCKET_SIZE >> PAGE_SHIFT; i += BITS_PER_LONG) {
+    for (i = 0; i < MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT; i += BITS_PER_LONG) {
         unsigned long word = 0;
-        j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> PAGE_SHIFT)) ?
-            (MCACHE_BUCKET_SIZE >> PAGE_SHIFT) % BITS_PER_LONG : BITS_PER_LONG;
+        j = ((i + BITS_PER_LONG) > (MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT)) ?
+            (MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT) % BITS_PER_LONG : 
BITS_PER_LONG;
         while (j > 0)
             word = (word << 1) | (((pfns[i + --j] >> 28) & 0xf) != 0xf);
         entry->valid_mapping[i / BITS_PER_LONG] = word;
@@ -143,10 +136,10 @@ uint8_t *qemu_map_cache(target_phys_addr
     entry = &mapcache_entry[address_index % nr_buckets];
 
     if (entry->vaddr_base == NULL || entry->paddr_index != address_index ||
-        !test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
+        !test_bit(address_offset>>XC_PAGE_SHIFT, entry->valid_mapping))
         qemu_remap_bucket(entry, address_index);
 
-    if (!test_bit(address_offset>>PAGE_SHIFT, entry->valid_mapping))
+    if (!test_bit(address_offset>>XC_PAGE_SHIFT, entry->valid_mapping))
         return NULL;
 
     last_address_index = address_index;
@@ -213,7 +206,7 @@ static void xen_init_fv(uint64_t ram_siz
 
     xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn);
     fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn);
-    shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+    shared_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
                                        PROT_READ|PROT_WRITE, ioreq_pfn);
     if (shared_page == NULL) {
         fprintf(logfile, "map shared IO page returned error %d\n", errno);
@@ -222,7 +215,7 @@ static void xen_init_fv(uint64_t ram_siz
 
     xc_get_hvm_param(xc_handle, domid, HVM_PARAM_BUFIOREQ_PFN, &ioreq_pfn);
     fprintf(logfile, "buffered io page at pfn %lx\n", ioreq_pfn);
-    buffered_io_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
+    buffered_io_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE,
                                             PROT_READ|PROT_WRITE, ioreq_pfn);
     if (buffered_io_page == NULL) {
         fprintf(logfile, "map buffered IO page returned error %d\n", errno);
@@ -272,9 +265,9 @@ static void xen_init_fv(uint64_t ram_siz
     /* VTI will not use memory between 3G~4G, so we just pass a legal pfn
        to make QEMU map continuous virtual memory space */
     if (ram_size > MMIO_START) {       
-        for (i = 0 ; i < (MEM_G >> PAGE_SHIFT); i++)
-            page_array[(MMIO_START >> PAGE_SHIFT) + i] =
-                (STORE_PAGE_START >> PAGE_SHIFT); 
+        for (i = 0 ; i < (MEM_G >> XC_PAGE_SHIFT); i++)
+            page_array[(MMIO_START >> XC_PAGE_SHIFT) + i] =
+                (STORE_XC_PAGE_START >> XC_PAGE_SHIFT); 
     }
 
     phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/ia64/xen/mm.c    Wed Nov 07 14:48:48 2007 -0700
@@ -2894,11 +2894,9 @@ arch_memory_op(int op, XEN_GUEST_HANDLE(
     return 0;
 }
 
-int
-iomem_page_test(unsigned long mfn, struct page_info *page)
-{
-       return unlikely(!mfn_valid(mfn)) ||
-              unlikely(page_get_owner(page) == dom_io);
+int is_iomem_page(unsigned long mfn)
+{
+    return (!mfn_valid(mfn) || (page_get_owner(mfn_to_page(mfn)) == dom_io));
 }
 
 /*
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/domain.c     Wed Nov 07 14:48:48 2007 -0700
@@ -415,7 +415,8 @@ int vcpu_initialise(struct vcpu *v)
             v->arch.cr3           = __pa(idle_pg_table);
         }
 
-        v->arch.guest_context.ctrlreg[4] = mmu_cr4_features;
+        v->arch.guest_context.ctrlreg[4] =
+            real_cr4_to_pv_guest_cr4(mmu_cr4_features);
     }
 
     v->arch.perdomain_ptes =
@@ -573,17 +574,18 @@ void arch_domain_destroy(struct domain *
 
 unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4)
 {
-    unsigned long hv_cr4 = read_cr4(), hv_cr4_mask = ~X86_CR4_TSD;
+    unsigned long hv_cr4_mask, hv_cr4 = real_cr4_to_pv_guest_cr4(read_cr4());
+
+    hv_cr4_mask = ~X86_CR4_TSD;
     if ( cpu_has_de )
         hv_cr4_mask &= ~X86_CR4_DE;
 
-    if ( (guest_cr4 & hv_cr4_mask) !=
-         (hv_cr4 & hv_cr4_mask & ~(X86_CR4_PGE|X86_CR4_PSE)) )
+    if ( (guest_cr4 & hv_cr4_mask) != (hv_cr4 & hv_cr4_mask) )
         gdprintk(XENLOG_WARNING,
                  "Attempt to change CR4 flags %08lx -> %08lx\n",
                  hv_cr4 & ~(X86_CR4_PGE|X86_CR4_PSE), guest_cr4);
 
-    return  (hv_cr4 & hv_cr4_mask) | (guest_cr4 & ~hv_cr4_mask);
+    return (hv_cr4 & hv_cr4_mask) | (guest_cr4 & ~hv_cr4_mask);
 }
 
 /* This is called by arch_final_setup_guest and do_boot_vcpu */
@@ -684,8 +686,8 @@ int arch_set_info_guest(
     v->arch.guest_context.user_regs.eflags |= EF_IE;
 
     cr4 = v->arch.guest_context.ctrlreg[4];
-    v->arch.guest_context.ctrlreg[4] =
-        (cr4 == 0) ? mmu_cr4_features : pv_guest_cr4_fixup(cr4);
+    v->arch.guest_context.ctrlreg[4] = cr4 ? pv_guest_cr4_fixup(cr4) :
+        real_cr4_to_pv_guest_cr4(mmu_cr4_features);
 
     memset(v->arch.guest_context.debugreg, 0,
            sizeof(v->arch.guest_context.debugreg));
@@ -1223,11 +1225,14 @@ static void paravirt_ctxt_switch_from(st
 
 static void paravirt_ctxt_switch_to(struct vcpu *v)
 {
+    unsigned long cr4;
+
     set_int80_direct_trap(v);
     switch_kernel_stack(v);
 
-    if ( unlikely(read_cr4() != v->arch.guest_context.ctrlreg[4]) )
-        write_cr4(v->arch.guest_context.ctrlreg[4]);
+    cr4 = pv_guest_cr4_to_real_cr4(v->arch.guest_context.ctrlreg[4]);
+    if ( unlikely(cr4 != read_cr4()) )
+        write_cr4(cr4);
 
     if ( unlikely(v->arch.guest_context.debugreg[7]) )
     {
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c    Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/hvm/irq.c    Wed Nov 07 14:48:48 2007 -0700
@@ -192,15 +192,12 @@ void hvm_set_pci_link_route(struct domai
     hvm_irq->pci_link.route[link] = isa_irq;
 
     /* PCI pass-through fixup. */
-    if ( hvm_irq->dpci && hvm_irq->dpci->girq[old_isa_irq].valid )
-    {
-        uint32_t device = hvm_irq->dpci->girq[old_isa_irq].device;
-        uint32_t intx = hvm_irq->dpci->girq[old_isa_irq].intx;
-        if ( link == hvm_pci_intx_link(device, intx) )
-        {
-            hvm_irq->dpci->girq[isa_irq] = hvm_irq->dpci->girq[old_isa_irq];
+    if ( hvm_irq->dpci && hvm_irq->dpci->link[link].valid )
+    {
+        hvm_irq->dpci->girq[isa_irq] = hvm_irq->dpci->link[link];
+        if ( hvm_irq->dpci->girq[old_isa_irq].device ==
+             hvm_irq->dpci->link[link].device )
             hvm_irq->dpci->girq[old_isa_irq].valid = 0;
-        }
     }
 
     if ( hvm_irq->pci_link_assert_count[link] == 0 )
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/hvm/vmx/intr.c
--- a/xen/arch/x86/hvm/vmx/intr.c       Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/hvm/vmx/intr.c       Wed Nov 07 14:48:48 2007 -0700
@@ -113,6 +113,7 @@ static void vmx_dirq_assist(struct vcpu 
     uint32_t device, intx;
     struct domain *d = v->domain;
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
+    struct dev_intx_gsi *dig;
 
     if ( !vtd_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
         return;
@@ -122,11 +123,17 @@ static void vmx_dirq_assist(struct vcpu 
           irq = find_next_bit(hvm_irq_dpci->dirq_mask, NR_IRQS, irq + 1) )
     {
         stop_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(irq)]);
-
-        test_and_clear_bit(irq, &hvm_irq_dpci->dirq_mask);
-        device = hvm_irq_dpci->mirq[irq].device;
-        intx = hvm_irq_dpci->mirq[irq].intx;
-        hvm_pci_intx_assert(d, device, intx);
+        clear_bit(irq, &hvm_irq_dpci->dirq_mask);
+
+        list_for_each_entry ( dig, &hvm_irq_dpci->mirq[irq].dig_list, list )
+        {
+            device = dig->device;
+            intx = dig->intx;
+            hvm_pci_intx_assert(d, device, intx);
+            spin_lock(&hvm_irq_dpci->dirq_lock);
+            hvm_irq_dpci->mirq[irq].pending++;
+            spin_unlock(&hvm_irq_dpci->dirq_lock);
+        }
 
         /*
          * Set a timer to see if the guest can finish the interrupt or not. For
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
--- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c    Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c    Wed Nov 07 14:48:48 2007 -0700
@@ -688,6 +688,9 @@ static int iommu_enable_translation(stru
             break;
         cpu_relax();
     }
+
+    /* Disable PMRs when VT-d engine takes effect per spec definition */
+    disable_pmr(iommu);
     spin_unlock_irqrestore(&iommu->register_lock, flags);
     return 0;
 }
@@ -1767,7 +1770,7 @@ int iommu_setup(void)
     struct hvm_iommu *hd  = domain_hvm_iommu(dom0);
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
-    unsigned long i, status;
+    unsigned long i;
 
     if ( !vtd_enabled )
         return 0;
@@ -1796,10 +1799,6 @@ int iommu_setup(void)
     setup_dom0_rmrr();
     if ( enable_vtd_translation() )
         goto error;
-
-    status = dmar_readl(iommu->reg, DMAR_PMEN_REG);
-    if (status & DMA_PMEN_PRS)
-        disable_pmr(iommu);
 
     return 0;
 
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/hvm/vmx/vtd/io.c
--- a/xen/arch/x86/hvm/vmx/vtd/io.c     Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/hvm/vmx/vtd/io.c     Wed Nov 07 14:48:48 2007 -0700
@@ -47,14 +47,27 @@
 
 static void pt_irq_time_out(void *data)
 {
-    struct hvm_irq_dpci_mapping *irq_map = data;
-    unsigned int guest_gsi, machine_gsi;
-    struct domain *d = irq_map->dom;
-
-    guest_gsi = irq_map->guest_gsi;
-    machine_gsi = d->arch.hvm_domain.irq.dpci->girq[guest_gsi].machine_gsi;
-    clear_bit(machine_gsi, d->arch.hvm_domain.irq.dpci->dirq_mask);
-    hvm_dpci_eoi(irq_map->dom, guest_gsi, NULL);
+    struct hvm_mirq_dpci_mapping *irq_map = data;
+    unsigned int guest_gsi, machine_gsi = 0;
+    struct hvm_irq_dpci *dpci = irq_map->dom->arch.hvm_domain.irq.dpci;
+    struct dev_intx_gsi *dig;
+    uint32_t device, intx;
+
+    list_for_each_entry ( dig, &irq_map->dig_list, list )
+    {
+        guest_gsi = dig->gsi;
+        machine_gsi = dpci->girq[guest_gsi].machine_gsi;
+        device = dig->device;
+        intx = dig->intx;
+        hvm_pci_intx_deassert(irq_map->dom, device, intx);
+    }
+
+    clear_bit(machine_gsi, dpci->dirq_mask);
+    stop_timer(&dpci->hvm_timer[irq_to_vector(machine_gsi)]);
+    spin_lock(&dpci->dirq_lock);
+    dpci->mirq[machine_gsi].pending = 0;
+    spin_unlock(&dpci->dirq_lock);
+    pirq_guest_eoi(irq_map->dom, machine_gsi);
 }
 
 int pt_irq_create_bind_vtd(
@@ -62,8 +75,8 @@ int pt_irq_create_bind_vtd(
 {
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t machine_gsi, guest_gsi;
-    uint32_t device, intx;
-    uint32_t link, isa_irq;
+    uint32_t device, intx, link;
+    struct dev_intx_gsi *dig;
 
     if ( hvm_irq_dpci == NULL )
     {
@@ -72,6 +85,9 @@ int pt_irq_create_bind_vtd(
             return -ENOMEM;
 
         memset(hvm_irq_dpci, 0, sizeof(*hvm_irq_dpci));
+        spin_lock_init(&hvm_irq_dpci->dirq_lock);
+        for ( int i = 0; i < NR_IRQS; i++ )
+            INIT_LIST_HEAD(&hvm_irq_dpci->mirq[i].dig_list);
 
         if ( cmpxchg((unsigned long *)&d->arch.hvm_domain.irq.dpci,
                      0, (unsigned long)hvm_irq_dpci) != 0 )
@@ -85,35 +101,42 @@ int pt_irq_create_bind_vtd(
     intx = pt_irq_bind->u.pci.intx;
     guest_gsi = hvm_pci_intx_gsi(device, intx);
     link = hvm_pci_intx_link(device, intx);
-    isa_irq = d->arch.hvm_domain.irq.pci_link.route[link];
-
-    hvm_irq_dpci->mirq[machine_gsi].valid = 1;
-    hvm_irq_dpci->mirq[machine_gsi].device = device;
-    hvm_irq_dpci->mirq[machine_gsi].intx = intx;
-    hvm_irq_dpci->mirq[machine_gsi].guest_gsi = guest_gsi;
-    hvm_irq_dpci->mirq[machine_gsi].dom = d;
-
+
+    dig = xmalloc(struct dev_intx_gsi);
+    if ( !dig )
+        return -ENOMEM;
+
+    dig->device = device;
+    dig->intx = intx;
+    dig->gsi = guest_gsi;
+    list_add_tail(&dig->list,
+                  &hvm_irq_dpci->mirq[machine_gsi].dig_list);
+ 
     hvm_irq_dpci->girq[guest_gsi].valid = 1;
     hvm_irq_dpci->girq[guest_gsi].device = device;
     hvm_irq_dpci->girq[guest_gsi].intx = intx;
     hvm_irq_dpci->girq[guest_gsi].machine_gsi = machine_gsi;
-    hvm_irq_dpci->girq[guest_gsi].dom = d;
-
-    hvm_irq_dpci->girq[isa_irq].valid = 1;
-    hvm_irq_dpci->girq[isa_irq].device = device;
-    hvm_irq_dpci->girq[isa_irq].intx = intx;
-    hvm_irq_dpci->girq[isa_irq].machine_gsi = machine_gsi;
-    hvm_irq_dpci->girq[isa_irq].dom = d;
-
-    init_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)],
-               pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], 0);
-
-    /* Deal with GSI for legacy devices. */
-    pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WILL_SHARE);
-    gdprintk(XENLOG_ERR,
-             "XEN_DOMCTL_irq_mapping: m_irq = %x device = %x intx = %x\n",
+
+    hvm_irq_dpci->link[link].valid = 1;
+    hvm_irq_dpci->link[link].device = device;
+    hvm_irq_dpci->link[link].intx = intx;
+    hvm_irq_dpci->link[link].machine_gsi = machine_gsi;
+
+    /* Bind the same mirq once in the same domain */
+    if ( !hvm_irq_dpci->mirq[machine_gsi].valid )
+    {
+        hvm_irq_dpci->mirq[machine_gsi].valid = 1;
+        hvm_irq_dpci->mirq[machine_gsi].dom = d;
+
+        init_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)],
+                   pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], 0);
+        /* Deal with gsi for legacy devices */
+        pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WILL_SHARE);
+    }
+
+    gdprintk(XENLOG_INFO,
+             "VT-d irq bind: m_irq = %x device = %x intx = %x\n",
              machine_gsi, device, intx);
-
     return 0;
 }
 
@@ -150,14 +173,22 @@ void hvm_dpci_eoi(struct domain *d, unsi
         return;
 
     machine_gsi = hvm_irq_dpci->girq[guest_gsi].machine_gsi;
-    stop_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)]);
     device = hvm_irq_dpci->girq[guest_gsi].device;
     intx = hvm_irq_dpci->girq[guest_gsi].intx;
-    gdprintk(XENLOG_INFO, "hvm_dpci_eoi:: device %x intx %x\n",
-             device, intx);
     hvm_pci_intx_deassert(d, device, intx);
-    if ( (ent == NULL) || !ent->fields.mask )
-        pirq_guest_eoi(d, machine_gsi);
+ 
+    spin_lock(&hvm_irq_dpci->dirq_lock);
+    if ( --hvm_irq_dpci->mirq[machine_gsi].pending == 0 )
+    {
+        spin_unlock(&hvm_irq_dpci->dirq_lock);
+
+        gdprintk(XENLOG_INFO, "hvm_dpci_eoi:: mirq = %x\n", machine_gsi);
+        stop_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)]);
+        if ( (ent == NULL) || !ent->fields.mask )
+            pirq_guest_eoi(d, machine_gsi);
+    }
+    else
+        spin_unlock(&hvm_irq_dpci->dirq_lock);
 }
 
 void iommu_domain_destroy(struct domain *d)
@@ -165,8 +196,9 @@ void iommu_domain_destroy(struct domain 
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     uint32_t i;
     struct hvm_iommu *hd  = domain_hvm_iommu(d);
-    struct list_head *ioport_list, *tmp;
+    struct list_head *ioport_list, *dig_list, *tmp;
     struct g2m_ioport *ioport;
+    struct dev_intx_gsi *dig;
 
     if ( !vtd_enabled )
         return;
@@ -178,7 +210,16 @@ void iommu_domain_destroy(struct domain 
             {
                 pirq_guest_unbind(d, i);
                 kill_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(i)]);
+
+                list_for_each_safe ( dig_list, tmp,
+                                     &hvm_irq_dpci->mirq[i].dig_list )
+                {
+                    dig = list_entry(dig_list, struct dev_intx_gsi, list);
+                    list_del(&dig->list);
+                    xfree(dig);
+                }
             }
+
         d->arch.hvm_domain.irq.dpci = NULL;
         xfree(hvm_irq_dpci);
     }
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/hvm/vmx/vtd/utils.c
--- a/xen/arch/x86/hvm/vmx/vtd/utils.c  Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/hvm/vmx/vtd/utils.c  Wed Nov 07 14:48:48 2007 -0700
@@ -67,25 +67,30 @@ int vtd_hw_check(void)
 /* Disable vt-d protected memory registers. */
 void disable_pmr(struct iommu *iommu)
 {
-    unsigned long start_time, status;
+    unsigned long start_time;
     unsigned int val;
 
     val = dmar_readl(iommu->reg, DMAR_PMEN_REG);
+    if ( !(val & DMA_PMEN_PRS) )
+        return;
+
     dmar_writel(iommu->reg, DMAR_PMEN_REG, val & ~DMA_PMEN_EPM);
     start_time = jiffies;
 
     for ( ; ; )
     {
-        status = dmar_readl(iommu->reg, DMAR_PMEN_REG);
-        if ( (status & DMA_PMEN_PRS) == 0 )
+        val = dmar_readl(iommu->reg, DMAR_PMEN_REG);
+        if ( (val & DMA_PMEN_PRS) == 0 )
             break;
+
         if ( time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT) )
-            panic("Cannot set QIE field for queue invalidation\n");
+            panic("Disable PMRs timeout\n");
+
         cpu_relax();
     }
 
     dprintk(XENLOG_INFO VTDPREFIX,
-            "disabled protected memory registers\n");
+            "Disabled protected memory registers\n");
 }
 
 #if defined(__x86_64__)
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c    Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/hvm/vpt.c    Wed Nov 07 14:48:48 2007 -0700
@@ -59,7 +59,7 @@ static void pt_process_missed_ticks(stru
     if ( mode_is(pt->vcpu->domain, no_missed_tick_accounting) )
     {
         pt->pending_intr_nr = 1;
-        pt->scheduled = now + pt->scheduled;
+        pt->scheduled = now + pt->period;
     }
     else
     {
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/mm.c Wed Nov 07 14:48:48 2007 -0700
@@ -607,10 +607,9 @@ get_##level##_linear_pagetable(         
 }
 
 
-int iomem_page_test(unsigned long mfn, struct page_info *page)
-{
-    return unlikely(!mfn_valid(mfn)) ||
-        unlikely(page_get_owner(page) == dom_io);
+int is_iomem_page(unsigned long mfn)
+{
+    return (!mfn_valid(mfn) || (page_get_owner(mfn_to_page(mfn)) == dom_io));
 }
 
 
@@ -620,19 +619,19 @@ get_page_from_l1e(
 {
     unsigned long mfn = l1e_get_pfn(l1e);
     struct page_info *page = mfn_to_page(mfn);
+    uint32_t l1f = l1e_get_flags(l1e);
     int okay;
 
-    if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) )
+    if ( !(l1f & _PAGE_PRESENT) )
         return 1;
 
-    if ( unlikely(l1e_get_flags(l1e) & l1_disallow_mask(d)) )
-    {
-        MEM_LOG("Bad L1 flags %x",
-                l1e_get_flags(l1e) & l1_disallow_mask(d));
+    if ( unlikely(l1f & l1_disallow_mask(d)) )
+    {
+        MEM_LOG("Bad L1 flags %x", l1f & l1_disallow_mask(d));
         return 0;
     }
 
-    if ( iomem_page_test(mfn, page) )
+    if ( is_iomem_page(mfn) )
     {
         /* DOMID_IO reverts to caller for privilege checks. */
         if ( d == dom_io )
@@ -657,7 +656,7 @@ get_page_from_l1e(
      * contribute to writeable mapping refcounts.  (This allows the
      * qemu-dm helper process in dom0 to map the domain's memory without
      * messing up the count of "real" writable mappings.) */
-    okay = (((l1e_get_flags(l1e) & _PAGE_RW) && 
+    okay = (((l1f & _PAGE_RW) && 
              !(unlikely(paging_mode_external(d) && (d != current->domain))))
             ? get_page_and_type(page, d, PGT_writable_page)
             : get_page(page, d));
@@ -667,6 +666,36 @@ get_page_from_l1e(
                 " for dom%d",
                 mfn, get_gpfn_from_mfn(mfn),
                 l1e_get_intpte(l1e), d->domain_id);
+    }
+    else if ( (pte_flags_to_cacheattr(l1f) !=
+               ((page->count_info >> PGC_cacheattr_base) & 7)) &&
+              !is_iomem_page(mfn) )
+    {
+        uint32_t x, nx, y = page->count_info;
+        uint32_t cacheattr = pte_flags_to_cacheattr(l1f);
+
+        if ( is_xen_heap_frame(page) )
+        {
+            if ( (l1f & _PAGE_RW) &&
+                 !(unlikely(paging_mode_external(d) &&
+                            (d != current->domain))) )
+                put_page_type(page);
+            put_page(page);
+            MEM_LOG("Attempt to change cache attributes of Xen heap page");
+            return 0;
+        }
+
+        while ( ((y >> PGC_cacheattr_base) & 7) != cacheattr )
+        {
+            x  = y;
+            nx = (x & ~PGC_cacheattr_mask) | (cacheattr << PGC_cacheattr_base);
+            y  = cmpxchg(&page->count_info, x, nx);
+        }
+
+#ifdef __x86_64__
+        map_pages_to_xen((unsigned long)mfn_to_virt(mfn), mfn, 1,
+                         PAGE_HYPERVISOR | cacheattr_to_pte_flags(cacheattr));
+#endif
     }
 
     return okay;
@@ -1825,6 +1854,24 @@ int get_page_type(struct page_info *page
     }
 
     return 1;
+}
+
+
+void cleanup_page_cacheattr(struct page_info *page)
+{
+    uint32_t cacheattr = (page->count_info >> PGC_cacheattr_base) & 7;
+
+    if ( likely(cacheattr == 0) )
+        return;
+
+    page->count_info &= ~PGC_cacheattr_mask;
+
+    BUG_ON(is_xen_heap_frame(page));
+
+#ifdef __x86_64__
+    map_pages_to_xen((unsigned long)page_to_virt(page), page_to_mfn(page),
+                     1, PAGE_HYPERVISOR);
+#endif
 }
 
 
@@ -3803,7 +3850,7 @@ static void __memguard_change_range(void
 {
     unsigned long _p = (unsigned long)p;
     unsigned long _l = (unsigned long)l;
-    unsigned long flags = __PAGE_HYPERVISOR | MAP_SMALL_PAGES;
+    unsigned int flags = __PAGE_HYPERVISOR | MAP_SMALL_PAGES;
 
     /* Ensure we are dealing with a page-aligned whole number of pages. */
     ASSERT((_p&~PAGE_MASK) == 0);
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/mm/shadow/multi.c    Wed Nov 07 14:48:48 2007 -0700
@@ -716,12 +716,14 @@ _sh_propagate(struct vcpu *v,
         goto done;
     }
 
-    // Must have a valid target_mfn unless this is a prefetch.  In the
-    // case of a prefetch, an invalid mfn means that we can not usefully
-    // shadow anything, and so we return early.
+    // Must have a valid target_mfn unless this is a prefetch or an l1
+    // pointing at MMIO space.  In the case of a prefetch, an invalid
+    // mfn means that we can not usefully shadow anything, and so we
+    // return early.
     //
-    if ( shadow_mode_refcounts(d) && 
-         !mfn_valid(target_mfn) && (p2mt != p2m_mmio_direct) )
+    if ( !mfn_valid(target_mfn)
+         && !(level == 1 && (!shadow_mode_refcounts(d) 
+                             || p2mt == p2m_mmio_direct)) )
     {
         ASSERT((ft == ft_prefetch));
         *sp = shadow_l1e_empty();
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/arch/x86/traps.c      Wed Nov 07 14:48:48 2007 -0700
@@ -1797,7 +1797,8 @@ static int emulate_privileged_op(struct 
 
         case 4: /* Write CR4 */
             v->arch.guest_context.ctrlreg[4] = pv_guest_cr4_fixup(*reg);
-            write_cr4(v->arch.guest_context.ctrlreg[4]);
+            write_cr4(pv_guest_cr4_to_real_cr4(
+                v->arch.guest_context.ctrlreg[4]));
             break;
 
         default:
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/common/grant_table.c  Wed Nov 07 14:48:48 2007 -0700
@@ -332,7 +332,7 @@ __gnttab_map_grant_ref(
     if ( op->flags & GNTMAP_host_map ) 
     {
         /* Could be an iomem page for setting up permission */
-        if ( iomem_page_test(frame, mfn_to_page(frame)) )
+        if ( is_iomem_page(frame) )
         {
             is_iomem = 1;
             if ( iomem_permit_access(ld, frame, frame) )
@@ -527,7 +527,7 @@ __gnttab_unmap_common(
                                                   op->flags)) < 0 )
                 goto unmap_out;
         }
-        else if ( iomem_page_test(op->frame, mfn_to_page(op->frame)) &&
+        else if ( is_iomem_page(op->frame) &&
                   iomem_access_permitted(ld, op->frame, op->frame) )
         {
             if ( (rc = iomem_deny_access(ld, op->frame, op->frame)) < 0 )
@@ -1651,7 +1651,7 @@ gnttab_release_mappings(
                 BUG_ON(!(act->pin & GNTPIN_hstw_mask));
                 act->pin -= GNTPIN_hstw_inc;
 
-                if ( iomem_page_test(act->frame, mfn_to_page(act->frame)) &&
+                if ( is_iomem_page(act->frame) &&
                      iomem_access_permitted(rd, act->frame, act->frame) )
                     rc = iomem_deny_access(rd, act->frame, act->frame);
                 else 
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/include/asm-ia64/mm.h Wed Nov 07 14:48:48 2007 -0700
@@ -185,8 +185,7 @@ static inline int get_page(struct page_i
     return 1;
 }
 
-/* Decide whether this page looks like iomem or real memory */
-int iomem_page_test(unsigned long mfn, struct page_info *page);
+int is_iomem_page(unsigned long mfn);
 
 extern void put_page_type(struct page_info *page);
 extern int get_page_type(struct page_info *page, u32 type);
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/include/asm-x86/domain.h      Wed Nov 07 14:48:48 2007 -0700
@@ -350,7 +350,14 @@ struct arch_vcpu
 /* Continue the current hypercall via func(data) on specified cpu. */
 int continue_hypercall_on_cpu(int cpu, long (*func)(void *data), void *data);
 
+/* Clean up CR4 bits that are not under guest control. */
 unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4);
+
+/* Convert between guest-visible and real CR4 values. */
+#define pv_guest_cr4_to_real_cr4(c) \
+    ((c) | (mmu_cr4_features & (X86_CR4_PGE | X86_CR4_PSE)))
+#define real_cr4_to_pv_guest_cr4(c) \
+    ((c) & ~(X86_CR4_PGE | X86_CR4_PSE))
 
 #endif /* __ASM_DOMAIN_H__ */
 
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/include/asm-x86/hvm/irq.h
--- a/xen/include/asm-x86/hvm/irq.h     Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/include/asm-x86/hvm/irq.h     Wed Nov 07 14:48:48 2007 -0700
@@ -30,22 +30,35 @@
 #include <asm/hvm/vioapic.h>
 #include <public/hvm/save.h>
 
-struct hvm_irq_dpci_mapping {
+struct dev_intx_gsi {
+    struct list_head list;
+    uint8_t device;
+    uint8_t intx;
+    uint8_t gsi;
+};
+
+struct hvm_mirq_dpci_mapping {
+    uint8_t valid;
+    int pending;
+    struct list_head dig_list;
+    struct domain *dom;
+};
+
+struct hvm_girq_dpci_mapping {
     uint8_t valid;
     uint8_t device;
     uint8_t intx;
-    struct domain *dom;
-    union {
-        uint8_t guest_gsi;
-        uint8_t machine_gsi;
-    };
+    uint8_t machine_gsi;
 };
 
 struct hvm_irq_dpci {
+    spinlock_t dirq_lock;
     /* Machine IRQ to guest device/intx mapping. */
-    struct hvm_irq_dpci_mapping mirq[NR_IRQS];
+    struct hvm_mirq_dpci_mapping mirq[NR_IRQS];
     /* Guest IRQ to guest device/intx mapping. */
-    struct hvm_irq_dpci_mapping girq[NR_IRQS];
+    struct hvm_girq_dpci_mapping girq[NR_IRQS];
+    /* Link to guest device/intx mapping. */
+    struct hvm_girq_dpci_mapping link[4];
     DECLARE_BITMAP(dirq_mask, NR_IRQS);
     struct timer hvm_timer[NR_IRQS];
 };
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/include/asm-x86/mm.h  Wed Nov 07 14:48:48 2007 -0700
@@ -84,25 +84,23 @@ struct page_info
 #define _PGT_pae_xen_l2     26
 #define PGT_pae_xen_l2      (1U<<_PGT_pae_xen_l2)
 
- /* 16-bit count of uses of this frame as its current type. */
-#define PGT_count_mask      ((1U<<16)-1)
+ /* 26-bit count of uses of this frame as its current type. */
+#define PGT_count_mask      ((1U<<26)-1)
 
  /* Cleared when the owning guest 'frees' this page. */
 #define _PGC_allocated      31
 #define PGC_allocated       (1U<<_PGC_allocated)
  /* Set on a *guest* page to mark it out-of-sync with its shadow */
-#define _PGC_out_of_sync     30
+#define _PGC_out_of_sync    30
 #define PGC_out_of_sync     (1U<<_PGC_out_of_sync)
  /* Set when is using a page as a page table */
-#define _PGC_page_table      29
+#define _PGC_page_table     29
 #define PGC_page_table      (1U<<_PGC_page_table)
- /* 29-bit count of references to this frame. */
-#define PGC_count_mask      ((1U<<29)-1)
-
-/* We trust the slab allocator in slab.c, and our use of it. */
-#define PageSlab(page)     (1)
-#define PageSetSlab(page)   ((void)0)
-#define PageClearSlab(page) ((void)0)
+ /* 3-bit PAT/PCD/PWT cache-attribute hint. */
+#define PGC_cacheattr_base  26
+#define PGC_cacheattr_mask  (7U<<PGC_cacheattr_base)
+ /* 26-bit count of references to this frame. */
+#define PGC_count_mask      ((1U<<26)-1)
 
 #define is_xen_heap_frame(pfn) ({                                       \
     paddr_t maddr = page_to_maddr(pfn);                                 \
@@ -147,6 +145,8 @@ void free_page_type(struct page_info *pa
 void free_page_type(struct page_info *page, unsigned long type);
 int _shadow_mode_refcounts(struct domain *d);
 
+void cleanup_page_cacheattr(struct page_info *page);
+
 static inline void put_page(struct page_info *page)
 {
     u32 nx, x, y = page->count_info;
@@ -158,7 +158,10 @@ static inline void put_page(struct page_
     while ( unlikely((y = cmpxchg(&page->count_info, x, nx)) != x) );
 
     if ( unlikely((nx & PGC_count_mask) == 0) )
+    {
+        cleanup_page_cacheattr(page);
         free_domheap_page(page);
+    }
 }
 
 
@@ -196,8 +199,7 @@ static inline int get_page(struct page_i
     return 1;
 }
 
-/* Decide whether this page looks like iomem or real memory */
-int iomem_page_test(unsigned long mfn, struct page_info *page);
+int is_iomem_page(unsigned long mfn);
 
 void put_page_type(struct page_info *page);
 int  get_page_type(struct page_info *page, unsigned long type);
diff -r ef6415fdaf8a -r a1247c2df2b4 xen/include/asm-x86/page.h
--- a/xen/include/asm-x86/page.h        Wed Nov 07 11:01:23 2007 -0700
+++ b/xen/include/asm-x86/page.h        Wed Nov 07 14:48:48 2007 -0700
@@ -360,6 +360,16 @@ int map_pages_to_xen(
     unsigned int flags);
 void destroy_xen_mappings(unsigned long v, unsigned long e);
 
+/* Convert between PAT/PCD/PWT embedded in PTE flags and 3-bit cacheattr. */
+static inline uint32_t pte_flags_to_cacheattr(uint32_t flags)
+{
+    return ((flags >> 5) & 4) | ((flags >> 3) & 3);
+}
+static inline uint32_t cacheattr_to_pte_flags(uint32_t cacheattr)
+{
+    return ((cacheattr & 4) << 5) | ((cacheattr & 3) << 3);
+}
+
 #endif /* !__ASSEMBLY__ */
 
 #define PFN_DOWN(x)   ((x) >> PAGE_SHIFT)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.