Re: [PATCH kernel] KVM: PPC: Book3s: Retire H_PUT_TCE/etc real mode handlers

2022-05-02 Thread Fabiano Rosas
Alexey Kardashevskiy  writes:

> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S 
> b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index d185dee26026..44d74bfe05df 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -1784,13 +1784,8 @@ hcall_real_table:
>   .long   DOTSYM(kvmppc_h_clear_mod) - hcall_real_table
>   .long   DOTSYM(kvmppc_h_clear_ref) - hcall_real_table
>   .long   DOTSYM(kvmppc_h_protect) - hcall_real_table
> -#ifdef CONFIG_SPAPR_TCE_IOMMU
> - .long   DOTSYM(kvmppc_h_get_tce) - hcall_real_table
> - .long   DOTSYM(kvmppc_rm_h_put_tce) - hcall_real_table
> -#else
>   .long   0   /* 0x1c */
>   .long   0   /* 0x20 */
> -#endif
>   .long   0   /* 0x24 - H_SET_SPRG0 */
>   .long   DOTSYM(kvmppc_h_set_dabr) - hcall_real_table
>   .long   DOTSYM(kvmppc_rm_h_page_init) - hcall_real_table
> @@ -1868,13 +1863,8 @@ hcall_real_table:
>   .long   0   /* 0x12c */
>   .long   0   /* 0x130 */
>   .long   DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table
> -#ifdef CONFIG_SPAPR_TCE_IOMMU
> - .long   DOTSYM(kvmppc_rm_h_stuff_tce) - hcall_real_table
> - .long   DOTSYM(kvmppc_rm_h_put_tce_indirect) - hcall_real_table
> -#else
>   .long   0   /* 0x138 */
>   .long   0   /* 0x13c */
> -#endif
>   .long   0   /* 0x140 */
>   .long   0   /* 0x144 */
>   .long   0   /* 0x148 */

The ones you remove from here need to be added to kvmppc_hcall_impl_hv,
otherwise we get the WARN at init_default_hcalls because
kvmppc_hcall_impl_hv_realmode can't find them.


[PATCH kernel] KVM: PPC: Book3s: Retire H_PUT_TCE/etc real mode handlers

2022-04-28 Thread Alexey Kardashevskiy
LoPAPR defines guest visible IOMMU with hypercalls to use it -
H_PUT_TCE/etc. Implemented first on POWER7 where hypercalls would trap
in the KVM in the real mode (with MMU off). The problem with the real mode
is some memory is not available and some API usage crashed the host but
enabling MMU was an expensive operation.

The problems with the real mode handlers are:
1. Occasionally these cannot complete the request so the code is
copied+modified to work in the virtual mode, very little is shared;
2. The real mode handlers have to be linked into vmlinux to work;
3. An exception in real mode immediately reboots the machine.

If the small DMA window is used, the real mode handlers bring better
performance. However since POWER8, there has always been a bigger DMA
window which VMs use to map the entire VM memory to avoid calling
H_PUT_TCE. Such 1:1 mapping happens once and uses H_PUT_TCE_INDIRECT
(a bulk version of H_PUT_TCE) which virtual mode handler is even closer
to its real mode version.

On POWER9 hypercalls trap straight to the virtual mode so the real mode
handlers never execute on POWER9 and later CPUs.

So with the current use of the DMA windows and MMU improvements in
POWER9 and later, there is no point in duplicating the code.
The 32bit passed through devices may slow down but we do not have many
of these in practice. For example, with this applied, a 1Gbit ethernet
adapter still demostrates above 800Mbit/s of actual throughput.

This removes the real mode handlers from KVM and related code from
the powernv platform.

This changes ABI - kvmppc_h_get_tce() moves to the KVM module and
kvmppc_find_table() is static now.

Signed-off-by: Alexey Kardashevskiy 
---
 arch/powerpc/kvm/Makefile |   3 -
 arch/powerpc/include/asm/iommu.h  |   6 +-
 arch/powerpc/include/asm/kvm_ppc.h|   2 -
 arch/powerpc/include/asm/mmu_context.h|   5 -
 arch/powerpc/platforms/powernv/pci.h  |   3 +-
 arch/powerpc/kernel/iommu.c   |   4 +-
 arch/powerpc/kvm/book3s_64_vio.c  |  43 ++
 arch/powerpc/kvm/book3s_64_vio_hv.c   | 672 --
 arch/powerpc/mm/book3s64/iommu_api.c  |  68 --
 arch/powerpc/platforms/powernv/pci-ioda-tce.c |   5 +-
 arch/powerpc/platforms/powernv/pci-ioda.c |  46 +-
 arch/powerpc/platforms/pseries/iommu.c|   3 +-
 arch/powerpc/kvm/book3s_hv_rmhandlers.S   |  10 -
 13 files changed, 69 insertions(+), 801 deletions(-)
 delete mode 100644 arch/powerpc/kvm/book3s_64_vio_hv.c

diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 9bdfc8b50899..8e3681a86074 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -37,9 +37,6 @@ kvm-e500mc-objs := \
e500_emulate.o
 kvm-objs-$(CONFIG_KVM_E500MC) := $(kvm-e500mc-objs)
 
-kvm-book3s_64-builtin-objs-$(CONFIG_SPAPR_TCE_IOMMU) := \
-   book3s_64_vio_hv.o
-
 kvm-pr-y := \
fpu.o \
emulate.o \
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index d7912b66c874..7e29c73e3dd4 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -51,13 +51,11 @@ struct iommu_table_ops {
int (*xchg_no_kill)(struct iommu_table *tbl,
long index,
unsigned long *hpa,
-   enum dma_data_direction *direction,
-   bool realmode);
+   enum dma_data_direction *direction);
 
void (*tce_kill)(struct iommu_table *tbl,
unsigned long index,
-   unsigned long pages,
-   bool realmode);
+   unsigned long pages);
 
__be64 *(*useraddrptr)(struct iommu_table *tbl, long index, bool alloc);
 #endif
diff --git a/arch/powerpc/include/asm/kvm_ppc.h 
b/arch/powerpc/include/asm/kvm_ppc.h
index 838d4cb460b7..44200a27371b 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -177,8 +177,6 @@ extern void kvmppc_setup_partition_table(struct kvm *kvm);
 
 extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
struct kvm_create_spapr_tce_64 *args);
-extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
-   struct kvm *kvm, unsigned long liobn);
 #define kvmppc_ioba_validate(stt, ioba, npages) \
(iommu_tce_check_ioba((stt)->page_shift, (stt)->offset, \
(stt)->size, (ioba), (npages)) ?\
diff --git a/arch/powerpc/include/asm/mmu_context.h 
b/arch/powerpc/include/asm/mmu_context.h
index b8527a74bd4d..3f25bd3e14eb 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -34,15 +34,10 @@ extern void mm_iommu_init(struct mm_struct *mm);
 extern void mm_iommu_cleanup(struct mm_struct *mm);
 extern struct mm_iommu_table_group_mem_t *mm_iommu_lookup(struct