linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH kernel 0/4] KVM: PPC: Add in-kernel acceleration for 64bit DMA
@ 2016-01-21  8:15 Alexey Kardashevskiy
  2016-01-21  8:15 ` [PATCH kernel 1/4] KVM: PPC: Reserve KVM_CAP_SPAPR_TCE_64 capability number Alexey Kardashevskiy
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Alexey Kardashevskiy @ 2016-01-21  8:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Paul Mackerras, David Gibson, kvm-ppc, kvm

This extends the existing H_PUT_TCE/etc in-kernel acceleration to 64bit
DMA windows mapped at addresses other than zero. This accelerates huge
DMA windows which pseries guests create using Dynamic DMA window (DDW) API.

This does not affect VFIO yet.

This depends on:

69b907297f4e list: Add lockless list traversal primitives
and recently posted:
powerpc: Make vmalloc_to_phys() public
KVM: PPC: Add in-kernel multitce handling


Please comment. Thanks!


Alexey Kardashevskiy (4):
  KVM: PPC: Reserve KVM_CAP_SPAPR_TCE_64 capability number
  KVM: PPC: Add @page_shift to kvmppc_spapr_tce_table
  KVM: PPC: Add @offset to kvmppc_spapr_tce_table
  KVM: PPC: Add support for 64bit TCE windows

 Documentation/virtual/kvm/api.txt   | 32 ++++++++++++++++++++++++++++++++
 arch/powerpc/include/asm/kvm_host.h |  4 +++-
 arch/powerpc/include/asm/kvm_ppc.h  |  2 +-
 arch/powerpc/include/uapi/asm/kvm.h |  9 +++++++++
 arch/powerpc/kvm/book3s_64_vio.c    | 35 ++++++++++++++++++++---------------
 arch/powerpc/kvm/book3s_64_vio_hv.c | 22 ++++++++++++----------
 arch/powerpc/kvm/powerpc.c          | 25 ++++++++++++++++++++++++-
 include/uapi/linux/kvm.h            |  3 +++
 8 files changed, 104 insertions(+), 28 deletions(-)

-- 
2.5.0.rc3

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH kernel 1/4] KVM: PPC: Reserve KVM_CAP_SPAPR_TCE_64 capability number
  2016-01-21  8:15 [PATCH kernel 0/4] KVM: PPC: Add in-kernel acceleration for 64bit DMA Alexey Kardashevskiy
@ 2016-01-21  8:15 ` Alexey Kardashevskiy
  2016-01-25  5:23   ` David Gibson
  2016-01-21  8:15 ` [PATCH kernel 2/4] KVM: PPC: Add @page_shift to kvmppc_spapr_tce_table Alexey Kardashevskiy
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Alexey Kardashevskiy @ 2016-01-21  8:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Paul Mackerras, David Gibson, kvm-ppc, kvm

This adds a capability number for 64-bit TCE tables support.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 include/uapi/linux/kvm.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 9da9051..8ce5f64 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -850,6 +850,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
 #define KVM_CAP_HYPERV_SYNIC 123
 #define KVM_CAP_S390_RI 124
+#define KVM_CAP_SPAPR_TCE_64 125
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.5.0.rc3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH kernel 2/4] KVM: PPC: Add @page_shift to kvmppc_spapr_tce_table
  2016-01-21  8:15 [PATCH kernel 0/4] KVM: PPC: Add in-kernel acceleration for 64bit DMA Alexey Kardashevskiy
  2016-01-21  8:15 ` [PATCH kernel 1/4] KVM: PPC: Reserve KVM_CAP_SPAPR_TCE_64 capability number Alexey Kardashevskiy
@ 2016-01-21  8:15 ` Alexey Kardashevskiy
  2016-01-25  5:30   ` David Gibson
  2016-01-21  8:15 ` [PATCH kernel 3/4] KVM: PPC: Add @offset " Alexey Kardashevskiy
  2016-01-21  8:15 ` [PATCH kernel 4/4] KVM: PPC: Add support for 64bit TCE windows Alexey Kardashevskiy
  3 siblings, 1 reply; 12+ messages in thread
From: Alexey Kardashevskiy @ 2016-01-21  8:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Paul Mackerras, David Gibson, kvm-ppc, kvm

At the moment the kvmppc_spapr_tce_table struct can only describe
4GB windows and handle fixed size (4K) pages. Dynamic DMA windows
support more so these limits need to be extended.

This replaces window_size (in bytes, 4GB max) with page_shift (32bit)
and size (64bit, in pages).

This should cause no behavioural change.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 arch/powerpc/include/asm/kvm_host.h |  3 ++-
 arch/powerpc/kvm/book3s_64_vio.c    | 29 +++++++++++++++--------------
 arch/powerpc/kvm/book3s_64_vio_hv.c | 20 ++++++++++----------
 3 files changed, 27 insertions(+), 25 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index c7ee696..a4ed9f5 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -183,8 +183,9 @@ struct kvmppc_spapr_tce_table {
 	struct list_head list;
 	struct kvm *kvm;
 	u64 liobn;
-	u32 window_size;
 	struct rcu_head rcu;
+	u32 page_shift;
+	u64 size;		/* in pages */
 	struct page *pages[0];
 };
 
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 987f406..85ee572 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -40,10 +40,9 @@
 #include <asm/iommu.h>
 #include <asm/tce.h>
 
-static unsigned long kvmppc_stt_npages(unsigned long window_size)
+static unsigned long kvmppc_stt_npages(unsigned long size)
 {
-	return ALIGN((window_size >> IOMMU_PAGE_SHIFT_4K)
-		     * sizeof(u64), PAGE_SIZE) / PAGE_SIZE;
+	return ALIGN(size * sizeof(u64), PAGE_SIZE) / PAGE_SIZE;
 }
 
 static long kvmppc_account_memlimit(unsigned long npages, bool inc)
@@ -92,8 +91,8 @@ static void release_spapr_tce_table(struct rcu_head *head)
 {
 	struct kvmppc_spapr_tce_table *stt = container_of(head,
 			struct kvmppc_spapr_tce_table, rcu);
-	int i;
-	unsigned long npages = kvmppc_stt_npages(stt->window_size);
+	unsigned long i;
+	unsigned long npages = kvmppc_stt_npages(stt->size);
 
 	for (i = 0; i < npages; i++)
 		__free_page(stt->pages[i]);
@@ -106,7 +105,7 @@ static int kvm_spapr_tce_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 	struct kvmppc_spapr_tce_table *stt = vma->vm_file->private_data;
 	struct page *page;
 
-	if (vmf->pgoff >= kvmppc_stt_npages(stt->window_size))
+	if (vmf->pgoff >= kvmppc_stt_npages(stt->size))
 		return VM_FAULT_SIGBUS;
 
 	page = stt->pages[vmf->pgoff];
@@ -133,7 +132,7 @@ static int kvm_spapr_tce_release(struct inode *inode, struct file *filp)
 
 	kvm_put_kvm(stt->kvm);
 
-	kvmppc_account_memlimit(kvmppc_stt_npages(stt->window_size), false);
+	kvmppc_account_memlimit(kvmppc_stt_npages(stt->size), false);
 	call_rcu(&stt->rcu, release_spapr_tce_table);
 
 	return 0;
@@ -148,7 +147,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 				   struct kvm_create_spapr_tce *args)
 {
 	struct kvmppc_spapr_tce_table *stt = NULL;
-	unsigned long npages;
+	unsigned long npages, size;
 	int ret = -ENOMEM;
 	int i;
 
@@ -158,7 +157,8 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 			return -EBUSY;
 	}
 
-	npages = kvmppc_stt_npages(args->window_size);
+	size = args->window_size >> IOMMU_PAGE_SHIFT_4K;
+	npages = kvmppc_stt_npages(size);
 	ret = kvmppc_account_memlimit(npages, true);
 	if (ret) {
 		stt = NULL;
@@ -171,7 +171,8 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 		goto fail;
 
 	stt->liobn = args->liobn;
-	stt->window_size = args->window_size;
+	stt->page_shift = IOMMU_PAGE_SHIFT_4K;
+	stt->size = size;
 	stt->kvm = kvm;
 
 	for (i = 0; i < npages; i++) {
@@ -220,7 +221,7 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu,
 	if (ret != H_SUCCESS)
 		return ret;
 
-	kvmppc_tce_put(stt, ioba >> IOMMU_PAGE_SHIFT_4K, tce);
+	kvmppc_tce_put(stt, ioba >> stt->page_shift, tce);
 
 	return H_SUCCESS;
 }
@@ -239,7 +240,7 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 	if (!stt)
 		return H_TOO_HARD;
 
-	entry = ioba >> IOMMU_PAGE_SHIFT_4K;
+	entry = ioba >> stt->page_shift;
 	/*
 	 * SPAPR spec says that the maximum size of the list is 512 TCEs
 	 * so the whole table fits in 4K page
@@ -300,8 +301,8 @@ long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu,
 	if (tce_value & (TCE_PCI_WRITE | TCE_PCI_READ))
 		return H_PARAMETER;
 
-	for (i = 0; i < npages; ++i, ioba += IOMMU_PAGE_SIZE_4K)
-		kvmppc_tce_put(stt, ioba >> IOMMU_PAGE_SHIFT_4K, tce_value);
+	for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift))
+		kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value);
 
 	return H_SUCCESS;
 }
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 58c63ed..01ef9f9 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -72,11 +72,10 @@ EXPORT_SYMBOL_GPL(kvmppc_find_table);
 long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
 		unsigned long ioba, unsigned long npages)
 {
-	unsigned long mask = IOMMU_PAGE_MASK_4K;
-	unsigned long idx = ioba >> IOMMU_PAGE_SHIFT_4K;
-	unsigned long size = stt->window_size >> IOMMU_PAGE_SHIFT_4K;
+	unsigned long mask = ~((1ULL << stt->page_shift) - 1);
+	unsigned long idx = ioba >> stt->page_shift;
 
-	if ((ioba & ~mask) || (idx + npages > size))
+	if ((ioba & ~mask) || (idx + npages > stt->size))
 		return H_PARAMETER;
 
 	return H_SUCCESS;
@@ -96,7 +95,8 @@ EXPORT_SYMBOL_GPL(kvmppc_ioba_validate);
  */
 long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt, unsigned long tce)
 {
-	unsigned long mask = IOMMU_PAGE_MASK_4K | TCE_PCI_WRITE | TCE_PCI_READ;
+	unsigned long mask = ~((1ULL << stt->page_shift) - 1) |
+			TCE_PCI_WRITE | TCE_PCI_READ;
 
 	if (tce & ~mask)
 		return H_PARAMETER;
@@ -197,7 +197,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 	if (ret != H_SUCCESS)
 		return ret;
 
-	kvmppc_tce_put(stt, ioba >> IOMMU_PAGE_SHIFT_4K, tce);
+	kvmppc_tce_put(stt, ioba >> stt->page_shift, tce);
 
 	return H_SUCCESS;
 }
@@ -242,7 +242,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
 	if (!stt)
 		return H_TOO_HARD;
 
-	entry = ioba >> IOMMU_PAGE_SHIFT_4K;
+	entry = ioba >> stt->page_shift;
 	/*
 	 * The spec says that the maximum size of the list is 512 TCEs
 	 * so the whole table addressed resides in 4K page
@@ -302,8 +302,8 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
 	if (tce_value & (TCE_PCI_WRITE | TCE_PCI_READ))
 		return H_PARAMETER;
 
-	for (i = 0; i < npages; ++i, ioba += IOMMU_PAGE_SIZE_4K)
-		kvmppc_tce_put(stt, ioba >> IOMMU_PAGE_SHIFT_4K, tce_value);
+	for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift))
+		kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value);
 
 	return H_SUCCESS;
 }
@@ -324,7 +324,7 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 	if (ret != H_SUCCESS)
 		return ret;
 
-	idx = ioba >> IOMMU_PAGE_SHIFT_4K;
+	idx = ioba >> stt->page_shift;
 	page = stt->pages[idx / TCES_PER_PAGE];
 	tbl = (u64 *)page_address(page);
 
-- 
2.5.0.rc3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH kernel 3/4] KVM: PPC: Add @offset to kvmppc_spapr_tce_table
  2016-01-21  8:15 [PATCH kernel 0/4] KVM: PPC: Add in-kernel acceleration for 64bit DMA Alexey Kardashevskiy
  2016-01-21  8:15 ` [PATCH kernel 1/4] KVM: PPC: Reserve KVM_CAP_SPAPR_TCE_64 capability number Alexey Kardashevskiy
  2016-01-21  8:15 ` [PATCH kernel 2/4] KVM: PPC: Add @page_shift to kvmppc_spapr_tce_table Alexey Kardashevskiy
@ 2016-01-21  8:15 ` Alexey Kardashevskiy
  2016-01-25  5:33   ` David Gibson
  2016-01-21  8:15 ` [PATCH kernel 4/4] KVM: PPC: Add support for 64bit TCE windows Alexey Kardashevskiy
  3 siblings, 1 reply; 12+ messages in thread
