All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] kvm: sev: Add SNP guest request throttling
@ 2022-11-08 21:32 Dionna Glaze
  2022-11-08 21:32 ` [PATCH 1/2] kvm: sev: Add SEV-SNP " Dionna Glaze
  2022-11-08 21:32 ` [PATCH 2/2] kvm: sev: If ccp is busy, report throttled to guest Dionna Glaze
  0 siblings, 2 replies; 3+ messages in thread
From: Dionna Glaze @ 2022-11-08 21:32 UTC (permalink / raw)
  To: linux-kernel, x86
  Cc: Dionna Glaze, Tom Lendacky, Ashish Kalra, Paolo Bonzini,
	Joerg Roedel, Peter Gonda, Thomas Gleixner, Dave Hansen

This patch series is based on

[PATCH Part2 v6 00/49] Add AMD Secure Nested Paging (SEV-SNP)

and is requested to be rolled into the upcoming v7 of that patch series.

The GHCB specification recommends that SNP guest requests should be
rate limited. This 2 patch series adds such rate limiting with a 2
burst, 2 second interval per VM as the default values for two new
kvm-amd module parameters:
  guest_request_throttle_s
  guest_request_throttle_burst

This patch series cooperates with the guest series,

 Add throttling detection to sev-guest

in order for guests to retry when throttled, rather than disable the
VMPCK and fail to complete their request.

Cc: Tom Lendacky <Thomas.Lendacky@amd.com>
Cc: Ashish Kalra <Ashish.Kalra@amd.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Joerg Roedel <jroedel@suse.de>
Cc: Peter Gonda <pgonda@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>

Dionna Glaze (2):
  kvm: sev: Add SEV-SNP guest request throttling
  kvm: sev: If ccp is busy, report throttled to guest

 arch/x86/include/asm/sev-common.h |  1 +
 arch/x86/kvm/svm/sev.c            | 46 +++++++++++++++++++++++++++++--
 arch/x86/kvm/svm/svm.h            |  3 ++
 3 files changed, 48 insertions(+), 2 deletions(-)

-- 
2.38.1.431.g37b22c650d-goog


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] kvm: sev: Add SEV-SNP guest request throttling
  2022-11-08 21:32 [PATCH 0/2] kvm: sev: Add SNP guest request throttling Dionna Glaze
@ 2022-11-08 21:32 ` Dionna Glaze
  2022-11-08 21:32 ` [PATCH 2/2] kvm: sev: If ccp is busy, report throttled to guest Dionna Glaze
  1 sibling, 0 replies; 3+ messages in thread
From: Dionna Glaze @ 2022-11-08 21:32 UTC (permalink / raw)
  To: linux-kernel, x86; +Cc: Dionna Glaze

The AMD-SP is a precious resource that doesn't have a scheduler other
than a mutex lock queue. To avoid customers from causing a DoS, we
implement a module_param-set rate limit with a default of 2 requests
per 2 seconds.

These defaults were chosen empirically with a the assumption that
current server-grade SEV-SNP machines will rarely exceed 128 VMs under
usual circumstance.

The 2 burst per 2 seconds means on average 1 request every second. We
allow 2 requests back to back to allow for the guest to query the
certificate length in an extended guest request without a pause. The
1 second average is our target for quality of service since empirical
tests show that 64 VMs can concurrently request an attestation report
with a maximum latency of 1 second. We don't anticipate more
concurrency than that for a seldom used request for a majority well-
behaved set of VMs. The majority point is decided as >64 VMs given
the assumed 128 VM count for "extreme load".

The throttling code is 2 << 32 given that invalid length is 1 and 2 is
the next available code. This was suggested by Tom Lendacky, and will
be included in a new revision of the GHCB specification.

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 arch/x86/include/asm/sev-common.h |  1 +
 arch/x86/kvm/svm/sev.c            | 29 +++++++++++++++++++++++++++++
 arch/x86/kvm/svm/svm.h            |  3 +++
 3 files changed, 33 insertions(+)

diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h
index 1b111cde8c82..e3a6b039480d 100644
--- a/arch/x86/include/asm/sev-common.h
+++ b/arch/x86/include/asm/sev-common.h
@@ -158,6 +158,7 @@ struct snp_psc_desc {
 
 /* Guest message request error code */
 #define SNP_GUEST_REQ_INVALID_LEN	BIT_ULL(32)
+#define SNP_GUEST_REQ_THROTTLED		(((u64)2) << 32)
 
 #define GHCB_MSR_TERM_REQ		0x100
 #define GHCB_MSR_TERM_REASON_SET_POS	12
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index e1dd67e12774..a9f67bfd60d9 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -61,6 +61,14 @@ module_param_named(sev_es, sev_es_enabled, bool, 0444);
 /* enable/disable SEV-SNP support */
 static bool sev_snp_enabled = true;
 module_param_named(sev_snp, sev_snp_enabled, bool, 0444);
+
+/* Throttle guest requests to a burst # per this many seconds */
+unsigned int guest_request_throttle_s = 2;
+module_param(guest_request_throttle_s, int, 0444);
+
+/* Throttle guest requests to this many per the above many seconds */
+unsigned int guest_request_throttle_burst = 2;
+module_param(guest_request_throttle_burst, int, 0444);
 #else
 #define sev_enabled false
 #define sev_es_enabled false
@@ -345,6 +353,9 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
 		spin_lock_init(&sev->psc_lock);
 		ret = sev_snp_init(&argp->error);
 		mutex_init(&sev->guest_req_lock);
+		ratelimit_state_init(&sev->snp_guest_msg_rs,
+				     guest_request_throttle_s * HZ,
+				     guest_request_throttle_burst);
 	} else {
 		ret = sev_platform_init(&argp->error);
 	}
