- patches.rt/0001-sched-count-of-queued-RT-tasks.patch: Delete.
[linux-flexiantxendom0-3.2.10.git] / include / asm-x86 / mach-xen / asm / maddr_32.h
1 #ifndef _I386_MADDR_H
2 #define _I386_MADDR_H
3
4 #include <xen/features.h>
5 #include <xen/interface/xen.h>
6
7 /**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
8 #define INVALID_P2M_ENTRY       (~0UL)
9 #define FOREIGN_FRAME_BIT       (1UL<<31)
10 #define FOREIGN_FRAME(m)        ((m) | FOREIGN_FRAME_BIT)
11
12 /* Definitions for machine and pseudophysical addresses. */
13 #ifdef CONFIG_X86_PAE
14 typedef unsigned long long paddr_t;
15 typedef unsigned long long maddr_t;
16 #else
17 typedef unsigned long paddr_t;
18 typedef unsigned long maddr_t;
19 #endif
20
21 #ifdef CONFIG_XEN
22
23 extern unsigned long *phys_to_machine_mapping;
24 extern unsigned long  max_mapnr;
25
26 #undef machine_to_phys_mapping
27 extern unsigned long *machine_to_phys_mapping;
28 extern unsigned int   machine_to_phys_order;
29
30 static inline unsigned long pfn_to_mfn(unsigned long pfn)
31 {
32         if (xen_feature(XENFEAT_auto_translated_physmap))
33                 return pfn;
34         BUG_ON(max_mapnr && pfn >= max_mapnr);
35         return phys_to_machine_mapping[pfn] & ~FOREIGN_FRAME_BIT;
36 }
37
38 static inline int phys_to_machine_mapping_valid(unsigned long pfn)
39 {
40         if (xen_feature(XENFEAT_auto_translated_physmap))
41                 return 1;
42         BUG_ON(max_mapnr && pfn >= max_mapnr);
43         return (phys_to_machine_mapping[pfn] != INVALID_P2M_ENTRY);
44 }
45
46 static inline unsigned long mfn_to_pfn(unsigned long mfn)
47 {
48         unsigned long pfn;
49
50         if (xen_feature(XENFEAT_auto_translated_physmap))
51                 return mfn;
52
53         if (unlikely((mfn >> machine_to_phys_order) != 0))
54                 return max_mapnr;
55
56         /* The array access can fail (e.g., device space beyond end of RAM). */
57         asm (
58                 "1:     movl %1,%0\n"
59                 "2:\n"
60                 ".section .fixup,\"ax\"\n"
61                 "3:     movl %2,%0\n"
62                 "       jmp  2b\n"
63                 ".previous\n"
64                 ".section __ex_table,\"a\"\n"
65                 "       .align 4\n"
66                 "       .long 1b,3b\n"
67                 ".previous"
68                 : "=r" (pfn)
69                 : "m" (machine_to_phys_mapping[mfn]), "m" (max_mapnr) );
70
71         return pfn;
72 }
73
74 /*
75  * We detect special mappings in one of two ways:
76  *  1. If the MFN is an I/O page then Xen will set the m2p entry
77  *     to be outside our maximum possible pseudophys range.
78  *  2. If the MFN belongs to a different domain then we will certainly
79  *     not have MFN in our p2m table. Conversely, if the page is ours,
80  *     then we'll have p2m(m2p(MFN))==MFN.
81  * If we detect a special mapping then it doesn't have a 'struct page'.
82  * We force !pfn_valid() by returning an out-of-range pointer.
83  *
84  * NB. These checks require that, for any MFN that is not in our reservation,
85  * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
86  * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
87  * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
88  *
89  * NB2. When deliberately mapping foreign pages into the p2m table, you *must*
90  *      use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
91  *      require. In all the cases we care about, the FOREIGN_FRAME bit is
92  *      masked (e.g., pfn_to_mfn()) so behaviour there is correct.
93  */
94 static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
95 {
96         unsigned long pfn = mfn_to_pfn(mfn);
97         if ((pfn < max_mapnr)
98             && !xen_feature(XENFEAT_auto_translated_physmap)
99             && (phys_to_machine_mapping[pfn] != mfn))
100                 return max_mapnr; /* force !pfn_valid() */
101         return pfn;
102 }
103
104 static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
105 {
106         BUG_ON(max_mapnr && pfn >= max_mapnr);
107         if (xen_feature(XENFEAT_auto_translated_physmap)) {
108                 BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY);
109                 return;
110         }
111         phys_to_machine_mapping[pfn] = mfn;
112 }
113
114 static inline maddr_t phys_to_machine(paddr_t phys)
115 {
116         maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
117         machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
118         return machine;
119 }
120
121 static inline paddr_t machine_to_phys(maddr_t machine)
122 {
123         paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
124         phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
125         return phys;
126 }
127
128 #ifdef CONFIG_X86_PAE
129 static inline paddr_t pte_phys_to_machine(paddr_t phys)
130 {
131         /*
132          * In PAE mode, the NX bit needs to be dealt with in the value
133          * passed to pfn_to_mfn(). On x86_64, we need to mask it off,
134          * but for i386 the conversion to ulong for the argument will
135          * clip it off.
136          */
137         maddr_t machine = pfn_to_mfn(phys >> PAGE_SHIFT);
138         machine = (machine << PAGE_SHIFT) | (phys & ~PHYSICAL_PAGE_MASK);
139         return machine;
140 }
141
142 static inline paddr_t pte_machine_to_phys(maddr_t machine)
143 {
144         /*
145          * In PAE mode, the NX bit needs to be dealt with in the value
146          * passed to mfn_to_pfn(). On x86_64, we need to mask it off,
147          * but for i386 the conversion to ulong for the argument will
148          * clip it off.
149          */
150         paddr_t phys = mfn_to_pfn(machine >> PAGE_SHIFT);
151         phys = (phys << PAGE_SHIFT) | (machine & ~PHYSICAL_PAGE_MASK);
152         return phys;
153 }
154 #endif
155
156 #ifdef CONFIG_X86_PAE
157 extern unsigned long long __supported_pte_mask;
158 static inline pte_t pfn_pte_ma(unsigned long page_nr, pgprot_t pgprot)
159 {
160         pte_t pte;
161
162         pte.pte_high = (page_nr >> (32 - PAGE_SHIFT)) | \
163                                         (pgprot_val(pgprot) >> 32);
164         pte.pte_high &= (__supported_pte_mask >> 32);
165         pte.pte_low = ((page_nr << PAGE_SHIFT) | pgprot_val(pgprot)) & \
166                                                         __supported_pte_mask;
167         return pte;
168 }
169 #else
170 #define pfn_pte_ma(pfn, prot)   __pte_ma(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
171 #endif
172
173 #define __pte_ma(x)     ((pte_t) { (x) } )
174
175 #else /* !CONFIG_XEN */
176
177 #define pfn_to_mfn(pfn) (pfn)
178 #define mfn_to_pfn(mfn) (mfn)
179 #define mfn_to_local_pfn(mfn) (mfn)
180 #define set_phys_to_machine(pfn, mfn) ((void)0)
181 #define phys_to_machine_mapping_valid(pfn) (1)
182 #define phys_to_machine(phys) ((maddr_t)(phys))
183 #define machine_to_phys(mach) ((paddr_t)(mach))
184 #define pfn_pte_ma(pfn, prot) pfn_pte(pfn, prot)
185 #define __pte_ma(x) __pte(x)
186
187 #endif /* !CONFIG_XEN */
188
189 /* VIRT <-> MACHINE conversion */
190 #define virt_to_machine(v)      (phys_to_machine(__pa(v)))
191 #define virt_to_mfn(v)          (pfn_to_mfn(__pa(v) >> PAGE_SHIFT))
192 #define mfn_to_virt(m)          (__va(mfn_to_pfn(m) << PAGE_SHIFT))
193
194 #endif /* _I386_MADDR_H */