Messages in this thread | | | Subject | Re: [PATCH v2 14/14] KVM: SVM: Skip SEV cache flush if no ASIDs have been used | From | Tom Lendacky <> | Date | Fri, 15 Jan 2021 09:07:02 -0600 |
| |
On 1/13/21 6:37 PM, Sean Christopherson wrote: > Skip SEV's expensive WBINVD and DF_FLUSH if there are no SEV ASIDs > waiting to be reclaimed, e.g. if SEV was never used. This "fixes" an > issue where the DF_FLUSH fails during hardware teardown if the original > SEV_INIT failed. Ideally, SEV wouldn't be marked as enabled in KVM if > SEV_INIT fails, but that's a problem for another day. > > Signed-off-by: Sean Christopherson <seanjc@google.com> > --- > arch/x86/kvm/svm/sev.c | 22 ++++++++++------------ > 1 file changed, 10 insertions(+), 12 deletions(-) > > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c > index 23a4bead4a82..e71bc742d8da 100644 > --- a/arch/x86/kvm/svm/sev.c > +++ b/arch/x86/kvm/svm/sev.c > @@ -56,9 +56,14 @@ struct enc_region { > unsigned long size; > }; > > -static int sev_flush_asids(void) > +static int sev_flush_asids(int min_asid, int max_asid) > { > - int ret, error = 0; > + int ret, pos, error = 0; > + > + /* Check if there are any ASIDs to reclaim before performing a flush */ > + pos = find_next_bit(sev_reclaim_asid_bitmap, max_sev_asid, min_asid); > + if (pos >= max_asid) > + return -EBUSY; > > /* > * DEACTIVATE will clear the WBINVD indicator causing DF_FLUSH to fail, > @@ -80,14 +85,7 @@ static int sev_flush_asids(void) > /* Must be called with the sev_bitmap_lock held */ > static bool __sev_recycle_asids(int min_asid, int max_asid) > { > - int pos; > - > - /* Check if there are any ASIDs to reclaim before performing a flush */ > - pos = find_next_bit(sev_reclaim_asid_bitmap, max_sev_asid, min_asid); > - if (pos >= max_asid) > - return false; > - > - if (sev_flush_asids()) > + if (sev_flush_asids(min_asid, max_asid)) > return false; > > /* The flush process will flush all reclaimable SEV and SEV-ES ASIDs */ > @@ -1323,10 +1321,10 @@ void sev_hardware_teardown(void) > if (!sev_enabled) > return; > > + sev_flush_asids(0, max_sev_asid);
I guess you could have called __sev_recycle_asids(0, max_sev_asid) here and left things unchanged up above. It would do the extra bitmap_xor() and bitmap_zero() operations, though. What do you think?
Also, maybe a comment about not needing the bitmap lock because this is during teardown.
Thanks, Tom
> + > bitmap_free(sev_asid_bitmap); > bitmap_free(sev_reclaim_asid_bitmap); > - > - sev_flush_asids(); > } > > int sev_cpu_init(struct svm_cpu_data *sd) >
| |