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

[Xen-changelog] Add new feature XENFEAT_auto_translated_physmap.



# HG changeset patch
# User Ian.Campbell@xxxxxxxxxxxxx
# Node ID c84a051d89670408e696cad2528ad14d062f9345
# Parent  0e87a5bd6e8bbfe5e6921e32e0d6cc91d14bded8
Add new feature XENFEAT_auto_translated_physmap.

This feature causes the guest OS to ignore the P2M and M2P tables and
to assume that P==M.

Signed-off-by: Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>

diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Wed Feb  1 20:11:18 2006
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Wed Feb  1 20:12:51 2006
@@ -1310,7 +1310,9 @@
        }
 #endif
 
-       phys_to_machine_mapping = (unsigned long *)xen_start_info->mfn_list;
+       if (!xen_feature(XENFEAT_auto_translated_physmap))
+               phys_to_machine_mapping =
+                       (unsigned long *)xen_start_info->mfn_list;
 }
 
 /*
@@ -1746,42 +1748,43 @@
 #endif
 
        /* Make sure we have a correctly sized P->M table. */
-       phys_to_machine_mapping = alloc_bootmem_low_pages(
-               max_pfn * sizeof(unsigned long));
-       memset(phys_to_machine_mapping, ~0,
-               max_pfn * sizeof(unsigned long));
-       memcpy(phys_to_machine_mapping,
-               (unsigned long *)xen_start_info->mfn_list,
-               xen_start_info->nr_pages * sizeof(unsigned long));
-       free_bootmem(
-               __pa(xen_start_info->mfn_list), 
-               PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
-               sizeof(unsigned long))));
-
-       /* 
-        * Initialise the list of the frames that specify the list of 
-        * frames that make up the p2m table. Used by save/restore
-        */
-       pfn_to_mfn_frame_list_list = alloc_bootmem_low_pages(PAGE_SIZE);
-       HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
-         virt_to_mfn(pfn_to_mfn_frame_list_list);
-              
-       fpp = PAGE_SIZE/sizeof(unsigned long);
-       for ( i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++ )
-       {
-           if ( (j % fpp) == 0 )
-           {
-               k++;
-               BUG_ON(k>=16);
-               pfn_to_mfn_frame_list[k] = alloc_bootmem_low_pages(PAGE_SIZE);
-               pfn_to_mfn_frame_list_list[k] = 
-                   virt_to_mfn(pfn_to_mfn_frame_list[k]);
-               j=0;
-           }
-           pfn_to_mfn_frame_list[k][j] = 
-               virt_to_mfn(&phys_to_machine_mapping[i]);
-       }
-       HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
+       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+               phys_to_machine_mapping = alloc_bootmem_low_pages(
+                    max_pfn * sizeof(unsigned long));
+               memset(phys_to_machine_mapping, ~0,
+                      max_pfn * sizeof(unsigned long));
+               memcpy(phys_to_machine_mapping,
+                      (unsigned long *)xen_start_info->mfn_list,
+                      xen_start_info->nr_pages * sizeof(unsigned long));
+               free_bootmem(
+                    __pa(xen_start_info->mfn_list),
+                    PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
+                                    sizeof(unsigned long))));
+
+               /*
+                * Initialise the list of the frames that specify the list of
+                * frames that make up the p2m table. Used by save/restore
+                */
+               pfn_to_mfn_frame_list_list = alloc_bootmem_low_pages(PAGE_SIZE);
+               HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
+                    virt_to_mfn(pfn_to_mfn_frame_list_list);
+
+               fpp = PAGE_SIZE/sizeof(unsigned long);
+               for (i=0, j=0, k=-1; i< max_pfn; i+=fpp, j++) {
+                       if ((j % fpp) == 0) {
+                               k++;
+                               BUG_ON(k>=16);
+                               pfn_to_mfn_frame_list[k] =
+                                       alloc_bootmem_low_pages(PAGE_SIZE);
+                               pfn_to_mfn_frame_list_list[k] =
+                                       virt_to_mfn(pfn_to_mfn_frame_list[k]);
+                               j=0;
+                       }
+                       pfn_to_mfn_frame_list[k][j] =
+                               virt_to_mfn(&phys_to_machine_mapping[i]);
+               }
+               HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
+       }
 
        /*
         * NOTE: at this point the bootmem allocator is fully available.
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Wed Feb  1 20:11:18 2006
+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c    Wed Feb  1 20:12:51 2006
@@ -35,6 +35,7 @@
 #include <asm/pgtable.h>
 #include <asm/hypervisor.h>
 #include <xen/balloon.h>
+#include <xen/features.h>
 #include <xen/interface/memory.h>
 #include <linux/module.h>
 #include <linux/percpu.h>
@@ -100,6 +101,10 @@
 void xen_machphys_update(unsigned long mfn, unsigned long pfn)
 {
        mmu_update_t u;
+       if (xen_feature(XENFEAT_auto_translated_physmap)) {
+               BUG_ON(pfn != mfn);
+               return;
+       }
        u.ptr = ((unsigned long long)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
        u.val = pfn;
        BUG_ON(HYPERVISOR_mmu_update(&u, 1, NULL, DOMID_SELF) < 0);
@@ -322,6 +327,11 @@
                .extent_order = 0,
                .domid        = DOMID_SELF
        };
+
+       if (xen_feature(XENFEAT_auto_translated_physmap)) {
+               BUG_ON(order >= 1);
+               return 0;
+       }
 
        scrub_pages(vstart, 1 << order);
 
@@ -401,6 +411,9 @@
                .domid        = DOMID_SELF
        };
 
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return;
+
        scrub_pages(vstart, 1 << order);
 
        balloon_lock(flags);
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Wed Feb  1 20:11:18 2006
+++ b/linux-2.6-xen-sparse/arch/i386/mm/ioremap-xen.c   Wed Feb  1 20:12:51 2006
@@ -177,15 +177,13 @@
 /*
  * Does @address reside within a non-highmem page that is local to this virtual
  * machine (i.e., not an I/O page, nor a memory page belonging to another VM).
- * See the comment that accompanies pte_pfn() in pgtable-2level.h to understand
+ * See the comment that accompanies mfn_to_local_pfn() in page.h to understand
  * why this works.
  */
 static inline int is_local_lowmem(unsigned long address)
 {
        extern unsigned long max_low_pfn;
-       unsigned long mfn = address >> PAGE_SHIFT;
-       unsigned long pfn = mfn_to_pfn(mfn);
-       return ((pfn < max_low_pfn) && (phys_to_machine_mapping[pfn] == mfn));
+       return (mfn_to_local_pfn(address >> PAGE_SHIFT) < max_low_pfn);
 }
 
 /*
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Wed Feb  1 20:11:18 2006
+++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c   Wed Feb  1 20:12:51 2006
@@ -522,6 +522,9 @@
        pte_t *pte;
        int    g, u, m;
 
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return;
+
        for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) {
                if (pgd_none(*pgd))
                        continue;
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c      Wed Feb  1 
20:11:18 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head64-xen.c      Wed Feb  1 
20:12:51 2006
@@ -89,9 +89,12 @@
 {
        int i;
 
-        phys_to_machine_mapping = (unsigned long *)xen_start_info->mfn_list;
-        start_pfn = (__pa(xen_start_info->pt_base) >> PAGE_SHIFT) + 
-               xen_start_info->nr_pt_frames;
+       if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+               phys_to_machine_mapping =
+                       (unsigned long *)xen_start_info->mfn_list;
+               start_pfn = (__pa(xen_start_info->pt_base) >> PAGE_SHIFT) +
+                       xen_start_info->nr_pt_frames;
+       }
 
        for (i = 0; i < 256; i++)
                set_intr_gate(i, early_idt_handler);
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Wed Feb  1 
20:11:18 2006
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c       Wed Feb  1 
20:12:51 2006
@@ -784,27 +784,6 @@
                int i, j, k, fpp;
                unsigned long va;
 
-               /* Make sure we have a large enough P->M table. */
-               phys_to_machine_mapping = alloc_bootmem(
-                       end_pfn * sizeof(unsigned long));
-               memset(phys_to_machine_mapping, ~0,
-                      end_pfn * sizeof(unsigned long));
-               memcpy(phys_to_machine_mapping,
-                      (unsigned long *)xen_start_info->mfn_list,
-                      xen_start_info->nr_pages * sizeof(unsigned long));
-               free_bootmem(
-                       __pa(xen_start_info->mfn_list), 
-                       PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
-                                       sizeof(unsigned long))));
-
-               /* 'Initial mapping' of old p2m table must be destroyed. */
-               for (va = xen_start_info->mfn_list;
-                    va < (xen_start_info->mfn_list +
-                          (xen_start_info->nr_pages*sizeof(unsigned long)));
-                    va += PAGE_SIZE) {
-                       HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
-               }
-
                /* 'Initial mapping' of initrd must be destroyed. */
                for (va = xen_start_info->mod_start;
                     va < (xen_start_info->mod_start+xen_start_info->mod_len);
@@ -812,30 +791,53 @@
                        HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0);
                }
 
