From patchwork Fri Apr 15 22:01:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 12815438 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 49B68C433F5 for ; Fri, 15 Apr 2022 22:01:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356276AbiDOWEE (ORCPT ); Fri, 15 Apr 2022 18:04:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40640 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231476AbiDOWEB (ORCPT ); Fri, 15 Apr 2022 18:04:01 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B33B62A278; Fri, 15 Apr 2022 15:01:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650060091; x=1681596091; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4jrQfGzOOz8NYN3WWxiP4ysiHxJPzuBRgwyiKBFv+oo=; b=DrD8wg5aUCfBgemjiurqYSfVJ2uJzxi6AmMwDysWkH+8Olz1HSpO0RZA jkLcfWxDG+3iMNlg3Qg92m+nAzca5N67Spk0EgeP8a2EjsfxDjWOuiiUS GUUn9/WA3KnQvxKCXEUB3DKAlWQAxcrxA9su7ifWj4vNks5y89aR4wwZ2 HrgZvAFcyxwNrozPg8m5/TQR0YSSzp36COpvYP38Q5xm9RVekb6yR+S9H 9CONNJ4H2j3/J64cc1UipvoO+kBGCzYknYO+D9QZzUjGBAQ32QLeB+8Y+ EtJJl/+w2XhEtKjZtiGzLG/zeU4K8n+dQ6gjrzxSqstbftjRhKe8ue+vR g==; X-IronPort-AV: E=McAfee;i="6400,9594,10318"; a="288303530" X-IronPort-AV: E=Sophos;i="5.90,263,1643702400"; d="scan'208";a="288303530" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Apr 2022 15:01:30 -0700 X-IronPort-AV: E=Sophos;i="5.90,263,1643702400"; d="scan'208";a="612949090" Received: from smashtou-mobl1.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.212.128.210]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Apr 2022 15:01:29 -0700 From: Kuppuswamy Sathyanarayanan To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Hans de Goede , Mark Gross Cc: "H . Peter Anvin" , Kuppuswamy Sathyanarayanan , "Kirill A . Shutemov" , Tony Luck , Andi Kleen , linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v3 1/4] x86/tdx: Add tdx_mcall_tdreport() API support Date: Fri, 15 Apr 2022 15:01:06 -0700 Message-Id: <20220415220109.282834-2-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220415220109.282834-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20220415220109.282834-1-sathyanarayanan.kuppuswamy@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org In TDX guest, attestation is mainly used to verify the trustworthiness of a TD to the 3rd party key servers. First step in attestation process is to get the TDREPORT data and the generated data is further used in subsequent steps of the attestation process. TDREPORT data contains details like TDX module version information, measurement of the TD, along with a TD-specified nonce Add a wrapper function (tdx_mcall_tdreport()) to get the TDREPORT from the TDX Module. More details about the TDREPORT TDCALL can be found in TDX Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section titled "TDCALL [MR.REPORT]". Steps involved in attestation process can be found in TDX Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section titled "TD attestation" This API will be mainly used by the attestation driver. Attestation driver support will be added by upcoming patches. Reviewed-by: Tony Luck Reviewed-by: Andi Kleen Acked-by: Kirill A. Shutemov Signed-off-by: Kuppuswamy Sathyanarayanan --- arch/x86/coco/tdx/tdx.c | 46 ++++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/tdx.h | 2 ++ 2 files changed, 48 insertions(+) diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c index 03deb4d6920d..3e409b618d3f 100644 --- a/arch/x86/coco/tdx/tdx.c +++ b/arch/x86/coco/tdx/tdx.c @@ -11,10 +11,12 @@ #include #include #include +#include /* TDX module Call Leaf IDs */ #define TDX_GET_INFO 1 #define TDX_GET_VEINFO 3 +#define TDX_GET_REPORT 4 #define TDX_ACCEPT_PAGE 6 /* TDX hypercall Leaf IDs */ @@ -34,6 +36,10 @@ #define VE_GET_PORT_NUM(e) ((e) >> 16) #define VE_IS_IO_STRING(e) ((e) & BIT(4)) +/* TDX Module call error codes */ +#define TDCALL_RETURN_CODE_MASK 0xffffffff00000000 +#define TDCALL_RETURN_CODE(a) ((a) & TDCALL_RETURN_CODE_MASK) + /* * Wrapper for standard use of __tdx_hypercall with no output aside from * return code. @@ -98,6 +104,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_mcall_tdreport() - Generate TDREPORT_STRUCT using TDCALL. + * + * @data : Address of 1024B aligned data to store + * TDREPORT_STRUCT. + * @reportdata : Address of 64B aligned report data + * + * return 0 on success or failure error number. + */ +long tdx_mcall_tdreport(void *data, void *reportdata) +{ + u64 ret; + + /* + * Check for a valid TDX guest to ensure this API is only + * used by TDX guest platform. Also make sure "data" and + * "reportdata" pointers are valid. + */ + if (!data || !reportdata || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return -EINVAL; + + /* + * Pass the physical address of user generated reportdata + * and the physical address of out pointer to store the + * TDREPORT data to the TDX module to generate the + * TD report. Generated data contains measurements/configuration + * data of the TD guest. More info about ABI can be found in TDX + * Guest-Host-Communication Interface (GHCI), sec titled + * "TDG.MR.REPORT". + */ + ret = __tdx_module_call(TDX_GET_REPORT, virt_to_phys(data), + virt_to_phys(reportdata), 0, 0, NULL); + + if (ret) + return TDCALL_RETURN_CODE(ret); + + return 0; +} +EXPORT_SYMBOL_GPL(tdx_mcall_tdreport); + static u64 get_cc_mask(void) { struct tdx_module_output out; diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index 020c81a7c729..a151f69dd6ef 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -67,6 +67,8 @@ void tdx_safe_halt(void); bool tdx_early_handle_ve(struct pt_regs *regs); +long tdx_mcall_tdreport(void *data, void *reportdata); + #else static inline void tdx_early_init(void) { }; From patchwork Fri Apr 15 22:01:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 12815442 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96F5CC43219 for ; Fri, 15 Apr 2022 22:01:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356310AbiDOWEJ (ORCPT ); Fri, 15 Apr 2022 18:04:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40668 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356269AbiDOWEC (ORCPT ); Fri, 15 Apr 2022 18:04:02 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 270FA35DE2; Fri, 15 Apr 2022 15:01:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650060093; x=1681596093; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MFGHhgLkVammlMUcup3VFIj0qo6uQ1md0in8hWs4fk0=; b=aAQvBSlMRtbqBeDLsytxJbLWtLYsX70UPMlNjdMoOJzRG8XO/zbUuGTm WnDI8WzvLoQmlvvI0Q26jZQz9doSswnZWtZASvJ6iA0gEmfcZLokOtRT1 oSceJMpeEmjEUfn+/2Qna6MaXRB5wtxKmDMdPJ5lKVZHz9Y+tEmN5p68J wYpHTPu8QRYx0gsRzYw1ti6GxxYzBSP+hKq4vIAbNq8GBOlC3SETszR8e 7bucajJzVI4MXi2Z3QklYDkFzKybBteA9J3PVj8d/P+48LoMVBglQmzvE MgF+9ejNrOm4IjbEwH4ARo/VStc8o3L15wZeB4N3uVc22W01KIqyGkooP Q==; X-IronPort-AV: E=McAfee;i="6400,9594,10318"; a="288303532" X-IronPort-AV: E=Sophos;i="5.90,263,1643702400"; d="scan'208";a="288303532" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Apr 2022 15:01:31 -0700 X-IronPort-AV: E=Sophos;i="5.90,263,1643702400"; d="scan'208";a="612949094" Received: from smashtou-mobl1.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.212.128.210]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Apr 2022 15:01:30 -0700 From: Kuppuswamy Sathyanarayanan To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Hans de Goede , Mark Gross Cc: "H . Peter Anvin" , Kuppuswamy Sathyanarayanan , "Kirill A . Shutemov" , Tony Luck , Andi Kleen , linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v3 2/4] x86/tdx: Add tdx_hcall_get_quote() API support Date: Fri, 15 Apr 2022 15:01:07 -0700 Message-Id: <20220415220109.282834-3-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220415220109.282834-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20220415220109.282834-1-sathyanarayanan.kuppuswamy@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Attestation is the process used by two un-trusted entities to prove to each other that it can be trusted. In TDX guest, attestation is mainly used to verify the trustworthiness of a TD to the 3rd party key servers. First step in the attestation process is to generate the TDREPORT data. This support is added using tdx_mcall_tdreport() API. The second stage in the attestation process is for the guest to request the VMM generate and sign a quote based on the TDREPORT acquired earlier. More details about the steps involved in attestation process can be found in TDX Guest-Host Communication Interface (GHCI) for Intel TDX 1.5, section titled "TD attestation" Add tdx_hcall_get_quote() helper function to implement the GetQuote hypercall. More details about the GetQuote TDVMCALL are in the Guest-Host Communication Interface (GHCI) Specification, sec 3.3, titled "VP.VMCALL". This will be used by the TD attestation driver in follow-on patches. Reviewed-by: Tony Luck Reviewed-by: Andi Kleen Acked-by: Kirill A. Shutemov Signed-off-by: Kuppuswamy Sathyanarayanan --- arch/x86/coco/tdx/tdx.c | 38 ++++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/tdx.h | 2 ++ 2 files changed, 40 insertions(+) diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c index 3e409b618d3f..c259d81a5d7f 100644 --- a/arch/x86/coco/tdx/tdx.c +++ b/arch/x86/coco/tdx/tdx.c @@ -21,6 +21,7 @@ /* TDX hypercall Leaf IDs */ #define TDVMCALL_MAP_GPA 0x10001 +#define TDVMCALL_GET_QUOTE 0x10002 /* MMIO direction */ #define EPT_READ 0 @@ -144,6 +145,43 @@ long tdx_mcall_tdreport(void *data, void *reportdata) } EXPORT_SYMBOL_GPL(tdx_mcall_tdreport); +/* + * tdx_hcall_get_quote() - Generate TDQUOTE using TDREPORT_STRUCT. + * + * @data : Address of 8KB GPA memory which contains + * TDREPORT_STRUCT. + * @len : Length of the GPA in bytes. + * + * return 0 on success or failure error number. + */ +long tdx_hcall_get_quote(void *data, u64 len) +{ + u64 ret; + + /* + * Use confidential guest TDX check to ensure this API is only + * used by TDX guest platforms. + */ + if (!data || !cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return -EINVAL; + + /* + * Pass the physical address of tdreport data to the VMM + * and trigger the tdquote generation. Quote data will be + * stored back in the same physical address space. More info + * about ABI can be found in TDX Guest-Host-Communication + * Interface (GHCI), sec titled "TDG.VP.VMCALL". + */ + ret = _tdx_hypercall(TDVMCALL_GET_QUOTE, cc_mkdec(virt_to_phys(data)), + len, 0, 0); + + if (ret) + return ret; + + return 0; +} +EXPORT_SYMBOL_GPL(tdx_hcall_get_quote); + static u64 get_cc_mask(void) { struct tdx_module_output out; diff --git a/arch/x86/include/asm/tdx.h b/arch/x86/include/asm/tdx.h index a151f69dd6ef..014cc6192dc5 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -69,6 +69,8 @@ bool tdx_early_handle_ve(struct pt_regs *regs); long tdx_mcall_tdreport(void *data, void *reportdata); +long tdx_hcall_get_quote(void *data, u64 len); + #else static inline void tdx_early_init(void) { }; From patchwork Fri Apr 15 22:01:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 12815441 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03693C433F5 for ; Fri, 15 Apr 2022 22:01:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232282AbiDOWEH (ORCPT ); Fri, 15 Apr 2022 18:04:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40702 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242867AbiDOWEE (ORCPT ); Fri, 15 Apr 2022 18:04:04 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB70D3A1BC; Fri, 15 Apr 2022 15:01:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650060093; x=1681596093; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oydq3+d7mQBMPGq1EzH0wO2zS1pExRBKPUcB38S3vLo=; b=iWPJmoWV2Gq9sUIqmzJwgJM/xs56g26NQrS4Y2YAAQbKirkAbEz72D9D 1oQ2PA0Bth/rVXSVnkBDdwJrp1Dzhe0UVf5R+q0vCaE949IXwl64OH7p+ eNGGE+515yixmDZRtc0zvbCOI5VQDzBrlimi1zqes2W8y4xTERIos3gkO QbpA+Jac27ZxT5S31aXwSk5Bz48f4AgV3K45dcpxrGB2TbGr16BY5laOe DE6wNwvsId67V9Rh9ie7pfIFNy1FsAo0w5NwyvaOd3TXAPQXsp+Z7rYQe Do7J43weh1KQhVkzDWSny6B5vnqoHYXZgJmcEQxtfEnfYAUM85ogbxFzo A==; X-IronPort-AV: E=McAfee;i="6400,9594,10318"; a="288303534" X-IronPort-AV: E=Sophos;i="5.90,263,1643702400"; d="scan'208";a="288303534" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Apr 2022 15:01:31 -0700 X-IronPort-AV: E=Sophos;i="5.90,263,1643702400"; d="scan'208";a="612949097" Received: from smashtou-mobl1.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.212.128.210]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Apr 2022 15:01:31 -0700 From: Kuppuswamy Sathyanarayanan To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Hans de Goede , Mark Gross Cc: "H . Peter Anvin" , Kuppuswamy Sathyanarayanan , "Kirill A . Shutemov" , Tony Luck , Andi Kleen , linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v3 3/4] x86/tdx: Add TDX Guest event notify interrupt support Date: Fri, 15 Apr 2022 15:01:08 -0700 Message-Id: <20220415220109.282834-4-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220415220109.282834-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20220415220109.282834-1-sathyanarayanan.kuppuswamy@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Host-guest event notification via configured interrupt vector is useful in cases where guest makes asynchronous request (like attestation quote generate request) and need a callback from host to indicate the completion or to let host notify the guest about events like device removal 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 Signed-off-by: Kuppuswamy Sathyanarayanan --- arch/x86/coco/tdx/tdx.c | 77 ++++++++++++++++++++++++++++++ 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, 101 insertions(+), 1 deletion(-) diff --git a/arch/x86/coco/tdx/tdx.c b/arch/x86/coco/tdx/tdx.c index c259d81a5d7f..3b6fdfb31e87 100644 --- a/arch/x86/coco/tdx/tdx.c +++ b/arch/x86/coco/tdx/tdx.c @@ -12,6 +12,10 @@ #include #include #include +#include +#include +#include +#include /* TDX module Call Leaf IDs */ #define TDX_GET_INFO 1 @@ -22,6 +26,7 @@ /* TDX hypercall Leaf IDs */ #define TDVMCALL_MAP_GPA 0x10001 #define TDVMCALL_GET_QUOTE 0x10002 +#define TDVMCALL_SETUP_NOTIFY_INTR 0x10004 /* MMIO direction */ #define EPT_READ 0 @@ -41,6 +46,28 @@ #define TDCALL_RETURN_CODE_MASK 0xffffffff00000000 #define TDCALL_RETURN_CODE(a) ((a) & TDCALL_RETURN_CODE_MASK) +/* + * 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. @@ -105,6 +132,21 @@ 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_mcall_tdreport() - Generate TDREPORT_STRUCT using TDCALL. * @@ -182,6 +224,35 @@ long tdx_hcall_get_quote(void *data, u64 len) } EXPORT_SYMBOL_GPL(tdx_hcall_get_quote); +/* + * 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) +{ + u64 ret; + + /* 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". + */ + ret = _tdx_hypercall(TDVMCALL_SETUP_NOTIFY_INTR, vector, 0, 0, 0); + + if (ret) + return ret; + + return 0; +} + static u64 get_cc_mask(void) { struct tdx_module_output out; @@ -772,5 +843,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..331d343e1d46 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 +#ifdef 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 014cc6192dc5..7b8479f46757 100644 --- a/arch/x86/include/asm/tdx.h +++ b/arch/x86/include/asm/tdx.h @@ -71,6 +71,10 @@ long tdx_mcall_tdreport(void *data, void *reportdata); long tdx_hcall_get_quote(void *data, u64 len); +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; } From patchwork Fri Apr 15 22:01:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kuppuswamy Sathyanarayanan X-Patchwork-Id: 12815440 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 388FDC433FE for ; Fri, 15 Apr 2022 22:01:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1356274AbiDOWEG (ORCPT ); Fri, 15 Apr 2022 18:04:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1356279AbiDOWEF (ORCPT ); Fri, 15 Apr 2022 18:04:05 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0CF843A723; Fri, 15 Apr 2022 15:01:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1650060094; x=1681596094; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vymGa2uYsRtZ2q7z3TTqcP9ARcW12kzwr1nbT+PSPeE=; b=Wtj8HZQgeUxo8pU3/J0eylwHTVQjzYk+cM3xHBDhiOVcT06e7pzQpeLb pDnIoDAo+OXJYAwQNCdSEOUEEnkE8fEEh1LtTYcKJYb/F8dJ7W1Oppl4w wIsKdUdcFPSXE3zleXI+92esx94A1AoImFh3bwUfbN0q1X4mh9Fp45Lsv RSZ11tB2kI81s+TqOHh5CzGCkqJ4+x9SsYqP2/T8Xme2JZMPR7Dulb3zz fQ+Tavx5nm8F7gkq7jWghYDTFdNTRCI2oPG+TvC1q7t+j/fY8ZWKREnl5 AOt3kszTdQSXiSgpIQPSW7aj0DTIcsM4KDHnw/hO3v7bkbozVnT1z3nJH w==; X-IronPort-AV: E=McAfee;i="6400,9594,10318"; a="288303537" X-IronPort-AV: E=Sophos;i="5.90,263,1643702400"; d="scan'208";a="288303537" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Apr 2022 15:01:32 -0700 X-IronPort-AV: E=Sophos;i="5.90,263,1643702400"; d="scan'208";a="612949103" Received: from smashtou-mobl1.amr.corp.intel.com (HELO skuppusw-desk1.amr.corp.intel.com) ([10.212.128.210]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 15 Apr 2022 15:01:31 -0700 From: Kuppuswamy Sathyanarayanan To: Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, Hans de Goede , Mark Gross Cc: "H . Peter Anvin" , Kuppuswamy Sathyanarayanan , "Kirill A . Shutemov" , Tony Luck , Andi Kleen , linux-kernel@vger.kernel.org, platform-driver-x86@vger.kernel.org Subject: [PATCH v3 4/4] platform/x86: intel_tdx_attest: Add TDX Guest attestation interface driver Date: Fri, 15 Apr 2022 15:01:09 -0700 Message-Id: <20220415220109.282834-5-sathyanarayanan.kuppuswamy@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220415220109.282834-1-sathyanarayanan.kuppuswamy@linux.intel.com> References: <20220415220109.282834-1-sathyanarayanan.kuppuswamy@linux.intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org TDX guest supports encrypted disk as root or secondary drives. Decryption keys required to access such drives are usually maintained by 3rd party key servers. Attestation is required by 3rd party key servers to get the key for an encrypted disk volume, or possibly other encrypted services. Attestation is used to prove to the key server that the TD guest is running in a valid TD and the kernel and virtual BIOS and other environment are secure. During the boot process various components before the kernel accumulate hashes in the TDX module, which can then combined into a report. This would typically include a hash of the bios, bios configuration, boot loader, command line, kernel, initrd. After checking the hashes the key server will securely release the keys. The actual details of the attestation protocol depend on the particular key server configuration, but some parts are common and need to communicate with the TDX module. This communication is implemented in the attestation driver. The supported steps are: 1. TD guest generates the TDREPORT that contains version information about the Intel TDX module, measurement of the TD, along with a TD-specified nonce.   2. TD guest shares the TDREPORT with TD host via GetQuote hypercall which is used by the host to generate a quote via quoting enclave (QE).   3. Quote generation completion notification is sent to TD OS via callback interrupt vector configured by TD using SetupEventNotifyInterrupt hypercall.   4. After receiving the generated TDQUOTE, a remote verifier can be used to verify the quote and confirm the trustworthiness of the TD. Attestation agent uses IOCTLs implemented by the attestation driver to complete the various steps of the attestation process. Also note that, explicit access permissions are not enforced in this driver because the quote and measurements are not a secret. However the access permissions of the device node can be used to set any desired access policy. The udev default is usually root access only. TDX_CMD_GEN_QUOTE IOCTL can be used to create an computation on the host, but TDX assumes that the host is able to deal with malicious guest flooding it anyways. The interaction with the TDX module is like a RPM protocol here. There are several operations (get tdreport, get quote) that need to input a blob, and then output another blob. It was considered to use a sysfs interface for this, but it doesn't fit well into the standard sysfs model for configuring values. It would be possible to do read/write on files, but it would need multiple file descriptors, which would be somewhat messy. ioctls seems to be the best fitting and simplest model here. There is one ioctl per operation, that takes the input blob and returns the output blob, and as well as auxiliary ioctls to return the blob lengths. The ioctls are documented in the header file.  [Chenyi Qiang: Proposed struct tdx_gen_quote for passing user buffer] Reviewed-by: Tony Luck Reviewed-by: Andi Kleen Acked-by: Kirill A. Shutemov Acked-by: Hans de Goede Signed-off-by: Kuppuswamy Sathyanarayanan --- Changes since v2: * Combined attestation related global variables into struct attest_dev to make the code clean. * Added support to pass TDREPORT and GetQuote TDCALLs error code back to user on failure. * Modified the driver to use platform device driver model and added check to ensure only one device is allowed. drivers/platform/x86/intel/Kconfig | 2 +- drivers/platform/x86/intel/Makefile | 1 + drivers/platform/x86/intel/tdx/Kconfig | 13 + drivers/platform/x86/intel/tdx/Makefile | 3 + .../platform/x86/intel/tdx/intel_tdx_attest.c | 302 ++++++++++++++++++ include/uapi/misc/tdx.h | 42 +++ 6 files changed, 362 insertions(+), 1 deletion(-) create mode 100644 drivers/platform/x86/intel/tdx/Kconfig create mode 100644 drivers/platform/x86/intel/tdx/Makefile create mode 100644 drivers/platform/x86/intel/tdx/intel_tdx_attest.c create mode 100644 include/uapi/misc/tdx.h diff --git a/drivers/platform/x86/intel/Kconfig b/drivers/platform/x86/intel/Kconfig index 1f01a8a23c57..a2e2a5a29bde 100644 --- a/drivers/platform/x86/intel/Kconfig +++ b/drivers/platform/x86/intel/Kconfig @@ -12,7 +12,7 @@ source "drivers/platform/x86/intel/speed_select_if/Kconfig" source "drivers/platform/x86/intel/telemetry/Kconfig" source "drivers/platform/x86/intel/wmi/Kconfig" source "drivers/platform/x86/intel/uncore-frequency/Kconfig" - +source "drivers/platform/x86/intel/tdx/Kconfig" config INTEL_HID_EVENT tristate "Intel HID Event" diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/intel/Makefile index c61bc3e97121..6b7c94051519 100644 --- a/drivers/platform/x86/intel/Makefile +++ b/drivers/platform/x86/intel/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_INTEL_SKL_INT3472) += int3472/ obj-$(CONFIG_INTEL_PMC_CORE) += pmc/ obj-$(CONFIG_INTEL_PMT_CLASS) += pmt/ obj-$(CONFIG_INTEL_SPEED_SELECT_INTERFACE) += speed_select_if/ +obj-$(CONFIG_INTEL_TDX_GUEST) += tdx/ obj-$(CONFIG_INTEL_TELEMETRY) += telemetry/ obj-$(CONFIG_INTEL_WMI) += wmi/ obj-$(CONFIG_INTEL_UNCORE_FREQ_CONTROL) += uncore-frequency/ diff --git a/drivers/platform/x86/intel/tdx/Kconfig b/drivers/platform/x86/intel/tdx/Kconfig new file mode 100644 index 000000000000..332a10313b49 --- /dev/null +++ b/drivers/platform/x86/intel/tdx/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# X86 TDX Platform Specific Drivers +# + +config INTEL_TDX_ATTESTATION + tristate "Intel TDX attestation driver" + depends on INTEL_TDX_GUEST + help + The TDX attestation driver provides IOCTL interfaces to the user to + request TDREPORT from the TDX module or request quote from the VMM + or to get quote buffer size. It is mainly used to get secure disk + decryption keys from the key server. diff --git a/drivers/platform/x86/intel/tdx/Makefile b/drivers/platform/x86/intel/tdx/Makefile new file mode 100644 index 000000000000..94eea6108fbd --- /dev/null +++ b/drivers/platform/x86/intel/tdx/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_INTEL_TDX_ATTESTATION) += intel_tdx_attest.o diff --git a/drivers/platform/x86/intel/tdx/intel_tdx_attest.c b/drivers/platform/x86/intel/tdx/intel_tdx_attest.c new file mode 100644 index 000000000000..9124db800d4f --- /dev/null +++ b/drivers/platform/x86/intel/tdx/intel_tdx_attest.c @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * intel_tdx_attest.c - TDX guest attestation interface driver. + * + * Implements user interface to trigger attestation process and + * read the TD Quote result. + * + * Copyright (C) 2021-2022 Intel Corporation + * + * Author: + * Kuppuswamy Sathyanarayanan + */ + +#define pr_fmt(fmt) "x86/tdx: attest: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "tdx-attest" + +/* Used in Quote memory allocation */ +#define QUOTE_SIZE (2 * PAGE_SIZE) +/* Used in Get Quote request memory allocation */ +#define GET_QUOTE_MAX_SIZE (4 * PAGE_SIZE) +/* Get Quote timeout in msec */ +#define GET_QUOTE_TIMEOUT (5000) + +struct attest_dev { + /* Mutex to serialize attestation requests */ + struct mutex lock; + /* Completion object to track GetQuote completion status */ + struct completion req_compl; + /* Buffer used to copy report data in attestation handler */ + u8 report_buf[TDX_REPORT_DATA_LEN] __aligned(64); + /* Data pointer used to get TD Quote data in attestation handler */ + void *tdquote_buf; + /* Data pointer used to get TDREPORT data in attestation handler */ + void *tdreport_buf; + /* DMA handle used to allocate and free tdquote DMA buffer */ + dma_addr_t handle; + struct miscdevice miscdev; +}; + +static struct platform_device *pdev; + +static void attestation_callback_handler(void) +{ + struct attest_dev *adev = platform_get_drvdata(pdev); + + complete(&adev->req_compl); +} + +static long tdx_attest_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct attest_dev *adev = platform_get_drvdata(pdev); + void __user *argp = (void __user *)arg; + struct tdx_gen_quote tdquote_req; + long ret = 0, err; + + mutex_lock(&adev->lock); + + switch (cmd) { + case TDX_CMD_GET_TDREPORT: + if (copy_from_user(adev->report_buf, argp, + TDX_REPORT_DATA_LEN)) { + ret = -EFAULT; + break; + } + + /* Generate TDREPORT_STRUCT */ + err = tdx_mcall_tdreport(adev->tdreport_buf, adev->report_buf); + if (err) { + ret = put_user(err, (long __user *)argp); + ret = -EIO; + break; + } + + if (copy_to_user(argp, adev->tdreport_buf, TDX_TDREPORT_LEN)) + ret = -EFAULT; + break; + case TDX_CMD_GEN_QUOTE: + reinit_completion(&adev->req_compl); + + /* Copy TDREPORT data from user buffer */ + if (copy_from_user(&tdquote_req, argp, sizeof(struct tdx_gen_quote))) { + ret = -EFAULT; + break; + } + + if (tdquote_req.len <= 0 || tdquote_req.len > GET_QUOTE_MAX_SIZE) { + ret = -EINVAL; + break; + } + + if (copy_from_user(adev->tdquote_buf, (void __user *)tdquote_req.buf, + tdquote_req.len)) { + ret = -EFAULT; + break; + } + + /* Submit GetQuote Request */ + err = tdx_hcall_get_quote(adev->tdquote_buf, GET_QUOTE_MAX_SIZE); + if (err) { + ret = put_user(err, (long __user *)argp); + ret = -EIO; + break; + } + + /* Wait for attestation completion */ + ret = wait_for_completion_interruptible_timeout( + &adev->req_compl, + msecs_to_jiffies(GET_QUOTE_TIMEOUT)); + if (ret <= 0) { + ret = -EIO; + break; + } + + /* ret will be positive if completed. */ + ret = 0; + + if (copy_to_user((void __user *)tdquote_req.buf, adev->tdquote_buf, + tdquote_req.len)) + ret = -EFAULT; + + break; + case TDX_CMD_GET_QUOTE_SIZE: + ret = put_user(QUOTE_SIZE, (u64 __user *)argp); + break; + default: + pr_err("cmd %d not supported\n", cmd); + break; + } + + mutex_unlock(&adev->lock); + + return ret; +} + +static const struct file_operations tdx_attest_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = tdx_attest_ioctl, + .llseek = no_llseek, +}; + +/* Helper function to cleanup attestation related allocations */ +static void _tdx_attest_remove(struct attest_dev *adev) +{ + misc_deregister(&adev->miscdev); + + tdx_remove_ev_notify_handler(); + + if (adev->tdquote_buf) + dma_free_coherent(&pdev->dev, GET_QUOTE_MAX_SIZE, + adev->tdquote_buf, adev->handle); + + if (adev->tdreport_buf) + free_pages((unsigned long)adev->tdreport_buf, 0); + + kfree(adev); +} + +static int tdx_attest_probe(struct platform_device *attest_pdev) +{ + struct device *dev = &attest_pdev->dev; + struct attest_dev *adev; + long ret = 0; + + /* Only single device is allowed */ + if (pdev) + return -EBUSY; + + adev = kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) + return -ENOMEM; + + mutex_init(&adev->lock); + init_completion(&adev->req_compl); + pdev = attest_pdev; + platform_set_drvdata(pdev, adev); + + /* + * tdreport_data needs to be 64-byte aligned. + * Full page alignment is more than enough. + */ + adev->tdreport_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, + 0); + if (!adev->tdreport_buf) { + ret = -ENOMEM; + goto failed; + } + + ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(64)); + if (ret) { + pr_err("dma set coherent mask failed\n"); + goto failed; + } + + /* Allocate DMA buffer to get TDQUOTE data from the VMM */ + adev->tdquote_buf = dma_alloc_coherent(dev, GET_QUOTE_MAX_SIZE, + &adev->handle, + GFP_KERNEL | __GFP_ZERO); + if (!adev->tdquote_buf) { + ret = -ENOMEM; + goto failed; + } + + /* Register attestation event notify handler */ + tdx_setup_ev_notify_handler(attestation_callback_handler); + + adev->miscdev.name = DRIVER_NAME; + adev->miscdev.minor = MISC_DYNAMIC_MINOR; + adev->miscdev.fops = &tdx_attest_fops; + adev->miscdev.parent = dev; + + ret = misc_register(&adev->miscdev); + if (ret) { + pr_err("misc device registration failed\n"); + goto failed; + } + + pr_debug("module initialization success\n"); + + return 0; + +failed: + _tdx_attest_remove(adev); + + pr_debug("module initialization failed\n"); + + return ret; +} + +static int tdx_attest_remove(struct platform_device *attest_pdev) +{ + struct attest_dev *adev = platform_get_drvdata(attest_pdev); + + mutex_lock(&adev->lock); + _tdx_attest_remove(adev); + mutex_unlock(&adev->lock); + pr_debug("module is successfully removed\n"); + return 0; +} + +static struct platform_driver tdx_attest_driver = { + .probe = tdx_attest_probe, + .remove = tdx_attest_remove, + .driver = { + .name = DRIVER_NAME, + }, +}; + +static int __init tdx_attest_init(void) +{ + int ret; + + /* Make sure we are in a valid TDX platform */ + if (!cpu_feature_enabled(X86_FEATURE_TDX_GUEST)) + return -EIO; + + ret = platform_driver_register(&tdx_attest_driver); + if (ret) { + pr_err("failed to register driver, err=%d\n", ret); + return ret; + } + + pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); + if (IS_ERR(pdev)) { + ret = PTR_ERR(pdev); + pr_err("failed to allocate device, err=%d\n", ret); + platform_driver_unregister(&tdx_attest_driver); + return ret; + } + + return 0; +} + +static void __exit tdx_attest_exit(void) +{ + platform_device_unregister(pdev); + platform_driver_unregister(&tdx_attest_driver); +} + +module_init(tdx_attest_init); +module_exit(tdx_attest_exit); + +MODULE_AUTHOR("Kuppuswamy Sathyanarayanan "); +MODULE_DESCRIPTION("TDX attestation driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/uapi/misc/tdx.h b/include/uapi/misc/tdx.h new file mode 100644 index 000000000000..9920f36c79fe --- /dev/null +++ b/include/uapi/misc/tdx.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_MISC_TDX_H +#define _UAPI_MISC_TDX_H + +#include +#include + +/* Input report data length for TDX_CMD_GET_TDREPORT IOCTL request */ +#define TDX_REPORT_DATA_LEN 64 + +/* Output TD report data length after TDX_CMD_GET_TDREPORT IOCTL execution */ +#define TDX_TDREPORT_LEN 1024 + +/* + * TDX_CMD_GET_TDREPORT IOCTL is used to get TDREPORT data from the TDX + * Module. Users should pass report data of size TDX_REPORT_DATA_LEN bytes + * via user input buffer of size TDX_TDREPORT_LEN. Once IOCTL is successful + * TDREPORT data is copied to the user buffer. + */ +#define TDX_CMD_GET_TDREPORT _IOWR('T', 0x01, __u64) + +/* + * TDX_CMD_GEN_QUOTE IOCTL is used to request TD QUOTE from the VMM. User + * should pass TD report data of size TDX_TDREPORT_LEN bytes via user input + * buffer of quote size. Once IOCTL is successful quote data is copied back to + * the user buffer. + */ +#define TDX_CMD_GEN_QUOTE _IOR('T', 0x02, __u64) + +/* + * TDX_CMD_GET_QUOTE_SIZE IOCTL is used to get the TD Quote size info in bytes. + * This will be used for determining the input buffer allocation size when + * using TDX_CMD_GEN_QUOTE IOCTL. + */ +#define TDX_CMD_GET_QUOTE_SIZE _IOR('T', 0x03, __u64) + +struct tdx_gen_quote { + __u64 buf; + __u64 len; +}; + +#endif /* _UAPI_MISC_TDX_H */