diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index ef1573d26036..7e625669bce2 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -32,6 +32,7 @@ enum pkvm_page_state { /* Meta-states which aren't encoded directly in the PTE's SW bits */ PKVM_NOPAGE = BIT(0), PKVM_PAGE_RESTRICTED_PROT = BIT(1), + PKVM_MODULE_DONT_TOUCH = BIT(2), }; #define PKVM_PAGE_STATE_PROT_MASK (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1) diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h index a8d4a5b919d2..74d7d3b506c0 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h @@ -13,6 +13,7 @@ */ #define HOST_PAGE_NEED_POISONING BIT(0) #define HOST_PAGE_PENDING_RECLAIM BIT(1) +#define MODULE_OWNED_PAGE BIT(2) struct hyp_page { unsigned short refcount; diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 56ac2519b0e5..944fc2f7c5e3 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -903,15 +903,19 @@ static int check_page_state_range(struct kvm_pgtable *pgt, u64 addr, u64 size, static enum pkvm_page_state host_get_page_state(kvm_pte_t pte, u64 addr) { + bool is_memory = addr_is_memory(addr); enum pkvm_page_state state = 0; enum kvm_pgtable_prot prot; + if (is_memory && hyp_phys_to_page(addr)->flags & MODULE_OWNED_PAGE) + return PKVM_MODULE_DONT_TOUCH; + if (!kvm_pte_valid(pte) && pte) return PKVM_NOPAGE; prot = kvm_pgtable_stage2_pte_prot(pte); if (kvm_pte_valid(pte)) { - if ((prot & KVM_PGTABLE_PROT_RWX) != default_host_prot(addr_is_memory(addr))) + if ((prot & KVM_PGTABLE_PROT_RWX) != default_host_prot(is_memory)) state = PKVM_PAGE_RESTRICTED_PROT; }