18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_ARM_XEN_PAGE_H 38c2ecf20Sopenharmony_ci#define _ASM_ARM_XEN_PAGE_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <asm/page.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/pfn.h> 88c2ecf20Sopenharmony_ci#include <linux/types.h> 98c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 108c2ecf20Sopenharmony_ci#include <linux/pgtable.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <xen/xen.h> 138c2ecf20Sopenharmony_ci#include <xen/interface/grant_table.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define phys_to_machine_mapping_valid(pfn) (1) 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* Xen machine address */ 188c2ecf20Sopenharmony_citypedef struct xmaddr { 198c2ecf20Sopenharmony_ci phys_addr_t maddr; 208c2ecf20Sopenharmony_ci} xmaddr_t; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* Xen pseudo-physical address */ 238c2ecf20Sopenharmony_citypedef struct xpaddr { 248c2ecf20Sopenharmony_ci phys_addr_t paddr; 258c2ecf20Sopenharmony_ci} xpaddr_t; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define XMADDR(x) ((xmaddr_t) { .maddr = (x) }) 288c2ecf20Sopenharmony_ci#define XPADDR(x) ((xpaddr_t) { .paddr = (x) }) 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define INVALID_P2M_ENTRY (~0UL) 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* 338c2ecf20Sopenharmony_ci * The pseudo-physical frame (pfn) used in all the helpers is always based 348c2ecf20Sopenharmony_ci * on Xen page granularity (i.e 4KB). 358c2ecf20Sopenharmony_ci * 368c2ecf20Sopenharmony_ci * A Linux page may be split across multiple non-contiguous Xen page so we 378c2ecf20Sopenharmony_ci * have to keep track with frame based on 4KB page granularity. 388c2ecf20Sopenharmony_ci * 398c2ecf20Sopenharmony_ci * PV drivers should never make a direct usage of those helpers (particularly 408c2ecf20Sopenharmony_ci * pfn_to_gfn and gfn_to_pfn). 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ciunsigned long __pfn_to_mfn(unsigned long pfn); 448c2ecf20Sopenharmony_ciextern struct rb_root phys_to_mach; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/* Pseudo-physical <-> Guest conversion */ 478c2ecf20Sopenharmony_cistatic inline unsigned long pfn_to_gfn(unsigned long pfn) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci return pfn; 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistatic inline unsigned long gfn_to_pfn(unsigned long gfn) 538c2ecf20Sopenharmony_ci{ 548c2ecf20Sopenharmony_ci return gfn; 558c2ecf20Sopenharmony_ci} 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* Pseudo-physical <-> BUS conversion */ 588c2ecf20Sopenharmony_cistatic inline unsigned long pfn_to_bfn(unsigned long pfn) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci unsigned long mfn; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci if (phys_to_mach.rb_node != NULL) { 638c2ecf20Sopenharmony_ci mfn = __pfn_to_mfn(pfn); 648c2ecf20Sopenharmony_ci if (mfn != INVALID_P2M_ENTRY) 658c2ecf20Sopenharmony_ci return mfn; 668c2ecf20Sopenharmony_ci } 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return pfn; 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic inline unsigned long bfn_to_pfn(unsigned long bfn) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci return bfn; 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci#define bfn_to_local_pfn(bfn) bfn_to_pfn(bfn) 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci/* VIRT <-> GUEST conversion */ 798c2ecf20Sopenharmony_ci#define virt_to_gfn(v) \ 808c2ecf20Sopenharmony_ci ({ \ 818c2ecf20Sopenharmony_ci WARN_ON_ONCE(!virt_addr_valid(v)); \ 828c2ecf20Sopenharmony_ci pfn_to_gfn(virt_to_phys(v) >> XEN_PAGE_SHIFT); \ 838c2ecf20Sopenharmony_ci }) 848c2ecf20Sopenharmony_ci#define gfn_to_virt(m) (__va(gfn_to_pfn(m) << XEN_PAGE_SHIFT)) 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci#define percpu_to_gfn(v) \ 878c2ecf20Sopenharmony_ci (pfn_to_gfn(per_cpu_ptr_to_phys(v) >> XEN_PAGE_SHIFT)) 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci/* Only used in PV code. But ARM guests are always HVM. */ 908c2ecf20Sopenharmony_cistatic inline xmaddr_t arbitrary_virt_to_machine(void *vaddr) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci BUG(); 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ciextern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops, 968c2ecf20Sopenharmony_ci struct gnttab_map_grant_ref *kmap_ops, 978c2ecf20Sopenharmony_ci struct page **pages, unsigned int count); 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ciextern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops, 1008c2ecf20Sopenharmony_ci struct gnttab_unmap_grant_ref *kunmap_ops, 1018c2ecf20Sopenharmony_ci struct page **pages, unsigned int count); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cibool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); 1048c2ecf20Sopenharmony_cibool __set_phys_to_machine_multi(unsigned long pfn, unsigned long mfn, 1058c2ecf20Sopenharmony_ci unsigned long nr_pages); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistatic inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci return __set_phys_to_machine(pfn, mfn); 1108c2ecf20Sopenharmony_ci} 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci#define xen_remap(cookie, size) ioremap_cache((cookie), (size)) 1138c2ecf20Sopenharmony_ci#define xen_unmap(cookie) iounmap((cookie)) 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cibool xen_arch_need_swiotlb(struct device *dev, 1168c2ecf20Sopenharmony_ci phys_addr_t phys, 1178c2ecf20Sopenharmony_ci dma_addr_t dev_addr); 1188c2ecf20Sopenharmony_ciunsigned long xen_get_swiotlb_free_pages(unsigned int order); 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#endif /* _ASM_ARM_XEN_PAGE_H */ 121