KVM: arm64: Count pKVM stage-2 usage in secondary pagetable stats
authorVincent Donnefort <vdonnefort@google.com>
Thu, 13 Mar 2025 11:40:38 +0000 (11:40 +0000)
committerOliver Upton <oliver.upton@linux.dev>
Fri, 14 Mar 2025 07:56:30 +0000 (00:56 -0700)
Count the pages used by pKVM for the guest stage-2 in memory stats under
secondary pagetable, similarly to what the VHE mode does.

Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Acked-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20250313114038.1502357-4-vdonnefort@google.com
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/mmu.c
arch/arm64/kvm/pkvm.c

index ace3969e8106fee9e8ae028a0ea9617eafc29346..51754a354b7a468c854bd09242df134dbe2b56ac 100644 (file)
@@ -86,6 +86,8 @@ struct kvm_hyp_memcache {
        phys_addr_t head;
        unsigned long nr_pages;
        struct pkvm_mapping *mapping; /* only used from EL1 */
+
+#define        HYP_MEMCACHE_ACCOUNT_STAGE2     BIT(1)
        unsigned long flags;
 };
 
index 6107a3c8ccf63e8ef671dcbae898b3b79aa74fa7..2feb6c6b63af6c7970a8a41a7eec1bf3c659c9eb 100644 (file)
@@ -1088,12 +1088,24 @@ void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu)
 
 static void hyp_mc_free_fn(void *addr, void *mc)
 {
+       struct kvm_hyp_memcache *memcache = mc;
+
+       if (memcache->flags & HYP_MEMCACHE_ACCOUNT_STAGE2)
+               kvm_account_pgtable_pages(addr, -1);
+
        free_page((unsigned long)addr);
 }
 
 static void *hyp_mc_alloc_fn(void *mc)
 {
-       return (void *)__get_free_page(GFP_KERNEL_ACCOUNT);
+       struct kvm_hyp_memcache *memcache = mc;
+       void *addr;
+
+       addr = (void *)__get_free_page(GFP_KERNEL_ACCOUNT);
+       if (addr && memcache->flags & HYP_MEMCACHE_ACCOUNT_STAGE2)
+               kvm_account_pgtable_pages(addr, 1);
+
+       return addr;
 }
 
 void free_hyp_memcache(struct kvm_hyp_memcache *mc)
index 19921ca407c617a300eaf6e5137da0e7aab47923..4409a10d02b661dbd45c2de0d1998a00d9364e3b 100644 (file)
@@ -165,12 +165,16 @@ static int __pkvm_create_hyp_vm(struct kvm *host_kvm)
        handle = ret;
 
        host_kvm->arch.pkvm.handle = handle;
+       host_kvm->arch.pkvm.stage2_teardown_mc.flags |= HYP_MEMCACHE_ACCOUNT_STAGE2;
+       kvm_account_pgtable_pages(pgd, pgd_sz / PAGE_SIZE);
 
        /* Donate memory for the vcpus at hyp and initialize it. */
        hyp_vcpu_sz = PAGE_ALIGN(PKVM_HYP_VCPU_SIZE);
        kvm_for_each_vcpu(idx, host_vcpu, host_kvm) {
                void *hyp_vcpu;
 
+               host_vcpu->arch.pkvm_memcache.flags |= HYP_MEMCACHE_ACCOUNT_STAGE2;
+
                /* Indexing of the vcpus to be sequential starting at 0. */
                if (WARN_ON(host_vcpu->vcpu_idx != idx)) {
                        ret = -EINVAL;