From: Alexey Kardashevskiy @ 2016-01-21  8:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Paul Mackerras, David Gibson, kvm-ppc, kvm

This enables userspace view of TCE tables to start from non-zero offset
on a bus. This will be used for huge DMA windows.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 arch/powerpc/include/asm/kvm_host.h | 1 +
 arch/powerpc/kvm/book3s_64_vio_hv.c | 6 ++++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index a4ed9f5..8769f91 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -185,6 +185,7 @@ struct kvmppc_spapr_tce_table {
 	u64 liobn;
 	struct rcu_head rcu;
 	u32 page_shift;
+	u64 offset;		/* in pages */
 	u64 size;		/* in pages */
 	struct page *pages[0];
 };
diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
index 01ef9f9..0e66459 100644
--- a/arch/powerpc/kvm/book3s_64_vio_hv.c
+++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
@@ -75,7 +75,8 @@ long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
 	unsigned long mask = ~((1ULL << stt->page_shift) - 1);
 	unsigned long idx = ioba >> stt->page_shift;
 
-	if ((ioba & ~mask) || (idx + npages > stt->size))
+	if ((ioba & ~mask) || (idx < stt->offset) ||
+			(idx - stt->offset + npages > stt->size))
 		return H_PARAMETER;
 
 	return H_SUCCESS;
@@ -147,6 +148,7 @@ void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
 	struct page *page;
 	u64 *tbl;
 
+	idx -= stt->offset;
 	page = stt->pages[idx / TCES_PER_PAGE];
 	tbl = kvmppc_page_address(page);
 
@@ -324,7 +326,7 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
 	if (ret != H_SUCCESS)
 		return ret;
 
-	idx = ioba >> stt->page_shift;
+	idx = (ioba >> stt->page_shift) - stt->offset;
 	page = stt->pages[idx / TCES_PER_PAGE];
 	tbl = (u64 *)page_address(page);
 
-- 
2.5.0.rc3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH kernel 4/4] KVM: PPC: Add support for 64bit TCE windows
  2016-01-21  8:15 [PATCH kernel 0/4] KVM: PPC: Add in-kernel acceleration for 64bit DMA Alexey Kardashevskiy
                   ` (2 preceding siblings ...)
  2016-01-21  8:15 ` [PATCH kernel 3/4] KVM: PPC: Add @offset " Alexey Kardashevskiy
@ 2016-01-21  8:15 ` Alexey Kardashevskiy
  2016-01-25  5:37   ` David Gibson
  3 siblings, 1 reply; 12+ messages in thread
From: Alexey Kardashevskiy @ 2016-01-21  8:15 UTC (permalink / raw)
  To: linuxppc-dev
  Cc: Alexey Kardashevskiy, Paul Mackerras, David Gibson, kvm-ppc, kvm

The existing KVM_CREATE_SPAPR_TCE only supports 32bit windows which is not
enough for directly mapped windows as the guest can get more than 4GB.

This adds KVM_CREATE_SPAPR_TCE_64 ioctl and advertises it
via KVM_CAP_SPAPR_TCE_64 capability.

Since 64bit windows are to support Dynamic DMA windows (DDW), let's add
@bus_offset and @page_shift which are also required by DDW.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
 Documentation/virtual/kvm/api.txt   | 32 ++++++++++++++++++++++++++++++++
 arch/powerpc/include/asm/kvm_ppc.h  |  2 +-
 arch/powerpc/include/uapi/asm/kvm.h |  9 +++++++++
 arch/powerpc/kvm/book3s_64_vio.c    | 10 +++++++---
 arch/powerpc/kvm/powerpc.c          | 25 ++++++++++++++++++++++++-
 include/uapi/linux/kvm.h            |  2 ++
 6 files changed, 75 insertions(+), 5 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index da39435..d1c5655 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3060,6 +3060,38 @@ an implementation for these despite the in kernel acceleration.
 
 This capability is always enabled.
 
