PAMT memory can add up to substantial portion of system memory. Account these pages and print them into /proc/meminfo as TDX. When no TD running PAMT memory consumption suppose to be zero. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> --- arch/x86/include/asm/set_memory.h | 2 ++ arch/x86/include/asm/tdx.h | 2 ++ arch/x86/mm/Makefile | 2 ++ arch/x86/mm/meminfo.c | 11 +++++++++++ arch/x86/mm/pat/set_memory.c | 2 +- arch/x86/virt/vmx/tdx/tdx.c | 26 ++++++++++++++++++++++++-- 6 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 arch/x86/mm/meminfo.c diff --git a/arch/x86/include/asm/set_memory.h b/arch/x86/include/asm/set_memory.h index 8d9f1c9aaa4c..e729e9f86e67 100644 --- a/arch/x86/include/asm/set_memory.h +++ b/arch/x86/include/asm/set_memory.h @@ -90,6 +90,8 @@ int set_direct_map_default_noflush(struct page *page); int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid); bool kernel_page_present(struct page *page); +void direct_pages_meminfo(struct seq_file *m); + extern int kernel_set_to_readonly; #endif /* _ASM_X86_SET_MEMORY_H */ diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index a134cf3ecd17..8091bf5b43cc 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -205,6 +205,7 @@ u64 tdh_phymem_page_wbinvd_hkid(u64 hkid, struct page *page); u64 tdh_phymem_pamt_add(unsigned long hpa, struct list_head *pamt_pages); u64 tdh_phymem_pamt_remove(unsigned long hpa, struct list_head *pamt_pages); +void tdx_meminfo(struct seq_file *m); #else static inline void tdx_init(void) { } static inline int tdx_cpu_enable(void) { return -ENODEV; } @@ -213,6 +214,7 @@ static inline u32 tdx_get_nr_guest_keyids(void) { return 0; } static inline const char *tdx_dump_mce_info(struct mce *m) { return NULL; } static inline const struct tdx_sys_info *tdx_get_sysinfo(void) { return NULL; } static inline int tdx_nr_pamt_pages(const struct tdx_sys_info *sysinfo) { return 0; } +static inline void tdx_meminfo(struct seq_file *m) {} #endif /* CONFIG_INTEL_TDX_HOST */ #endif /* !__ASSEMBLER__ */ diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 32035d5be5a0..311d60801871 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile @@ -38,6 +38,8 @@ CFLAGS_fault.o := -I $(src)/../include/asm/trace obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o +obj-$(CONFIG_PROC_FS) += meminfo.o + obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_PTDUMP) += dump_pagetables.o obj-$(CONFIG_PTDUMP_DEBUGFS) += debug_pagetables.o diff --git a/arch/x86/mm/meminfo.c b/arch/x86/mm/meminfo.c new file mode 100644 index 000000000000..7bdb5df014de --- /dev/null +++ b/arch/x86/mm/meminfo.c @@ -0,0 +1,11 @@ +#include <linux/proc_fs.h> +#include <linux/seq_file.h> + +#include <asm/set_memory.h> +#include <asm/tdx.h> + +void arch_report_meminfo(struct seq_file *m) +{ + direct_pages_meminfo(m); + tdx_meminfo(m); +} diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index def3d9284254..59432b92e80e 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -118,7 +118,7 @@ static void collapse_page_count(int level) direct_pages_count[level - 1] -= PTRS_PER_PTE; } -void arch_report_meminfo(struct seq_file *m) +void direct_pages_meminfo(struct seq_file *m) { seq_printf(m, "DirectMap4k: %8lu kB\n", direct_pages_count[PG_LEVEL_4K] << 2); diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 29defdb7f6bc..74bd81acef7b 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -2000,13 +2000,28 @@ u64 tdh_phymem_page_wbinvd_hkid(u64 hkid, struct page *page) } EXPORT_SYMBOL_GPL(tdh_phymem_page_wbinvd_hkid); +static atomic_long_t tdx_pamt_count = ATOMIC_LONG_INIT(0); + +void tdx_meminfo(struct seq_file *m) +{ + unsigned long usage; + + if (!cpu_feature_enabled(X86_FEATURE_TDX_HOST_PLATFORM)) + return; + + usage = atomic_long_read(&tdx_pamt_count) * + tdx_nr_pamt_pages(&tdx_sysinfo) * PAGE_SIZE / SZ_1K; + + seq_printf(m, "TDX: %8lu kB\n", usage); +} + u64 tdh_phymem_pamt_add(unsigned long hpa, struct list_head *pamt_pages) { struct tdx_module_args args = { .rcx = hpa, }; struct page *page; - u64 *p; + u64 *p, ret; WARN_ON_ONCE(!IS_ALIGNED(hpa & PAGE_MASK, PMD_SIZE)); @@ -2016,7 +2031,12 @@ u64 tdh_phymem_pamt_add(unsigned long hpa, struct list_head *pamt_pages) p++; } - return seamcall(TDH_PHYMEM_PAMT_ADD, &args); + ret = seamcall(TDH_PHYMEM_PAMT_ADD, &args); + + if (!ret) + atomic_long_inc(&tdx_pamt_count); + + return ret; } EXPORT_SYMBOL_GPL(tdh_phymem_pamt_add); @@ -2034,6 +2054,8 @@ u64 tdh_phymem_pamt_remove(unsigned long hpa, struct list_head *pamt_pages) if (ret) return ret; + atomic_long_dec(&tdx_pamt_count); + p = &args.rdx; for (int i = 0; i < tdx_nr_pamt_pages(&tdx_sysinfo); i++) { page = phys_to_page(*p); -- 2.47.2