*/
bool nested_stage2_enabled;
+#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
+ struct dentry *shadow_pt_debugfs_dentry;
+#endif
+
/*
* true when this MMU needs to be unmapped before being used for a new
* purpose.
* the associated pKVM instance in the hypervisor.
*/
struct kvm_protected_vm pkvm;
+
+#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
+ /* Nested virtualization info */
+ struct dentry *debugfs_nv_dentry;
+#endif
};
struct kvm_vcpu_fault_info {
#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
+void kvm_nested_s2_ptdump_create_debugfs(struct kvm_s2_mmu *mmu);
+void kvm_nested_s2_ptdump_remove_debugfs(struct kvm_s2_mmu *mmu);
#else
static inline void kvm_s2_ptdump_create_debugfs(struct kvm *kvm) {}
+static inline void kvm_nested_s2_ptdump_create_debugfs(struct kvm_s2_mmu *mmu) {}
+static inline void kvm_nested_s2_ptdump_remove_debugfs(struct kvm_s2_mmu *mmu) {}
#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
#endif /* __ASSEMBLER__ */
kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size;
/* Make sure we don't forget to do the laundry */
- if (kvm_s2_mmu_valid(s2_mmu))
+ if (kvm_s2_mmu_valid(s2_mmu)) {
+ kvm_nested_s2_ptdump_remove_debugfs(s2_mmu);
s2_mmu->pending_unmap = true;
+ }
/*
* The virtual VMID (modulo CnP) will be used as a key when matching
s2_mmu->tlb_vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
s2_mmu->nested_stage2_enabled = vcpu_read_sys_reg(vcpu, HCR_EL2) & HCR_VM;
+ kvm_nested_s2_ptdump_create_debugfs(s2_mmu);
+
out:
atomic_inc(&s2_mmu->refcnt);
#include <linux/kvm_host.h>
#include <linux/seq_file.h>
+#include <asm/cpufeature.h>
#include <asm/kvm_mmu.h>
#include <asm/kvm_pgtable.h>
#include <asm/ptdump.h>
#define MARKERS_LEN 2
#define KVM_PGTABLE_MAX_LEVELS (KVM_PGTABLE_LAST_LEVEL + 1)
+#define S2FNAMESZ sizeof("0x0123456789abcdef-0x0123456789abcdef-s2-disabled")
struct kvm_ptdump_guest_state {
struct kvm_s2_mmu *mmu;
.release = kvm_pgtable_debugfs_close,
};
+void kvm_nested_s2_ptdump_create_debugfs(struct kvm_s2_mmu *mmu)
+{
+ struct dentry *dent;
+ char file_name[S2FNAMESZ];
+
+ snprintf(file_name, sizeof(file_name), "0x%016llx-0x%016llx-s2-%sabled",
+ mmu->tlb_vttbr,
+ mmu->tlb_vtcr,
+ mmu->nested_stage2_enabled ? "en" : "dis");
+
+ dent = debugfs_create_file(file_name, 0400,
+ mmu->arch->debugfs_nv_dentry, mmu,
+ &kvm_ptdump_guest_fops);
+
+ mmu->shadow_pt_debugfs_dentry = dent;
+}
+
+void kvm_nested_s2_ptdump_remove_debugfs(struct kvm_s2_mmu *mmu)
+{
+ debugfs_remove(mmu->shadow_pt_debugfs_dentry);
+}
+
void kvm_s2_ptdump_create_debugfs(struct kvm *kvm)
{
debugfs_create_file("stage2_page_tables", 0400, kvm->debugfs_dentry,
&kvm->arch.mmu, &kvm_pgtable_range_fops);
debugfs_create_file("stage2_levels", 0400, kvm->debugfs_dentry,
&kvm->arch.mmu, &kvm_pgtable_levels_fops);
+ if (cpus_have_final_cap(ARM64_HAS_NESTED_VIRT))
+ kvm->arch.debugfs_nv_dentry = debugfs_create_dir("nested", kvm->debugfs_dentry);
}