-               /* 
-                * Initialise the list of the frames that specify the list of 
-                * frames that make up the p2m table. Used by save/restore
-                */
-               pfn_to_mfn_frame_list_list = alloc_bootmem(PAGE_SIZE);
-               HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
-                 virt_to_mfn(pfn_to_mfn_frame_list_list);
-
-               fpp = PAGE_SIZE/sizeof(unsigned long);
-               for ( i=0, j=0, k=-1; i< end_pfn; i+=fpp, j++ )
-               {
-                       if ( (j % fpp) == 0 )
-                       {
-                               k++;
-                               BUG_ON(k>=fpp);
-                               pfn_to_mfn_frame_list[k] = 
alloc_bootmem(PAGE_SIZE);
-                               pfn_to_mfn_frame_list_list[k] = 
-                                       virt_to_mfn(pfn_to_mfn_frame_list[k]);
-                               j=0;
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       /* Make sure we have a large enough P->M table. */
+                       phys_to_machine_mapping = alloc_bootmem(
+                               end_pfn * sizeof(unsigned long));
+                       memset(phys_to_machine_mapping, ~0,
+                              end_pfn * sizeof(unsigned long));
+                       memcpy(phys_to_machine_mapping,
+                              (unsigned long *)xen_start_info->mfn_list,
+                              xen_start_info->nr_pages * sizeof(unsigned 
long));
+                       free_bootmem(
+                               __pa(xen_start_info->mfn_list),
+                               PFN_PHYS(PFN_UP(xen_start_info->nr_pages *
+                                               sizeof(unsigned long))));
+
+                       /* Destroyed 'initial mapping' of old p2m table. */
+                       for (va = xen_start_info->mfn_list;
+                            va < (xen_start_info->mfn_list +
+                                  (xen_start_info->nr_pages*sizeof(unsigned 
long)));
+                            va += PAGE_SIZE) {
+                               HYPERVISOR_update_va_mapping(va, __pte_ma(0), 
0);
                        }
-                       pfn_to_mfn_frame_list[k][j] = 
-                               virt_to_mfn(&phys_to_machine_mapping[i]);
+
+                       /*
+                        * Initialise the list of the frames that specify the
+                        * list of frames that make up the p2m table. Used by
+                         * save/restore.
+                        */
+                       pfn_to_mfn_frame_list_list = alloc_bootmem(PAGE_SIZE);
+                       HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list 
=
+                               virt_to_mfn(pfn_to_mfn_frame_list_list);
+
+                       fpp = PAGE_SIZE/sizeof(unsigned long);
+                       for (i=0, j=0, k=-1; i< end_pfn; i+=fpp, j++) {
+                               if ((j % fpp) == 0) {
+                                       k++;
+                                       BUG_ON(k>=fpp);
+                                       pfn_to_mfn_frame_list[k] =
+                                               alloc_bootmem(PAGE_SIZE);
+                                       pfn_to_mfn_frame_list_list[k] =
+                                               
virt_to_mfn(pfn_to_mfn_frame_list[k]);
+                                       j=0;
+                               }
+                               pfn_to_mfn_frame_list[k][j] =
+                                       
virt_to_mfn(&phys_to_machine_mapping[i]);
+                       }
+                       HYPERVISOR_shared_info->arch.max_pfn = end_pfn;
                }
-               HYPERVISOR_shared_info->arch.max_pfn = end_pfn;
 
        }
 
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/drivers/xen/core/reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Wed Feb  1 20:11:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/core/reboot.c    Wed Feb  1 20:12:51 2006
@@ -101,6 +101,12 @@
 
        BUG_ON(smp_processor_id() != 0);
        BUG_ON(in_interrupt());
