WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Add new feature XENFEAT_auto_translated_physmap.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Add new feature XENFEAT_auto_translated_physmap.
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 02 Feb 2006 15:40:08 +0000
Delivery-date: Thu, 02 Feb 2006 15:51:05 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Add new feature XENFEAT_auto_translated_physmap., Xen patchbot -unstable <=