Merge branches 'stable/ia64', 'stable/blkfront-cleanup' and 'stable/cleanup' of git...
[pandora-kernel.git] / arch / x86 / include / asm / xen / page.h
index f25bdf2..c61934f 100644 (file)
@@ -29,8 +29,10 @@ typedef struct xpaddr {
 
 /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
 #define INVALID_P2M_ENTRY      (~0UL)
-#define FOREIGN_FRAME_BIT      (1UL<<31)
+#define FOREIGN_FRAME_BIT      (1UL<<(BITS_PER_LONG-1))
+#define IDENTITY_FRAME_BIT     (1UL<<(BITS_PER_LONG-2))
 #define FOREIGN_FRAME(m)       ((m) | FOREIGN_FRAME_BIT)
+#define IDENTITY_FRAME(m)      ((m) | IDENTITY_FRAME_BIT)
 
 /* Maximum amount of memory we can handle in a domain in pages */
 #define MAX_DOMAIN_PAGES                                               \
@@ -41,12 +43,18 @@ extern unsigned int   machine_to_phys_order;
 
 extern unsigned long get_phys_to_machine(unsigned long pfn);
 extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
+extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
+extern unsigned long set_phys_range_identity(unsigned long pfn_s,
+                                            unsigned long pfn_e);
 
 extern int m2p_add_override(unsigned long mfn, struct page *page);
 extern int m2p_remove_override(struct page *page);
 extern struct page *m2p_find_override(unsigned long mfn);
 extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
 
+#ifdef CONFIG_XEN_DEBUG_FS
+extern int p2m_dump_show(struct seq_file *m, void *v);
+#endif
 static inline unsigned long pfn_to_mfn(unsigned long pfn)
 {
        unsigned long mfn;
@@ -57,7 +65,7 @@ static inline unsigned long pfn_to_mfn(unsigned long pfn)
        mfn = get_phys_to_machine(pfn);
 
        if (mfn != INVALID_P2M_ENTRY)
-               mfn &= ~FOREIGN_FRAME_BIT;
+               mfn &= ~(FOREIGN_FRAME_BIT | IDENTITY_FRAME_BIT);
 
        return mfn;
 }
@@ -73,25 +81,44 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
 static inline unsigned long mfn_to_pfn(unsigned long mfn)
 {
        unsigned long pfn;
+       int ret = 0;
 
        if (xen_feature(XENFEAT_auto_translated_physmap))
                return mfn;
 
+       if (unlikely((mfn >> machine_to_phys_order) != 0)) {
+               pfn = ~0;
+               goto try_override;
+       }
        pfn = 0;
        /*
         * The array access can fail (e.g., device space beyond end of RAM).
         * In such cases it doesn't matter what we return (we return garbage),
         * but we must handle the fault without crashing!
         */
-       __get_user(pfn, &machine_to_phys_mapping[mfn]);
-
-       /*
-        * If this appears to be a foreign mfn (because the pfn
-        * doesn't map back to the mfn), then check the local override
-        * table to see if there's a better pfn to use.
+       ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
+try_override:
+       /* ret might be < 0 if there are no entries in the m2p for mfn */
+       if (ret < 0)
+               pfn = ~0;
+       else if (get_phys_to_machine(pfn) != mfn)
+               /*
+                * If this appears to be a foreign mfn (because the pfn
+                * doesn't map back to the mfn), then check the local override
+                * table to see if there's a better pfn to use.
+                *
+                * m2p_find_override_pfn returns ~0 if it doesn't find anything.
+                */
+               pfn = m2p_find_override_pfn(mfn, ~0);
+
+       /* 
+        * pfn is ~0 if there are no entries in the m2p for mfn or if the
+        * entry doesn't map back to the mfn and m2p_override doesn't have a
+        * valid entry for it.
         */
-       if (get_phys_to_machine(pfn) != mfn)
-               pfn = m2p_find_override_pfn(mfn, pfn);
+       if (pfn == ~0 &&
+                       get_phys_to_machine(mfn) == IDENTITY_FRAME(mfn))
+               pfn = mfn;
 
        return pfn;
 }