aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/xen/page.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/include/asm/xen/page.h')
-rw-r--r--arch/x86/include/asm/xen/page.h67
1 files changed, 57 insertions, 10 deletions
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index bf5f7d32bd08..64a619d47d34 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -5,6 +5,7 @@
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/spinlock.h> 6#include <linux/spinlock.h>
7#include <linux/pfn.h> 7#include <linux/pfn.h>
8#include <linux/mm.h>
8 9
9#include <asm/uaccess.h> 10#include <asm/uaccess.h>
10#include <asm/page.h> 11#include <asm/page.h>
@@ -28,23 +29,46 @@ typedef struct xpaddr {
28 29
29/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/ 30/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
30#define INVALID_P2M_ENTRY (~0UL) 31#define INVALID_P2M_ENTRY (~0UL)
31#define FOREIGN_FRAME_BIT (1UL<<31) 32#define FOREIGN_FRAME_BIT (1UL<<(BITS_PER_LONG-1))
33#define IDENTITY_FRAME_BIT (1UL<<(BITS_PER_LONG-2))
32#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT) 34#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT)
35#define IDENTITY_FRAME(m) ((m) | IDENTITY_FRAME_BIT)
33 36
34/* Maximum amount of memory we can handle in a domain in pages */ 37/* Maximum amount of memory we can handle in a domain in pages */
35#define MAX_DOMAIN_PAGES \ 38#define MAX_DOMAIN_PAGES \
36 ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE)) 39 ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE))
37 40
41extern unsigned long *machine_to_phys_mapping;
42extern unsigned int machine_to_phys_order;
38 43
39extern unsigned long get_phys_to_machine(unsigned long pfn); 44extern unsigned long get_phys_to_machine(unsigned long pfn);
40extern void set_phys_to_machine(unsigned long pfn, unsigned long mfn); 45extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
41 46extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
47extern unsigned long set_phys_range_identity(unsigned long pfn_s,
48 unsigned long pfn_e);
49
50extern int m2p_add_override(unsigned long mfn, struct page *page,
51 bool clear_pte);
52extern int m2p_remove_override(struct page *page, bool clear_pte);
53extern struct page *m2p_find_override(unsigned long mfn);
54extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
55
56#ifdef CONFIG_XEN_DEBUG_FS
57extern int p2m_dump_show(struct seq_file *m, void *v);
58#endif
42static inline unsigned long pfn_to_mfn(unsigned long pfn) 59static inline unsigned long pfn_to_mfn(unsigned long pfn)
43{ 60{
61 unsigned long mfn;
62
44 if (xen_feature(XENFEAT_auto_translated_physmap)) 63 if (xen_feature(XENFEAT_auto_translated_physmap))
45 return pfn; 64 return pfn;
46 65
47 return get_phys_to_machine(pfn) & ~FOREIGN_FRAME_BIT; 66 mfn = get_phys_to_machine(pfn);
67
68 if (mfn != INVALID_P2M_ENTRY)
69 mfn &= ~(FOREIGN_FRAME_BIT | IDENTITY_FRAME_BIT);
70
71 return mfn;
48} 72}
49 73
50static inline int phys_to_machine_mapping_valid(unsigned long pfn) 74static inline int phys_to_machine_mapping_valid(unsigned long pfn)
@@ -58,22 +82,44 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
58static inline unsigned long mfn_to_pfn(unsigned long mfn) 82static inline unsigned long mfn_to_pfn(unsigned long mfn)
59{ 83{
60 unsigned long pfn; 84 unsigned long pfn;
85 int ret = 0;
61 86
62 if (xen_feature(XENFEAT_auto_translated_physmap)) 87 if (xen_feature(XENFEAT_auto_translated_physmap))
63 return mfn; 88 return mfn;
64 89
65#if 0 90 if (unlikely((mfn >> machine_to_phys_order) != 0)) {
66 if (unlikely((mfn >> machine_to_phys_order) != 0)) 91 pfn = ~0;
67 return max_mapnr; 92 goto try_override;
68#endif 93 }
69
70 pfn = 0; 94 pfn = 0;
71 /* 95 /*
72 * The array access can fail (e.g., device space beyond end of RAM). 96 * The array access can fail (e.g., device space beyond end of RAM).
73 * In such cases it doesn't matter what we return (we return garbage), 97 * In such cases it doesn't matter what we return (we return garbage),
74 * but we must handle the fault without crashing! 98 * but we must handle the fault without crashing!
75 */ 99 */
76 __get_user(pfn, &machine_to_phys_mapping[mfn]); 100 ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
101try_override:
102 /* ret might be < 0 if there are no entries in the m2p for mfn */
103 if (ret < 0)
104 pfn = ~0;
105 else if (get_phys_to_machine(pfn) != mfn)
106 /*
107 * If this appears to be a foreign mfn (because the pfn
108 * doesn't map back to the mfn), then check the local override
109 * table to see if there's a better pfn to use.
110 *
111 * m2p_find_override_pfn returns ~0 if it doesn't find anything.
112 */
113 pfn = m2p_find_override_pfn(mfn, ~0);
114
115 /*
116 * pfn is ~0 if there are no entries in the m2p for mfn or if the
117 * entry doesn't map back to the mfn and m2p_override doesn't have a
118 * valid entry for it.
119 */
120 if (pfn == ~0 &&
121 get_phys_to_machine(mfn) == IDENTITY_FRAME(mfn))
122 pfn = mfn;
77 123
78 return pfn; 124 return pfn;
79} 125}
@@ -159,6 +205,7 @@ static inline pte_t __pte_ma(pteval_t x)
159 205
160#define pgd_val_ma(x) ((x).pgd) 206#define pgd_val_ma(x) ((x).pgd)
161 207
208void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid);
162 209
163xmaddr_t arbitrary_virt_to_machine(void *address); 210xmaddr_t arbitrary_virt_to_machine(void *address);
164unsigned long arbitrary_virt_to_mfn(void *vaddr); 211unsigned long arbitrary_virt_to_mfn(void *vaddr);