@@ -3594,6 +3605,14 @@ static void snp_cleanup_guest_buf(struct sev_data_snp_guest_request *data, unsig
 		*rc = SEV_RET_INVALID_ADDRESS;
 }
 
+static bool snp_throttle_guest_request(struct kvm_sev_info *sev) {
+	if (__ratelimit(&sev->snp_guest_msg_rs))
+		return false;
+
+	pr_info_ratelimited("svm: too many guest message requests\n");
+	return true;
+}
+
 static void snp_handle_guest_request(struct vcpu_svm *svm, gpa_t req_gpa, gpa_t resp_gpa)
 {
 	struct sev_data_snp_guest_request data = {0};
@@ -3610,6 +3629,11 @@ static void snp_handle_guest_request(struct vcpu_svm *svm, gpa_t req_gpa, gpa_t
 
 	sev = &to_kvm_svm(kvm)->sev_info;
 
+	if (snp_throttle_guest_request(sev)) {
+		rc = SNP_GUEST_REQ_THROTTLED;
+		goto e_fail;
+	}
+
 	mutex_lock(&sev->guest_req_lock);
 
 	rc = snp_setup_guest_buf(svm, &data, req_gpa, resp_gpa);
@@ -3647,6 +3671,11 @@ static void snp_handle_ext_guest_request(struct vcpu_svm *svm, gpa_t req_gpa, gp
 
 	sev = &to_kvm_svm(kvm)->sev_info;
 
+	if (snp_throttle_guest_request(sev)) {
+		rc = SNP_GUEST_REQ_THROTTLED;
+		goto e_fail;
+	}
+
 	data_gpa = vcpu->arch.regs[VCPU_REGS_RAX];
 	data_npages = vcpu->arch.regs[VCPU_REGS_RBX];
 
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 2cdfc79bf2cf..2201458c4cf7 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -18,6 +18,7 @@
 #include <linux/kvm_types.h>
 #include <linux/kvm_host.h>
 #include <linux/bits.h>
+#include <linux/ratelimit.h>
 
 #include <asm/svm.h>
 #include <asm/sev-common.h>
@@ -101,6 +102,8 @@ struct kvm_sev_info {
 	void *snp_certs_data;
 	struct mutex guest_req_lock;
 
+	struct ratelimit_state snp_guest_msg_rs;  /* Limit guest requests */
+
 	u64 sev_features;	/* Features set at VMSA creation */
 };
 
-- 
2.38.1.431.g37b22c650d-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] kvm: sev: If ccp is busy, report throttled to guest
  2022-11-08 21:32 [PATCH 0/2] kvm: sev: Add SNP guest request throttling Dionna Glaze
  2022-11-08 21:32 ` [PATCH 1/2] kvm: sev: Add SEV-SNP " Dionna Glaze
@ 2022-11-08 21:32 ` Dionna Glaze
  1 sibling, 0 replies; 3+ messages in thread
From: Dionna Glaze @ 2022-11-08 21:32 UTC (permalink / raw)
  To: linux-kernel, x86; +Cc: Dionna Glaze

The ccp driver can be overloaded even with 1 HZ throttling. The return
value of -EBUSY means that there is no firmware error to report back to
user space, so the guest VM would see this as exitinfo2 = 0. The false
success can trick the guest to update its the message sequence number
when it shouldn't have.

Instead, when ccp returns -EBUSY, we report that to userspace as the
throttling return value.

Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
 arch/x86/kvm/svm/sev.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index a9f67bfd60d9..6493fb527110 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3641,7 +3641,13 @@ static void snp_handle_guest_request(struct vcpu_svm *svm, gpa_t req_gpa, gpa_t
 		goto unlock;
 
 	rc = sev_issue_cmd(kvm, SEV_CMD_SNP_GUEST_REQUEST, &data, &err);
-	if (rc)
+	/*
+	 * The ccp driver can return -EBUSY if the PSP is overloaded, so
+	 * we offer that as a throttling signal too.
+	 */
+	if (rc == -EBUSY)
+		rc = SNP_GUEST_REQ_THROTTLED;
+	else if (rc)
 		/* use the firmware error code */
 		rc = err;
 
@@ -3698,7 +3704,14 @@ static void snp_handle_ext_guest_request(struct vcpu_svm *svm, gpa_t req_gpa, gp
 
 	rc = snp_guest_ext_guest_request(&req, (unsigned long)sev->snp_certs_data,
 					 &data_npages, &err);
-	if (rc) {
+	/*
+	 * The ccp driver can return -EBUSY if the PSP is overloaded, so
+	 * we offer that as a throttling signal too.
+	 */
+	if (rc == -EBUSY) {
+               rc = SNP_GUEST_REQ_THROTTLED;
+	       goto cleanup;
+	} else if (rc) {
 		/*
 		 * If buffer length is small then return the expected
 		 * length in rbx.
-- 
2.38.1.431.g37b22c650d-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-11-08 21:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-08 21:32 [PATCH 0/2] kvm: sev: Add SNP guest request throttling Dionna Glaze
2022-11-08 21:32 ` [PATCH 1/2] kvm: sev: Add SEV-SNP " Dionna Glaze
2022-11-08 21:32 ` [PATCH 2/2] kvm: sev: If ccp is busy, report throttled to guest Dionna Glaze

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.