+
+       if (xen_feature(XENFEAT_auto_translated_physmap)) {
+               printk(KERN_WARNING "Cannot suspend in "
+                      "auto_translated_physmap mode.\n");
+               return -EOPNOTSUPP;
+       }
 
 #if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
        if (num_online_cpus() > 1) {
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Feb  1 
20:11:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c        Wed Feb  1 
20:12:51 2006
@@ -236,10 +236,12 @@
                netif->rx.req_cons++;
                gop++;
 
-               mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
-                       MMU_MACHPHYS_UPDATE;
-               mmu->val = __pa(vdata) >> PAGE_SHIFT;  
-               mmu++;
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) |
+                               MMU_MACHPHYS_UPDATE;
+                       mmu->val = __pa(vdata) >> PAGE_SHIFT;
+                       mmu++;
+               }
 
                __skb_queue_tail(&rxq, skb);
 
@@ -251,14 +253,17 @@
        if (mcl == rx_mcl)
                return;
 
-       mcl->op = __HYPERVISOR_mmu_update;
-       mcl->args[0] = (unsigned long)rx_mmu;
-       mcl->args[1] = mmu - rx_mmu;
-       mcl->args[2] = 0;
-       mcl->args[3] = DOMID_SELF;
-       mcl++;
-
-       mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
+       mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
+
+       if (mmu - rx_mmu) {
+               mcl->op = __HYPERVISOR_mmu_update;
+               mcl->args[0] = (unsigned long)rx_mmu;
+               mcl->args[1] = mmu - rx_mmu;
+               mcl->args[2] = 0;
+               mcl->args[3] = DOMID_SELF;
+               mcl++;
+       }
+
        ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl);
        BUG_ON(ret != 0);
 
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Feb  1 
20:11:18 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Wed Feb  1 
20:12:51 2006
@@ -802,14 +802,17 @@
                np->stats.rx_bytes += rx->status;
 
                /* Remap the page. */
