xref: /kernel/linux/linux-6.6/include/xen/arm/page.h (revision 62306a36)
162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _ASM_ARM_XEN_PAGE_H
362306a36Sopenharmony_ci#define _ASM_ARM_XEN_PAGE_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <asm/page.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/pfn.h>
862306a36Sopenharmony_ci#include <linux/types.h>
962306a36Sopenharmony_ci#include <linux/dma-mapping.h>
1062306a36Sopenharmony_ci#include <linux/pgtable.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <xen/xen.h>
1362306a36Sopenharmony_ci#include <xen/interface/grant_table.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define phys_to_machine_mapping_valid(pfn) (1)
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/* Xen machine address */
1862306a36Sopenharmony_citypedef struct xmaddr {
1962306a36Sopenharmony_ci	phys_addr_t maddr;
2062306a36Sopenharmony_ci} xmaddr_t;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* Xen pseudo-physical address */
2362306a36Sopenharmony_citypedef struct xpaddr {
2462306a36Sopenharmony_ci	phys_addr_t paddr;
2562306a36Sopenharmony_ci} xpaddr_t;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define XMADDR(x)	((xmaddr_t) { .maddr = (x) })
2862306a36Sopenharmony_ci#define XPADDR(x)	((xpaddr_t) { .paddr = (x) })
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#define INVALID_P2M_ENTRY      (~0UL)
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci/*
3362306a36Sopenharmony_ci * The pseudo-physical frame (pfn) used in all the helpers is always based
3462306a36Sopenharmony_ci * on Xen page granularity (i.e 4KB).
3562306a36Sopenharmony_ci *
3662306a36Sopenharmony_ci * A Linux page may be split across multiple non-contiguous Xen page so we
3762306a36Sopenharmony_ci * have to keep track with frame based on 4KB page granularity.
3862306a36Sopenharmony_ci *
3962306a36Sopenharmony_ci * PV drivers should never make a direct usage of those helpers (particularly
4062306a36Sopenharmony_ci * pfn_to_gfn and gfn_to_pfn).
4162306a36Sopenharmony_ci */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ciunsigned long __pfn_to_mfn(unsigned long pfn);
4462306a36Sopenharmony_ciextern struct rb_root phys_to_mach;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* Pseudo-physical <-> Guest conversion */
4762306a36Sopenharmony_cistatic inline unsigned long pfn_to_gfn(unsigned long pfn)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	return pfn;
5062306a36Sopenharmony_ci}
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistatic inline unsigned long gfn_to_pfn(unsigned long gfn)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	return gfn;
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/* Pseudo-physical <-> BUS conversion */
5862306a36Sopenharmony_cistatic inline unsigned long pfn_to_bfn(unsigned long pfn)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	unsigned long mfn;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	if (phys_to_mach.rb_node != NULL) {
6362306a36Sopenharmony_ci		mfn = __pfn_to_mfn(pfn);
6462306a36Sopenharmony_ci		if (mfn != INVALID_P2M_ENTRY)
6562306a36Sopenharmony_ci			return mfn;
6662306a36Sopenharmony_ci	}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	return pfn;
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic inline unsigned long bfn_to_pfn(unsigned long bfn)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	return bfn;
7462306a36Sopenharmony_ci}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define bfn_to_local_pfn(bfn)	bfn_to_pfn(bfn)
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/* VIRT <-> GUEST conversion */
7962306a36Sopenharmony_ci#define virt_to_gfn(v)                                                         \
8062306a36Sopenharmony_ci	({                                                                     \
8162306a36Sopenharmony_ci		WARN_ON_ONCE(!virt_addr_valid(v));                              \
8262306a36Sopenharmony_ci		pfn_to_gfn(virt_to_phys(v) >> XEN_PAGE_SHIFT);                 \
8362306a36Sopenharmony_ci	})
8462306a36Sopenharmony_ci#define gfn_to_virt(m)		(__va(gfn_to_pfn(m) << XEN_PAGE_SHIFT))
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci#define percpu_to_gfn(v)	\
8762306a36Sopenharmony_ci	(pfn_to_gfn(per_cpu_ptr_to_phys(v) >> XEN_PAGE_SHIFT))
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/* Only used in PV code. But ARM guests are always HVM. */
9062306a36Sopenharmony_cistatic inline xmaddr_t arbitrary_virt_to_machine(void *vaddr)
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	BUG();
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ciextern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
9662306a36Sopenharmony_ci				   struct gnttab_map_grant_ref *kmap_ops,
9762306a36Sopenharmony_ci				   struct page **pages, unsigned int count);
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ciextern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
10062306a36Sopenharmony_ci				     struct gnttab_unmap_grant_ref *kunmap_ops,
10162306a36Sopenharmony_ci				     struct page **pages, unsigned int count);
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cibool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
10462306a36Sopenharmony_cibool __set_phys_to_machine_multi(unsigned long pfn, unsigned long mfn,
10562306a36Sopenharmony_ci		unsigned long nr_pages);
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistatic inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	return __set_phys_to_machine(pfn, mfn);
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cibool xen_arch_need_swiotlb(struct device *dev,
11362306a36Sopenharmony_ci			   phys_addr_t phys,
11462306a36Sopenharmony_ci			   dma_addr_t dev_addr);
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci#endif /* _ASM_ARM_XEN_PAGE_H */
117