Message ID | 20230206172340.2639971-4-rananta@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: arm64: Add support for FEAT_TLBIRANGE | expand |
On Mon, Feb 06, 2023 at 05:23:36PM +0000, Raghavendra Rao Ananta wrote: > Define __kvm_tlb_flush_range_vmid_ipa() (for VHE and nVHE) bikeshed: Personally, I find that range implies it takes an address as an argument already. Maybe just call it __kvm_tlb_flush_vmid_range() > to flush a range of stage-2 page-tables using IPA in one go. > If the system supports FEAT_TLBIRANGE, the following patches > would conviniently replace global TLBI such as vmalls12e1is > in the map, unmap, and dirty-logging paths with ripas2e1is > instead. > > Signed-off-by: Raghavendra Rao Ananta <rananta@google.com> > --- > arch/arm64/include/asm/kvm_asm.h | 3 +++ > arch/arm64/kvm/hyp/nvhe/hyp-main.c | 12 ++++++++++++ > arch/arm64/kvm/hyp/nvhe/tlb.c | 28 ++++++++++++++++++++++++++++ > arch/arm64/kvm/hyp/vhe/tlb.c | 24 ++++++++++++++++++++++++ > 4 files changed, 67 insertions(+) > > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h > index 995ff048e8851..80a8ea85e84f8 100644 > --- a/arch/arm64/include/asm/kvm_asm.h > +++ b/arch/arm64/include/asm/kvm_asm.h > @@ -79,6 +79,7 @@ enum __kvm_host_smccc_func { > __KVM_HOST_SMCCC_FUNC___pkvm_init_vm, > __KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu, > __KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm, > + __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_range_vmid_ipa, > }; > > #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] > @@ -243,6 +244,8 @@ extern void __kvm_flush_vm_context(void); > extern void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu); > extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa, > int level); > +extern void __kvm_tlb_flush_range_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t start, > + phys_addr_t end, int level, int tlb_level); > extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu); > > extern void __kvm_timer_set_cntvoff(u64 cntvoff); > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c > index 728e01d4536b0..5787eee4c9fe4 100644 > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c > @@ -125,6 +125,17 @@ static void handle___kvm_tlb_flush_vmid_ipa(struct kvm_cpu_context *host_ctxt) > __kvm_tlb_flush_vmid_ipa(kern_hyp_va(mmu), ipa, level); > } > > +static void handle___kvm_tlb_flush_range_vmid_ipa(struct kvm_cpu_context *host_ctxt) > +{ > + DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); > + DECLARE_REG(phys_addr_t, start, host_ctxt, 2); > + DECLARE_REG(phys_addr_t, end, host_ctxt, 3); > + DECLARE_REG(int, level, host_ctxt, 4); > + DECLARE_REG(int, tlb_level, host_ctxt, 5); > + > + __kvm_tlb_flush_range_vmid_ipa(kern_hyp_va(mmu), start, end, level, tlb_level); > +} > + > static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt) > { > DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); > @@ -315,6 +326,7 @@ static const hcall_t host_hcall[] = { > HANDLE_FUNC(__kvm_vcpu_run), > HANDLE_FUNC(__kvm_flush_vm_context), > HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa), > + HANDLE_FUNC(__kvm_tlb_flush_range_vmid_ipa), > HANDLE_FUNC(__kvm_tlb_flush_vmid), > HANDLE_FUNC(__kvm_flush_cpu_context), > HANDLE_FUNC(__kvm_timer_set_cntvoff), > diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c > index d296d617f5896..7398dd00445e7 100644 > --- a/arch/arm64/kvm/hyp/nvhe/tlb.c > +++ b/arch/arm64/kvm/hyp/nvhe/tlb.c > @@ -109,6 +109,34 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, > __tlb_switch_to_host(&cxt); > } > > +void __kvm_tlb_flush_range_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t start, > + phys_addr_t end, int level, int tlb_level) > +{ > + struct tlb_inv_context cxt; > + > + dsb(ishst); > + > + /* Switch to requested VMID */ > + __tlb_switch_to_guest(mmu, &cxt); > + > + __kvm_tlb_flush_range(ipas2e1is, mmu, start, end, level, tlb_level); > + > + /* > + * Range-based ipas2e1is flushes only Stage-2 entries, and since the > + * VA isn't available for Stage-1 entries, flush the entire stage-1. > + */ nit: if we are going to preserve some of the commentary over in __kvm_tlb_flush_vmid_ipa(), I would prefer just an exact copy/paste. But, FWIW, I think you can just elide the clarifying comments altogether since the relationship between stage-1 and stage-2 invalidations is already documented. > + dsb(ish); > + __tlbi(vmalle1is); > + dsb(ish); > + isb(); > + > + /* See the comment below in __kvm_tlb_flush_vmid_ipa() */ Same comment as above.
On Wed, Mar 29, 2023 at 5:59 PM Oliver Upton <oliver.upton@linux.dev> wrote: > > On Mon, Feb 06, 2023 at 05:23:36PM +0000, Raghavendra Rao Ananta wrote: > > Define __kvm_tlb_flush_range_vmid_ipa() (for VHE and nVHE) > > bikeshed: Personally, I find that range implies it takes an address as an > argument already. Maybe just call it __kvm_tlb_flush_vmid_range() > Hmm, since TLBI instructions takes-in a variety of ranges, VA or IPA, I just thought of extending the '_ipa' to make things clear. Moreover it aligns with the existing __kvm_tlb_flush_vmid_ipa(). WDYT? Thank you. Raghavendra > > to flush a range of stage-2 page-tables using IPA in one go. > > If the system supports FEAT_TLBIRANGE, the following patches > > would conviniently replace global TLBI such as vmalls12e1is > > in the map, unmap, and dirty-logging paths with ripas2e1is > > instead. > > > > Signed-off-by: Raghavendra Rao Ananta <rananta@google.com> > > --- > > arch/arm64/include/asm/kvm_asm.h | 3 +++ > > arch/arm64/kvm/hyp/nvhe/hyp-main.c | 12 ++++++++++++ > > arch/arm64/kvm/hyp/nvhe/tlb.c | 28 ++++++++++++++++++++++++++++ > > arch/arm64/kvm/hyp/vhe/tlb.c | 24 ++++++++++++++++++++++++ > > 4 files changed, 67 insertions(+) > > > > diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h > > index 995ff048e8851..80a8ea85e84f8 100644 > > --- a/arch/arm64/include/asm/kvm_asm.h > > +++ b/arch/arm64/include/asm/kvm_asm.h > > @@ -79,6 +79,7 @@ enum __kvm_host_smccc_func { > > __KVM_HOST_SMCCC_FUNC___pkvm_init_vm, > > __KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu, > > __KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm, > > + __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_range_vmid_ipa, > > }; > > > > #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] > > @@ -243,6 +244,8 @@ extern void __kvm_flush_vm_context(void); > > extern void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu); > > extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa, > > int level); > > +extern void __kvm_tlb_flush_range_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t start, > > + phys_addr_t end, int level, int tlb_level); > > extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu); > > > > extern void __kvm_timer_set_cntvoff(u64 cntvoff); > > diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c > > index 728e01d4536b0..5787eee4c9fe4 100644 > > --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c > > +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c > > @@ -125,6 +125,17 @@ static void handle___kvm_tlb_flush_vmid_ipa(struct kvm_cpu_context *host_ctxt) > > __kvm_tlb_flush_vmid_ipa(kern_hyp_va(mmu), ipa, level); > > } > > > > +static void handle___kvm_tlb_flush_range_vmid_ipa(struct kvm_cpu_context *host_ctxt) > > +{ > > + DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); > > + DECLARE_REG(phys_addr_t, start, host_ctxt, 2); > > + DECLARE_REG(phys_addr_t, end, host_ctxt, 3); > > + DECLARE_REG(int, level, host_ctxt, 4); > > + DECLARE_REG(int, tlb_level, host_ctxt, 5); > > + > > + __kvm_tlb_flush_range_vmid_ipa(kern_hyp_va(mmu), start, end, level, tlb_level); > > +} > > + > > static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt) > > { > > DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); > > @@ -315,6 +326,7 @@ static const hcall_t host_hcall[] = { > > HANDLE_FUNC(__kvm_vcpu_run), > > HANDLE_FUNC(__kvm_flush_vm_context), > > HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa), > > + HANDLE_FUNC(__kvm_tlb_flush_range_vmid_ipa), > > HANDLE_FUNC(__kvm_tlb_flush_vmid), > > HANDLE_FUNC(__kvm_flush_cpu_context), > > HANDLE_FUNC(__kvm_timer_set_cntvoff), > > diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c > > index d296d617f5896..7398dd00445e7 100644 > > --- a/arch/arm64/kvm/hyp/nvhe/tlb.c > > +++ b/arch/arm64/kvm/hyp/nvhe/tlb.c > > @@ -109,6 +109,34 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, > > __tlb_switch_to_host(&cxt); > > } > > > > +void __kvm_tlb_flush_range_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t start, > > + phys_addr_t end, int level, int tlb_level) > > +{ > > + struct tlb_inv_context cxt; > > + > > + dsb(ishst); > > + > > + /* Switch to requested VMID */ > > + __tlb_switch_to_guest(mmu, &cxt); > > + > > + __kvm_tlb_flush_range(ipas2e1is, mmu, start, end, level, tlb_level); > > + > > + /* > > + * Range-based ipas2e1is flushes only Stage-2 entries, and since the > > + * VA isn't available for Stage-1 entries, flush the entire stage-1. > > + */ > > nit: if we are going to preserve some of the commentary over in > __kvm_tlb_flush_vmid_ipa(), I would prefer just an exact copy/paste. > But, FWIW, I think you can just elide the clarifying comments altogether > since the relationship between stage-1 and stage-2 invalidations is > already documented. > > > + dsb(ish); > > + __tlbi(vmalle1is); > > + dsb(ish); > > + isb(); > > + > > + /* See the comment below in __kvm_tlb_flush_vmid_ipa() */ > > Same comment as above. > > -- > Thanks, > Oliver
On Mon, Apr 03, 2023 at 02:08:29PM -0700, Raghavendra Rao Ananta wrote: > On Wed, Mar 29, 2023 at 5:59 PM Oliver Upton <oliver.upton@linux.dev> wrote: > > > > On Mon, Feb 06, 2023 at 05:23:36PM +0000, Raghavendra Rao Ananta wrote: > > > Define __kvm_tlb_flush_range_vmid_ipa() (for VHE and nVHE) > > > > bikeshed: Personally, I find that range implies it takes an address as an > > argument already. Maybe just call it __kvm_tlb_flush_vmid_range() > > > Hmm, since TLBI instructions takes-in a variety of ranges, VA or IPA, > I just thought of extending the '_ipa' to make things clear. Moreover > it aligns with the existing __kvm_tlb_flush_vmid_ipa(). WDYT? Like I said, just a bikeshed and it seemed trivial to eliminate a token in the function name. FWIW, you're dealing in terms of the IPA space by definition, as a VMID identifies an IPA address space. Range-based invalidations by VA would instead take an ASID as the address space identifier.
On Tue, Apr 4, 2023 at 11:46 AM Oliver Upton <oliver.upton@linux.dev> wrote: > > On Mon, Apr 03, 2023 at 02:08:29PM -0700, Raghavendra Rao Ananta wrote: > > On Wed, Mar 29, 2023 at 5:59 PM Oliver Upton <oliver.upton@linux.dev> wrote: > > > > > > On Mon, Feb 06, 2023 at 05:23:36PM +0000, Raghavendra Rao Ananta wrote: > > > > Define __kvm_tlb_flush_range_vmid_ipa() (for VHE and nVHE) > > > > > > bikeshed: Personally, I find that range implies it takes an address as an > > > argument already. Maybe just call it __kvm_tlb_flush_vmid_range() > > > > > Hmm, since TLBI instructions takes-in a variety of ranges, VA or IPA, > > I just thought of extending the '_ipa' to make things clear. Moreover > > it aligns with the existing __kvm_tlb_flush_vmid_ipa(). WDYT? > > Like I said, just a bikeshed and it seemed trivial to eliminate a token > in the function name. FWIW, you're dealing in terms of the IPA space by > definition, as a VMID identifies an IPA address space. Range-based > invalidations by VA would instead take an ASID as the address space > identifier. > Okay, let's rename it to __kvm_tlb_flush_vmid_range(). Thanks, Raghavendra > -- > Thanks, > Oliver
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 995ff048e8851..80a8ea85e84f8 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -79,6 +79,7 @@ enum __kvm_host_smccc_func { __KVM_HOST_SMCCC_FUNC___pkvm_init_vm, __KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu, __KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm, + __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_range_vmid_ipa, }; #define DECLARE_KVM_VHE_SYM(sym) extern char sym[] @@ -243,6 +244,8 @@ extern void __kvm_flush_vm_context(void); extern void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu); extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa, int level); +extern void __kvm_tlb_flush_range_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t start, + phys_addr_t end, int level, int tlb_level); extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu); extern void __kvm_timer_set_cntvoff(u64 cntvoff); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index 728e01d4536b0..5787eee4c9fe4 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -125,6 +125,17 @@ static void handle___kvm_tlb_flush_vmid_ipa(struct kvm_cpu_context *host_ctxt) __kvm_tlb_flush_vmid_ipa(kern_hyp_va(mmu), ipa, level); } +static void handle___kvm_tlb_flush_range_vmid_ipa(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); + DECLARE_REG(phys_addr_t, start, host_ctxt, 2); + DECLARE_REG(phys_addr_t, end, host_ctxt, 3); + DECLARE_REG(int, level, host_ctxt, 4); + DECLARE_REG(int, tlb_level, host_ctxt, 5); + + __kvm_tlb_flush_range_vmid_ipa(kern_hyp_va(mmu), start, end, level, tlb_level); +} + static void handle___kvm_tlb_flush_vmid(struct kvm_cpu_context *host_ctxt) { DECLARE_REG(struct kvm_s2_mmu *, mmu, host_ctxt, 1); @@ -315,6 +326,7 @@ static const hcall_t host_hcall[] = { HANDLE_FUNC(__kvm_vcpu_run), HANDLE_FUNC(__kvm_flush_vm_context), HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa), + HANDLE_FUNC(__kvm_tlb_flush_range_vmid_ipa), HANDLE_FUNC(__kvm_tlb_flush_vmid), HANDLE_FUNC(__kvm_flush_cpu_context), HANDLE_FUNC(__kvm_timer_set_cntvoff), diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c index d296d617f5896..7398dd00445e7 100644 --- a/arch/arm64/kvm/hyp/nvhe/tlb.c +++ b/arch/arm64/kvm/hyp/nvhe/tlb.c @@ -109,6 +109,34 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, __tlb_switch_to_host(&cxt); } +void __kvm_tlb_flush_range_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t start, + phys_addr_t end, int level, int tlb_level) +{ + struct tlb_inv_context cxt; + + dsb(ishst); + + /* Switch to requested VMID */ + __tlb_switch_to_guest(mmu, &cxt); + + __kvm_tlb_flush_range(ipas2e1is, mmu, start, end, level, tlb_level); + + /* + * Range-based ipas2e1is flushes only Stage-2 entries, and since the + * VA isn't available for Stage-1 entries, flush the entire stage-1. + */ + dsb(ish); + __tlbi(vmalle1is); + dsb(ish); + isb(); + + /* See the comment below in __kvm_tlb_flush_vmid_ipa() */ + if (icache_is_vpipt()) + icache_inval_all_pou(); + + __tlb_switch_to_host(&cxt); +} + void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu) { struct tlb_inv_context cxt; diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c index 24cef9b87f9e9..e9c1d69f7ddf7 100644 --- a/arch/arm64/kvm/hyp/vhe/tlb.c +++ b/arch/arm64/kvm/hyp/vhe/tlb.c @@ -111,6 +111,30 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, __tlb_switch_to_host(&cxt); } +void __kvm_tlb_flush_range_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t start, + phys_addr_t end, int level, int tlb_level) +{ + struct tlb_inv_context cxt; + + dsb(ishst); + + /* Switch to requested VMID */ + __tlb_switch_to_guest(mmu, &cxt); + + __kvm_tlb_flush_range(ipas2e1is, mmu, start, end, level, tlb_level); + + /* + * Range-based ipas2e1is flushes only Stage-2 entries, and since the + * VA isn't available for Stage-1 entries, flush the entire stage-1. + */ + dsb(ish); + __tlbi(vmalle1is); + dsb(ish); + isb(); + + __tlb_switch_to_host(&cxt); +} + void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu) { struct tlb_inv_context cxt;
Define __kvm_tlb_flush_range_vmid_ipa() (for VHE and nVHE) to flush a range of stage-2 page-tables using IPA in one go. If the system supports FEAT_TLBIRANGE, the following patches would conviniently replace global TLBI such as vmalls12e1is in the map, unmap, and dirty-logging paths with ripas2e1is instead. Signed-off-by: Raghavendra Rao Ananta <rananta@google.com> --- arch/arm64/include/asm/kvm_asm.h | 3 +++ arch/arm64/kvm/hyp/nvhe/hyp-main.c | 12 ++++++++++++ arch/arm64/kvm/hyp/nvhe/tlb.c | 28 ++++++++++++++++++++++++++++ arch/arm64/kvm/hyp/vhe/tlb.c | 24 ++++++++++++++++++++++++ 4 files changed, 67 insertions(+)