+4.96 KVM_CREATE_SPAPR_TCE_64
+
+Capability: KVM_CAP_SPAPR_TCE_64
+Architectures: powerpc
+Type: vm ioctl
+Parameters: struct kvm_create_spapr_tce_64 (in)
+Returns: file descriptor for manipulating the created TCE table
+
+This is an extension for KVM_CAP_SPAPR_TCE which only supports 32bit
+windows, described in 4.62 KVM_CREATE_SPAPR_TCE
+
+This capability uses extended struct in ioctl interface:
+
+/* for KVM_CAP_SPAPR_TCE_64 */
+struct kvm_create_spapr_tce_64 {
+	__u64 liobn;
+	__u32 page_shift;
+	__u64 offset;	/* in pages */
+	__u64 size; 	/* in pages */
+	__u32 flags;
+};
+
+The aim of extension is to support an additional bigger DMA window with
+a variable page size.
+KVM_CREATE_SPAPR_TCE_64 receives a 64bit window size, an IOMMU page shift and
+a bus offset of the corresponding DMA window, @size and @offset are numbers
+of IOMMU pages.
+
+@flags are not used at the moment.
+
+The rest of functionality is identical to KVM_CREATE_SPAPR_TCE.
+
 5. The kvm_run structure
 ------------------------
 
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 4cadee5..6e4d1dc 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -165,7 +165,7 @@ extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
 extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu);
 
 extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
-				struct kvm_create_spapr_tce *args);
+				struct kvm_create_spapr_tce_64 *args);
 extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
 		struct kvm_vcpu *vcpu, unsigned long liobn);
 extern long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index ab4d473..9c8b4cbc 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -333,6 +333,15 @@ struct kvm_create_spapr_tce {
 	__u32 window_size;
 };
 
+/* for KVM_CAP_SPAPR_TCE_64 */
+struct kvm_create_spapr_tce_64 {
+	__u64 liobn;
+	__u32 page_shift;
+	__u64 offset;	/* in pages */
+	__u64 size;	/* in pages */
+	__u32 flags;
+};
+
 /* for KVM_ALLOCATE_RMA */
 struct kvm_allocate_rma {
 	__u64 rma_size;
diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
index 85ee572..5479446 100644
--- a/arch/powerpc/kvm/book3s_64_vio.c
+++ b/arch/powerpc/kvm/book3s_64_vio.c
@@ -144,20 +144,23 @@ static const struct file_operations kvm_spapr_tce_fops = {
 };
 
 long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
-				   struct kvm_create_spapr_tce *args)
+				   struct kvm_create_spapr_tce_64 *args)
 {
 	struct kvmppc_spapr_tce_table *stt = NULL;
 	unsigned long npages, size;
 	int ret = -ENOMEM;
 	int i;
 
+	if (!args->size)
+		return -EINVAL;
+
 	/* Check this LIOBN hasn't been previously allocated */
 	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
 		if (stt->liobn == args->liobn)
 			return -EBUSY;
 	}
 
-	size = args->window_size >> IOMMU_PAGE_SHIFT_4K;
+	size = args->size;
 	npages = kvmppc_stt_npages(size);
 	ret = kvmppc_account_memlimit(npages, true);
 	if (ret) {
@@ -171,7 +174,8 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
 		goto fail;
 
 	stt->liobn = args->liobn;
-	stt->page_shift = IOMMU_PAGE_SHIFT_4K;
+	stt->page_shift = args->page_shift;
+	stt->offset = args->offset;
 	stt->size = size;
 	stt->kvm = kvm;
 
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 164735c..2b0fe92 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -33,6 +33,7 @@
 #include <asm/tlbflush.h>
 #include <asm/cputhreads.h>
 #include <asm/irqflags.h>
+#include <asm/iommu.h>
 #include "timing.h"
 #include "irq.h"
 #include "../mm/mmu_decl.h"
@@ -509,6 +510,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 
 #ifdef CONFIG_PPC_BOOK3S_64
 	case KVM_CAP_SPAPR_TCE:
+	case KVM_CAP_SPAPR_TCE_64:
 	case KVM_CAP_PPC_ALLOC_HTAB:
 	case KVM_CAP_PPC_RTAS:
 	case KVM_CAP_PPC_FIXUP_HCALL:
@@ -1334,13 +1336,34 @@ long kvm_arch_vm_ioctl(struct file *filp,
 		break;
 	}
 #ifdef CONFIG_PPC_BOOK3S_64
+	case KVM_CREATE_SPAPR_TCE_64: {
+		struct kvm_create_spapr_tce_64 create_tce_64;
+
+		r = -EFAULT;
+		if (copy_from_user(&create_tce_64, argp, sizeof(create_tce_64)))
+			goto out;
+		if (create_tce_64.flags) {
+			r = -EINVAL;
+			goto out;
+		}
+		r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce_64);
+		goto out;
+	}
 	case KVM_CREATE_SPAPR_TCE: {
 		struct kvm_create_spapr_tce create_tce;
+		struct kvm_create_spapr_tce_64 create_tce_64;
 
 		r = -EFAULT;
 		if (copy_from_user(&create_tce, argp, sizeof(create_tce)))
 			goto out;
-		r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce);
+
+		create_tce_64.liobn = create_tce.liobn;
+		create_tce_64.page_shift = IOMMU_PAGE_SHIFT_4K;
+		create_tce_64.offset = 0;
+		create_tce_64.size = create_tce.window_size >>
+				IOMMU_PAGE_SHIFT_4K;
+		create_tce_64.flags = 0;
+		r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce_64);
 		goto out;
 	}
 	case KVM_PPC_GET_SMMU_INFO: {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 8ce5f64..b06208b 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1143,6 +1143,8 @@ struct kvm_s390_ucas_mapping {
 /* Available with KVM_CAP_PPC_ALLOC_HTAB */
 #define KVM_PPC_ALLOCATE_HTAB	  _IOWR(KVMIO, 0xa7, __u32)
 #define KVM_CREATE_SPAPR_TCE	  _IOW(KVMIO,  0xa8, struct kvm_create_spapr_tce)
+#define KVM_CREATE_SPAPR_TCE_64	  _IOW(KVMIO,  0xa8, \
+				       struct kvm_create_spapr_tce_64)
 /* Available with KVM_CAP_RMA */
 #define KVM_ALLOCATE_RMA	  _IOR(KVMIO,  0xa9, struct kvm_allocate_rma)
 /* Available with KVM_CAP_PPC_HTAB_FD */
-- 
2.5.0.rc3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH kernel 1/4] KVM: PPC: Reserve KVM_CAP_SPAPR_TCE_64 capability number
  2016-01-21  8:15 ` [PATCH kernel 1/4] KVM: PPC: Reserve KVM_CAP_SPAPR_TCE_64 capability number Alexey Kardashevskiy
@ 2016-01-25  5:23   ` David Gibson
  0 siblings, 0 replies; 12+ messages in thread
From: David Gibson @ 2016-01-25  5:23 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: linuxppc-dev, Paul Mackerras, kvm-ppc, kvm

