From: Dionna Glaze <dionnaglaze@google.com>
To: kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, linux-coco@lists.linux.dev,
Dionna Glaze <dionnaglaze@google.com>,
Thomas Lendacky <Thomas.Lendacky@amd.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Joerg Roedel <jroedel@suse.de>, Peter Gonda <pgonda@google.com>,
Borislav Petkov <bp@alien8.de>,
Sean Christopherson <seanjc@google.com>
Subject: [PATCH v4 1/2] kvm: sev: Add SEV-SNP guest request throttling
Date: Wed, 14 May 2025 18:41:34 +0000 [thread overview]
Message-ID: <20250514184136.238446-2-dionnaglaze@google.com> (raw)
In-Reply-To: <20250514184136.238446-1-dionnaglaze@google.com>
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, a
mem_enc_ioctl command for rate limiting guest requests is added.
Recommended values are {.interval_ms = 1000, .burst = 1} or
{.interval_ms = 2000, .burst = 2} to average 1 request every second.
You may need to 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".
Cc: Thomas Lendacky <Thomas.Lendacky@amd.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Joerg Roedel <jroedel@suse.de>
Cc: Peter Gonda <pgonda@google.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Sean Christopherson <seanjc@google.com>
Signed-off-by: Dionna Glaze <dionnaglaze@google.com>
---
.../virt/kvm/x86/amd-memory-encryption.rst | 23 ++++++++++++++
arch/x86/include/uapi/asm/kvm.h | 7 +++++
arch/x86/kvm/svm/sev.c | 31 +++++++++++++++++++
arch/x86/kvm/svm/svm.h | 2 ++
4 files changed, 63 insertions(+)
diff --git a/Documentation/virt/kvm/x86/amd-memory-encryption.rst b/Documentation/virt/kvm/x86/amd-memory-encryption.rst
index 1ddb6a86ce7f..1b5b4fc35aac 100644
--- a/Documentation/virt/kvm/x86/amd-memory-encryption.rst
+++ b/Documentation/virt/kvm/x86/amd-memory-encryption.rst
@@ -572,6 +572,29 @@ Returns: 0 on success, -negative on error
See SNP_LAUNCH_FINISH in the SEV-SNP specification [snp-fw-abi]_ for further
details on the input parameters in ``struct kvm_sev_snp_launch_finish``.
+21. KVM_SEV_SNP_SET_REQUEST_THROTTLE_RATE
+-----------------------------------------
+
+The KVM_SEV_SNP_SET_REQUEST_THROTTLE_RATE command is used to set a per-VM rate
+limit on responding to requests for AMD-SP to process a guest request.
+The AMD-SP is a global resource with limited capacity, so to avoid noisy
+neighbor effects, the host may set a request rate for guests.
+
+Parameters (in): struct kvm_sev_snp_set_request_throttle_rate
+
+Returns: 0 on success, -negative on error
+
+::
+
+ struct kvm_sev_snp_set_request_throttle_rate {
+ __u32 interval_ms;
+ __u32 burst;
+ };
+
+The interval will be translated into jiffies, so if it after transformation
+the interval is 0, the command will return ``-EINVAL``. The ``burst`` value
+must be greater than 0.
+
Device attribute API
====================
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index 460306b35a4b..d92242d9b9af 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -708,6 +708,8 @@ enum sev_cmd_id {
KVM_SEV_SNP_LAUNCH_UPDATE,
KVM_SEV_SNP_LAUNCH_FINISH,
+ KVM_SEV_SNP_SET_REQUEST_THROTTLE_RATE,
+
KVM_SEV_NR_MAX,
};
@@ -877,6 +879,11 @@ struct kvm_sev_snp_launch_finish {
__u64 pad1[4];
};
+struct kvm_sev_snp_set_request_throttle_rate {
+ __u32 interval_ms;
+ __u32 burst;
+};
+
#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index a7a7dc507336..febf4b45fddf 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -2535,6 +2535,29 @@ static int snp_launch_finish(struct kvm *kvm, struct kvm_sev_cmd *argp)
return ret;
}
+static int snp_set_request_throttle_ms(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+ struct kvm_sev_info *sev = to_kvm_sev_info(kvm);
+ struct kvm_sev_snp_set_request_throttle_rate params;
+ int ret;
+ u64 jiffies;
+
+ if (!sev_snp_guest(kvm))
+ return -ENOTTY;
+
+ if (copy_from_user(¶ms, u64_to_user_ptr(argp->data), sizeof(params)))
+ return -EFAULT;
+
+ jiffies = (params.interval_ms * HZ) / 1000;
+
+ if (!jiffies || !params.burst)
+ return -EINVAL;
+
+ ratelimit_state_init(&sev->snp_guest_msg_rs, jiffies, params.burst);
+
+ return 0;
+}
+
int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
{
struct kvm_sev_cmd sev_cmd;
@@ -2640,6 +2663,9 @@ int sev_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
case KVM_SEV_SNP_LAUNCH_FINISH:
r = snp_launch_finish(kvm, &sev_cmd);
break;
+ case KVM_SEV_SNP_SET_REQUEST_THROTTLE_RATE_MS:
+ r = snp_set_request_throttle_ms(kvm, &sev_cmd);
+ break;
default:
r = -EINVAL;
goto out;
@@ -4015,6 +4041,11 @@ static int snp_handle_guest_req(struct vcpu_svm *svm, gpa_t req_gpa, gpa_t resp_
mutex_lock(&sev->guest_req_mutex);
+ if (!__ratelimit(&sev->snp_guest_msg_rs)) {
+ rc = SNP_GUEST_VMM_ERR_BUSY;
+ goto out_unlock;
+ }
+
if (kvm_read_guest(kvm, req_gpa, sev->guest_req_buf, PAGE_SIZE)) {
ret = -EIO;
goto out_unlock;
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index f16b068c4228..0a7c8d3a7560 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -112,6 +112,8 @@ struct kvm_sev_info {
void *guest_req_buf; /* Bounce buffer for SNP Guest Request input */
void *guest_resp_buf; /* Bounce buffer for SNP Guest Request output */
struct mutex guest_req_mutex; /* Must acquire before using bounce buffers */
+
+ struct ratelimit_state snp_guest_msg_rs; /* Limit guest requests */
};
struct kvm_svm {
--
2.49.0.1045.g170613ef41-goog
next prev parent reply other threads:[~2025-05-14 18:41 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-14 18:41 [PATCH v4 0/2] kvm: sev: Add SNP " Dionna Glaze
2025-05-14 18:41 ` Dionna Glaze [this message]
2025-05-14 18:50 ` [PATCH v4 1/2] kvm: sev: Add SEV-SNP " Dionna Amalie Glaze
2025-05-15 18:21 ` kernel test robot
2025-05-14 18:41 ` [PATCH v4 2/2] kvm: sev: If ccp is busy, report busy to guest Dionna Glaze
2025-05-14 18:41 ` [PATCH v4 2/2] The ccp driver can be overloaded even with guest request rate limits. 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 message sequence number when it shouldn't have Dionna Glaze
2025-05-14 18:47 ` Dionna Amalie Glaze
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=20250514184136.238446-2-dionnaglaze@google.com \
--to=dionnaglaze@google.com \
--cc=Thomas.Lendacky@amd.com \
--cc=bp@alien8.de \
--cc=jroedel@suse.de \
--cc=kvm@vger.kernel.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=pgonda@google.com \
--cc=seanjc@google.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®