0001
0002 #ifndef _ASM_X86_XEN_PAGE_H
0003 #define _ASM_X86_XEN_PAGE_H
0004
0005 #include <linux/kernel.h>
0006 #include <linux/types.h>
0007 #include <linux/spinlock.h>
0008 #include <linux/pfn.h>
0009 #include <linux/mm.h>
0010 #include <linux/device.h>
0011
0012 #include <asm/extable.h>
0013 #include <asm/page.h>
0014
0015 #include <xen/interface/xen.h>
0016 #include <xen/interface/grant_table.h>
0017 #include <xen/features.h>
0018
0019
0020 typedef struct xmaddr {
0021 phys_addr_t maddr;
0022 } xmaddr_t;
0023
0024
0025 typedef struct xpaddr {
0026 phys_addr_t paddr;
0027 } xpaddr_t;
0028
0029 #ifdef CONFIG_X86_64
0030 #define XEN_PHYSICAL_MASK __sme_clr((1UL << 52) - 1)
0031 #else
0032 #define XEN_PHYSICAL_MASK __PHYSICAL_MASK
0033 #endif
0034
0035 #define XEN_PTE_MFN_MASK ((pteval_t)(((signed long)PAGE_MASK) & \
0036 XEN_PHYSICAL_MASK))
0037
0038 #define XMADDR(x) ((xmaddr_t) { .maddr = (x) })
0039 #define XPADDR(x) ((xpaddr_t) { .paddr = (x) })
0040
0041
0042 #define INVALID_P2M_ENTRY (~0UL)
0043 #define FOREIGN_FRAME_BIT (1UL<<(BITS_PER_LONG-1))
0044 #define IDENTITY_FRAME_BIT (1UL<<(BITS_PER_LONG-2))
0045 #define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT)
0046 #define IDENTITY_FRAME(m) ((m) | IDENTITY_FRAME_BIT)
0047
0048 #define P2M_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
0049
0050 extern unsigned long *machine_to_phys_mapping;
0051 extern unsigned long machine_to_phys_nr;
0052 extern unsigned long *xen_p2m_addr;
0053 extern unsigned long xen_p2m_size;
0054 extern unsigned long xen_max_p2m_pfn;
0055
0056 extern int xen_alloc_p2m_entry(unsigned long pfn);
0057
0058 extern unsigned long get_phys_to_machine(unsigned long pfn);
0059 extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
0060 extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
0061 extern unsigned long __init set_phys_range_identity(unsigned long pfn_s,
0062 unsigned long pfn_e);
0063
0064 #ifdef CONFIG_XEN_PV
0065 extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
0066 struct gnttab_map_grant_ref *kmap_ops,
0067 struct page **pages, unsigned int count);
0068 extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
0069 struct gnttab_unmap_grant_ref *kunmap_ops,
0070 struct page **pages, unsigned int count);
0071 #else
0072 static inline int
0073 set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
0074 struct gnttab_map_grant_ref *kmap_ops,
0075 struct page **pages, unsigned int count)
0076 {
0077 return 0;
0078 }
0079
0080 static inline int
0081 clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
0082 struct gnttab_unmap_grant_ref *kunmap_ops,
0083 struct page **pages, unsigned int count)
0084 {
0085 return 0;
0086 }
0087 #endif
0088
0089
0090
0091
0092
0093 static inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val)
0094 {
0095 int ret = 0;
0096
0097 asm volatile("1: mov %[val], %[ptr]\n"
0098 "2:\n"
0099 _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %[ret])
0100 : [ret] "+r" (ret), [ptr] "=m" (*addr)
0101 : [val] "r" (val));
0102
0103 return ret;
0104 }
0105
0106 static inline int xen_safe_read_ulong(const unsigned long *addr,
0107 unsigned long *val)
0108 {
0109 unsigned long rval = ~0ul;
0110 int ret = 0;
0111
0112 asm volatile("1: mov %[ptr], %[rval]\n"
0113 "2:\n"
0114 _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %[ret])
0115 : [ret] "+r" (ret), [rval] "+r" (rval)
0116 : [ptr] "m" (*addr));
0117 *val = rval;
0118
0119 return ret;
0120 }
0121
0122 #ifdef CONFIG_XEN_PV
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 static inline unsigned long __pfn_to_mfn(unsigned long pfn)
0134 {
0135 unsigned long mfn;
0136
0137 if (pfn < xen_p2m_size)
0138 mfn = xen_p2m_addr[pfn];
0139 else if (unlikely(pfn < xen_max_p2m_pfn))
0140 return get_phys_to_machine(pfn);
0141 else
0142 return IDENTITY_FRAME(pfn);
0143
0144 if (unlikely(mfn == INVALID_P2M_ENTRY))
0145 return get_phys_to_machine(pfn);
0146
0147 return mfn;
0148 }
0149 #else
0150 static inline unsigned long __pfn_to_mfn(unsigned long pfn)
0151 {
0152 return pfn;
0153 }
0154 #endif
0155
0156 static inline unsigned long pfn_to_mfn(unsigned long pfn)
0157 {
0158 unsigned long mfn;
0159
0160
0161
0162
0163
0164
0165 if (xen_feature(XENFEAT_auto_translated_physmap))
0166 return pfn;
0167
0168 mfn = __pfn_to_mfn(pfn);
0169
0170 if (mfn != INVALID_P2M_ENTRY)
0171 mfn &= ~(FOREIGN_FRAME_BIT | IDENTITY_FRAME_BIT);
0172
0173 return mfn;
0174 }
0175
0176 static inline int phys_to_machine_mapping_valid(unsigned long pfn)
0177 {
0178 if (xen_feature(XENFEAT_auto_translated_physmap))
0179 return 1;
0180
0181 return __pfn_to_mfn(pfn) != INVALID_P2M_ENTRY;
0182 }
0183
0184 static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn)
0185 {
0186 unsigned long pfn;
0187 int ret;
0188
0189 if (unlikely(mfn >= machine_to_phys_nr))
0190 return ~0;
0191
0192
0193
0194
0195
0196
0197 ret = xen_safe_read_ulong(&machine_to_phys_mapping[mfn], &pfn);
0198 if (ret < 0)
0199 return ~0;
0200
0201 return pfn;
0202 }
0203
0204 static inline unsigned long mfn_to_pfn(unsigned long mfn)
0205 {
0206 unsigned long pfn;
0207
0208
0209
0210
0211
0212
0213 if (xen_feature(XENFEAT_auto_translated_physmap))
0214 return mfn;
0215
0216 pfn = mfn_to_pfn_no_overrides(mfn);
0217 if (__pfn_to_mfn(pfn) != mfn)
0218 pfn = ~0;
0219
0220
0221
0222
0223
0224 if (pfn == ~0 && __pfn_to_mfn(mfn) == IDENTITY_FRAME(mfn))
0225 pfn = mfn;
0226
0227 return pfn;
0228 }
0229
0230 static inline xmaddr_t phys_to_machine(xpaddr_t phys)
0231 {
0232 unsigned offset = phys.paddr & ~PAGE_MASK;
0233 return XMADDR(PFN_PHYS(pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
0234 }
0235
0236 static inline xpaddr_t machine_to_phys(xmaddr_t machine)
0237 {
0238 unsigned offset = machine.maddr & ~PAGE_MASK;
0239 return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
0240 }
0241
0242
0243 static inline unsigned long pfn_to_gfn(unsigned long pfn)
0244 {
0245 if (xen_feature(XENFEAT_auto_translated_physmap))
0246 return pfn;
0247 else
0248 return pfn_to_mfn(pfn);
0249 }
0250
0251 static inline unsigned long gfn_to_pfn(unsigned long gfn)
0252 {
0253 if (xen_feature(XENFEAT_auto_translated_physmap))
0254 return gfn;
0255 else
0256 return mfn_to_pfn(gfn);
0257 }
0258
0259
0260 #define pfn_to_bfn(pfn) pfn_to_gfn(pfn)
0261 #define bfn_to_pfn(bfn) gfn_to_pfn(bfn)
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 static inline unsigned long bfn_to_local_pfn(unsigned long mfn)
0284 {
0285 unsigned long pfn;
0286
0287 if (xen_feature(XENFEAT_auto_translated_physmap))
0288 return mfn;
0289
0290 pfn = mfn_to_pfn(mfn);
0291 if (__pfn_to_mfn(pfn) != mfn)
0292 return -1;
0293 return pfn;
0294 }
0295
0296
0297 #define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v))))
0298 #define virt_to_pfn(v) (PFN_DOWN(__pa(v)))
0299 #define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v)))
0300 #define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
0301
0302
0303 #define virt_to_gfn(v) (pfn_to_gfn(virt_to_pfn(v)))
0304 #define gfn_to_virt(g) (__va(gfn_to_pfn(g) << PAGE_SHIFT))
0305
0306 static inline unsigned long pte_mfn(pte_t pte)
0307 {
0308 return (pte.pte & XEN_PTE_MFN_MASK) >> PAGE_SHIFT;
0309 }
0310
0311 static inline pte_t mfn_pte(unsigned long page_nr, pgprot_t pgprot)
0312 {
0313 pte_t pte;
0314
0315 pte.pte = ((phys_addr_t)page_nr << PAGE_SHIFT) |
0316 massage_pgprot(pgprot);
0317
0318 return pte;
0319 }
0320
0321 static inline pteval_t pte_val_ma(pte_t pte)
0322 {
0323 return pte.pte;
0324 }
0325
0326 static inline pte_t __pte_ma(pteval_t x)
0327 {
0328 return (pte_t) { .pte = x };
0329 }
0330
0331 #define pmd_val_ma(v) ((v).pmd)
0332 #ifdef __PAGETABLE_PUD_FOLDED
0333 #define pud_val_ma(v) ((v).p4d.pgd.pgd)
0334 #else
0335 #define pud_val_ma(v) ((v).pud)
0336 #endif
0337 #define __pmd_ma(x) ((pmd_t) { (x) } )
0338
0339 #ifdef __PAGETABLE_P4D_FOLDED
0340 #define p4d_val_ma(x) ((x).pgd.pgd)
0341 #else
0342 #define p4d_val_ma(x) ((x).p4d)
0343 #endif
0344
0345 xmaddr_t arbitrary_virt_to_machine(void *address);
0346 unsigned long arbitrary_virt_to_mfn(void *vaddr);
0347 void make_lowmem_page_readonly(void *vaddr);
0348 void make_lowmem_page_readwrite(void *vaddr);
0349
0350 static inline bool xen_arch_need_swiotlb(struct device *dev,
0351 phys_addr_t phys,
0352 dma_addr_t dev_addr)
0353 {
0354 return false;
0355 }
0356
0357 #endif