-               mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE;
-               mmu->val  = __pa(skb->head) >> PAGE_SHIFT;
-               mmu++;
                MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
                                        pfn_pte_ma(mfn, PAGE_KERNEL), 0);
                mcl++;
-
-               set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, mfn);
+               if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+                       mmu->ptr = ((maddr_t)mfn << PAGE_SHIFT)
+                               | MMU_MACHPHYS_UPDATE;
+                       mmu->val = __pa(skb->head) >> PAGE_SHIFT;
+                       mmu++;
+
+                       set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, mfn);
+               }
 
                __skb_queue_tail(&rxq, skb);
        }
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Wed Feb  1 
20:11:18 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/page.h Wed Feb  1 
20:12:51 2006
@@ -18,6 +18,7 @@
 #include <linux/kernel.h>
 #include <asm/bug.h>
 #include <xen/interface/xen.h>
+#include <xen/features.h>
 #include <xen/foreign_page.h>
 
 #define arch_free_page(_page,_order)                   \
@@ -61,15 +62,31 @@
 
 /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
 #define INVALID_P2M_ENTRY      (~0UL)
-#define FOREIGN_FRAME(m)       ((m) | (1UL<<31))
+#define FOREIGN_FRAME_BIT      (1UL<<31)
+#define FOREIGN_FRAME(m)       ((m) | FOREIGN_FRAME_BIT)
+
 extern unsigned long *phys_to_machine_mapping;
