18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_X86_XEN_PAGE_H 38c2ecf20Sopenharmony_ci#define _ASM_X86_XEN_PAGE_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/kernel.h> 68c2ecf20Sopenharmony_ci#include <linux/types.h> 78c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 88c2ecf20Sopenharmony_ci#include <linux/pfn.h> 98c2ecf20Sopenharmony_ci#include <linux/mm.h> 108c2ecf20Sopenharmony_ci#include <linux/device.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <asm/extable.h> 138c2ecf20Sopenharmony_ci#include <asm/page.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <xen/interface/xen.h> 168c2ecf20Sopenharmony_ci#include <xen/interface/grant_table.h> 178c2ecf20Sopenharmony_ci#include <xen/features.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* Xen machine address */ 208c2ecf20Sopenharmony_citypedef struct xmaddr { 218c2ecf20Sopenharmony_ci phys_addr_t maddr; 228c2ecf20Sopenharmony_ci} xmaddr_t; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* Xen pseudo-physical address */ 258c2ecf20Sopenharmony_citypedef struct xpaddr { 268c2ecf20Sopenharmony_ci phys_addr_t paddr; 278c2ecf20Sopenharmony_ci} xpaddr_t; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64 308c2ecf20Sopenharmony_ci#define XEN_PHYSICAL_MASK __sme_clr((1UL << 52) - 1) 318c2ecf20Sopenharmony_ci#else 328c2ecf20Sopenharmony_ci#define XEN_PHYSICAL_MASK __PHYSICAL_MASK 338c2ecf20Sopenharmony_ci#endif 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define XEN_PTE_MFN_MASK ((pteval_t)(((signed long)PAGE_MASK) & \ 368c2ecf20Sopenharmony_ci XEN_PHYSICAL_MASK)) 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#define XMADDR(x) ((xmaddr_t) { .maddr = (x) }) 398c2ecf20Sopenharmony_ci#define XPADDR(x) ((xpaddr_t) { .paddr = (x) }) 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/ 428c2ecf20Sopenharmony_ci#define INVALID_P2M_ENTRY (~0UL) 438c2ecf20Sopenharmony_ci#define FOREIGN_FRAME_BIT (1UL<<(BITS_PER_LONG-1)) 448c2ecf20Sopenharmony_ci#define IDENTITY_FRAME_BIT (1UL<<(BITS_PER_LONG-2)) 458c2ecf20Sopenharmony_ci#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT) 468c2ecf20Sopenharmony_ci#define IDENTITY_FRAME(m) ((m) | IDENTITY_FRAME_BIT) 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#define P2M_PER_PAGE (PAGE_SIZE / sizeof(unsigned long)) 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ciextern unsigned long *machine_to_phys_mapping; 518c2ecf20Sopenharmony_ciextern unsigned long machine_to_phys_nr; 528c2ecf20Sopenharmony_ciextern unsigned long *xen_p2m_addr; 538c2ecf20Sopenharmony_ciextern unsigned long xen_p2m_size; 548c2ecf20Sopenharmony_ciextern unsigned long xen_max_p2m_pfn; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ciextern int xen_alloc_p2m_entry(unsigned long pfn); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ciextern unsigned long get_phys_to_machine(unsigned long pfn); 598c2ecf20Sopenharmony_ciextern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); 608c2ecf20Sopenharmony_ciextern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); 618c2ecf20Sopenharmony_ciextern unsigned long __init set_phys_range_identity(unsigned long pfn_s, 628c2ecf20Sopenharmony_ci unsigned long pfn_e); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#ifdef CONFIG_XEN_PV 658c2ecf20Sopenharmony_ciextern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, 668c2ecf20Sopenharmony_ci struct gnttab_map_grant_ref *kmap_ops, 678c2ecf20Sopenharmony_ci struct page **pages, unsigned int count); 688c2ecf20Sopenharmony_ciextern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, 698c2ecf20Sopenharmony_ci struct gnttab_unmap_grant_ref *kunmap_ops, 708c2ecf20Sopenharmony_ci struct page **pages, unsigned int count); 718c2ecf20Sopenharmony_ci#else 728c2ecf20Sopenharmony_cistatic inline int 738c2ecf20Sopenharmony_ciset_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, 748c2ecf20Sopenharmony_ci struct gnttab_map_grant_ref *kmap_ops, 758c2ecf20Sopenharmony_ci struct page **pages, unsigned int count) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci return 0; 788c2ecf20Sopenharmony_ci} 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistatic inline int 818c2ecf20Sopenharmony_ciclear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, 828c2ecf20Sopenharmony_ci struct gnttab_unmap_grant_ref *kunmap_ops, 838c2ecf20Sopenharmony_ci struct page **pages, unsigned int count) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci return 0; 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci#endif 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci/* 908c2ecf20Sopenharmony_ci * Helper functions to write or read unsigned long values to/from 918c2ecf20Sopenharmony_ci * memory, when the access may fault. 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_cistatic inline int xen_safe_write_ulong(unsigned long *addr, unsigned long val) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci int ret = 0; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci asm volatile("1: mov %[val], %[ptr]\n" 988c2ecf20Sopenharmony_ci "2:\n" 998c2ecf20Sopenharmony_ci ".section .fixup, \"ax\"\n" 1008c2ecf20Sopenharmony_ci "3: sub $1, %[ret]\n" 1018c2ecf20Sopenharmony_ci " jmp 2b\n" 1028c2ecf20Sopenharmony_ci ".previous\n" 1038c2ecf20Sopenharmony_ci _ASM_EXTABLE(1b, 3b) 1048c2ecf20Sopenharmony_ci : [ret] "+r" (ret), [ptr] "=m" (*addr) 1058c2ecf20Sopenharmony_ci : [val] "r" (val)); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci return ret; 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic inline int xen_safe_read_ulong(const unsigned long *addr, 1118c2ecf20Sopenharmony_ci unsigned long *val) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci int ret = 0; 1148c2ecf20Sopenharmony_ci unsigned long rval = ~0ul; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci asm volatile("1: mov %[ptr], %[rval]\n" 1178c2ecf20Sopenharmony_ci "2:\n" 1188c2ecf20Sopenharmony_ci ".section .fixup, \"ax\"\n" 1198c2ecf20Sopenharmony_ci "3: sub $1, %[ret]\n" 1208c2ecf20Sopenharmony_ci " jmp 2b\n" 1218c2ecf20Sopenharmony_ci ".previous\n" 1228c2ecf20Sopenharmony_ci _ASM_EXTABLE(1b, 3b) 1238c2ecf20Sopenharmony_ci : [ret] "+r" (ret), [rval] "+r" (rval) 1248c2ecf20Sopenharmony_ci : [ptr] "m" (*addr)); 1258c2ecf20Sopenharmony_ci *val = rval; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci return ret; 1288c2ecf20Sopenharmony_ci} 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci#ifdef CONFIG_XEN_PV 1318c2ecf20Sopenharmony_ci/* 1328c2ecf20Sopenharmony_ci * When to use pfn_to_mfn(), __pfn_to_mfn() or get_phys_to_machine(): 1338c2ecf20Sopenharmony_ci * - pfn_to_mfn() returns either INVALID_P2M_ENTRY or the mfn. No indicator 1348c2ecf20Sopenharmony_ci * bits (identity or foreign) are set. 1358c2ecf20Sopenharmony_ci * - __pfn_to_mfn() returns the found entry of the p2m table. A possibly set 1368c2ecf20Sopenharmony_ci * identity or foreign indicator will be still set. __pfn_to_mfn() is 1378c2ecf20Sopenharmony_ci * encapsulating get_phys_to_machine() which is called in special cases only. 1388c2ecf20Sopenharmony_ci * - get_phys_to_machine() is to be called by __pfn_to_mfn() only in special 1398c2ecf20Sopenharmony_ci * cases needing an extended handling. 1408c2ecf20Sopenharmony_ci */ 1418c2ecf20Sopenharmony_cistatic inline unsigned long __pfn_to_mfn(unsigned long pfn) 1428c2ecf20Sopenharmony_ci{ 1438c2ecf20Sopenharmony_ci unsigned long mfn; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci if (pfn < xen_p2m_size) 1468c2ecf20Sopenharmony_ci mfn = xen_p2m_addr[pfn]; 1478c2ecf20Sopenharmony_ci else if (unlikely(pfn < xen_max_p2m_pfn)) 1488c2ecf20Sopenharmony_ci return get_phys_to_machine(pfn); 1498c2ecf20Sopenharmony_ci else 1508c2ecf20Sopenharmony_ci return IDENTITY_FRAME(pfn); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci if (unlikely(mfn == INVALID_P2M_ENTRY)) 1538c2ecf20Sopenharmony_ci return get_phys_to_machine(pfn); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci return mfn; 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci#else 1588c2ecf20Sopenharmony_cistatic inline unsigned long __pfn_to_mfn(unsigned long pfn) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci return pfn; 1618c2ecf20Sopenharmony_ci} 1628c2ecf20Sopenharmony_ci#endif 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic inline unsigned long pfn_to_mfn(unsigned long pfn) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci unsigned long mfn; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci /* 1698c2ecf20Sopenharmony_ci * Some x86 code are still using pfn_to_mfn instead of 1708c2ecf20Sopenharmony_ci * pfn_to_mfn. This will have to be removed when we figured 1718c2ecf20Sopenharmony_ci * out which call. 1728c2ecf20Sopenharmony_ci */ 1738c2ecf20Sopenharmony_ci if (xen_feature(XENFEAT_auto_translated_physmap)) 1748c2ecf20Sopenharmony_ci return pfn; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci mfn = __pfn_to_mfn(pfn); 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci if (mfn != INVALID_P2M_ENTRY) 1798c2ecf20Sopenharmony_ci mfn &= ~(FOREIGN_FRAME_BIT | IDENTITY_FRAME_BIT); 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci return mfn; 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_cistatic inline int phys_to_machine_mapping_valid(unsigned long pfn) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci if (xen_feature(XENFEAT_auto_translated_physmap)) 1878c2ecf20Sopenharmony_ci return 1; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci return __pfn_to_mfn(pfn) != INVALID_P2M_ENTRY; 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci unsigned long pfn; 1958c2ecf20Sopenharmony_ci int ret; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci if (unlikely(mfn >= machine_to_phys_nr)) 1988c2ecf20Sopenharmony_ci return ~0; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* 2018c2ecf20Sopenharmony_ci * The array access can fail (e.g., device space beyond end of RAM). 2028c2ecf20Sopenharmony_ci * In such cases it doesn't matter what we return (we return garbage), 2038c2ecf20Sopenharmony_ci * but we must handle the fault without crashing! 2048c2ecf20Sopenharmony_ci */ 2058c2ecf20Sopenharmony_ci ret = xen_safe_read_ulong(&machine_to_phys_mapping[mfn], &pfn); 2068c2ecf20Sopenharmony_ci if (ret < 0) 2078c2ecf20Sopenharmony_ci return ~0; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci return pfn; 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic inline unsigned long mfn_to_pfn(unsigned long mfn) 2138c2ecf20Sopenharmony_ci{ 2148c2ecf20Sopenharmony_ci unsigned long pfn; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci /* 2178c2ecf20Sopenharmony_ci * Some x86 code are still using mfn_to_pfn instead of 2188c2ecf20Sopenharmony_ci * gfn_to_pfn. This will have to be removed when we figure 2198c2ecf20Sopenharmony_ci * out which call. 2208c2ecf20Sopenharmony_ci */ 2218c2ecf20Sopenharmony_ci if (xen_feature(XENFEAT_auto_translated_physmap)) 2228c2ecf20Sopenharmony_ci return mfn; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci pfn = mfn_to_pfn_no_overrides(mfn); 2258c2ecf20Sopenharmony_ci if (__pfn_to_mfn(pfn) != mfn) 2268c2ecf20Sopenharmony_ci pfn = ~0; 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci /* 2298c2ecf20Sopenharmony_ci * pfn is ~0 if there are no entries in the m2p for mfn or the 2308c2ecf20Sopenharmony_ci * entry doesn't map back to the mfn. 2318c2ecf20Sopenharmony_ci */ 2328c2ecf20Sopenharmony_ci if (pfn == ~0 && __pfn_to_mfn(mfn) == IDENTITY_FRAME(mfn)) 2338c2ecf20Sopenharmony_ci pfn = mfn; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci return pfn; 2368c2ecf20Sopenharmony_ci} 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cistatic inline xmaddr_t phys_to_machine(xpaddr_t phys) 2398c2ecf20Sopenharmony_ci{ 2408c2ecf20Sopenharmony_ci unsigned offset = phys.paddr & ~PAGE_MASK; 2418c2ecf20Sopenharmony_ci return XMADDR(PFN_PHYS(pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset); 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cistatic inline xpaddr_t machine_to_phys(xmaddr_t machine) 2458c2ecf20Sopenharmony_ci{ 2468c2ecf20Sopenharmony_ci unsigned offset = machine.maddr & ~PAGE_MASK; 2478c2ecf20Sopenharmony_ci return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset); 2488c2ecf20Sopenharmony_ci} 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci/* Pseudo-physical <-> Guest conversion */ 2518c2ecf20Sopenharmony_cistatic inline unsigned long pfn_to_gfn(unsigned long pfn) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci if (xen_feature(XENFEAT_auto_translated_physmap)) 2548c2ecf20Sopenharmony_ci return pfn; 2558c2ecf20Sopenharmony_ci else 2568c2ecf20Sopenharmony_ci return pfn_to_mfn(pfn); 2578c2ecf20Sopenharmony_ci} 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_cistatic inline unsigned long gfn_to_pfn(unsigned long gfn) 2608c2ecf20Sopenharmony_ci{ 2618c2ecf20Sopenharmony_ci if (xen_feature(XENFEAT_auto_translated_physmap)) 2628c2ecf20Sopenharmony_ci return gfn; 2638c2ecf20Sopenharmony_ci else 2648c2ecf20Sopenharmony_ci return mfn_to_pfn(gfn); 2658c2ecf20Sopenharmony_ci} 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci/* Pseudo-physical <-> Bus conversion */ 2688c2ecf20Sopenharmony_ci#define pfn_to_bfn(pfn) pfn_to_gfn(pfn) 2698c2ecf20Sopenharmony_ci#define bfn_to_pfn(bfn) gfn_to_pfn(bfn) 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci/* 2728c2ecf20Sopenharmony_ci * We detect special mappings in one of two ways: 2738c2ecf20Sopenharmony_ci * 1. If the MFN is an I/O page then Xen will set the m2p entry 2748c2ecf20Sopenharmony_ci * to be outside our maximum possible pseudophys range. 2758c2ecf20Sopenharmony_ci * 2. If the MFN belongs to a different domain then we will certainly 2768c2ecf20Sopenharmony_ci * not have MFN in our p2m table. Conversely, if the page is ours, 2778c2ecf20Sopenharmony_ci * then we'll have p2m(m2p(MFN))==MFN. 2788c2ecf20Sopenharmony_ci * If we detect a special mapping then it doesn't have a 'struct page'. 2798c2ecf20Sopenharmony_ci * We force !pfn_valid() by returning an out-of-range pointer. 2808c2ecf20Sopenharmony_ci * 2818c2ecf20Sopenharmony_ci * NB. These checks require that, for any MFN that is not in our reservation, 2828c2ecf20Sopenharmony_ci * there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if 2838c2ecf20Sopenharmony_ci * we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN. 2848c2ecf20Sopenharmony_ci * Yikes! Various places must poke in INVALID_P2M_ENTRY for safety. 2858c2ecf20Sopenharmony_ci * 2868c2ecf20Sopenharmony_ci * NB2. When deliberately mapping foreign pages into the p2m table, you *must* 2878c2ecf20Sopenharmony_ci * use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we 2888c2ecf20Sopenharmony_ci * require. In all the cases we care about, the FOREIGN_FRAME bit is 2898c2ecf20Sopenharmony_ci * masked (e.g., pfn_to_mfn()) so behaviour there is correct. 2908c2ecf20Sopenharmony_ci */ 2918c2ecf20Sopenharmony_cistatic inline unsigned long bfn_to_local_pfn(unsigned long mfn) 2928c2ecf20Sopenharmony_ci{ 2938c2ecf20Sopenharmony_ci unsigned long pfn; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci if (xen_feature(XENFEAT_auto_translated_physmap)) 2968c2ecf20Sopenharmony_ci return mfn; 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci pfn = mfn_to_pfn(mfn); 2998c2ecf20Sopenharmony_ci if (__pfn_to_mfn(pfn) != mfn) 3008c2ecf20Sopenharmony_ci return -1; /* force !pfn_valid() */ 3018c2ecf20Sopenharmony_ci return pfn; 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci/* VIRT <-> MACHINE conversion */ 3058c2ecf20Sopenharmony_ci#define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v)))) 3068c2ecf20Sopenharmony_ci#define virt_to_pfn(v) (PFN_DOWN(__pa(v))) 3078c2ecf20Sopenharmony_ci#define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v))) 3088c2ecf20Sopenharmony_ci#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT)) 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci/* VIRT <-> GUEST conversion */ 3118c2ecf20Sopenharmony_ci#define virt_to_gfn(v) (pfn_to_gfn(virt_to_pfn(v))) 3128c2ecf20Sopenharmony_ci#define gfn_to_virt(g) (__va(gfn_to_pfn(g) << PAGE_SHIFT)) 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_cistatic inline unsigned long pte_mfn(pte_t pte) 3158c2ecf20Sopenharmony_ci{ 3168c2ecf20Sopenharmony_ci return (pte.pte & XEN_PTE_MFN_MASK) >> PAGE_SHIFT; 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cistatic inline pte_t mfn_pte(unsigned long page_nr, pgprot_t pgprot) 3208c2ecf20Sopenharmony_ci{ 3218c2ecf20Sopenharmony_ci pte_t pte; 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_ci pte.pte = ((phys_addr_t)page_nr << PAGE_SHIFT) | 3248c2ecf20Sopenharmony_ci massage_pgprot(pgprot); 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci return pte; 3278c2ecf20Sopenharmony_ci} 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_cistatic inline pteval_t pte_val_ma(pte_t pte) 3308c2ecf20Sopenharmony_ci{ 3318c2ecf20Sopenharmony_ci return pte.pte; 3328c2ecf20Sopenharmony_ci} 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_cistatic inline pte_t __pte_ma(pteval_t x) 3358c2ecf20Sopenharmony_ci{ 3368c2ecf20Sopenharmony_ci return (pte_t) { .pte = x }; 3378c2ecf20Sopenharmony_ci} 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci#define pmd_val_ma(v) ((v).pmd) 3408c2ecf20Sopenharmony_ci#ifdef __PAGETABLE_PUD_FOLDED 3418c2ecf20Sopenharmony_ci#define pud_val_ma(v) ((v).p4d.pgd.pgd) 3428c2ecf20Sopenharmony_ci#else 3438c2ecf20Sopenharmony_ci#define pud_val_ma(v) ((v).pud) 3448c2ecf20Sopenharmony_ci#endif 3458c2ecf20Sopenharmony_ci#define __pmd_ma(x) ((pmd_t) { (x) } ) 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci#ifdef __PAGETABLE_P4D_FOLDED 3488c2ecf20Sopenharmony_ci#define p4d_val_ma(x) ((x).pgd.pgd) 3498c2ecf20Sopenharmony_ci#else 3508c2ecf20Sopenharmony_ci#define p4d_val_ma(x) ((x).p4d) 3518c2ecf20Sopenharmony_ci#endif 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_cixmaddr_t arbitrary_virt_to_machine(void *address); 3548c2ecf20Sopenharmony_ciunsigned long arbitrary_virt_to_mfn(void *vaddr); 3558c2ecf20Sopenharmony_civoid make_lowmem_page_readonly(void *vaddr); 3568c2ecf20Sopenharmony_civoid make_lowmem_page_readwrite(void *vaddr); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci#define xen_remap(cookie, size) ioremap((cookie), (size)); 3598c2ecf20Sopenharmony_ci#define xen_unmap(cookie) iounmap((cookie)) 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_cistatic inline bool xen_arch_need_swiotlb(struct device *dev, 3628c2ecf20Sopenharmony_ci phys_addr_t phys, 3638c2ecf20Sopenharmony_ci dma_addr_t dev_addr) 3648c2ecf20Sopenharmony_ci{ 3658c2ecf20Sopenharmony_ci return false; 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_cistatic inline unsigned long xen_get_swiotlb_free_pages(unsigned int order) 3698c2ecf20Sopenharmony_ci{ 3708c2ecf20Sopenharmony_ci return __get_free_pages(__GFP_NOWARN, order); 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci#endif /* _ASM_X86_XEN_PAGE_H */ 374