1e7596040SQuentin Perret /* SPDX-License-Identifier: GPL-2.0-only */ 2e7596040SQuentin Perret #ifndef __KVM_HYP_MEMORY_H 3e7596040SQuentin Perret #define __KVM_HYP_MEMORY_H 4e7596040SQuentin Perret 55c92a764SMarc Zyngier #include <asm/kvm_mmu.h> 6e7596040SQuentin Perret #include <asm/page.h> 7e7596040SQuentin Perret 8e7596040SQuentin Perret #include <linux/types.h> 9e7596040SQuentin Perret 108e17c662SQuentin Perret struct hyp_page { 116929586dSQuentin Perret unsigned short refcount; 1287ec0606SQuentin Perret unsigned short order; 138e17c662SQuentin Perret }; 148e17c662SQuentin Perret 158e17c662SQuentin Perret extern u64 __hyp_vmemmap; 168e17c662SQuentin Perret #define hyp_vmemmap ((struct hyp_page *)__hyp_vmemmap) 17e7596040SQuentin Perret 18e7596040SQuentin Perret #define __hyp_va(phys) ((void *)((phys_addr_t)(phys) - hyp_physvirt_offset)) 19e7596040SQuentin Perret hyp_phys_to_virt(phys_addr_t phys)20e7596040SQuentin Perretstatic inline void *hyp_phys_to_virt(phys_addr_t phys) 21e7596040SQuentin Perret { 22e7596040SQuentin Perret return __hyp_va(phys); 23e7596040SQuentin Perret } 24e7596040SQuentin Perret hyp_virt_to_phys(void * addr)25e7596040SQuentin Perretstatic inline phys_addr_t hyp_virt_to_phys(void *addr) 26e7596040SQuentin Perret { 27e7596040SQuentin Perret return __hyp_pa(addr); 28e7596040SQuentin Perret } 29e7596040SQuentin Perret 308e17c662SQuentin Perret #define hyp_phys_to_pfn(phys) ((phys) >> PAGE_SHIFT) 318e17c662SQuentin Perret #define hyp_pfn_to_phys(pfn) ((phys_addr_t)((pfn) << PAGE_SHIFT)) 328e17c662SQuentin Perret #define hyp_phys_to_page(phys) (&hyp_vmemmap[hyp_phys_to_pfn(phys)]) 338e17c662SQuentin Perret #define hyp_virt_to_page(virt) hyp_phys_to_page(__hyp_pa(virt)) 348e17c662SQuentin Perret #define hyp_virt_to_pfn(virt) hyp_phys_to_pfn(__hyp_pa(virt)) 358e17c662SQuentin Perret 368e17c662SQuentin Perret #define hyp_page_to_pfn(page) ((struct hyp_page *)(page) - hyp_vmemmap) 378e17c662SQuentin Perret #define hyp_page_to_phys(page) hyp_pfn_to_phys((hyp_page_to_pfn(page))) 388e17c662SQuentin Perret #define hyp_page_to_virt(page) __hyp_va(hyp_page_to_phys(page)) 398e17c662SQuentin Perret #define hyp_page_to_pool(page) (((struct hyp_page *)page)->pool) 408e17c662SQuentin Perret 410f4f7ae1SQuentin Perret /* 420f4f7ae1SQuentin Perret * Refcounting for 'struct hyp_page'. 430f4f7ae1SQuentin Perret * hyp_pool::lock must be held if atomic access to the refcount is required. 440f4f7ae1SQuentin Perret */ hyp_page_count(void * addr)458e17c662SQuentin Perretstatic inline int hyp_page_count(void *addr) 468e17c662SQuentin Perret { 478e17c662SQuentin Perret struct hyp_page *p = hyp_virt_to_page(addr); 488e17c662SQuentin Perret 498e17c662SQuentin Perret return p->refcount; 508e17c662SQuentin Perret } 518e17c662SQuentin Perret hyp_page_ref_inc(struct hyp_page * p)520f4f7ae1SQuentin Perretstatic inline void hyp_page_ref_inc(struct hyp_page *p) 530f4f7ae1SQuentin Perret { 540f4f7ae1SQuentin Perret BUG_ON(p->refcount == USHRT_MAX); 550f4f7ae1SQuentin Perret p->refcount++; 560f4f7ae1SQuentin Perret } 570f4f7ae1SQuentin Perret hyp_page_ref_dec(struct hyp_page * p)58*9926cfceSQuentin Perretstatic inline void hyp_page_ref_dec(struct hyp_page *p) 590f4f7ae1SQuentin Perret { 600f4f7ae1SQuentin Perret BUG_ON(!p->refcount); 610f4f7ae1SQuentin Perret p->refcount--; 62*9926cfceSQuentin Perret } 63*9926cfceSQuentin Perret hyp_page_ref_dec_and_test(struct hyp_page * p)64*9926cfceSQuentin Perretstatic inline int hyp_page_ref_dec_and_test(struct hyp_page *p) 65*9926cfceSQuentin Perret { 66*9926cfceSQuentin Perret hyp_page_ref_dec(p); 670f4f7ae1SQuentin Perret return (p->refcount == 0); 680f4f7ae1SQuentin Perret } 690f4f7ae1SQuentin Perret hyp_set_page_refcounted(struct hyp_page * p)700f4f7ae1SQuentin Perretstatic inline void hyp_set_page_refcounted(struct hyp_page *p) 710f4f7ae1SQuentin Perret { 720f4f7ae1SQuentin Perret BUG_ON(p->refcount); 730f4f7ae1SQuentin Perret p->refcount = 1; 740f4f7ae1SQuentin Perret } 75e7596040SQuentin Perret #endif /* __KVM_HYP_MEMORY_H */ 76