Re: [PATCH v4 2/3] KVM: PPC: Book3S HV: Add support for H_RPT_INVALIDATE
On Mon, Feb 22, 2021 at 12:16:08PM +0530, Bharata B Rao wrote: > On Wed, Feb 17, 2021 at 11:38:07AM +1100, David Gibson wrote: > > On Mon, Feb 15, 2021 at 12:05:41PM +0530, Bharata B Rao wrote: > > > Implement H_RPT_INVALIDATE hcall and add KVM capability > > > KVM_CAP_PPC_RPT_INVALIDATE to indicate the support for the same. > > > > > > This hcall does two types of TLB invalidations: > > > > > > 1. Process-scoped invalidations for guests with LPCR[GTSE]=0. > > >This is currently not used in KVM as GTSE is not usually > > >disabled in KVM. > > > 2. Partition-scoped invalidations that an L1 hypervisor does on > > >behalf of an L2 guest. This replaces the uses of the existing > > >hcall H_TLB_INVALIDATE. > > > > > > In order to handle process scoped invalidations of L2, we > > > intercept the nested exit handling code in L0 only to handle > > > H_TLB_INVALIDATE hcall. > > > > > > Signed-off-by: Bharata B Rao > > > --- > > > Documentation/virt/kvm/api.rst | 17 + > > > arch/powerpc/include/asm/kvm_book3s.h | 3 + > > > arch/powerpc/include/asm/mmu_context.h | 11 +++ > > > arch/powerpc/kvm/book3s_hv.c | 91 > > > arch/powerpc/kvm/book3s_hv_nested.c| 96 ++ > > > arch/powerpc/kvm/powerpc.c | 3 + > > > arch/powerpc/mm/book3s64/radix_tlb.c | 25 +++ > > > include/uapi/linux/kvm.h | 1 + > > > 8 files changed, 247 insertions(+) > > > > > > diff --git a/Documentation/virt/kvm/api.rst > > > b/Documentation/virt/kvm/api.rst > > > index 99ceb978c8b0..416c36aa35d4 100644 > > > --- a/Documentation/virt/kvm/api.rst > > > +++ b/Documentation/virt/kvm/api.rst > > > @@ -6038,6 +6038,23 @@ KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR exit > > > notifications which user space > > > can then handle to implement model specific MSR handling and/or user > > > notifications > > > to inform a user that an MSR was not handled. > > > > > > +7.22 KVM_CAP_PPC_RPT_INVALIDATE > > > +-- > > > + > > > +:Capability: KVM_CAP_PPC_RPT_INVALIDATE > > > +:Architectures: ppc > > > +:Type: vm > > > + > > > +This capability indicates that the kernel is capable of handling > > > +H_RPT_INVALIDATE hcall. > > > + > > > +In order to enable the use of H_RPT_INVALIDATE in the guest, > > > +user space might have to advertise it for the guest. For example, > > > +IBM pSeries (sPAPR) guest starts using it if "hcall-rpt-invalidate" is > > > +present in the "ibm,hypertas-functions" device-tree property. > > > + > > > +This capability is always enabled. > > > > I guess that means it's always enabled when it's available - I'm > > pretty sure it won't be enabled on POWER8 or on PR KVM. > > Correct, will reword this and restrict this to POWER9, radix etc > > > > > > + > > > 8. Other capabilities. > > > == > > > > > > diff --git a/arch/powerpc/include/asm/kvm_book3s.h > > > b/arch/powerpc/include/asm/kvm_book3s.h > > > index d32ec9ae73bd..0f1c5fa6e8ce 100644 > > > --- a/arch/powerpc/include/asm/kvm_book3s.h > > > +++ b/arch/powerpc/include/asm/kvm_book3s.h > > > @@ -298,6 +298,9 @@ void kvmhv_set_ptbl_entry(unsigned int lpid, u64 dw0, > > > u64 dw1); > > > void kvmhv_release_all_nested(struct kvm *kvm); > > > long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu); > > > long kvmhv_do_nested_tlbie(struct kvm_vcpu *vcpu); > > > +long kvmhv_h_rpti_nested(struct kvm_vcpu *vcpu, unsigned long lpid, > > > + unsigned long type, unsigned long pg_sizes, > > > + unsigned long start, unsigned long end); > > > int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, > > > u64 time_limit, unsigned long lpcr); > > > void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state > > > *hr); > > > diff --git a/arch/powerpc/include/asm/mmu_context.h > > > b/arch/powerpc/include/asm/mmu_context.h > > > index d5821834dba9..fbf3b5b45fe9 100644 > > > --- a/arch/powerpc/include/asm/mmu_context.h > > > +++ b/arch/powerpc/include/asm/mmu_context.h > > > @@ -124,8 +124,19 @@ static inline bool need_extra_context(struct > > > mm_struct *mm, unsigned long ea) > > > > > > #if defined(CONFIG_KVM_BOOK3S_HV_POSSIBLE) && > > > defined(CONFIG_PPC_RADIX_MMU) > > > extern void radix_kvm_prefetch_workaround(struct mm_struct *mm); > > > +void do_h_rpt_invalidate(unsigned long pid, unsigned long lpid, > > > + unsigned long type, unsigned long page_size, > > > + unsigned long psize, unsigned long start, > > > + unsigned long end); > > > #else > > > static inline void radix_kvm_prefetch_workaround(struct mm_struct *mm) { > > > } > > > +static inline void do_h_rpt_invalidate(unsigned long pid, > > > +unsigned long lpid, > > > +unsigned long type, > > > +unsigned long page_size, > > > +
Re: [PATCH v4 2/3] KVM: PPC: Book3S HV: Add support for H_RPT_INVALIDATE
On Wed, Feb 17, 2021 at 11:38:07AM +1100, David Gibson wrote: > On Mon, Feb 15, 2021 at 12:05:41PM +0530, Bharata B Rao wrote: > > Implement H_RPT_INVALIDATE hcall and add KVM capability > > KVM_CAP_PPC_RPT_INVALIDATE to indicate the support for the same. > > > > This hcall does two types of TLB invalidations: > > > > 1. Process-scoped invalidations for guests with LPCR[GTSE]=0. > >This is currently not used in KVM as GTSE is not usually > >disabled in KVM. > > 2. Partition-scoped invalidations that an L1 hypervisor does on > >behalf of an L2 guest. This replaces the uses of the existing > >hcall H_TLB_INVALIDATE. > > > > In order to handle process scoped invalidations of L2, we > > intercept the nested exit handling code in L0 only to handle > > H_TLB_INVALIDATE hcall. > > > > Signed-off-by: Bharata B Rao > > --- > > Documentation/virt/kvm/api.rst | 17 + > > arch/powerpc/include/asm/kvm_book3s.h | 3 + > > arch/powerpc/include/asm/mmu_context.h | 11 +++ > > arch/powerpc/kvm/book3s_hv.c | 91 > > arch/powerpc/kvm/book3s_hv_nested.c| 96 ++ > > arch/powerpc/kvm/powerpc.c | 3 + > > arch/powerpc/mm/book3s64/radix_tlb.c | 25 +++ > > include/uapi/linux/kvm.h | 1 + > > 8 files changed, 247 insertions(+) > > > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > > index 99ceb978c8b0..416c36aa35d4 100644 > > --- a/Documentation/virt/kvm/api.rst > > +++ b/Documentation/virt/kvm/api.rst > > @@ -6038,6 +6038,23 @@ KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR exit > > notifications which user space > > can then handle to implement model specific MSR handling and/or user > > notifications > > to inform a user that an MSR was not handled. > > > > +7.22 KVM_CAP_PPC_RPT_INVALIDATE > > +-- > > + > > +:Capability: KVM_CAP_PPC_RPT_INVALIDATE > > +:Architectures: ppc > > +:Type: vm > > + > > +This capability indicates that the kernel is capable of handling > > +H_RPT_INVALIDATE hcall. > > + > > +In order to enable the use of H_RPT_INVALIDATE in the guest, > > +user space might have to advertise it for the guest. For example, > > +IBM pSeries (sPAPR) guest starts using it if "hcall-rpt-invalidate" is > > +present in the "ibm,hypertas-functions" device-tree property. > > + > > +This capability is always enabled. > > I guess that means it's always enabled when it's available - I'm > pretty sure it won't be enabled on POWER8 or on PR KVM. Correct, will reword this and restrict this to POWER9, radix etc > > > + > > 8. Other capabilities. > > == > > > > diff --git a/arch/powerpc/include/asm/kvm_book3s.h > > b/arch/powerpc/include/asm/kvm_book3s.h > > index d32ec9ae73bd..0f1c5fa6e8ce 100644 > > --- a/arch/powerpc/include/asm/kvm_book3s.h > > +++ b/arch/powerpc/include/asm/kvm_book3s.h > > @@ -298,6 +298,9 @@ void kvmhv_set_ptbl_entry(unsigned int lpid, u64 dw0, > > u64 dw1); > > void kvmhv_release_all_nested(struct kvm *kvm); > > long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu); > > long kvmhv_do_nested_tlbie(struct kvm_vcpu *vcpu); > > +long kvmhv_h_rpti_nested(struct kvm_vcpu *vcpu, unsigned long lpid, > > +unsigned long type, unsigned long pg_sizes, > > +unsigned long start, unsigned long end); > > int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, > > u64 time_limit, unsigned long lpcr); > > void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr); > > diff --git a/arch/powerpc/include/asm/mmu_context.h > > b/arch/powerpc/include/asm/mmu_context.h > > index d5821834dba9..fbf3b5b45fe9 100644 > > --- a/arch/powerpc/include/asm/mmu_context.h > > +++ b/arch/powerpc/include/asm/mmu_context.h > > @@ -124,8 +124,19 @@ static inline bool need_extra_context(struct mm_struct > > *mm, unsigned long ea) > > > > #if defined(CONFIG_KVM_BOOK3S_HV_POSSIBLE) && defined(CONFIG_PPC_RADIX_MMU) > > extern void radix_kvm_prefetch_workaround(struct mm_struct *mm); > > +void do_h_rpt_invalidate(unsigned long pid, unsigned long lpid, > > +unsigned long type, unsigned long page_size, > > +unsigned long psize, unsigned long start, > > +unsigned long end); > > #else > > static inline void radix_kvm_prefetch_workaround(struct mm_struct *mm) { } > > +static inline void do_h_rpt_invalidate(unsigned long pid, > > + unsigned long lpid, > > + unsigned long type, > > + unsigned long page_size, > > + unsigned long psize, > > + unsigned long start, > > + unsigned long end) { } > > #endif > > > > extern void switch_cop(struct mm_struct *next); > > diff --git a/arch/powerpc/kvm/book3s_hv.c
Re: [PATCH v4 2/3] KVM: PPC: Book3S HV: Add support for H_RPT_INVALIDATE
On Mon, Feb 15, 2021 at 12:05:41PM +0530, Bharata B Rao wrote: > Implement H_RPT_INVALIDATE hcall and add KVM capability > KVM_CAP_PPC_RPT_INVALIDATE to indicate the support for the same. > > This hcall does two types of TLB invalidations: > > 1. Process-scoped invalidations for guests with LPCR[GTSE]=0. >This is currently not used in KVM as GTSE is not usually >disabled in KVM. > 2. Partition-scoped invalidations that an L1 hypervisor does on >behalf of an L2 guest. This replaces the uses of the existing >hcall H_TLB_INVALIDATE. > > In order to handle process scoped invalidations of L2, we > intercept the nested exit handling code in L0 only to handle > H_TLB_INVALIDATE hcall. > > Signed-off-by: Bharata B Rao > --- > Documentation/virt/kvm/api.rst | 17 + > arch/powerpc/include/asm/kvm_book3s.h | 3 + > arch/powerpc/include/asm/mmu_context.h | 11 +++ > arch/powerpc/kvm/book3s_hv.c | 91 > arch/powerpc/kvm/book3s_hv_nested.c| 96 ++ > arch/powerpc/kvm/powerpc.c | 3 + > arch/powerpc/mm/book3s64/radix_tlb.c | 25 +++ > include/uapi/linux/kvm.h | 1 + > 8 files changed, 247 insertions(+) > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst > index 99ceb978c8b0..416c36aa35d4 100644 > --- a/Documentation/virt/kvm/api.rst > +++ b/Documentation/virt/kvm/api.rst > @@ -6038,6 +6038,23 @@ KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR exit > notifications which user space > can then handle to implement model specific MSR handling and/or user > notifications > to inform a user that an MSR was not handled. > > +7.22 KVM_CAP_PPC_RPT_INVALIDATE > +-- > + > +:Capability: KVM_CAP_PPC_RPT_INVALIDATE > +:Architectures: ppc > +:Type: vm > + > +This capability indicates that the kernel is capable of handling > +H_RPT_INVALIDATE hcall. > + > +In order to enable the use of H_RPT_INVALIDATE in the guest, > +user space might have to advertise it for the guest. For example, > +IBM pSeries (sPAPR) guest starts using it if "hcall-rpt-invalidate" is > +present in the "ibm,hypertas-functions" device-tree property. > + > +This capability is always enabled. I guess that means it's always enabled when it's available - I'm pretty sure it won't be enabled on POWER8 or on PR KVM. > + > 8. Other capabilities. > == > > diff --git a/arch/powerpc/include/asm/kvm_book3s.h > b/arch/powerpc/include/asm/kvm_book3s.h > index d32ec9ae73bd..0f1c5fa6e8ce 100644 > --- a/arch/powerpc/include/asm/kvm_book3s.h > +++ b/arch/powerpc/include/asm/kvm_book3s.h > @@ -298,6 +298,9 @@ void kvmhv_set_ptbl_entry(unsigned int lpid, u64 dw0, u64 > dw1); > void kvmhv_release_all_nested(struct kvm *kvm); > long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu); > long kvmhv_do_nested_tlbie(struct kvm_vcpu *vcpu); > +long kvmhv_h_rpti_nested(struct kvm_vcpu *vcpu, unsigned long lpid, > + unsigned long type, unsigned long pg_sizes, > + unsigned long start, unsigned long end); > int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, > u64 time_limit, unsigned long lpcr); > void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr); > diff --git a/arch/powerpc/include/asm/mmu_context.h > b/arch/powerpc/include/asm/mmu_context.h > index d5821834dba9..fbf3b5b45fe9 100644 > --- a/arch/powerpc/include/asm/mmu_context.h > +++ b/arch/powerpc/include/asm/mmu_context.h > @@ -124,8 +124,19 @@ static inline bool need_extra_context(struct mm_struct > *mm, unsigned long ea) > > #if defined(CONFIG_KVM_BOOK3S_HV_POSSIBLE) && defined(CONFIG_PPC_RADIX_MMU) > extern void radix_kvm_prefetch_workaround(struct mm_struct *mm); > +void do_h_rpt_invalidate(unsigned long pid, unsigned long lpid, > + unsigned long type, unsigned long page_size, > + unsigned long psize, unsigned long start, > + unsigned long end); > #else > static inline void radix_kvm_prefetch_workaround(struct mm_struct *mm) { } > +static inline void do_h_rpt_invalidate(unsigned long pid, > +unsigned long lpid, > +unsigned long type, > +unsigned long page_size, > +unsigned long psize, > +unsigned long start, > +unsigned long end) { } > #endif > > extern void switch_cop(struct mm_struct *next); > diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c > index 6f612d240392..802cb77c39cc 100644 > --- a/arch/powerpc/kvm/book3s_hv.c > +++ b/arch/powerpc/kvm/book3s_hv.c > @@ -904,6 +904,64 @@ static int kvmppc_get_yield_count(struct kvm_vcpu *vcpu) > return yield_count; > } > > +static void do_h_rpt_invalidate_prs(unsigned long
[PATCH v4 2/3] KVM: PPC: Book3S HV: Add support for H_RPT_INVALIDATE
Implement H_RPT_INVALIDATE hcall and add KVM capability KVM_CAP_PPC_RPT_INVALIDATE to indicate the support for the same. This hcall does two types of TLB invalidations: 1. Process-scoped invalidations for guests with LPCR[GTSE]=0. This is currently not used in KVM as GTSE is not usually disabled in KVM. 2. Partition-scoped invalidations that an L1 hypervisor does on behalf of an L2 guest. This replaces the uses of the existing hcall H_TLB_INVALIDATE. In order to handle process scoped invalidations of L2, we intercept the nested exit handling code in L0 only to handle H_TLB_INVALIDATE hcall. Signed-off-by: Bharata B Rao --- Documentation/virt/kvm/api.rst | 17 + arch/powerpc/include/asm/kvm_book3s.h | 3 + arch/powerpc/include/asm/mmu_context.h | 11 +++ arch/powerpc/kvm/book3s_hv.c | 91 arch/powerpc/kvm/book3s_hv_nested.c| 96 ++ arch/powerpc/kvm/powerpc.c | 3 + arch/powerpc/mm/book3s64/radix_tlb.c | 25 +++ include/uapi/linux/kvm.h | 1 + 8 files changed, 247 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 99ceb978c8b0..416c36aa35d4 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -6038,6 +6038,23 @@ KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR exit notifications which user space can then handle to implement model specific MSR handling and/or user notifications to inform a user that an MSR was not handled. +7.22 KVM_CAP_PPC_RPT_INVALIDATE +-- + +:Capability: KVM_CAP_PPC_RPT_INVALIDATE +:Architectures: ppc +:Type: vm + +This capability indicates that the kernel is capable of handling +H_RPT_INVALIDATE hcall. + +In order to enable the use of H_RPT_INVALIDATE in the guest, +user space might have to advertise it for the guest. For example, +IBM pSeries (sPAPR) guest starts using it if "hcall-rpt-invalidate" is +present in the "ibm,hypertas-functions" device-tree property. + +This capability is always enabled. + 8. Other capabilities. == diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index d32ec9ae73bd..0f1c5fa6e8ce 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h @@ -298,6 +298,9 @@ void kvmhv_set_ptbl_entry(unsigned int lpid, u64 dw0, u64 dw1); void kvmhv_release_all_nested(struct kvm *kvm); long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu); long kvmhv_do_nested_tlbie(struct kvm_vcpu *vcpu); +long kvmhv_h_rpti_nested(struct kvm_vcpu *vcpu, unsigned long lpid, +unsigned long type, unsigned long pg_sizes, +unsigned long start, unsigned long end); int kvmhv_run_single_vcpu(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long lpcr); void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr); diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index d5821834dba9..fbf3b5b45fe9 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -124,8 +124,19 @@ static inline bool need_extra_context(struct mm_struct *mm, unsigned long ea) #if defined(CONFIG_KVM_BOOK3S_HV_POSSIBLE) && defined(CONFIG_PPC_RADIX_MMU) extern void radix_kvm_prefetch_workaround(struct mm_struct *mm); +void do_h_rpt_invalidate(unsigned long pid, unsigned long lpid, +unsigned long type, unsigned long page_size, +unsigned long psize, unsigned long start, +unsigned long end); #else static inline void radix_kvm_prefetch_workaround(struct mm_struct *mm) { } +static inline void do_h_rpt_invalidate(unsigned long pid, + unsigned long lpid, + unsigned long type, + unsigned long page_size, + unsigned long psize, + unsigned long start, + unsigned long end) { } #endif extern void switch_cop(struct mm_struct *next); diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 6f612d240392..802cb77c39cc 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -904,6 +904,64 @@ static int kvmppc_get_yield_count(struct kvm_vcpu *vcpu) return yield_count; } +static void do_h_rpt_invalidate_prs(unsigned long pid, unsigned long lpid, + unsigned long type, unsigned long pg_sizes, + unsigned long start, unsigned long end) +{ + unsigned long psize; + + if (pg_sizes & H_RPTI_PAGE_64K) { + psize = rpti_pgsize_to_psize(pg_sizes & H_RPTI_PAGE_64K); + do_h_rpt_invalidate(pid, lpid,