KVM: TDX: Register TDX host key IDs to cgroup misc controller
authorZhiming Hu <zhiming.hu@intel.com>
Wed, 19 Feb 2025 14:02:51 +0000 (09:02 -0500)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 14 Mar 2025 18:20:51 +0000 (14:20 -0400)
TDX host key IDs (HKID) are limit resources in a machine, and the misc
cgroup lets the machine owner track their usage and limits the possibility
of abusing them outside the owner's control.

The cgroup v2 miscellaneous subsystem was introduced to control the
resource of AMD SEV & SEV-ES ASIDs.  Likewise introduce HKIDs as a misc
resource.

Signed-off-by: Zhiming Hu <zhiming.hu@intel.com>
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/tdx.h
arch/x86/kvm/vmx/tdx.c
arch/x86/kvm/vmx/tdx.h
arch/x86/virt/vmx/tdx/tdx.c
include/linux/misc_cgroup.h
kernel/cgroup/misc.c

index 1a8c687..2879fc5 100644 (file)
@@ -125,6 +125,7 @@ const char *tdx_dump_mce_info(struct mce *m);
 const struct tdx_sys_info *tdx_get_sysinfo(void);
 
 int tdx_guest_keyid_alloc(void);
+u32 tdx_get_nr_guest_keyids(void);
 void tdx_guest_keyid_free(unsigned int keyid);
 
 struct tdx_td {
@@ -180,6 +181,7 @@ u64 tdh_phymem_page_wbinvd_tdr(struct tdx_td *td);
 static inline void tdx_init(void) { }
 static inline int tdx_cpu_enable(void) { return -ENODEV; }
 static inline int tdx_enable(void)  { return -ENODEV; }
+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; }
 #endif /* CONFIG_INTEL_TDX_HOST */
index 2ac925e..01166cb 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/cpu.h>
 #include <asm/cpufeature.h>
+#include <linux/misc_cgroup.h>
 #include <asm/tdx.h>
 #include "capabilities.h"
 #include "mmu.h"
@@ -140,6 +141,9 @@ static inline void tdx_hkid_free(struct kvm_tdx *kvm_tdx)
        tdx_guest_keyid_free(kvm_tdx->hkid);
        kvm_tdx->hkid = -1;
        atomic_dec(&nr_configured_hkid);
+       misc_cg_uncharge(MISC_CG_RES_TDX, kvm_tdx->misc_cg, 1);
+       put_misc_cg(kvm_tdx->misc_cg);
+       kvm_tdx->misc_cg = NULL;
 }
 
 static inline bool is_hkid_assigned(struct kvm_tdx *kvm_tdx)
@@ -675,6 +679,10 @@ static int __tdx_td_init(struct kvm *kvm, struct td_params *td_params,
        if (ret < 0)
                return ret;
        kvm_tdx->hkid = ret;
+       kvm_tdx->misc_cg = get_current_misc_cg();
+       ret = misc_cg_try_charge(MISC_CG_RES_TDX, kvm_tdx->misc_cg, 1);
+       if (ret)
+               goto free_hkid;
 
        ret = -ENOMEM;
 
@@ -1459,6 +1467,11 @@ static int __init __tdx_bringup(void)
                goto get_sysinfo_err;
        }
 
+       if (misc_cg_set_capacity(MISC_CG_RES_TDX, tdx_get_nr_guest_keyids())) {
+               r = -EINVAL;
+               goto get_sysinfo_err;
+       }
+
        /*
         * Leave hardware virtualization enabled after TDX is enabled
         * successfully.  TDX CPU hotplug depends on this.
@@ -1475,6 +1488,7 @@ tdx_bringup_err:
 void tdx_cleanup(void)
 {
        if (enable_tdx) {
+               misc_cg_set_capacity(MISC_CG_RES_TDX, 0);
                __tdx_cleanup();
                kvm_disable_virtualization();
        }
index 6ec7ac1..0559126 100644 (file)
@@ -21,6 +21,7 @@ enum kvm_tdx_state {
 struct kvm_tdx {
        struct kvm kvm;
 
+       struct misc_cg *misc_cg;
        int hkid;
        enum kvm_tdx_state state;
 
index 9f0c482..3a272e9 100644 (file)
@@ -1476,6 +1476,12 @@ const struct tdx_sys_info *tdx_get_sysinfo(void)
 }
 EXPORT_SYMBOL_GPL(tdx_get_sysinfo);
 
+u32 tdx_get_nr_guest_keyids(void)
+{
+       return tdx_nr_guest_keyids;
+}
+EXPORT_SYMBOL_GPL(tdx_get_nr_guest_keyids);
+
 int tdx_guest_keyid_alloc(void)
 {
        return ida_alloc_range(&tdx_guest_keyid_pool, tdx_guest_keyid_start,
index 49eef10..8c0e4f4 100644 (file)
@@ -17,6 +17,10 @@ enum misc_res_type {
        MISC_CG_RES_SEV,
        /** @MISC_CG_RES_SEV_ES: AMD SEV-ES ASIDs resource */
        MISC_CG_RES_SEV_ES,
+#endif
+#ifdef CONFIG_INTEL_TDX_HOST
+       /* Intel TDX HKIDs resource */
+       MISC_CG_RES_TDX,
 #endif
        /** @MISC_CG_RES_TYPES: count of enum misc_res_type constants */
        MISC_CG_RES_TYPES
index 0e26068..264aad2 100644 (file)
@@ -24,6 +24,10 @@ static const char *const misc_res_name[] = {
        /* AMD SEV-ES ASIDs resource */
        "sev_es",
 #endif
+#ifdef CONFIG_INTEL_TDX_HOST
+       /* Intel TDX HKIDs resource */
+       "tdx",
+#endif
 };
 
 /* Root misc cgroup */