[-- Attachment #1: Type: text/plain, Size: 943 bytes --]

On Thu, Jan 21, 2016 at 07:15:23PM +1100, Alexey Kardashevskiy wrote:
> This adds a capability number for 64-bit TCE tables support.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  include/uapi/linux/kvm.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 9da9051..8ce5f64 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -850,6 +850,7 @@ struct kvm_ppc_smmu_info {
>  #define KVM_CAP_IOEVENTFD_ANY_LENGTH 122
>  #define KVM_CAP_HYPERV_SYNIC 123
>  #define KVM_CAP_S390_RI 124
> +#define KVM_CAP_SPAPR_TCE_64 125
>  
>  #ifdef KVM_CAP_IRQ_ROUTING
>  

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH kernel 2/4] KVM: PPC: Add @page_shift to kvmppc_spapr_tce_table
  2016-01-21  8:15 ` [PATCH kernel 2/4] KVM: PPC: Add @page_shift to kvmppc_spapr_tce_table Alexey Kardashevskiy
@ 2016-01-25  5:30   ` David Gibson
  0 siblings, 0 replies; 12+ messages in thread
From: David Gibson @ 2016-01-25  5:30 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: linuxppc-dev, Paul Mackerras, kvm-ppc, kvm

[-- Attachment #1: Type: text/plain, Size: 8073 bytes --]

On Thu, Jan 21, 2016 at 07:15:24PM +1100, Alexey Kardashevskiy wrote:
> At the moment the kvmppc_spapr_tce_table struct can only describe
> 4GB windows and handle fixed size (4K) pages. Dynamic DMA windows
> support more so these limits need to be extended.
> 
> This replaces window_size (in bytes, 4GB max) with page_shift (32bit)
> and size (64bit, in pages).
> 
> This should cause no behavioural change.

This commit message could be clearer about the fact that this is
changing the internal structures only - the user interface still only
allows one to create a 32-bit table with 4KiB pages at this stage.

> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Apart from that,

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  arch/powerpc/include/asm/kvm_host.h |  3 ++-
>  arch/powerpc/kvm/book3s_64_vio.c    | 29 +++++++++++++++--------------
>  arch/powerpc/kvm/book3s_64_vio_hv.c | 20 ++++++++++----------
>  3 files changed, 27 insertions(+), 25 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index c7ee696..a4ed9f5 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -183,8 +183,9 @@ struct kvmppc_spapr_tce_table {
>  	struct list_head list;
>  	struct kvm *kvm;
>  	u64 liobn;
> -	u32 window_size;
>  	struct rcu_head rcu;
> +	u32 page_shift;
> +	u64 size;		/* in pages */
>  	struct page *pages[0];
>  };
>  
> diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
> index 987f406..85ee572 100644
> --- a/arch/powerpc/kvm/book3s_64_vio.c
> +++ b/arch/powerpc/kvm/book3s_64_vio.c
> @@ -40,10 +40,9 @@
>  #include <asm/iommu.h>
>  #include <asm/tce.h>
>  
> -static unsigned long kvmppc_stt_npages(unsigned long window_size)
> +static unsigned long kvmppc_stt_npages(unsigned long size)
>  {
> -	return ALIGN((window_size >> IOMMU_PAGE_SHIFT_4K)
> -		     * sizeof(u64), PAGE_SIZE) / PAGE_SIZE;
> +	return ALIGN(size * sizeof(u64), PAGE_SIZE) / PAGE_SIZE;
>  }
>  
>  static long kvmppc_account_memlimit(unsigned long npages, bool inc)
> @@ -92,8 +91,8 @@ static void release_spapr_tce_table(struct rcu_head *head)
>  {
>  	struct kvmppc_spapr_tce_table *stt = container_of(head,
>  			struct kvmppc_spapr_tce_table, rcu);
> -	int i;
> -	unsigned long npages = kvmppc_stt_npages(stt->window_size);
> +	unsigned long i;
> +	unsigned long npages = kvmppc_stt_npages(stt->size);
>  
>  	for (i = 0; i < npages; i++)
>  		__free_page(stt->pages[i]);
> @@ -106,7 +105,7 @@ static int kvm_spapr_tce_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
>  	struct kvmppc_spapr_tce_table *stt = vma->vm_file->private_data;
>  	struct page *page;
>  
> -	if (vmf->pgoff >= kvmppc_stt_npages(stt->window_size))
> +	if (vmf->pgoff >= kvmppc_stt_npages(stt->size))
>  		return VM_FAULT_SIGBUS;
>  
>  	page = stt->pages[vmf->pgoff];
> @@ -133,7 +132,7 @@ static int kvm_spapr_tce_release(struct inode *inode, struct file *filp)
>  
>  	kvm_put_kvm(stt->kvm);
>  
> -	kvmppc_account_memlimit(kvmppc_stt_npages(stt->window_size), false);
> +	kvmppc_account_memlimit(kvmppc_stt_npages(stt->size), false);
>  	call_rcu(&stt->rcu, release_spapr_tce_table);
>  
>  	return 0;
> @@ -148,7 +147,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  				   struct kvm_create_spapr_tce *args)
>  {
>  	struct kvmppc_spapr_tce_table *stt = NULL;
> -	unsigned long npages;
> +	unsigned long npages, size;
>  	int ret = -ENOMEM;
>  	int i;
>  
> @@ -158,7 +157,8 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  			return -EBUSY;
>  	}
>  
> -	npages = kvmppc_stt_npages(args->window_size);
> +	size = args->window_size >> IOMMU_PAGE_SHIFT_4K;
> +	npages = kvmppc_stt_npages(size);
>  	ret = kvmppc_account_memlimit(npages, true);
>  	if (ret) {
>  		stt = NULL;
> @@ -171,7 +171,8 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  		goto fail;
>  
>  	stt->liobn = args->liobn;
> -	stt->window_size = args->window_size;
> +	stt->page_shift = IOMMU_PAGE_SHIFT_4K;
> +	stt->size = size;
>  	stt->kvm = kvm;
>  
>  	for (i = 0; i < npages; i++) {
> @@ -220,7 +221,7 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu,
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> -	kvmppc_tce_put(stt, ioba >> IOMMU_PAGE_SHIFT_4K, tce);
> +	kvmppc_tce_put(stt, ioba >> stt->page_shift, tce);
>  
>  	return H_SUCCESS;
>  }
> @@ -239,7 +240,7 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
>  	if (!stt)
>  		return H_TOO_HARD;
>  
> -	entry = ioba >> IOMMU_PAGE_SHIFT_4K;
> +	entry = ioba >> stt->page_shift;
>  	/*
>  	 * SPAPR spec says that the maximum size of the list is 512 TCEs
>  	 * so the whole table fits in 4K page
> @@ -300,8 +301,8 @@ long kvmppc_h_stuff_tce(struct kvm_vcpu *vcpu,
>  	if (tce_value & (TCE_PCI_WRITE | TCE_PCI_READ))
>  		return H_PARAMETER;
>  
> -	for (i = 0; i < npages; ++i, ioba += IOMMU_PAGE_SIZE_4K)
> -		kvmppc_tce_put(stt, ioba >> IOMMU_PAGE_SHIFT_4K, tce_value);
> +	for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift))
> +		kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value);
>  
>  	return H_SUCCESS;
>  }
> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index 58c63ed..01ef9f9 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -72,11 +72,10 @@ EXPORT_SYMBOL_GPL(kvmppc_find_table);
>  long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
>  		unsigned long ioba, unsigned long npages)
>  {
> -	unsigned long mask = IOMMU_PAGE_MASK_4K;
> -	unsigned long idx = ioba >> IOMMU_PAGE_SHIFT_4K;
> -	unsigned long size = stt->window_size >> IOMMU_PAGE_SHIFT_4K;
> +	unsigned long mask = ~((1ULL << stt->page_shift) - 1);
> +	unsigned long idx = ioba >> stt->page_shift;
>  
> -	if ((ioba & ~mask) || (idx + npages > size))
> +	if ((ioba & ~mask) || (idx + npages > stt->size))
>  		return H_PARAMETER;
>  
>  	return H_SUCCESS;
> @@ -96,7 +95,8 @@ EXPORT_SYMBOL_GPL(kvmppc_ioba_validate);
>   */
>  long kvmppc_tce_validate(struct kvmppc_spapr_tce_table *stt, unsigned long tce)
>  {
> -	unsigned long mask = IOMMU_PAGE_MASK_4K | TCE_PCI_WRITE | TCE_PCI_READ;
> +	unsigned long mask = ~((1ULL << stt->page_shift) - 1) |
> +			TCE_PCI_WRITE | TCE_PCI_READ;
>  
>  	if (tce & ~mask)
>  		return H_PARAMETER;
> @@ -197,7 +197,7 @@ long kvmppc_rm_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> -	kvmppc_tce_put(stt, ioba >> IOMMU_PAGE_SHIFT_4K, tce);
> +	kvmppc_tce_put(stt, ioba >> stt->page_shift, tce);
>  
>  	return H_SUCCESS;
>  }
> @@ -242,7 +242,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
>  	if (!stt)
>  		return H_TOO_HARD;
>  
> -	entry = ioba >> IOMMU_PAGE_SHIFT_4K;
> +	entry = ioba >> stt->page_shift;
>  	/*
>  	 * The spec says that the maximum size of the list is 512 TCEs
>  	 * so the whole table addressed resides in 4K page
> @@ -302,8 +302,8 @@ long kvmppc_rm_h_stuff_tce(struct kvm_vcpu *vcpu,
>  	if (tce_value & (TCE_PCI_WRITE | TCE_PCI_READ))
>  		return H_PARAMETER;
>  
> -	for (i = 0; i < npages; ++i, ioba += IOMMU_PAGE_SIZE_4K)
> -		kvmppc_tce_put(stt, ioba >> IOMMU_PAGE_SHIFT_4K, tce_value);
> +	for (i = 0; i < npages; ++i, ioba += (1ULL << stt->page_shift))
> +		kvmppc_tce_put(stt, ioba >> stt->page_shift, tce_value);
>  
>  	return H_SUCCESS;
>  }
> @@ -324,7 +324,7 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> -	idx = ioba >> IOMMU_PAGE_SHIFT_4K;
> +	idx = ioba >> stt->page_shift;
>  	page = stt->pages[idx / TCES_PER_PAGE];
>  	tbl = (u64 *)page_address(page);
>  

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH kernel 3/4] KVM: PPC: Add @offset to kvmppc_spapr_tce_table
  2016-01-21  8:15 ` [PATCH kernel 3/4] KVM: PPC: Add @offset " Alexey Kardashevskiy
@ 2016-01-25  5:33   ` David Gibson
  2016-01-27  3:31     ` Alexey Kardashevskiy
  0 siblings, 1 reply; 12+ messages in thread
From: David Gibson @ 2016-01-25  5:33 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: linuxppc-dev, Paul Mackerras, kvm-ppc, kvm

[-- Attachment #1: Type: text/plain, Size: 2429 bytes --]

On Thu, Jan 21, 2016 at 07:15:25PM +1100, Alexey Kardashevskiy wrote:
> This enables userspace view of TCE tables to start from non-zero offset
> on a bus. This will be used for huge DMA windows.

Again I'd like the commit message adjusted to clarify the fact that
this has internal changes only which will need interface changes to
actually use.

> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

Reviewed-by: David Gibson <david@gibson.dropbear.id.au>

> ---
>  arch/powerpc/include/asm/kvm_host.h | 1 +
>  arch/powerpc/kvm/book3s_64_vio_hv.c | 6 ++++--
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
> index a4ed9f5..8769f91 100644
> --- a/arch/powerpc/include/asm/kvm_host.h
> +++ b/arch/powerpc/include/asm/kvm_host.h
> @@ -185,6 +185,7 @@ struct kvmppc_spapr_tce_table {
>  	u64 liobn;
>  	struct rcu_head rcu;
>  	u32 page_shift;
> +	u64 offset;		/* in pages */
>  	u64 size;		/* in pages */
>  	struct page *pages[0];
>  };
> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index 01ef9f9..0e66459 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -75,7 +75,8 @@ long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
>  	unsigned long mask = ~((1ULL << stt->page_shift) - 1);
>  	unsigned long idx = ioba >> stt->page_shift;
>  
> -	if ((ioba & ~mask) || (idx + npages > stt->size))
> +	if ((ioba & ~mask) || (idx < stt->offset) ||
> +			(idx - stt->offset + npages > stt->size))
>  		return H_PARAMETER;
>  
>  	return H_SUCCESS;
> @@ -147,6 +148,7 @@ void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
>  	struct page *page;
>  	u64 *tbl;
>  
> +	idx -= stt->offset;
>  	page = stt->pages[idx / TCES_PER_PAGE];
>  	tbl = kvmppc_page_address(page);
>  
> @@ -324,7 +326,7 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  	if (ret != H_SUCCESS)
>  		return ret;
>  
> -	idx = ioba >> stt->page_shift;
> +	idx = (ioba >> stt->page_shift) - stt->offset;
>  	page = stt->pages[idx / TCES_PER_PAGE];
>  	tbl = (u64 *)page_address(page);
>  

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH kernel 4/4] KVM: PPC: Add support for 64bit TCE windows
  2016-01-21  8:15 ` [PATCH kernel 4/4] KVM: PPC: Add support for 64bit TCE windows Alexey Kardashevskiy
@ 2016-01-25  5:37   ` David Gibson
  2016-01-27  3:29     ` Alexey Kardashevskiy
  0 siblings, 1 reply; 12+ messages in thread
From: David Gibson @ 2016-01-25  5:37 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: linuxppc-dev, Paul Mackerras, kvm-ppc, kvm

[-- Attachment #1: Type: text/plain, Size: 7867 bytes --]

On Thu, Jan 21, 2016 at 07:15:26PM +1100, Alexey Kardashevskiy wrote:
> The existing KVM_CREATE_SPAPR_TCE only supports 32bit windows which is not
> enough for directly mapped windows as the guest can get more than 4GB.
> 
> This adds KVM_CREATE_SPAPR_TCE_64 ioctl and advertises it
> via KVM_CAP_SPAPR_TCE_64 capability.
> 
> Since 64bit windows are to support Dynamic DMA windows (DDW), let's add
> @bus_offset and @page_shift which are also required by DDW.
> 
> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> ---
>  Documentation/virtual/kvm/api.txt   | 32 ++++++++++++++++++++++++++++++++
>  arch/powerpc/include/asm/kvm_ppc.h  |  2 +-
>  arch/powerpc/include/uapi/asm/kvm.h |  9 +++++++++
>  arch/powerpc/kvm/book3s_64_vio.c    | 10 +++++++---
>  arch/powerpc/kvm/powerpc.c          | 25 ++++++++++++++++++++++++-
>  include/uapi/linux/kvm.h            |  2 ++
>  6 files changed, 75 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index da39435..d1c5655 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -3060,6 +3060,38 @@ an implementation for these despite the in kernel acceleration.
>  
>  This capability is always enabled.
>  
> +4.96 KVM_CREATE_SPAPR_TCE_64
> +
> +Capability: KVM_CAP_SPAPR_TCE_64
> +Architectures: powerpc
> +Type: vm ioctl
> +Parameters: struct kvm_create_spapr_tce_64 (in)
> +Returns: file descriptor for manipulating the created TCE table
> +
> +This is an extension for KVM_CAP_SPAPR_TCE which only supports 32bit
> +windows, described in 4.62 KVM_CREATE_SPAPR_TCE
> +
> +This capability uses extended struct in ioctl interface:
> +
> +/* for KVM_CAP_SPAPR_TCE_64 */
> +struct kvm_create_spapr_tce_64 {
> +	__u64 liobn;
> +	__u32 page_shift;
> +	__u64 offset;	/* in pages */
> +	__u64 size; 	/* in pages */
> +	__u32 flags;

Best to move page_shift after offset and size, so the structure
doesn't get an alignment gap.

> +};
> +
> +The aim of extension is to support an additional bigger DMA window with
> +a variable page size.
> +KVM_CREATE_SPAPR_TCE_64 receives a 64bit window size, an IOMMU page shift and
> +a bus offset of the corresponding DMA window, @size and @offset are numbers
> +of IOMMU pages.
> +
> +@flags are not used at the moment.
> +
> +The rest of functionality is identical to KVM_CREATE_SPAPR_TCE.
> +
>  5. The kvm_run structure
>  ------------------------
>  
> diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
> index 4cadee5..6e4d1dc 100644
> --- a/arch/powerpc/include/asm/kvm_ppc.h
> +++ b/arch/powerpc/include/asm/kvm_ppc.h
> @@ -165,7 +165,7 @@ extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
>  extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu);
>  
>  extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
> -				struct kvm_create_spapr_tce *args);
> +				struct kvm_create_spapr_tce_64 *args);
>  extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
>  		struct kvm_vcpu *vcpu, unsigned long liobn);
>  extern long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
> index ab4d473..9c8b4cbc 100644
> --- a/arch/powerpc/include/uapi/asm/kvm.h
> +++ b/arch/powerpc/include/uapi/asm/kvm.h
> @@ -333,6 +333,15 @@ struct kvm_create_spapr_tce {
>  	__u32 window_size;
>  };
>  
> +/* for KVM_CAP_SPAPR_TCE_64 */
> +struct kvm_create_spapr_tce_64 {
> +	__u64 liobn;
> +	__u32 page_shift;
> +	__u64 offset;	/* in pages */
> +	__u64 size;	/* in pages */
> +	__u32 flags;
> +};
> +
>  /* for KVM_ALLOCATE_RMA */
>  struct kvm_allocate_rma {
>  	__u64 rma_size;
> diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
> index 85ee572..5479446 100644
> --- a/arch/powerpc/kvm/book3s_64_vio.c
> +++ b/arch/powerpc/kvm/book3s_64_vio.c
> @@ -144,20 +144,23 @@ static const struct file_operations kvm_spapr_tce_fops = {
>  };
>  
>  long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
> -				   struct kvm_create_spapr_tce *args)
> +				   struct kvm_create_spapr_tce_64 *args)
>  {
>  	struct kvmppc_spapr_tce_table *stt = NULL;
>  	unsigned long npages, size;
>  	int ret = -ENOMEM;
>  	int i;
>  
> +	if (!args->size)
> +		return -EINVAL;
> +
>  	/* Check this LIOBN hasn't been previously allocated */
>  	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
>  		if (stt->liobn == args->liobn)
>  			return -EBUSY;
>  	}
>  
> -	size = args->window_size >> IOMMU_PAGE_SHIFT_4K;
> +	size = args->size;

Doesn't this need some kind of bounds on the allowed size?

>  	npages = kvmppc_stt_npages(size);
>  	ret = kvmppc_account_memlimit(npages, true);
>  	if (ret) {
> @@ -171,7 +174,8 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  		goto fail;
>  
>  	stt->liobn = args->liobn;
> -	stt->page_shift = IOMMU_PAGE_SHIFT_4K;
> +	stt->page_shift = args->page_shift;
> +	stt->offset = args->offset;
>  	stt->size = size;
>  	stt->kvm = kvm;
>  
> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
> index 164735c..2b0fe92 100644
> --- a/arch/powerpc/kvm/powerpc.c
> +++ b/arch/powerpc/kvm/powerpc.c
> @@ -33,6 +33,7 @@
>  #include <asm/tlbflush.h>
>  #include <asm/cputhreads.h>
>  #include <asm/irqflags.h>
> +#include <asm/iommu.h>
>  #include "timing.h"
>  #include "irq.h"
>  #include "../mm/mmu_decl.h"
> @@ -509,6 +510,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>  
>  #ifdef CONFIG_PPC_BOOK3S_64
>  	case KVM_CAP_SPAPR_TCE:
> +	case KVM_CAP_SPAPR_TCE_64:
>  	case KVM_CAP_PPC_ALLOC_HTAB:
>  	case KVM_CAP_PPC_RTAS:
>  	case KVM_CAP_PPC_FIXUP_HCALL:
> @@ -1334,13 +1336,34 @@ long kvm_arch_vm_ioctl(struct file *filp,
>  		break;
>  	}
>  #ifdef CONFIG_PPC_BOOK3S_64
> +	case KVM_CREATE_SPAPR_TCE_64: {
> +		struct kvm_create_spapr_tce_64 create_tce_64;
> +
> +		r = -EFAULT;
> +		if (copy_from_user(&create_tce_64, argp, sizeof(create_tce_64)))
> +			goto out;
> +		if (create_tce_64.flags) {
> +			r = -EINVAL;
> +			goto out;
> +		}
> +		r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce_64);
> +		goto out;
> +	}
>  	case KVM_CREATE_SPAPR_TCE: {
>  		struct kvm_create_spapr_tce create_tce;
> +		struct kvm_create_spapr_tce_64 create_tce_64;
>  
>  		r = -EFAULT;
>  		if (copy_from_user(&create_tce, argp, sizeof(create_tce)))
>  			goto out;
> -		r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce);
> +
> +		create_tce_64.liobn = create_tce.liobn;
> +		create_tce_64.page_shift = IOMMU_PAGE_SHIFT_4K;
> +		create_tce_64.offset = 0;
> +		create_tce_64.size = create_tce.window_size >>
> +				IOMMU_PAGE_SHIFT_4K;
> +		create_tce_64.flags = 0;
> +		r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce_64);
>  		goto out;
>  	}
>  	case KVM_PPC_GET_SMMU_INFO: {
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 8ce5f64..b06208b 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -1143,6 +1143,8 @@ struct kvm_s390_ucas_mapping {
>  /* Available with KVM_CAP_PPC_ALLOC_HTAB */
>  #define KVM_PPC_ALLOCATE_HTAB	  _IOWR(KVMIO, 0xa7, __u32)
>  #define KVM_CREATE_SPAPR_TCE	  _IOW(KVMIO,  0xa8, struct kvm_create_spapr_tce)
> +#define KVM_CREATE_SPAPR_TCE_64	  _IOW(KVMIO,  0xa8, \
> +				       struct kvm_create_spapr_tce_64)
>  /* Available with KVM_CAP_RMA */
>  #define KVM_ALLOCATE_RMA	  _IOR(KVMIO,  0xa9, struct kvm_allocate_rma)
>  /* Available with KVM_CAP_PPC_HTAB_FD */

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH kernel 4/4] KVM: PPC: Add support for 64bit TCE windows
  2016-01-25  5:37   ` David Gibson
@ 2016-01-27  3:29     ` Alexey Kardashevskiy
  2016-01-27 23:53       ` David Gibson
  0 siblings, 1 reply; 12+ messages in thread
From: Alexey Kardashevskiy @ 2016-01-27  3:29 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev, Paul Mackerras, kvm-ppc, kvm

On 01/25/2016 04:37 PM, David Gibson wrote:
> On Thu, Jan 21, 2016 at 07:15:26PM +1100, Alexey Kardashevskiy wrote:
>> The existing KVM_CREATE_SPAPR_TCE only supports 32bit windows which is not
>> enough for directly mapped windows as the guest can get more than 4GB.
>>
>> This adds KVM_CREATE_SPAPR_TCE_64 ioctl and advertises it
>> via KVM_CAP_SPAPR_TCE_64 capability.
>>
>> Since 64bit windows are to support Dynamic DMA windows (DDW), let's add
>> @bus_offset and @page_shift which are also required by DDW.
>>
>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>> ---
>>   Documentation/virtual/kvm/api.txt   | 32 ++++++++++++++++++++++++++++++++
>>   arch/powerpc/include/asm/kvm_ppc.h  |  2 +-
>>   arch/powerpc/include/uapi/asm/kvm.h |  9 +++++++++
>>   arch/powerpc/kvm/book3s_64_vio.c    | 10 +++++++---
>>   arch/powerpc/kvm/powerpc.c          | 25 ++++++++++++++++++++++++-
>>   include/uapi/linux/kvm.h            |  2 ++
>>   6 files changed, 75 insertions(+), 5 deletions(-)
>>
>> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
>> index da39435..d1c5655 100644
>> --- a/Documentation/virtual/kvm/api.txt
>> +++ b/Documentation/virtual/kvm/api.txt
>> @@ -3060,6 +3060,38 @@ an implementation for these despite the in kernel acceleration.
>>
>>   This capability is always enabled.
>>
>> +4.96 KVM_CREATE_SPAPR_TCE_64
>> +
>> +Capability: KVM_CAP_SPAPR_TCE_64
>> +Architectures: powerpc
>> +Type: vm ioctl
>> +Parameters: struct kvm_create_spapr_tce_64 (in)
>> +Returns: file descriptor for manipulating the created TCE table
>> +
>> +This is an extension for KVM_CAP_SPAPR_TCE which only supports 32bit
>> +windows, described in 4.62 KVM_CREATE_SPAPR_TCE
>> +
>> +This capability uses extended struct in ioctl interface:
>> +
>> +/* for KVM_CAP_SPAPR_TCE_64 */
>> +struct kvm_create_spapr_tce_64 {
>> +	__u64 liobn;
>> +	__u32 page_shift;
>> +	__u64 offset;	/* in pages */
>> +	__u64 size; 	/* in pages */
>> +	__u32 flags;
>
> Best to move page_shift after offset and size, so the structure
> doesn't get an alignment gap.

Agrh. I did this again :-/


>> +};
>> +
>> +The aim of extension is to support an additional bigger DMA window with
>> +a variable page size.
>> +KVM_CREATE_SPAPR_TCE_64 receives a 64bit window size, an IOMMU page shift and
>> +a bus offset of the corresponding DMA window, @size and @offset are numbers
>> +of IOMMU pages.
>> +
>> +@flags are not used at the moment.
>> +
>> +The rest of functionality is identical to KVM_CREATE_SPAPR_TCE.
>> +
>>   5. The kvm_run structure
>>   ------------------------
>>
>> diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
>> index 4cadee5..6e4d1dc 100644
>> --- a/arch/powerpc/include/asm/kvm_ppc.h
>> +++ b/arch/powerpc/include/asm/kvm_ppc.h
>> @@ -165,7 +165,7 @@ extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
>>   extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu);
>>
>>   extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>> -				struct kvm_create_spapr_tce *args);
>> +				struct kvm_create_spapr_tce_64 *args);
>>   extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
>>   		struct kvm_vcpu *vcpu, unsigned long liobn);
>>   extern long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
>> diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
>> index ab4d473..9c8b4cbc 100644
>> --- a/arch/powerpc/include/uapi/asm/kvm.h
>> +++ b/arch/powerpc/include/uapi/asm/kvm.h
>> @@ -333,6 +333,15 @@ struct kvm_create_spapr_tce {
>>   	__u32 window_size;
>>   };
>>
>> +/* for KVM_CAP_SPAPR_TCE_64 */
>> +struct kvm_create_spapr_tce_64 {
>> +	__u64 liobn;
>> +	__u32 page_shift;
>> +	__u64 offset;	/* in pages */
>> +	__u64 size;	/* in pages */
>> +	__u32 flags;
>> +};
>> +
>>   /* for KVM_ALLOCATE_RMA */
>>   struct kvm_allocate_rma {
>>   	__u64 rma_size;
>> diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
>> index 85ee572..5479446 100644
>> --- a/arch/powerpc/kvm/book3s_64_vio.c
>> +++ b/arch/powerpc/kvm/book3s_64_vio.c
>> @@ -144,20 +144,23 @@ static const struct file_operations kvm_spapr_tce_fops = {
>>   };
>>
>>   long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>> -				   struct kvm_create_spapr_tce *args)
>> +				   struct kvm_create_spapr_tce_64 *args)
>>   {
>>   	struct kvmppc_spapr_tce_table *stt = NULL;
>>   	unsigned long npages, size;
>>   	int ret = -ENOMEM;
>>   	int i;
>>
>> +	if (!args->size)
>> +		return -EINVAL;
>> +
>>   	/* Check this LIOBN hasn't been previously allocated */
>>   	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
>>   		if (stt->liobn == args->liobn)
>>   			return -EBUSY;
>>   	}
>>
>> -	size = args->window_size >> IOMMU_PAGE_SHIFT_4K;
>> +	size = args->size;
>
> Doesn't this need some kind of bounds on the allowed size?


