Received: by 2002:a05:6602:18e:0:0:0:0 with SMTP id m14csp2535424ioo; Mon, 23 May 2022 23:17:51 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzRCVA6eGAy0qj0PgglNlRpMxvBxvhsX+7he1IiePmdfbm2lzvR5w0u7hjVzbykgy4Z0wBq X-Received: by 2002:a17:906:87cd:b0:6ff:6a:f38 with SMTP id zb13-20020a17090687cd00b006ff006a0f38mr2456555ejb.511.1653373071507; Mon, 23 May 2022 23:17:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1653373071; cv=none; d=google.com; s=arc-20160816; b=mEgC+0sTLmrOsoNSGkTlmiR4DRCLUypg3BrSL98grMd+jetiKzvlIqMH6LqM6VCvGw 1R2xQcR6OE7pD8nggEP/bql0n5BHRa9PXGJlKkvTkykskhrl17nbWHEIcRu/l1FtVHan dQchdtssrGu2yVXlQqvF9+SrTuwRO1VSxWsAwWzV1FufKpS/6wg1qhgyBoP8zUH90Qyt gUTR8tN2ConwcKf3wGgpU19ED56LUdeKV/h1xAcPkkGAwYOAz6wSFyN2uJZwz0KO60dy Ed2ySZ/TNcx3MNkWEY8XSfwpKk8eDmLp9YOXjkENEwt+pXShs6B86HX+89acEMFFyRWd AoSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=CRo74G38j/dtUD25Nd/m5CBIH9wFCAZaHQKS0Jo+pbc=; b=EnmKZ73UFiKIbQBHqY/V0xc409589fUDmar44VcJjoO8JdACsZ5c1v4oT5esVTfWhj 5WzoDXOhWPBDCGQDXEnjxYBMSpSZZwFRJMlQ63AYozXXl+vRuk2Z6cRciwccXXjOOnXF bOO9v6+JRF4QtuRhSizEOTOJzS5e94tMP2CgAQMPxpCOLlm5LWSNpPq3KtOr19gA97kU oyZqBJYrq9K8MS3xF6m4w6r+3V3DLbRaNJGwWn+erRdslmL0NBf9TvE9u3/u5fC5Y/Sj Bo8o5RtmwAY6imjCz6RzF1Gh/b8cCY1cMpSvTB1OYiCXtuQdf+xrrn0NDENaPGuguHph uWtA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=WtxXLKpW; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ec28-20020a0564020d5c00b00425c0e470e5si15088999edb.375.2022.05.23.23.17.25; Mon, 23 May 2022 23:17:51 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=WtxXLKpW; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233034AbiEXEGT (ORCPT + 99 others); Tue, 24 May 2022 00:06:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234135AbiEXEGC (ORCPT ); Tue, 24 May 2022 00:06:02 -0400 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C1232A6 for ; Mon, 23 May 2022 21:05:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1653365159; x=1684901159; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hDDJt6MYhoCh7Rj4OmR2N48edxZ1+wqyexSmp2CDOh0=; b=WtxXLKpWDHXzOL7yzRV0f99RdT7B6jS1V+sVVI3oaOy36Nz1SzcyYFfS 4nz1ljaSYMEYnOi9ceeZApdFUIjJSPgNUUfE2771B/ro8BhqgEp//pFeX b8Uv5j17Y6Rl5qpWF34Ry4yoxi8kdvPsi5x+wFudx/I25JarNrs6fjtgH 948DQQrMKA+KIUlHDmhG3VEB7dmpi4FRdKhsY7wDS1D05EbhMF8ybX9TJ KqCkqUBns6P8EgCi7rsLulUJQO0M12vE5glAzZfbydNHjZ+bqxjDHyRSg QRpnwBvQzZu16Bj1E0r7dy08tBvood9HYOQNDbszjIT6cF+sKMPT3bU3b g==; X-IronPort-AV: E=McAfee;i="6400,9594,10356"; a="336479187" X-IronPort-AV: E=Sophos;i="5.91,248,1647327600"; d="scan'208";a="336479187" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga105.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2022 21:05:56 -0700 X-IronPort-AV: E=Sophos;i="5.91,248,1647327600"; d="scan'208";a="526242033" Received: from jwosulli-mobl1.ger.corp.intel.com (HELO skuppusw-desk1.home) ([10.212.165.122]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 May 2022 21:05:55 -0700 From: Kuppuswamy Sathyanarayanan To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org Cc: "H . Peter Anvin" , Kuppuswamy Sathyanarayanan , "Kirill A . Shutemov" , Tony Luck , Andi Kleen , Kai Huang , Wander Lairson Costa , Isaku Yamahata , marcelo.cerri@canonical.com, tim.gardner@canonical.com, khalid.elmously@canonical.com, philip.cox@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH v7 2/5] x86/tdx: Add TDX Guest event notify interrupt support Date: Mon, 23 May 2022 21:05:14 -0700 Message-Id: <20220524040517.703581-3-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220524040517.703581-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20220524040517.703581-1-sathyanarayanan.kuppuswamy@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Host-guest event notification via configured interrupt vector is useful in cases where a guest makes an asynchronous request and needs a callback from the host to indicate the completion or to let the host notify the guest about events like device removal. One usage example is, callback requirement of GetQuote asynchronous hypercall. In TDX guest, SetupEventNotifyInterrupt hypercall can be used by the guest to specify which interrupt vector to use as an event-notify vector to the VMM. Details about the SetupEventNotifyInterrupt hypercall can be found in TDX Guest-Host Communication Interface (GHCI) Specification, sec 3.5 "VP.VMCALL". Add a tdx_hcall_set_notify_intr() helper function to implement the SetupEventNotifyInterrupt hypercall. Reserve 0xec IRQ vector address for TDX guest to receive the event completion notification from VMM. Also add related IDT handler to process the notification event. Add support to track the notification event status via /proc/interrupts. Reviewed-by: Tony Luck Reviewed-by: Andi Kleen Acked-by: Kirill A. Shutemov Acked-by: Wander Lairson Costa Signed-off-by: Kuppuswamy Sathyanarayanan --- arch/x86/coco/tdx/tdx.c | 73 ++++++++++++++++++++++++++++++ arch/x86/include/asm/hardirq.h | 3 ++ arch/x86/include/asm/idtentry.h | 4 ++ arch/x86/include/asm/irq_vectors.h | 7 ++- arch/x86/include/asm/tdx.h | 4 ++ arch/x86/kernel/irq.c | 7 +++ 6 files changed, 97 insertions(+), 1 deletion(-) diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c index 03deb4d6920d..b49211994864 100644 --- a/arch/x86/coco/tdx/tdx.c +++ b/arch/x86/coco/tdx/tdx.c @@ -11,6 +11,10 @@ #include #include #include +#include +#include +#include +#include /* TDX module Call Leaf IDs */ #define TDX_GET_INFO 1 @@ -19,6 +23,7 @@ /* TDX hypercall Leaf IDs */ #define TDVMCALL_MAP_GPA 0x10001 +#define TDVMCALL_SETUP_NOTIFY_INTR 0x10004 /* MMIO direction */ #define EPT_READ 0 @@ -34,6 +39,28 @@ #define VE_GET_PORT_NUM(e) ((e) >> 16) #define VE_IS_IO_STRING(e) ((e) & BIT(4)) +/* + * Handler used to report notifications about + * TDX_GUEST_EVENT_NOTIFY_VECTOR IRQ. Currently it will be + * used only by the attestation driver. So, race condition + * with read/write operation is not considered. + */ +static void (*tdx_event_notify_handler)(void); + +/* Helper function to register tdx_event_notify_handler */ +void tdx_setup_ev_notify_handler(void (*handler)(void)) +{ + tdx_event_notify_handler = handler; +} +EXPORT_SYMBOL_GPL(tdx_setup_ev_notify_handler); + +/* Helper function to unregister tdx_event_notify_handler */ +void tdx_remove_ev_notify_handler(void) +{ + tdx_event_notify_handler = NULL; +} +EXPORT_SYMBOL_GPL(tdx_remove_ev_notify_handler); + /* * Wrapper for standard use of __tdx_hypercall with no output aside from * return code. @@ -98,6 +125,46 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9, panic("TDCALL %lld failed (Buggy TDX module!)\n", fn); } +/* TDX guest event notification handler */ +DEFINE_IDTENTRY_SYSVEC(sysvec_tdx_event_notify) +{ + struct pt_regs *old_regs = set_irq_regs(regs); + + inc_irq_stat(irq_tdx_event_notify_count); + + if (tdx_event_notify_handler) + tdx_event_notify_handler(); + + ack_APIC_irq(); + + set_irq_regs(old_regs); +} + +/* + * tdx_hcall_set_notify_intr() - Setup Event Notify Interrupt Vector. + * + * @vector: Vector address to be used for notification. + * + * return 0 on success or failure error number. + */ +static long tdx_hcall_set_notify_intr(u8 vector) +{ + /* Minimum vector value allowed is 32 */ + if (vector < 32) + return -EINVAL; + + /* + * Register callback vector address with VMM. More details + * about the ABI can be found in TDX Guest-Host-Communication + * Interface (GHCI), sec titled + * "TDG.VP.VMCALL". + */ + if (_tdx_hypercall(TDVMCALL_SETUP_NOTIFY_INTR, vector, 0, 0, 0)) + return -EIO; + + return 0; +} + static u64 get_cc_mask(void) { struct tdx_module_output out; @@ -688,5 +755,11 @@ void __init tdx_early_init(void) x86_platform.guest.enc_tlb_flush_required = tdx_tlb_flush_required; x86_platform.guest.enc_status_change_finish = tdx_enc_status_changed; + alloc_intr_gate(TDX_GUEST_EVENT_NOTIFY_VECTOR, + asm_sysvec_tdx_event_notify); + + if (tdx_hcall_set_notify_intr(TDX_GUEST_EVENT_NOTIFY_VECTOR)) + pr_warn("Setting event notification interrupt failed\n"); + pr_info("Guest detected\n"); } diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h index 275e7fd20310..582deff56210 100644 --- a/arch/x86/include/asm/hardirq.h +++ b/arch/x86/include/asm/hardirq.h @@ -44,6 +44,9 @@ typedef struct { unsigned int irq_hv_reenlightenment_count; unsigned int hyperv_stimer0_count; #endif +#if IS_ENABLED(CONFIG_INTEL_TDX_GUEST) + unsigned int irq_tdx_event_notify_count; +#endif } ____cacheline_aligned irq_cpustat_t; DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h index 72184b0b2219..655086dd940e 100644 --- a/arch/x86/include/asm/idtentry.h +++ b/arch/x86/include/asm/idtentry.h @@ -700,6 +700,10 @@ DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_xen_hvm_callback); DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR, sysvec_kvm_asyncpf_interrupt); #endif +#if IS_ENABLED(CONFIG_INTEL_TDX_GUEST) +DECLARE_IDTENTRY_SYSVEC(TDX_GUEST_EVENT_NOTIFY_VECTOR, sysvec_tdx_event_notify); +#endif + #undef X86_TRAP_OTHER #endif diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index 43dcb9284208..82ac0c0a34b1 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h @@ -104,7 +104,12 @@ #define HYPERV_STIMER0_VECTOR 0xed #endif -#define LOCAL_TIMER_VECTOR 0xec +#if IS_ENABLED(CONFIG_INTEL_TDX_GUEST) +/* Vector on which TDX Guest event notification is delivered */ +#define TDX_GUEST_EVENT_NOTIFY_VECTOR 0xec +#endif + +#define LOCAL_TIMER_VECTOR 0xeb #define NR_VECTORS 256 diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index 020c81a7c729..eb4db837cc44 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -67,6 +67,10 @@ void tdx_safe_halt(void); bool tdx_early_handle_ve(struct pt_regs *regs); +void tdx_setup_ev_notify_handler(void (*handler)(void)); + +void tdx_remove_ev_notify_handler(void); + #else static inline void tdx_early_init(void) { }; diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 766ffe3ba313..a96ecd866723 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -181,6 +181,13 @@ int arch_show_interrupts(struct seq_file *p, int prec) seq_printf(p, "%10u ", irq_stats(j)->kvm_posted_intr_wakeup_ipis); seq_puts(p, " Posted-interrupt wakeup event\n"); +#endif +#if IS_ENABLED(CONFIG_INTEL_TDX_GUEST) + seq_printf(p, "%*s: ", prec, "TGN"); + for_each_online_cpu(j) + seq_printf(p, "%10u ", + irq_stats(j)->irq_tdx_event_notify_count); + seq_puts(p, " TDX Guest event notification\n"); #endif return 0; } -- 2.25.1