All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tom Lendacky <thomas.lendacky@amd.com>
To: Nikunj A Dadhania <nikunj@amd.com>,
	linux-kernel@vger.kernel.org, bp@alien8.de, x86@kernel.org
Cc: kvm@vger.kernel.org, mingo@redhat.com, tglx@linutronix.de,
	dave.hansen@linux.intel.com, pgonda@google.com,
	seanjc@google.com, pbonzini@redhat.com,
	francescolavra.fl@gmail.com
Subject: Re: [PATCH v16 05/13] x86/sev: Add Secure TSC support for SNP guests
Date: Tue, 7 Jan 2025 13:46:49 -0600	[thread overview]
Message-ID: <de503473-e0a8-bf65-39d2-2b6bd9fa638c@amd.com> (raw)
In-Reply-To: <20250106124633.1418972-6-nikunj@amd.com>

On 1/6/25 06:46, Nikunj A Dadhania wrote:
> Add support for Secure TSC in SNP-enabled guests. Secure TSC allows guests
> to securely use RDTSC/RDTSCP instructions, ensuring that the parameters
> used cannot be altered by the hypervisor once the guest is launched.
> 
> Secure TSC-enabled guests need to query TSC information from the AMD
> Security Processor. This communication channel is encrypted between the AMD
> Security Processor and the guest, with the hypervisor acting merely as a
> conduit to deliver the guest messages to the AMD Security Processor. Each
> message is protected with AEAD (AES-256 GCM).
> 
> Signed-off-by: Nikunj A Dadhania <nikunj@amd.com>

Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>

Although if you have to re-spin, it might make sense to use the __free()
support to reduce the number of gotos and labels in snp_get_tsc_info().
You could also use kfree_sensitive() to automatically do the
memzero_explicit(), too.