kvmppc_account_memlimit() below is some kind of bound, not enough?


>
>>   	npages = kvmppc_stt_npages(size);
>>   	ret = kvmppc_account_memlimit(npages, true);
>>   	if (ret) {
>> @@ -171,7 +174,8 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>>   		goto fail;
>>
>>   	stt->liobn = args->liobn;
>> -	stt->page_shift = IOMMU_PAGE_SHIFT_4K;
>> +	stt->page_shift = args->page_shift;
>> +	stt->offset = args->offset;
>>   	stt->size = size;
>>   	stt->kvm = kvm;
>>
>> diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
>> index 164735c..2b0fe92 100644
>> --- a/arch/powerpc/kvm/powerpc.c
>> +++ b/arch/powerpc/kvm/powerpc.c
>> @@ -33,6 +33,7 @@
>>   #include <asm/tlbflush.h>
>>   #include <asm/cputhreads.h>
>>   #include <asm/irqflags.h>
>> +#include <asm/iommu.h>
>>   #include "timing.h"
>>   #include "irq.h"
>>   #include "../mm/mmu_decl.h"
>> @@ -509,6 +510,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>>
>>   #ifdef CONFIG_PPC_BOOK3S_64
>>   	case KVM_CAP_SPAPR_TCE:
>> +	case KVM_CAP_SPAPR_TCE_64:
>>   	case KVM_CAP_PPC_ALLOC_HTAB:
>>   	case KVM_CAP_PPC_RTAS:
>>   	case KVM_CAP_PPC_FIXUP_HCALL:
>> @@ -1334,13 +1336,34 @@ long kvm_arch_vm_ioctl(struct file *filp,
>>   		break;
>>   	}
>>   #ifdef CONFIG_PPC_BOOK3S_64
>> +	case KVM_CREATE_SPAPR_TCE_64: {
>> +		struct kvm_create_spapr_tce_64 create_tce_64;
>> +
>> +		r = -EFAULT;
>> +		if (copy_from_user(&create_tce_64, argp, sizeof(create_tce_64)))
>> +			goto out;
>> +		if (create_tce_64.flags) {
>> +			r = -EINVAL;
>> +			goto out;
>> +		}
>> +		r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce_64);
>> +		goto out;
>> +	}
>>   	case KVM_CREATE_SPAPR_TCE: {
>>   		struct kvm_create_spapr_tce create_tce;
>> +		struct kvm_create_spapr_tce_64 create_tce_64;
>>
>>   		r = -EFAULT;
>>   		if (copy_from_user(&create_tce, argp, sizeof(create_tce)))
>>   			goto out;
>> -		r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce);
>> +
>> +		create_tce_64.liobn = create_tce.liobn;
>> +		create_tce_64.page_shift = IOMMU_PAGE_SHIFT_4K;
>> +		create_tce_64.offset = 0;
>> +		create_tce_64.size = create_tce.window_size >>
>> +				IOMMU_PAGE_SHIFT_4K;
>> +		create_tce_64.flags = 0;
>> +		r = kvm_vm_ioctl_create_spapr_tce(kvm, &create_tce_64);
>>   		goto out;
>>   	}
>>   	case KVM_PPC_GET_SMMU_INFO: {
>> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
>> index 8ce5f64..b06208b 100644
>> --- a/include/uapi/linux/kvm.h
>> +++ b/include/uapi/linux/kvm.h
>> @@ -1143,6 +1143,8 @@ struct kvm_s390_ucas_mapping {
>>   /* Available with KVM_CAP_PPC_ALLOC_HTAB */
>>   #define KVM_PPC_ALLOCATE_HTAB	  _IOWR(KVMIO, 0xa7, __u32)
>>   #define KVM_CREATE_SPAPR_TCE	  _IOW(KVMIO,  0xa8, struct kvm_create_spapr_tce)
>> +#define KVM_CREATE_SPAPR_TCE_64	  _IOW(KVMIO,  0xa8, \
>> +				       struct kvm_create_spapr_tce_64)
>>   /* Available with KVM_CAP_RMA */
>>   #define KVM_ALLOCATE_RMA	  _IOR(KVMIO,  0xa9, struct kvm_allocate_rma)
>>   /* Available with KVM_CAP_PPC_HTAB_FD */
>


-- 
Alexey

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH kernel 3/4] KVM: PPC: Add @offset to kvmppc_spapr_tce_table
  2016-01-25  5:33   ` David Gibson
@ 2016-01-27  3:31     ` Alexey Kardashevskiy
  0 siblings, 0 replies; 12+ messages in thread
