diff options
Diffstat (limited to 'arch/x86/include/asm/xen/page.h')
-rw-r--r-- | arch/x86/include/asm/xen/page.h | 67 |
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 | ||
41 | extern unsigned long *machine_to_phys_mapping; | ||
42 | extern unsigned int machine_to_phys_order; | ||
38 | 43 | ||
39 | extern unsigned long get_phys_to_machine(unsigned long pfn); | 44 | extern unsigned long get_phys_to_machine(unsigned long pfn); |
40 | extern void set_phys_to_machine(unsigned long pfn, unsigned long mfn); | 45 | extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); |
41 | 46 | extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); | |
47 | extern unsigned long set_phys_range_identity(unsigned long pfn_s, | ||
48 | unsigned long pfn_e); | ||
49 | |||
50 | extern int m2p_add_override(unsigned long mfn, struct page *page, | ||
51 | bool clear_pte); | ||
52 | extern int m2p_remove_override(struct page *page, bool clear_pte); | ||
53 | extern struct page *m2p_find_override(unsigned long mfn); | ||
54 | extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); | ||
55 | |||
56 | #ifdef CONFIG_XEN_DEBUG_FS | ||
57 | extern int p2m_dump_show(struct seq_file *m, void *v); | ||
58 | #endif | ||
42 | static inline unsigned long pfn_to_mfn(unsigned long pfn) | 59 | static 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 | ||
50 | static inline int phys_to_machine_mapping_valid(unsigned long pfn) | 74 | static 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) | |||
58 | static inline unsigned long mfn_to_pfn(unsigned long mfn) | 82 | static 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]); |
101 | try_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 | ||
208 | void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid); | ||
162 | 209 | ||
163 | xmaddr_t arbitrary_virt_to_machine(void *address); | 210 | xmaddr_t arbitrary_virt_to_machine(void *address); |
164 | unsigned long arbitrary_virt_to_mfn(void *vaddr); | 211 | unsigned long arbitrary_virt_to_mfn(void *vaddr); |