mirror of
https://github.com/torvalds/linux.git
synced 2026-07-28 01:55:51 +02:00
KVM: SEV: Add an anonymous "psc" struct to track current PSC metadata
Add a "psc" struct to vcpu_sev_es_state to avoid having to prefix all of the fields with "psc_". Take advantage of the code churn to opportunistically rename local variables to "guest_psc" to make it more obvious that the buffer is guest data, and more importantly, guest accessible! Opportunistically rename inflight => batch_size as well, because there can really only be one operation in-flight (per-vCPU), i.e. "inflight" _looks_ like a boolean, but in actuality is an integer tracking how many pages are being handled by the current operation. No functional change intended. Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Message-ID: <20260501202250.2115252-13-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20260529183549.1104619-13-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
17d62e0b15
commit
00b9744a36
|
|
@ -3845,9 +3845,7 @@ static int snp_begin_psc(struct vcpu_svm *svm);
|
|||
|
||||
static void snp_complete_psc(struct vcpu_svm *svm, u64 psc_ret)
|
||||
{
|
||||
svm->sev_es.psc_inflight = 0;
|
||||
svm->sev_es.psc_idx = 0;
|
||||
svm->sev_es.psc_2m = false;
|
||||
memset(&svm->sev_es.psc, 0, sizeof(svm->sev_es.psc));
|
||||
|
||||
/*
|
||||
* PSC requests always get a "no action" response in SW_EXITINFO1, with
|
||||
|
|
@ -3860,9 +3858,8 @@ static void snp_complete_psc(struct vcpu_svm *svm, u64 psc_ret)
|
|||
|
||||
static void __snp_complete_one_psc(struct vcpu_svm *svm)
|
||||
{
|
||||
struct psc_buffer *psc = svm->sev_es.ghcb_sa;
|
||||
struct psc_entry *entries = psc->entries;
|
||||
struct psc_hdr *hdr = &psc->hdr;
|
||||
struct vcpu_sev_es_state *sev_es = &svm->sev_es;
|
||||
struct psc_buffer *guest_psc = sev_es->ghcb_sa;
|
||||
__u16 idx;
|
||||
|
||||
/*
|
||||
|
|
@ -3870,14 +3867,14 @@ static void __snp_complete_one_psc(struct vcpu_svm *svm)
|
|||
* corresponding entries in the guest's PSC buffer and zero out the
|
||||
* count of in-flight PSC entries.
|
||||
*/
|
||||
for (idx = svm->sev_es.psc_idx; svm->sev_es.psc_inflight;
|
||||
svm->sev_es.psc_inflight--, idx++) {
|
||||
struct psc_entry entry = READ_ONCE(entries[idx]);
|
||||
for (idx = sev_es->psc.cur_idx; sev_es->psc.batch_size;
|
||||
sev_es->psc.batch_size--, idx++) {
|
||||
struct psc_entry entry = READ_ONCE(guest_psc->entries[idx]);
|
||||
|
||||
entries[idx].cur_page = entry.pagesize ? 512 : 1;
|
||||
guest_psc->entries[idx].cur_page = entry.pagesize ? 512 : 1;
|
||||
}
|
||||
|
||||
hdr->cur_entry = idx;
|
||||
guest_psc->hdr.cur_entry = idx;
|
||||
}
|
||||
|
||||
static int snp_complete_one_psc(struct kvm_vcpu *vcpu)
|
||||
|
|
@ -3898,10 +3895,8 @@ static int snp_complete_one_psc(struct kvm_vcpu *vcpu)
|
|||
static int snp_begin_psc(struct vcpu_svm *svm)
|
||||
{
|
||||
struct vcpu_sev_es_state *sev_es = &svm->sev_es;
|
||||
struct psc_buffer *psc = sev_es->ghcb_sa;
|
||||
struct psc_entry *entries = psc->entries;
|
||||
struct psc_buffer *guest_psc = sev_es->ghcb_sa;
|
||||
struct kvm_vcpu *vcpu = &svm->vcpu;
|
||||
struct psc_hdr *hdr = &psc->hdr;
|
||||
struct psc_entry entry_start;
|
||||
u16 idx, idx_start, idx_end, max_nr_entries;
|
||||
int npages;
|
||||
|
|
@ -3928,7 +3923,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
|
|||
|
||||
next_range:
|
||||
/* There should be no other PSCs in-flight at this point. */
|
||||
if (WARN_ON_ONCE(svm->sev_es.psc_inflight)) {
|
||||
if (WARN_ON_ONCE(svm->sev_es.psc.batch_size)) {
|
||||
snp_complete_psc(svm, VMGEXIT_PSC_ERROR_GENERIC);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -3938,8 +3933,8 @@ static int snp_begin_psc(struct vcpu_svm *svm)
|
|||
* validation, so take care to only use validated copies of values used
|
||||
* for things like array indexing.
|
||||
*/
|
||||
idx_start = READ_ONCE(hdr->cur_entry);
|
||||
idx_end = READ_ONCE(hdr->end_entry);
|
||||
idx_start = READ_ONCE(guest_psc->hdr.cur_entry);
|
||||
idx_end = READ_ONCE(guest_psc->hdr.end_entry);
|
||||
|
||||
if (idx_end >= max_nr_entries) {
|
||||
snp_complete_psc(svm, VMGEXIT_PSC_ERROR_INVALID_HDR);
|
||||
|
|
@ -3948,7 +3943,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
|
|||
|
||||
/* Find the start of the next range which needs processing. */
|
||||
for (idx = idx_start; idx <= idx_end; idx++) {
|
||||
entry_start = READ_ONCE(entries[idx]);
|
||||
entry_start = READ_ONCE(guest_psc->entries[idx]);
|
||||
|
||||
gfn = entry_start.gfn;
|
||||
huge = entry_start.pagesize;
|
||||
|
|
@ -3981,7 +3976,7 @@ static int snp_begin_psc(struct vcpu_svm *svm)
|
|||
* for READ_ONCE() as KVM doesn't consume the field, i.e. a
|
||||
* misbehaving guest can only break itself.
|
||||
*/
|
||||
hdr->cur_entry++;
|
||||
guest_psc->hdr.cur_entry++;
|
||||
}
|
||||
|
||||
if (idx > idx_end) {
|
||||
|
|
@ -3990,9 +3985,9 @@ static int snp_begin_psc(struct vcpu_svm *svm)
|
|||
return 1;
|
||||
}
|
||||
|
||||
svm->sev_es.psc_2m = huge;
|
||||
svm->sev_es.psc_idx = idx;
|
||||
svm->sev_es.psc_inflight = 1;
|
||||
sev_es->psc.is_2m = huge;
|
||||
sev_es->psc.cur_idx = idx;
|
||||
sev_es->psc.batch_size = 1;
|
||||
|
||||
/*
|
||||
* Find all subsequent PSC entries that contain adjacent GPA
|
||||
|
|
@ -4000,14 +3995,14 @@ static int snp_begin_psc(struct vcpu_svm *svm)
|
|||
* KVM_HC_MAP_GPA_RANGE exit.
|
||||
*/
|
||||
while (++idx <= idx_end) {
|
||||
struct psc_entry entry = READ_ONCE(entries[idx]);
|
||||
struct psc_entry entry = READ_ONCE(guest_psc->entries[idx]);
|
||||
|
||||
if (entry.operation != entry_start.operation ||
|
||||
entry.gfn != entry_start.gfn + npages ||
|
||||
entry.cur_page || !!entry.pagesize != huge)
|
||||
break;
|
||||
|
||||
svm->sev_es.psc_inflight++;
|
||||
sev_es->psc.batch_size++;
|
||||
npages += huge ? 512 : 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -257,9 +257,11 @@ struct vcpu_sev_es_state {
|
|||
bool ghcb_sa_free;
|
||||
|
||||
/* SNP Page-State-Change buffer entries currently being processed */
|
||||
u16 psc_idx;
|
||||
u16 psc_inflight;
|
||||
bool psc_2m;
|
||||
struct {
|
||||
u16 cur_idx;
|
||||
u16 batch_size;
|
||||
bool is_2m;
|
||||
} psc;
|
||||
|
||||
u64 ghcb_registered_gpa;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user