From: Alexey Kardashevskiy @ 2016-01-27  3:31 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev, Paul Mackerras, kvm-ppc, kvm

On 01/25/2016 04:33 PM, David Gibson wrote:
> On Thu, Jan 21, 2016 at 07:15:25PM +1100, Alexey Kardashevskiy wrote:
>> This enables userspace view of TCE tables to start from non-zero offset
>> on a bus. This will be used for huge DMA windows.
>
> Again I'd like the commit message adjusted to clarify the fact that
> this has internal changes only which will need interface changes to
> actually use.

May be this or I could just merge all four into one patch as it may make it 
easier to review but does not make much sense from bisectability prospective?


>
>> Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
>
>> ---
>>   arch/powerpc/include/asm/kvm_host.h | 1 +
>>   arch/powerpc/kvm/book3s_64_vio_hv.c | 6 ++++--
>>   2 files changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
>> index a4ed9f5..8769f91 100644
>> --- a/arch/powerpc/include/asm/kvm_host.h
>> +++ b/arch/powerpc/include/asm/kvm_host.h
>> @@ -185,6 +185,7 @@ struct kvmppc_spapr_tce_table {
>>   	u64 liobn;
>>   	struct rcu_head rcu;
>>   	u32 page_shift;
>> +	u64 offset;		/* in pages */
>>   	u64 size;		/* in pages */
>>   	struct page *pages[0];
>>   };
>> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
>> index 01ef9f9..0e66459 100644
>> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
>> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
>> @@ -75,7 +75,8 @@ long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
>>   	unsigned long mask = ~((1ULL << stt->page_shift) - 1);
>>   	unsigned long idx = ioba >> stt->page_shift;
>>
>> -	if ((ioba & ~mask) || (idx + npages > stt->size))
>> +	if ((ioba & ~mask) || (idx < stt->offset) ||
>> +			(idx - stt->offset + npages > stt->size))
>>   		return H_PARAMETER;
>>
>>   	return H_SUCCESS;
>> @@ -147,6 +148,7 @@ void kvmppc_tce_put(struct kvmppc_spapr_tce_table *stt,
>>   	struct page *page;
>>   	u64 *tbl;
>>
>> +	idx -= stt->offset;
>>   	page = stt->pages[idx / TCES_PER_PAGE];
>>   	tbl = kvmppc_page_address(page);
>>
>> @@ -324,7 +326,7 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>>   	if (ret != H_SUCCESS)
>>   		return ret;
>>
>> -	idx = ioba >> stt->page_shift;
>> +	idx = (ioba >> stt->page_shift) - stt->offset;
>>   	page = stt->pages[idx / TCES_PER_PAGE];
>>   	tbl = (u64 *)page_address(page);
>>
>


-- 
Alexey

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH kernel 4/4] KVM: PPC: Add support for 64bit TCE windows
  2016-01-27  3:29     ` Alexey Kardashevskiy
@ 2016-01-27 23:53       ` David Gibson
  0 siblings, 0 replies; 12+ messages in thread
