From nobody Tue Dec 16 14:38:14 2025 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 56DDF393DCF for ; Thu, 30 Oct 2025 20:10:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761855048; cv=none; b=Wdzu8M00d0vxDs1EW68cb9uqxKX9kqub8DX/yEjUIqh6kNuOdhaE8cpGWwDqKHxO7b1CHLbR2tjFxkw4dDo2CF3rJdC/Lni41bCXjMMvnHfm6mhanqOHE8uIe2qKw5uDFOEqofmkaD7UsYk38e2KTKRnSHVMCexIlk2qmXlrGGA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761855048; c=relaxed/simple; bh=YzrAcOy4kMGvZnv8LvvV5Xf4Ed5dS9yiBLT7BTZP694=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=WMDXuP3ThHKDQZ7kRdDXBRYqScpFl00E1ySpTAs2ksSmqzAkT/B0wW6dJvFzfCBDZi7iOIuOl6NCGW22r7wexVHuMwoZXO2AHovaKtEDTF2StCjTXMeQEpYr70NUtqjsXe2Eo84BvIyb/NEilrYtXxlIYPBa2fPStyHuWdethg0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=C+gCfhRh; arc=none smtp.client-ip=209.85.214.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="C+gCfhRh" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-290bd7c835dso15688975ad.3 for ; Thu, 30 Oct 2025 13:10:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1761855046; x=1762459846; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=HvkYP5K0H7bzidqYh2GUowDdUiZwtqWzbaGK7ATegJ0=; b=C+gCfhRhfMaUbe/qu8MiC2e8Nf40nf/ouA7X9hpRiI+86we8eLyErfsa7/lc0f6MC6 zkOIK8RXVvKngO0fZJNc4dmIUNwhv1IFc7tOiIn752k5JX+gggJEnOgH37epTbZGYPfo sEGZFdn4V091DVO5CsDyV3a7kGBfBe5nKnHxatAytIXt6lZnYVAhR8tD8yCl8sIib4i1 mgOiFDyEvFdpeBg5PXqPLlDu+mkKyaA1mLMcd8P4fYabEfv+8jkoeEF1IRiEmeJs8od6 oebl02lCTWYFkCjIesXI65RfbieFgAjkRAT9CzChJM5vp5zNxYIL7dlkXkYmLT5DTib2 s/nw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761855046; x=1762459846; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=HvkYP5K0H7bzidqYh2GUowDdUiZwtqWzbaGK7ATegJ0=; b=VZHUkkkblhUdSP/pUr+me5j/M3cJ8xUv53iVCPaWmTIP+LMtfMfRJ/GcwOJImhprGA RtvdvCMduu5xp/bRef5M5ie1khjByH9Oz4zEzLUtU850R34P90UWsR+rHbKwbDSQc2PE paOPuAzGsTr9htokk87TmJBTVTFq7QqVyo2NTvI9gcGBS83IZUhVzr6ejU9qdVfshkTn sI/cFsyZAFMiCGCOMU5PGBb1npKsGuE+w9uHX3WnpVsyvjx/D4FQm0u7gqlfyfRfYJ/i Q6DMlyS+BkwiCKvVYXiuztTEwKYBCci1dwnMV436l8t5mtjiqSjdSeVlgyRBdo6NXkE1 +B3w== X-Forwarded-Encrypted: i=1; AJvYcCUmJypb0Yuw6C7XsjfeLtVSjNsvasskIfEWu94XiXAZVqJspKf2F9893hLJkxQhCv2yrkfaW6IPQrf8lAk=@vger.kernel.org X-Gm-Message-State: AOJu0Yy+cd7d20cDrqphbwibwNVHaLp9nHKbq1LspSNEmf4c2YhOBqsY jqiFyiLRQ0kEWHdmfNaR4fu/OKuNZTjgX/1j2ukGp+GsFymcY4Zzqq+UHJevh4AijpExxe6beW+ 8LIJ16Q== X-Google-Smtp-Source: AGHT+IHb++2Z/KelxH0n+uChReZvIH66SFbrsagpgu5Hbz52plhdUUxmf4i41V+1yu1qPk273gNABB2ooWc= X-Received: from plmm17.prod.google.com ([2002:a17:902:c451:b0:294:fdb9:5c0a]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a17:902:fc85:b0:24c:ed95:2725 with SMTP id d9443c01a7336-2951a3712f9mr11351465ad.4.1761855045661; Thu, 30 Oct 2025 13:10:45 -0700 (PDT) Reply-To: Sean Christopherson Date: Thu, 30 Oct 2025 13:09:41 -0700 In-Reply-To: <20251030200951.3402865-1-seanjc@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251030200951.3402865-1-seanjc@google.com> X-Mailer: git-send-email 2.51.1.930.gacf6e81ea2-goog Message-ID: <20251030200951.3402865-19-seanjc@google.com> Subject: [PATCH v4 18/28] KVM: TDX: Combine KVM_BUG_ON + pr_tdx_error() into TDX_BUG_ON() From: Sean Christopherson To: Marc Zyngier , Oliver Upton , Tianrui Zhao , Bibo Mao , Huacai Chen , Madhavan Srinivasan , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Christian Borntraeger , Janosch Frank , Claudio Imbrenda , Sean Christopherson , Paolo Bonzini , "Kirill A. Shutemov" Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, kvm@vger.kernel.org, loongarch@lists.linux.dev, linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, x86@kernel.org, linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, Ira Weiny , Kai Huang , Binbin Wu , Michael Roth , Yan Zhao , Vishal Annapurve , Rick Edgecombe , Ackerley Tng Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add TDX_BUG_ON() macros (with varying numbers of arguments) to deduplicate the myriad flows that do KVM_BUG_ON()/WARN_ON_ONCE() followed by a call to pr_tdx_error(). In addition to reducing boilerplate copy+paste code, this also helps ensure that KVM provides consistent handling of SEAMCALL errors. Opportunistically convert a handful of bare WARN_ON_ONCE() paths to the equivalent of KVM_BUG_ON(), i.e. have them terminate the VM. If a SEAMCALL error is fatal enough to WARN on, it's fatal enough to terminate the TD. Reviewed-by: Rick Edgecombe Signed-off-by: Sean Christopherson Reviewed-by: Binbin Wu Reviewed-by: Kai Huang --- arch/x86/kvm/vmx/tdx.c | 110 +++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 64 deletions(-) diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 260b569309cf..5e6f2d8b6014 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -24,20 +24,32 @@ #undef pr_fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt =20 -#define pr_tdx_error(__fn, __err) \ - pr_err_ratelimited("SEAMCALL %s failed: 0x%llx\n", #__fn, __err) +#define __TDX_BUG_ON(__err, __f, __kvm, __fmt, __args...) \ +({ \ + struct kvm *_kvm =3D (__kvm); \ + bool __ret =3D !!(__err); \ + \ + if (WARN_ON_ONCE(__ret && (!_kvm || !_kvm->vm_bugged))) { \ + if (_kvm) \ + kvm_vm_bugged(_kvm); \ + pr_err_ratelimited("SEAMCALL " __f " failed: 0x%llx" __fmt "\n",\ + __err, __args); \ + } \ + unlikely(__ret); \ +}) =20 -#define __pr_tdx_error_N(__fn_str, __err, __fmt, ...) \ - pr_err_ratelimited("SEAMCALL " __fn_str " failed: 0x%llx, " __fmt, __err= , __VA_ARGS__) +#define TDX_BUG_ON(__err, __fn, __kvm) \ + __TDX_BUG_ON(__err, #__fn, __kvm, "%s", "") =20 -#define pr_tdx_error_1(__fn, __err, __rcx) \ - __pr_tdx_error_N(#__fn, __err, "rcx 0x%llx\n", __rcx) +#define TDX_BUG_ON_1(__err, __fn, __rcx, __kvm) \ + __TDX_BUG_ON(__err, #__fn, __kvm, ", rcx 0x%llx", __rcx) =20 -#define pr_tdx_error_2(__fn, __err, __rcx, __rdx) \ - __pr_tdx_error_N(#__fn, __err, "rcx 0x%llx, rdx 0x%llx\n", __rcx, __rdx) +#define TDX_BUG_ON_2(__err, __fn, __rcx, __rdx, __kvm) \ + __TDX_BUG_ON(__err, #__fn, __kvm, ", rcx 0x%llx, rdx 0x%llx", __rcx, __rd= x) + +#define TDX_BUG_ON_3(__err, __fn, __rcx, __rdx, __r8, __kvm) \ + __TDX_BUG_ON(__err, #__fn, __kvm, ", rcx 0x%llx, rdx 0x%llx, r8 0x%llx", = __rcx, __rdx, __r8) =20 -#define pr_tdx_error_3(__fn, __err, __rcx, __rdx, __r8) \ - __pr_tdx_error_N(#__fn, __err, "rcx 0x%llx, rdx 0x%llx, r8 0x%llx\n", __r= cx, __rdx, __r8) =20 bool enable_tdx __ro_after_init; module_param_named(tdx, enable_tdx, bool, 0444); @@ -313,10 +325,9 @@ static int __tdx_reclaim_page(struct page *page) * before the HKID is released and control pages have also been * released at this point, so there is no possibility of contention. */ - if (WARN_ON_ONCE(err)) { - pr_tdx_error_3(TDH_PHYMEM_PAGE_RECLAIM, err, rcx, rdx, r8); + if (TDX_BUG_ON_3(err, TDH_PHYMEM_PAGE_RECLAIM, rcx, rdx, r8, NULL)) return -EIO; - } + return 0; } =20 @@ -404,8 +415,8 @@ static void tdx_flush_vp_on_cpu(struct kvm_vcpu *vcpu) return; =20 smp_call_function_single(cpu, tdx_flush_vp, &arg, 1); - if (KVM_BUG_ON(arg.err, vcpu->kvm)) - pr_tdx_error(TDH_VP_FLUSH, arg.err); + + TDX_BUG_ON(arg.err, TDH_VP_FLUSH, vcpu->kvm); } =20 void tdx_disable_virtualization_cpu(void) @@ -464,8 +475,7 @@ static void smp_func_do_phymem_cache_wb(void *unused) } =20 out: - if (WARN_ON_ONCE(err)) - pr_tdx_error(TDH_PHYMEM_CACHE_WB, err); + TDX_BUG_ON(err, TDH_PHYMEM_CACHE_WB, NULL); } =20 void tdx_mmu_release_hkid(struct kvm *kvm) @@ -504,8 +514,7 @@ void tdx_mmu_release_hkid(struct kvm *kvm) err =3D tdh_mng_vpflushdone(&kvm_tdx->td); if (err =3D=3D TDX_FLUSHVP_NOT_DONE) goto out; - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error(TDH_MNG_VPFLUSHDONE, err); + if (TDX_BUG_ON(err, TDH_MNG_VPFLUSHDONE, kvm)) { pr_err("tdh_mng_vpflushdone() failed. HKID %d is leaked.\n", kvm_tdx->hkid); goto out; @@ -528,8 +537,7 @@ void tdx_mmu_release_hkid(struct kvm *kvm) * tdh_mng_key_freeid() will fail. */ err =3D tdh_mng_key_freeid(&kvm_tdx->td); - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error(TDH_MNG_KEY_FREEID, err); + if (TDX_BUG_ON(err, TDH_MNG_KEY_FREEID, kvm)) { pr_err("tdh_mng_key_freeid() failed. HKID %d is leaked.\n", kvm_tdx->hkid); } else { @@ -580,10 +588,9 @@ static void tdx_reclaim_td_control_pages(struct kvm *k= vm) * when it is reclaiming TDCS). */ err =3D tdh_phymem_page_wbinvd_tdr(&kvm_tdx->td); - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error(TDH_PHYMEM_PAGE_WBINVD, err); + if (TDX_BUG_ON(err, TDH_PHYMEM_PAGE_WBINVD, kvm)) return; - } + tdx_quirk_reset_page(kvm_tdx->td.tdr_page); =20 __free_page(kvm_tdx->td.tdr_page); @@ -606,11 +613,8 @@ static int tdx_do_tdh_mng_key_config(void *param) =20 /* TDX_RND_NO_ENTROPY related retries are handled by sc_retry() */ err =3D tdh_mng_key_config(&kvm_tdx->td); - - if (KVM_BUG_ON(err, &kvm_tdx->kvm)) { - pr_tdx_error(TDH_MNG_KEY_CONFIG, err); + if (TDX_BUG_ON(err, TDH_MNG_KEY_CONFIG, &kvm_tdx->kvm)) return -EIO; - } =20 return 0; } @@ -1601,10 +1605,8 @@ static int tdx_mem_page_add(struct kvm *kvm, gfn_t g= fn, enum pg_level level, if (unlikely(tdx_operand_busy(err))) return -EBUSY; =20 - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error_2(TDH_MEM_PAGE_ADD, err, entry, level_state); + if (TDX_BUG_ON_2(err, TDH_MEM_PAGE_ADD, entry, level_state, kvm)) return -EIO; - } =20 return 0; } @@ -1623,10 +1625,8 @@ static int tdx_mem_page_aug(struct kvm *kvm, gfn_t g= fn, if (unlikely(tdx_operand_busy(err))) return -EBUSY; =20 - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error_2(TDH_MEM_PAGE_AUG, err, entry, level_state); + if (TDX_BUG_ON_2(err, TDH_MEM_PAGE_AUG, entry, level_state, kvm)) return -EIO; - } =20 return 0; } @@ -1675,10 +1675,8 @@ static int tdx_sept_link_private_spt(struct kvm *kvm= , gfn_t gfn, if (unlikely(tdx_operand_busy(err))) return -EBUSY; =20 - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error_2(TDH_MEM_SEPT_ADD, err, entry, level_state); + if (TDX_BUG_ON_2(err, TDH_MEM_SEPT_ADD, entry, level_state, kvm)) return -EIO; - } =20 return 0; } @@ -1726,8 +1724,7 @@ static void tdx_track(struct kvm *kvm) tdx_no_vcpus_enter_stop(kvm); } =20 - if (KVM_BUG_ON(err, kvm)) - pr_tdx_error(TDH_MEM_TRACK, err); + TDX_BUG_ON(err, TDH_MEM_TRACK, kvm); =20 kvm_make_all_cpus_request(kvm, KVM_REQ_OUTSIDE_GUEST_MODE); } @@ -1784,10 +1781,8 @@ static void tdx_sept_remove_private_spte(struct kvm = *kvm, gfn_t gfn, tdx_no_vcpus_enter_stop(kvm); } =20 - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error_2(TDH_MEM_RANGE_BLOCK, err, entry, level_state); + if (TDX_BUG_ON_2(err, TDH_MEM_RANGE_BLOCK, entry, level_state, kvm)) return; - } =20 /* * TDX requires TLB tracking before dropping private page. Do @@ -1814,16 +1809,12 @@ static void tdx_sept_remove_private_spte(struct kvm= *kvm, gfn_t gfn, tdx_no_vcpus_enter_stop(kvm); } =20 - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error_2(TDH_MEM_PAGE_REMOVE, err, entry, level_state); + if (TDX_BUG_ON_2(err, TDH_MEM_PAGE_REMOVE, entry, level_state, kvm)) return; - } =20 err =3D tdh_phymem_page_wbinvd_hkid((u16)kvm_tdx->hkid, page); - if (KVM_BUG_ON(err, kvm)) { - pr_tdx_error(TDH_PHYMEM_PAGE_WBINVD, err); + if (TDX_BUG_ON(err, TDH_PHYMEM_PAGE_WBINVD, kvm)) return; - } =20 tdx_quirk_reset_page(page); } @@ -2463,8 +2454,7 @@ static int __tdx_td_init(struct kvm *kvm, struct td_p= arams *td_params, goto free_packages; } =20 - if (WARN_ON_ONCE(err)) { - pr_tdx_error(TDH_MNG_CREATE, err); + if (TDX_BUG_ON(err, TDH_MNG_CREATE, kvm)) { ret =3D -EIO; goto free_packages; } @@ -2505,8 +2495,7 @@ static int __tdx_td_init(struct kvm *kvm, struct td_p= arams *td_params, ret =3D -EAGAIN; goto teardown; } - if (WARN_ON_ONCE(err)) { - pr_tdx_error(TDH_MNG_ADDCX, err); + if (TDX_BUG_ON(err, TDH_MNG_ADDCX, kvm)) { ret =3D -EIO; goto teardown; } @@ -2523,8 +2512,7 @@ static int __tdx_td_init(struct kvm *kvm, struct td_p= arams *td_params, *seamcall_err =3D err; ret =3D -EINVAL; goto teardown; - } else if (WARN_ON_ONCE(err)) { - pr_tdx_error_1(TDH_MNG_INIT, err, rcx); + } else if (TDX_BUG_ON_1(err, TDH_MNG_INIT, rcx, kvm)) { ret =3D -EIO; goto teardown; } @@ -2792,10 +2780,8 @@ static int tdx_td_finalize(struct kvm *kvm, struct k= vm_tdx_cmd *cmd) cmd->hw_error =3D tdh_mr_finalize(&kvm_tdx->td); if (tdx_operand_busy(cmd->hw_error)) return -EBUSY; - if (KVM_BUG_ON(cmd->hw_error, kvm)) { - pr_tdx_error(TDH_MR_FINALIZE, cmd->hw_error); + if (TDX_BUG_ON(cmd->hw_error, TDH_MR_FINALIZE, kvm)) return -EIO; - } =20 kvm_tdx->state =3D TD_STATE_RUNNABLE; /* TD_STATE_RUNNABLE must be set before 'pre_fault_allowed' */ @@ -2882,16 +2868,14 @@ static int tdx_td_vcpu_init(struct kvm_vcpu *vcpu, = u64 vcpu_rcx) } =20 err =3D tdh_vp_create(&kvm_tdx->td, &tdx->vp); - if (KVM_BUG_ON(err, vcpu->kvm)) { + if (TDX_BUG_ON(err, TDH_VP_CREATE, vcpu->kvm)) { ret =3D -EIO; - pr_tdx_error(TDH_VP_CREATE, err); goto free_tdcx; } =20 for (i =3D 0; i < kvm_tdx->td.tdcx_nr_pages; i++) { err =3D tdh_vp_addcx(&tdx->vp, tdx->vp.tdcx_pages[i]); - if (KVM_BUG_ON(err, vcpu->kvm)) { - pr_tdx_error(TDH_VP_ADDCX, err); + if (TDX_BUG_ON(err, TDH_VP_ADDCX, vcpu->kvm)) { /* * Pages already added are reclaimed by the vcpu_free * method, but the rest are freed here. @@ -2905,10 +2889,8 @@ static int tdx_td_vcpu_init(struct kvm_vcpu *vcpu, u= 64 vcpu_rcx) } =20 err =3D tdh_vp_init(&tdx->vp, vcpu_rcx, vcpu->vcpu_id); - if (KVM_BUG_ON(err, vcpu->kvm)) { - pr_tdx_error(TDH_VP_INIT, err); + if (TDX_BUG_ON(err, TDH_VP_INIT, vcpu->kvm)) return -EIO; - } =20 vcpu->arch.mp_state =3D KVM_MP_STATE_RUNNABLE; =20 --=20 2.51.1.930.gacf6e81ea2-goog