-#define pfn_to_mfn(pfn)        \
-(phys_to_machine_mapping[(unsigned int)(pfn)] & ~(1UL<<31))
-#define        phys_to_machine_mapping_valid(pfn) \
-       (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY)
+
+static inline unsigned long pfn_to_mfn(unsigned long pfn)
+{
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return pfn;
+       return phys_to_machine_mapping[(unsigned int)(pfn)] & 
~FOREIGN_FRAME_BIT;
+}
+
+static inline int phys_to_machine_mapping_valid(unsigned long pfn)
+{
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return 1;
+       return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
+}
+
 static inline unsigned long mfn_to_pfn(unsigned long mfn)
 {
        unsigned long pfn;
+
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return mfn;
 
        /*
         * The array access can fail (e.g., device space beyond end of RAM).
@@ -88,8 +105,43 @@
        return pfn;
 }
 
+/*
+ * We detect special mappings in one of two ways:
+ *  1. If the MFN is an I/O page then Xen will set the m2p entry
+ *     to be outside our maximum possible pseudophys range.
+ *  2. If the MFN belongs to a different domain then we will certainly
+ *     not have MFN in our p2m table. Conversely, if the page is ours,
+ *     then we'll have p2m(m2p(MFN))==MFN.
+ * If we detect a special mapping then it doesn't have a 'struct page'.
+ * We force !pfn_valid() by returning an out-of-range pointer.
+ *
+ * NB. These checks require that, for any MFN that is not in our reservation,
+ * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
+ * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
+ * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
+ *
+ * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
+ *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
+ *      require. In all the cases we care about, the FOREIGN_FRAME bit is
+ *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
+ */
+static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
+{
+       extern unsigned long max_mapnr;
+       unsigned long pfn = mfn_to_pfn(mfn);
+       if ((pfn < max_mapnr)
+           && !xen_feature(XENFEAT_auto_translated_physmap)
+           && (phys_to_machine_mapping[pfn] != mfn))
+               return max_mapnr; /* force !pfn_valid() */
+       return pfn;
+}
+
 static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 {
+       if (xen_feature(XENFEAT_auto_translated_physmap)) {
+               BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+               return;
+       }
        phys_to_machine_mapping[pfn] = mfn;
 }
 
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h       
Wed Feb  1 20:11:18 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level.h       
Wed Feb  1 20:12:51 2006
@@ -39,35 +39,8 @@
 
 #define ptep_get_and_clear(mm,addr,xp) __pte_ma(xchg(&(xp)->pte_low, 0))
 #define pte_same(a, b)         ((a).pte_low == (b).pte_low)
-/*
- * We detect special mappings in one of two ways:
- *  1. If the MFN is an I/O page then Xen will set the m2p entry
- *     to be outside our maximum possible pseudophys range.
- *  2. If the MFN belongs to a different domain then we will certainly
- *     not have MFN in our p2m table. Conversely, if the page is ours,
- *     then we'll have p2m(m2p(MFN))==MFN.
- * If we detect a special mapping then it doesn't have a 'struct page'.
- * We force !pfn_valid() by returning an out-of-range pointer.
- *
- * NB. These checks require that, for any MFN that is not in our reservation,
- * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
- * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
- * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
- * 
- * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
- *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
- *      require. In all the cases we care about, the FOREIGN_FRAME bit is
- *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
- */
 #define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
-#define pte_pfn(_pte)                                                  \
-({                                                                     \
-       unsigned long mfn = pte_mfn(_pte);                              \
-       unsigned long pfn = mfn_to_pfn(mfn);                            \
-       if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
-               pfn = max_mapnr; /* special: force !pfn_valid() */      \
-       pfn;                                                            \
-})
+#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
 
 #define pte_page(_pte) pfn_to_page(pte_pfn(_pte))
 
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h       
Wed Feb  1 20:11:18 2006
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level.h       
Wed Feb  1 20:12:51 2006
@@ -140,14 +140,7 @@
 
 #define pte_mfn(_pte) ( ((_pte).pte_low >> PAGE_SHIFT) |\
                        (((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)) )
-#define pte_pfn(_pte)                                                  \
-({                                                                     \
-       unsigned long mfn = pte_mfn(_pte);                              \
-       unsigned long pfn = mfn_to_pfn(mfn);                            \
-       if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
-               pfn = max_mapnr; /* special: force !pfn_valid() */      \
-       pfn;                                                            \
-})
+#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
 
 extern unsigned long long __supported_pte_mask;
 
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h       Wed Feb 
 1 20:11:18 2006
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/page.h       Wed Feb 
 1 20:12:51 2006
@@ -4,7 +4,10 @@
 #include <linux/config.h>
 /* #include <linux/string.h> */
 #ifndef __ASSEMBLY__
+#include <linux/kernel.h>
 #include <linux/types.h>
+#include <asm/bug.h>
+#include <xen/features.h>
 #endif
 #include <xen/interface/xen.h> 
 #include <xen/foreign_page.h>
@@ -65,15 +68,31 @@
 
 /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
 #define INVALID_P2M_ENTRY      (~0UL)
-#define FOREIGN_FRAME(m)       ((m) | (1UL<<63))
+#define FOREIGN_FRAME_BIT      (1UL<<63)
+#define FOREIGN_FRAME(m)       ((m) | FOREIGN_FRAME_BIT)
+
 extern unsigned long *phys_to_machine_mapping;
-#define pfn_to_mfn(pfn)        \
-(phys_to_machine_mapping[(unsigned int)(pfn)] & ~(1UL << 63))
-#define        phys_to_machine_mapping_valid(pfn) \
-       (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY)
+
+static inline unsigned long pfn_to_mfn(unsigned long pfn)
+{
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return pfn;
+       return phys_to_machine_mapping[(unsigned int)(pfn)] & 
~FOREIGN_FRAME_BIT;
+}
+
+static inline int phys_to_machine_mapping_valid(unsigned long pfn)
+{
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return 1;
+       return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
+}
+
 static inline unsigned long mfn_to_pfn(unsigned long mfn)
 {
        unsigned long pfn;
+
+       if (xen_feature(XENFEAT_auto_translated_physmap))
+               return mfn;
 
        /*
         * The array access can fail (e.g., device space beyond end of RAM).
@@ -92,8 +111,43 @@
        return pfn;
 }
 
+/*
+ * We detect special mappings in one of two ways:
+ *  1. If the MFN is an I/O page then Xen will set the m2p entry
+ *     to be outside our maximum possible pseudophys range.
+ *  2. If the MFN belongs to a different domain then we will certainly
+ *     not have MFN in our p2m table. Conversely, if the page is ours,
+ *     then we'll have p2m(m2p(MFN))==MFN.
+ * If we detect a special mapping then it doesn't have a 'struct page'.
+ * We force !pfn_valid() by returning an out-of-range pointer.
+ *
+ * NB. These checks require that, for any MFN that is not in our reservation,
+ * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
+ * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
+ * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
+ *
+ * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
+ *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
+ *      require. In all the cases we care about, the FOREIGN_FRAME bit is
+ *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
+ */
+static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
+{
+       unsigned long pfn = mfn_to_pfn(mfn);
+       if ((pfn < end_pfn)
+           && !xen_feature(XENFEAT_auto_translated_physmap)
+           && (phys_to_machine_mapping[pfn] != mfn))
+               return end_pfn; /* force !pfn_valid() */
+       return pfn;
+}
+
+
 static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
 {
+       if (xen_feature(XENFEAT_auto_translated_physmap)) {
+               BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
+               return;
+       }
        phys_to_machine_mapping[pfn] = mfn;
 }
 
@@ -207,12 +261,6 @@
 
 #define KERNEL_TEXT_SIZE  (40UL*1024*1024)
 #define KERNEL_TEXT_START 0xffffffff80000000UL 
-
-#ifndef __ASSEMBLY__
-
-#include <asm/bug.h>
-
-#endif /* __ASSEMBLY__ */
 
 #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
 
diff -r 0e87a5bd6e8b -r c84a051d8967 
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h    Wed Feb 
 1 20:11:18 2006
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/pgtable.h    Wed Feb 
 1 20:12:51 2006
@@ -295,35 +295,8 @@
 
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 
-/*
- * We detect special mappings in one of two ways:
- *  1. If the MFN is an I/O page then Xen will set the m2p entry
- *     to be outside our maximum possible pseudophys range.
- *  2. If the MFN belongs to a different domain then we will certainly
- *     not have MFN in our p2m table. Conversely, if the page is ours,
- *     then we'll have p2m(m2p(MFN))==MFN.
- * If we detect a special mapping then it doesn't have a 'struct page'.
- * We force !pfn_valid() by returning an out-of-range pointer.
- *
- * NB. These checks require that, for any MFN that is not in our reservation,
- * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
- * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
- * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
- * 
- * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
- *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
- *      require. In all the cases we care about, the FOREIGN_FRAME bit is
- *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
- */
 #define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
-#define pte_pfn(_pte)                                                  \
-({                                                                     \
-       unsigned long mfn = pte_mfn(_pte);                              \
-       unsigned long pfn = mfn_to_pfn(mfn);                            \
-       if ((pfn >= end_pfn) || (phys_to_machine_mapping[pfn] != mfn))\
-               pfn = end_pfn; /* special: force !pfn_valid() */        \
-       pfn;                                                            \
-})
+#define pte_pfn(_pte) mfn_to_local_pfn(pte_mfn(_pte))
 
 #define pte_page(x)    pfn_to_page(pte_pfn(x))
 
diff -r 0e87a5bd6e8b -r c84a051d8967 xen/include/public/version.h
--- a/xen/include/public/version.h      Wed Feb  1 20:11:18 2006
+++ b/xen/include/public/version.h      Wed Feb  1 20:12:51 2006
@@ -47,6 +47,7 @@
 
 #define XENFEAT_writable_page_tables       0
 #define XENFEAT_writable_descriptor_tables 1
+#define XENFEAT_auto_translated_physmap    2
 
 #define XENFEAT_NR_SUBMAPS 1
 

_______________________________________________
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®.