From: David Gibson @ 2016-01-27 23:53 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: linuxppc-dev, Paul Mackerras, kvm-ppc, kvm

[-- Attachment #1: Type: text/plain, Size: 5540 bytes --]

On Wed, Jan 27, 2016 at 02:29:25PM +1100, Alexey Kardashevskiy wrote:
> On 01/25/2016 04:37 PM, David Gibson wrote:
> >On Thu, Jan 21, 2016 at 07:15:26PM +1100, Alexey Kardashevskiy wrote:
> >>The existing KVM_CREATE_SPAPR_TCE only supports 32bit windows which is not
> >>enough for directly mapped windows as the guest can get more than 4GB.
> >>
> >>This adds KVM_CREATE_SPAPR_TCE_64 ioctl and advertises it
> >>via KVM_CAP_SPAPR_TCE_64 capability.
> >>
> >>Since 64bit windows are to support Dynamic DMA windows (DDW), let's add
> >>@bus_offset and @page_shift which are also required by DDW.
> >>
> >>Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
> >>---
> >>  Documentation/virtual/kvm/api.txt   | 32 ++++++++++++++++++++++++++++++++
> >>  arch/powerpc/include/asm/kvm_ppc.h  |  2 +-
> >>  arch/powerpc/include/uapi/asm/kvm.h |  9 +++++++++
> >>  arch/powerpc/kvm/book3s_64_vio.c    | 10 +++++++---
> >>  arch/powerpc/kvm/powerpc.c          | 25 ++++++++++++++++++++++++-
> >>  include/uapi/linux/kvm.h            |  2 ++
> >>  6 files changed, 75 insertions(+), 5 deletions(-)
> >>
> >>diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> >>index da39435..d1c5655 100644
> >>--- a/Documentation/virtual/kvm/api.txt
> >>+++ b/Documentation/virtual/kvm/api.txt
> >>@@ -3060,6 +3060,38 @@ an implementation for these despite the in kernel acceleration.
> >>
> >>  This capability is always enabled.
> >>
> >>+4.96 KVM_CREATE_SPAPR_TCE_64
> >>+
> >>+Capability: KVM_CAP_SPAPR_TCE_64
> >>+Architectures: powerpc
> >>+Type: vm ioctl
> >>+Parameters: struct kvm_create_spapr_tce_64 (in)
> >>+Returns: file descriptor for manipulating the created TCE table
> >>+
> >>+This is an extension for KVM_CAP_SPAPR_TCE which only supports 32bit
> >>+windows, described in 4.62 KVM_CREATE_SPAPR_TCE
> >>+
> >>+This capability uses extended struct in ioctl interface:
> >>+
> >>+/* for KVM_CAP_SPAPR_TCE_64 */
> >>+struct kvm_create_spapr_tce_64 {
> >>+	__u64 liobn;
> >>+	__u32 page_shift;
> >>+	__u64 offset;	/* in pages */
> >>+	__u64 size; 	/* in pages */
> >>+	__u32 flags;
> >
> >Best to move page_shift after offset and size, so the structure
> >doesn't get an alignment gap.
> 
> Agrh. I did this again :-/
> 
> 
> >>+};
> >>+
> >>+The aim of extension is to support an additional bigger DMA window with
> >>+a variable page size.
> >>+KVM_CREATE_SPAPR_TCE_64 receives a 64bit window size, an IOMMU page shift and
> >>+a bus offset of the corresponding DMA window, @size and @offset are numbers
> >>+of IOMMU pages.
> >>+
> >>+@flags are not used at the moment.
> >>+
> >>+The rest of functionality is identical to KVM_CREATE_SPAPR_TCE.
> >>+
> >>  5. The kvm_run structure
> >>  ------------------------
> >>
> >>diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
> >>index 4cadee5..6e4d1dc 100644
> >>--- a/arch/powerpc/include/asm/kvm_ppc.h
> >>+++ b/arch/powerpc/include/asm/kvm_ppc.h
> >>@@ -165,7 +165,7 @@ extern void kvmppc_map_vrma(struct kvm_vcpu *vcpu,
> >>  extern int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu);
> >>
> >>  extern long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
> >>-				struct kvm_create_spapr_tce *args);
> >>+				struct kvm_create_spapr_tce_64 *args);
> >>  extern struct kvmppc_spapr_tce_table *kvmppc_find_table(
> >>  		struct kvm_vcpu *vcpu, unsigned long liobn);
> >>  extern long kvmppc_ioba_validate(struct kvmppc_spapr_tce_table *stt,
> >>diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
> >>index ab4d473..9c8b4cbc 100644
> >>--- a/arch/powerpc/include/uapi/asm/kvm.h
> >>+++ b/arch/powerpc/include/uapi/asm/kvm.h
> >>@@ -333,6 +333,15 @@ struct kvm_create_spapr_tce {
> >>  	__u32 window_size;
> >>  };
> >>
> >>+/* for KVM_CAP_SPAPR_TCE_64 */
> >>+struct kvm_create_spapr_tce_64 {
> >>+	__u64 liobn;
> >>+	__u32 page_shift;
> >>+	__u64 offset;	/* in pages */
> >>+	__u64 size;	/* in pages */
> >>+	__u32 flags;
> >>+};
> >>+
> >>  /* for KVM_ALLOCATE_RMA */
> >>  struct kvm_allocate_rma {
> >>  	__u64 rma_size;
> >>diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c
> >>index 85ee572..5479446 100644
> >>--- a/arch/powerpc/kvm/book3s_64_vio.c
> >>+++ b/arch/powerpc/kvm/book3s_64_vio.c
> >>@@ -144,20 +144,23 @@ static const struct file_operations kvm_spapr_tce_fops = {
> >>  };
> >>
> >>  long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
> >>-				   struct kvm_create_spapr_tce *args)
> >>+				   struct kvm_create_spapr_tce_64 *args)
> >>  {
> >>  	struct kvmppc_spapr_tce_table *stt = NULL;
> >>  	unsigned long npages, size;
> >>  	int ret = -ENOMEM;
> >>  	int i;
> >>
> >>+	if (!args->size)
> >>+		return -EINVAL;
> >>+
> >>  	/* Check this LIOBN hasn't been previously allocated */
> >>  	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
> >>  		if (stt->liobn == args->liobn)
> >>  			return -EBUSY;
> >>  	}
> >>
> >>-	size = args->window_size >> IOMMU_PAGE_SHIFT_4K;
> >>+	size = args->size;
> >
> >Doesn't this need some kind of bounds on the allowed size?
> 
> 
> kvmppc_account_memlimit() below is some kind of bound, not enough?

Ah, yes, that should be enough.

Sorry, missed that.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2016-01-27 23:54 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-21  8:15 [PATCH kernel 0/4] KVM: PPC: Add in-kernel acceleration for 64bit DMA Alexey Kardashevskiy
2016-01-21  8:15 ` [PATCH kernel 1/4] KVM: PPC: Reserve KVM_CAP_SPAPR_TCE_64 capability number Alexey Kardashevskiy
2016-01-25  5:23   ` David Gibson
2016-01-21  8:15 ` [PATCH kernel 2/4] KVM: PPC: Add @page_shift to kvmppc_spapr_tce_table Alexey Kardashevskiy
2016-01-25  5:30   ` David Gibson
2016-01-21  8:15 ` [PATCH kernel 3/4] KVM: PPC: Add @offset " Alexey Kardashevskiy
2016-01-25  5:33   ` David Gibson
2016-01-27  3:31     ` Alexey Kardashevskiy
2016-01-21  8:15 ` [PATCH kernel 4/4] KVM: PPC: Add support for 64bit TCE windows Alexey Kardashevskiy
2016-01-25  5:37   ` David Gibson
2016-01-27  3:29     ` Alexey Kardashevskiy
2016-01-27 23:53       ` David Gibson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).