> ---
>  arch/x86/include/asm/sev-common.h |   1 +
>  arch/x86/include/asm/sev.h        |  21 ++++++
>  arch/x86/include/asm/svm.h        |   6 +-
>  include/linux/cc_platform.h       |   8 +++
>  arch/x86/coco/core.c              |   4 ++
>  arch/x86/coco/sev/core.c          | 107 ++++++++++++++++++++++++++++++
>  arch/x86/mm/mem_encrypt.c         |   2 +
>  7 files changed, 147 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h
> index 50f5666938c0..6ef92432a5ce 100644
> --- a/arch/x86/include/asm/sev-common.h
> +++ b/arch/x86/include/asm/sev-common.h
> @@ -206,6 +206,7 @@ struct snp_psc_desc {
>  #define GHCB_TERM_NO_SVSM		7	/* SVSM is not advertised in the secrets page */
>  #define GHCB_TERM_SVSM_VMPL0		8	/* SVSM is present but has set VMPL to 0 */
>  #define GHCB_TERM_SVSM_CAA		9	/* SVSM is present but CAA is not page aligned */
> +#define GHCB_TERM_SECURE_TSC		10	/* Secure TSC initialization failed */
>  
>  #define GHCB_RESP_CODE(v)		((v) & GHCB_MSR_INFO_MASK)
>  
> diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
> index 0937ac7a96db..bdcdaac4df1c 100644
> --- a/arch/x86/include/asm/sev.h
> +++ b/arch/x86/include/asm/sev.h
> @@ -146,6 +146,9 @@ enum msg_type {
>  	SNP_MSG_VMRK_REQ,
>  	SNP_MSG_VMRK_RSP,
>  
> +	SNP_MSG_TSC_INFO_REQ = 17,
> +	SNP_MSG_TSC_INFO_RSP,
> +
>  	SNP_MSG_TYPE_MAX
>  };
>  
> @@ -174,6 +177,21 @@ struct snp_guest_msg {
>  	u8 payload[PAGE_SIZE - sizeof(struct snp_guest_msg_hdr)];
>  } __packed;
>  
> +#define SNP_TSC_INFO_REQ_SZ	128
> +
> +struct snp_tsc_info_req {
> +	u8 rsvd[SNP_TSC_INFO_REQ_SZ];
> +} __packed;
> +
> +struct snp_tsc_info_resp {
> +	u32 status;
> +	u32 rsvd1;
> +	u64 tsc_scale;
> +	u64 tsc_offset;
> +	u32 tsc_factor;
> +	u8 rsvd2[100];
> +} __packed;
> +
>  struct snp_guest_req {
>  	void *req_buf;
>  	size_t req_sz;
> @@ -463,6 +481,8 @@ void snp_msg_free(struct snp_msg_desc *mdesc);
>  int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
>  			   struct snp_guest_request_ioctl *rio);
>  
> +void __init snp_secure_tsc_prepare(void);
> +
>  #else	/* !CONFIG_AMD_MEM_ENCRYPT */
>  
>  #define snp_vmpl 0
> @@ -503,6 +523,7 @@ static inline struct snp_msg_desc *snp_msg_alloc(void) { return NULL; }
>  static inline void snp_msg_free(struct snp_msg_desc *mdesc) { }
>  static inline int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req,
>  					 struct snp_guest_request_ioctl *rio) { return -ENODEV; }
> +static inline void __init snp_secure_tsc_prepare(void) { }
>  
>  #endif	/* CONFIG_AMD_MEM_ENCRYPT */
>  
> diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
> index 2b59b9951c90..92e18798f197 100644
> --- a/arch/x86/include/asm/svm.h
> +++ b/arch/x86/include/asm/svm.h
> @@ -417,7 +417,9 @@ struct sev_es_save_area {
>  	u8 reserved_0x298[80];
>  	u32 pkru;
>  	u32 tsc_aux;
> -	u8 reserved_0x2f0[24];
> +	u64 tsc_scale;
> +	u64 tsc_offset;
> +	u8 reserved_0x300[8];
>  	u64 rcx;
>  	u64 rdx;
>  	u64 rbx;
> @@ -564,7 +566,7 @@ static inline void __unused_size_checks(void)
>  	BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x1c0);
>  	BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x248);
>  	BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x298);
> -	BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x2f0);
> +	BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x300);
>  	BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x320);
>  	BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x380);
>  	BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x3f0);
> diff --git a/include/linux/cc_platform.h b/include/linux/cc_platform.h
> index caa4b4430634..0bf7d33a1048 100644
> --- a/include/linux/cc_platform.h
> +++ b/include/linux/cc_platform.h
> @@ -81,6 +81,14 @@ enum cc_attr {
>  	 */
>  	CC_ATTR_GUEST_SEV_SNP,
>  
> +	/**
> +	 * @CC_ATTR_GUEST_SNP_SECURE_TSC: SNP Secure TSC is active.
> +	 *
> +	 * The platform/OS is running as a guest/virtual machine and actively
> +	 * using AMD SEV-SNP Secure TSC feature.
> +	 */
> +	CC_ATTR_GUEST_SNP_SECURE_TSC,
> +
>  	/**
>  	 * @CC_ATTR_HOST_SEV_SNP: AMD SNP enabled on the host.
>  	 *
> diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
> index 0f81f70aca82..715c2c09582f 100644
> --- a/arch/x86/coco/core.c
> +++ b/arch/x86/coco/core.c
> @@ -97,6 +97,10 @@ static bool noinstr amd_cc_platform_has(enum cc_attr attr)
>  	case CC_ATTR_GUEST_SEV_SNP:
>  		return sev_status & MSR_AMD64_SEV_SNP_ENABLED;
>  
> +	case CC_ATTR_GUEST_SNP_SECURE_TSC:
> +		return (sev_status & MSR_AMD64_SEV_SNP_ENABLED) &&
> +			(sev_status & MSR_AMD64_SNP_SECURE_TSC);
> +
>  	case CC_ATTR_HOST_SEV_SNP:
>  		return cc_flags.host_sev_snp;
>  
> diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
> index feb145df6bf7..00a0ac3baab7 100644
> --- a/arch/x86/coco/sev/core.c
> +++ b/arch/x86/coco/sev/core.c
> @@ -96,6 +96,14 @@ static u64 sev_hv_features __ro_after_init;
>  /* Secrets page physical address from the CC blob */
>  static u64 secrets_pa __ro_after_init;
>  
> +/*
> + * For Secure TSC guests, the BSP fetches TSC_INFO using SNP guest messaging and
> + * initializes snp_tsc_scale and snp_tsc_offset. These values are replicated
> + * across the APs VMSA fields (TSC_SCALE and TSC_OFFSET).
> + */
> +static u64 snp_tsc_scale __ro_after_init;
> +static u64 snp_tsc_offset __ro_after_init;
> +
>  /* #VC handler runtime per-CPU data */
>  struct sev_es_runtime_data {
>  	struct ghcb ghcb_page;
> @@ -1272,6 +1280,12 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip)
>  	vmsa->vmpl		= snp_vmpl;
>  	vmsa->sev_features	= sev_status >> 2;
>  
> +	/* Populate AP's TSC scale/offset to get accurate TSC values. */
> +	if (cc_platform_has(CC_ATTR_GUEST_SNP_SECURE_TSC)) {
> +		vmsa->tsc_scale = snp_tsc_scale;
> +		vmsa->tsc_offset = snp_tsc_offset;
> +	}
> +
>  	/* Switch the page over to a VMSA page now that it is initialized */
>  	ret = snp_set_vmsa(vmsa, caa, apic_id, true);
>  	if (ret) {
> @@ -3121,3 +3135,96 @@ int snp_send_guest_request(struct snp_msg_desc *mdesc, struct snp_guest_req *req
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(snp_send_guest_request);
> +
> +static int __init snp_get_tsc_info(void)
> +{
> +	struct snp_guest_request_ioctl *rio;
> +	struct snp_tsc_info_resp *tsc_resp;
> +	struct snp_tsc_info_req *tsc_req;
> +	struct snp_msg_desc *mdesc;
> +	struct snp_guest_req *req;
> +	int rc = -ENOMEM;
> +
> +	tsc_req = kzalloc(sizeof(*tsc_req), GFP_KERNEL);
> +	if (!tsc_req)
> +		return rc;
> +
> +	/*
> +	 * The intermediate response buffer is used while decrypting the
> +	 * response payload. Make sure that it has enough space to cover
> +	 * the authtag.
> +	 */
> +	tsc_resp = kzalloc(sizeof(*tsc_resp) + AUTHTAG_LEN, GFP_KERNEL);
> +	if (!tsc_resp)
> +		goto e_free_tsc_req;
> +
> +	req = kzalloc(sizeof(*req), GFP_KERNEL);
> +	if (!req)
> +		goto e_free_tsc_resp;
> +
> +	rio = kzalloc(sizeof(*rio), GFP_KERNEL);
> +	if (!rio)
> +		goto e_free_req;
> +
> +	mdesc = snp_msg_alloc();
> +	if (IS_ERR_OR_NULL(mdesc))
> +		goto e_free_rio;
> +
> +	rc = snp_msg_init(mdesc, snp_vmpl);
> +	if (rc)
> +		goto e_free_mdesc;
> +
> +	req->msg_version = MSG_HDR_VER;
> +	req->msg_type = SNP_MSG_TSC_INFO_REQ;
> +	req->vmpck_id = snp_vmpl;
> +	req->req_buf = tsc_req;
> +	req->req_sz = sizeof(*tsc_req);
> +	req->resp_buf = (void *)tsc_resp;
> +	req->resp_sz = sizeof(*tsc_resp) + AUTHTAG_LEN;
> +	req->exit_code = SVM_VMGEXIT_GUEST_REQUEST;
> +
> +	rc = snp_send_guest_request(mdesc, req, rio);
> +	if (rc)
> +		goto e_request;
> +
> +	pr_debug("%s: response status 0x%x scale 0x%llx offset 0x%llx factor 0x%x\n",
> +		 __func__, tsc_resp->status, tsc_resp->tsc_scale, tsc_resp->tsc_offset,
> +		 tsc_resp->tsc_factor);
> +
> +	if (!tsc_resp->status) {
> +		snp_tsc_scale = tsc_resp->tsc_scale;
> +		snp_tsc_offset = tsc_resp->tsc_offset;
> +	} else {
> +		pr_err("Failed to get TSC info, response status 0x%x\n", tsc_resp->status);
> +		rc = -EIO;
> +	}
> +
> +e_request:
> +	/* The response buffer contains sensitive data, explicitly clear it. */
> +	memzero_explicit(tsc_resp, sizeof(*tsc_resp) + AUTHTAG_LEN);
> +e_free_mdesc:
> +	snp_msg_free(mdesc);
> +e_free_rio:
> +	kfree(rio);
> +e_free_req:
> +	kfree(req);
> + e_free_tsc_resp:
> +	kfree(tsc_resp);
> +e_free_tsc_req:
> +	kfree(tsc_req);
> +
> +	return rc;
> +}
> +
> +void __init snp_secure_tsc_prepare(void)
> +{
> +	if (!cc_platform_has(CC_ATTR_GUEST_SNP_SECURE_TSC))
> +		return;
> +
> +	if (snp_get_tsc_info()) {
> +		pr_alert("Unable to retrieve Secure TSC info from ASP\n");
> +		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SECURE_TSC);
> +	}
> +
> +	pr_debug("SecureTSC enabled");
> +}
> diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
> index 0a120d85d7bb..95bae74fdab2 100644
> --- a/arch/x86/mm/mem_encrypt.c
> +++ b/arch/x86/mm/mem_encrypt.c
> @@ -94,6 +94,8 @@ void __init mem_encrypt_init(void)
>  	/* Call into SWIOTLB to update the SWIOTLB DMA buffers */
>  	swiotlb_update_mem_attributes();
>  
> +	snp_secure_tsc_prepare();
> +
>  	print_mem_encrypt_feature_info();
>  }
>  

  parent reply	other threads:[~2025-01-07 19:46 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-06 12:46 [PATCH v16 00/13] Add Secure TSC support for SNP guests Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 01/13] virt: sev-guest: Remove is_vmpck_empty() helper Nikunj A Dadhania
2025-01-07 18:38   ` Tom Lendacky
2025-01-09  9:43   ` [tip: x86/sev] " tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 02/13] virt: sev-guest: Replace GFP_KERNEL_ACCOUNT with GFP_KERNEL Nikunj A Dadhania
2025-01-07 18:40   ` Tom Lendacky
2025-01-09  9:43   ` [tip: x86/sev] " tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 03/13] x86/sev: Carve out and export SNP guest messaging init routines Nikunj A Dadhania
2025-01-09  9:43   ` [tip: x86/sev] " tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 04/13] x86/sev: Relocate SNP guest messaging routines to common code Nikunj A Dadhania
2025-01-09  9:43   ` [tip: x86/sev] " tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 05/13] x86/sev: Add Secure TSC support for SNP guests Nikunj A Dadhania
2025-01-07 10:42   ` Borislav Petkov
2025-01-07 11:43     ` Nikunj A. Dadhania
2025-01-07 12:37       ` Borislav Petkov
2025-01-07 18:53         ` Tom Lendacky
2025-01-07 19:18           ` Borislav Petkov
2025-01-08  7:47             ` Nikunj A. Dadhania
2025-01-08  8:05               ` Borislav Petkov
2025-01-08  8:37                 ` Nikunj A. Dadhania
2025-01-08  8:43                   ` Borislav Petkov
2025-01-07 19:46   ` Tom Lendacky [this message]
2025-01-07 19:53     ` Borislav Petkov
2025-01-09  9:43   ` [tip: x86/sev] " tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 06/13] x86/sev: Change TSC MSR behavior for Secure TSC enabled guests Nikunj A Dadhania
2025-01-07 20:09   ` Tom Lendacky
2025-01-09  9:43   ` [tip: x86/sev] " tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 07/13] x86/sev: Prevent GUEST_TSC_FREQ MSR interception " Nikunj A Dadhania
2025-01-09  9:43   ` [tip: x86/sev] " tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 08/13] x86/sev: Prevent RDTSC/RDTSCP " Nikunj A Dadhania
2025-01-09  9:43   ` [tip: x86/sev] " tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 09/13] x86/sev: Mark Secure TSC as reliable clocksource Nikunj A Dadhania
2025-01-09  9:43   ` [tip: x86/sev] x86/sev: Mark the TSC in a secure TSC guest as reliable tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 10/13] x86/tsc: Switch Secure TSC guests away from kvm-clock Nikunj A Dadhania
2025-01-07 15:16   ` Borislav Petkov
2025-01-08 10:45     ` Nikunj A. Dadhania
2025-01-09  9:43   ` [tip: x86/sev] x86/tsc: Init the TSC for Secure TSC guests tip-bot2 for Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 11/13] x86/tsc: Upgrade TSC clocksource rating for guests Nikunj A Dadhania
2025-01-07 17:51   ` Borislav Petkov
2025-01-06 12:46 ` [PATCH v16 12/13] x86/tsc: Switch to native sched clock Nikunj A Dadhania
2025-01-07 19:37   ` Borislav Petkov
2025-01-08  5:20     ` Nikunj A. Dadhania
2025-01-08  8:22       ` Borislav Petkov
2025-01-08  8:34         ` Nikunj A. Dadhania
2025-01-08 10:20           ` Nikunj A. Dadhania
2025-01-08 14:00             ` Sean Christopherson
2025-01-08 15:34               ` Borislav Petkov
2025-01-08 17:02                 ` Sean Christopherson
2025-01-08 19:53                   ` Borislav Petkov
2025-01-09  6:32                   ` Nikunj A. Dadhania
2025-01-15 21:37                     ` Sean Christopherson
2025-01-16 16:25                       ` Borislav Petkov
2025-01-16 16:56                         ` Sean Christopherson
2025-01-17 20:28                           ` Borislav Petkov
2025-01-17 20:59                             ` Sean Christopherson
2025-01-21 11:32                               ` Borislav Petkov
2025-01-21  3:59                       ` Nikunj A. Dadhania
2025-01-28  5:41                       ` Nikunj A Dadhania
2025-01-06 12:46 ` [PATCH v16 13/13] x86/sev: Allow Secure TSC feature for SNP guests Nikunj A Dadhania
2025-01-09  9:43   ` [tip: x86/sev] x86/sev: Add the " tip-bot2 for Nikunj A Dadhania

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=de503473-e0a8-bf65-39d2-2b6bd9fa638c@amd.com \
    --to=thomas.lendacky@amd.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=francescolavra.fl@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=nikunj@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=pgonda@google.com \
    --cc=seanjc@google.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.