diff mbox

[PATCH/RFC] kvm/powerpc: Add new ioctl to retreive support page sizes and encodings

Message ID 1331884552.3105.163.camel@pasglop
State New, archived
Headers show

Commit Message

Benjamin Herrenschmidt March 16, 2012, 7:55 a.m. UTC
This is necessary for qemu to be able to pass the right information
to the guest, as the supported sizes and encodings can vary depending
on the machine, the type of KVM used (PR vs HV) and the version of KVM

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

Please comment ASAP. I'm tired of the qemu side never working properly
because of that and our out-of-tree nasty patches we've been carrying
internally, so I'd like to get something like that in real quick :-)

I have the qemu side patches that use this to generate the appropriate
device-tree when available, and use heuristics for the fallback. I'll
post them later, let's agree on the kernel interfaces first.

The heuristics work as long as we have a reasonable guarantee that this
kernel patch will get in -before- any patch that enables the PVINFO
ioctl on "HV" KVM, that way I can rely on the later not working as
a way to differenciate PR and HV KVM if this new ioctl is not supported. 

Note: We probably want an other ioctl for getting other type of
MMU info, such as whether we support 1T segments etc... but I didn't
want to try to kill to many birds at once and end up in bike shed
painting on the mailing list for the next 6 month...

Cheers,
Ben.

 arch/powerpc/include/asm/kvm_ppc.h |    3 ++-
 arch/powerpc/kvm/book3s_hv.c       |   35 +++++++++++++++++++++++++++++++++++
 arch/powerpc/kvm/book3s_pr.c       |   22 ++++++++++++++++++++++
 arch/powerpc/kvm/powerpc.c         |   18 +++++++++++++++++-
 include/linux/kvm.h                |   29 +++++++++++++++++++++++++++++
 5 files changed, 105 insertions(+), 2 deletions(-)

Comments

Avi Kivity March 18, 2012, 10:23 a.m. UTC | #1
On 03/16/2012 09:55 AM, Benjamin Herrenschmidt wrote:
> This is necessary for qemu to be able to pass the right information
> to the guest, as the supported sizes and encodings can vary depending
> on the machine, the type of KVM used (PR vs HV) and the version of KVM
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> Please comment ASAP. I'm tired of the qemu side never working properly
> because of that and our out-of-tree nasty patches we've been carrying
> internally, so I'd like to get something like that in real quick :-)
>
> I have the qemu side patches that use this to generate the appropriate
> device-tree when available, and use heuristics for the fallback. I'll
> post them later, let's agree on the kernel interfaces first.
>
> The heuristics work as long as we have a reasonable guarantee that this
> kernel patch will get in -before- any patch that enables the PVINFO
> ioctl on "HV" KVM, that way I can rely on the later not working as
> a way to differenciate PR and HV KVM if this new ioctl is not supported. 
>
> Note: We probably want an other ioctl for getting other type of
> MMU info, such as whether we support 1T segments etc... but I didn't
> want to try to kill to many birds at once and end up in bike shed
> painting on the mailing list for the next 6 month...
>
> Cheers,
> Ben.
>
>  arch/powerpc/include/asm/kvm_ppc.h |    3 ++-
>  arch/powerpc/kvm/book3s_hv.c       |   35 +++++++++++++++++++++++++++++++++++
>  arch/powerpc/kvm/book3s_pr.c       |   22 ++++++++++++++++++++++
>  arch/powerpc/kvm/powerpc.c         |   18 +++++++++++++++++-
>  include/linux/kvm.h                |   29 +++++++++++++++++++++++++++++
>  5 files changed, 105 insertions(+), 2 deletions(-)
>

-ENODOCS
Benjamin Herrenschmidt March 18, 2012, 8:47 p.m. UTC | #2
On Sun, 2012-03-18 at 12:23 +0200, Avi Kivity wrote:
> -ENODOCS

What kind of docs do you expect ? Where ? I don't see any of the other
private ioctls we use on ppc documented either...

Ben.


--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Benjamin Herrenschmidt March 18, 2012, 9:05 p.m. UTC | #3
On Mon, 2012-03-19 at 07:47 +1100, Benjamin Herrenschmidt wrote:
> On Sun, 2012-03-18 at 12:23 +0200, Avi Kivity wrote:
> > -ENODOCS
> 
> What kind of docs do you expect ? Where ? I don't see any of the other
> private ioctls we use on ppc documented either...

Note also that after more thoughts I decided to make it a more complete
ioctl to retrieve MMU information for Book "S" ppc processors (ie, add
at least the SLB size and expose support for 1T segments), so ditch that
one patch for now, but let me know where you expect the documentation
(next to the arg struct definition ? in a Documentation/* file ?) since
I don't see any for our existing stuff.

Cheers,
Ben.


--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alexander Graf March 18, 2012, 9:16 p.m. UTC | #4
On 18.03.2012, at 21:47, Benjamin Herrenschmidt wrote:

> On Sun, 2012-03-18 at 12:23 +0200, Avi Kivity wrote:
>> -ENODOCS
> 
> What kind of docs do you expect ? Where ? I don't see any of the other
> private ioctls we use on ppc documented either...

They should be - all documentation is in Documentation/virt/kvm/api.txt.


Alex

--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Benjamin Herrenschmidt March 18, 2012, 9:22 p.m. UTC | #5
On Sun, 2012-03-18 at 22:16 +0100, Alexander Graf wrote:
> > What kind of docs do you expect ? Where ? I don't see any of the
> other
> > private ioctls we use on ppc documented either...
> 
> They should be - all documentation is in
> Documentation/virt/kvm/api.txt.

Ok, I missed that. I'll make sure this is updated in my next submission.

Thanks !

Cheers,
Ben.


--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Avi Kivity March 19, 2012, 9:18 a.m. UTC | #6
On 03/18/2012 10:47 PM, Benjamin Herrenschmidt wrote:
> On Sun, 2012-03-18 at 12:23 +0200, Avi Kivity wrote:
> > -ENODOCS
>
> What kind of docs do you expect ? Where ? 

Documentation/virtual/kvm/api.txt.

> I don't see any of the other
> private ioctls we use on ppc documented either...
>

Please send patches.
diff mbox

Patch

diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index c1069f6..bf530fd 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -140,7 +140,8 @@  extern int kvmppc_core_prepare_memory_region(struct kvm *kvm,
 				struct kvm_userspace_memory_region *mem);
 extern void kvmppc_core_commit_memory_region(struct kvm *kvm,
 				struct kvm_userspace_memory_region *mem);
-
+extern int kvm_vm_ioctl_get_page_sizes(struct kvm *kvm,
+				       struct kvm_ppc_page_sizes *ps);
 extern int kvmppc_bookehv_init(void);
 extern void kvmppc_bookehv_exit(void);
 
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 8ee46b9..c7f7f20 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1174,6 +1174,37 @@  long kvm_vm_ioctl_allocate_rma(struct kvm *kvm, struct kvm_allocate_rma *ret)
 	return fd;
 }
 
+static void kvmppc_add_seg_page_size(struct kvm_ppc_one_seg_page_size **sps,
+				     int linux_psize)
+{
+	struct mmu_psize_def *def = &mmu_psize_defs[linux_psize];
+
+	if (!def->shift)
+		return;
+	*sps->page_shift = def->shift;
+	*sps->slb_enc = def->sllp;
+	*sps->enc[0].page_shift = def->shift;
+	*sps->enc[0].pte_enc = def->penc;
+	*sps++;
+}
+
+int kvm_vm_ioctl_get_page_sizes(struct kvm *kvm, struct kvm_ppc_page_sizes *ps)
+{
+	struct kvm_ppc_one_seg_page_size *sps;
+	int i;
+
+	/* Page sizes limited by backing store */
+	ps->flags = KVM_PPC_PAGE_SIZES_REAL;
+
+	/* We only support these sizes for now, and no muti-size segments */
+	sps = &ps->sps[0];
+	kvmppc_add_seg_page_size(&sps, MMU_PAGE_4K);
+	kvmppc_add_seg_page_size(&sps, MMU_PAGE_64K);
+	kvmppc_add_seg_page_size(&sps, MMU_PAGE_16M);
+
+	return 0;
+}
+
 /*
  * Get (and clear) the dirty memory log for a memory slot.
  */
@@ -1211,6 +1242,10 @@  out:
 	return r;
 }
 
+int kvm_vm_ioctl_get_page_sizes(struct kvm *kvm, struct kvm_ppc_page_sizes *ps)
+{
+}
+
 static unsigned long slb_pgsize_encoding(unsigned long psize)
 {
 	unsigned long senc = 0;
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 5f0ee48..3c823ed 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -1154,6 +1154,28 @@  out:
 	return r;
 }
 
+#ifdef CONFIG_PPC64
+int kvm_vm_ioctl_get_page_sizes(struct kvm *kvm, struct kvm_ppc_page_sizes *ps)
+{
+	/* No flags */
+	ps->flags = 0;
+
+	/* Standard 4k base page size segment */
+	ps->sps[0].page_shift = 12;
+	ps->sps[0].slb_enc = 0;
+	ps->sps[0].enc[0].page_shift = 12;
+	ps->sps[0].enc[0].pte_enc = 0;
+
+	/* Standard 16M large page size segment */
+	ps->sps[1].page_shift = 24;
+	ps->sps[1].slb_enc = SLB_VSID_L;
+	ps->sps[1].enc[0].page_shift = 24;
+	ps->sps[1].enc[0].pte_enc = 0;
+
+	return 0;
+}
+#endif /* CONFIG_PPC64 */
+
 int kvmppc_core_prepare_memory_region(struct kvm *kvm,
 				      struct kvm_userspace_memory_region *mem)
 {
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 6ac3115..6f0c066 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -279,6 +279,11 @@  int kvm_dev_ioctl_check_extension(long ext)
 	case KVM_CAP_MAX_VCPUS:
 		r = KVM_MAX_VCPUS;
 		break;
+#ifdef CONFIG_PPC_BOOK3S_64
+	case KVM_CAP_PPC_GET_PAGE_SIZES:
+		r = 1;
+		break;
+#endif
 	default:
 		r = 0;
 		break;
@@ -718,7 +723,6 @@  long kvm_arch_vcpu_ioctl(struct file *filp,
 		break;
 	}
 #endif
-
 	default:
 		r = -EINVAL;
 	}
@@ -800,6 +804,18 @@  long kvm_arch_vm_ioctl(struct file *filp,
 	}
 #endif /* CONFIG_KVM_BOOK3S_64_HV */
 
+#ifdef CONFIG_PPC_BOOK3S_64
+	case KVM_PPC_GET_PAGE_SIZES: {
+		struct kvm *kvm = filp->private_data;
+		struct kvm_ppc_page_sizes sizes;
+
+		memset(&sizes, 0, sizeof(sizes));
+		r = kvm_vm_ioctl_get_page_sizes(kvm, &sizes);
+		if (r >= 0 && copy_to_user(argp, &sizes, sizeof(sizes)))
+			r = -EFAULT;
+		break;
+	}
+#endif /* CONFIG_PPC_BOOK3S_64 */
 	default:
 		r = -ENOTTY;
 	}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 7a9dd4b..a8b026c 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -449,6 +449,32 @@  struct kvm_ppc_pvinfo {
 	__u8  pad[108];
 };
 
+/* for KVM_PPC_GET_PAGE_SIZES */
+#define KVM_PPC_PAGE_SIZES_MAX_SZ	8
+
+struct kvm_ppc_one_page_size {
+	__u32 page_shift;	/* Page shift (or 0) */
+	__u32 pte_enc;		/* Encoding in the HPTE (>>12) */
+};
+
+struct kvm_ppc_one_seg_page_size {
+	__u32 page_shift;	/* Base page shift of segment (or 0) */
+	__u32 slb_enc;		/* SLB encoding for BookS */
+	struct kvm_ppc_one_page_size enc[KVM_PPC_PAGE_SIZES_MAX_SZ];
+};
+
+/* When that flag is set, guest page sizes must "fit"
+ * the backing store page sizes. When not set, any
+ * page size in the list can be used regardless of
+ * how they are backed
+ */
+#define KVM_PPC_PAGE_SIZES_REAL		0x00000001
+
+struct kvm_ppc_page_sizes {
+	__u32 flags;
+	struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ];
+};
+
 #define KVMIO 0xAE
 
 /* machine type bits, to be used as argument to KVM_CREATE_VM */
@@ -590,6 +616,7 @@  struct kvm_ppc_pvinfo {
 #define KVM_CAP_SYNC_REGS 74
 #define KVM_CAP_PCI_2_3 75
 #define KVM_CAP_KVMCLOCK_CTRL 76
+#define KVM_CAP_PPC_GET_PAGE_SIZES 77
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -789,6 +816,8 @@  struct kvm_s390_ucas_mapping {
 /* Available with KVM_CAP_PCI_2_3 */
 #define KVM_ASSIGN_SET_INTX_MASK  _IOW(KVMIO,  0xa4, \
 				       struct kvm_assigned_pci_dev)
+/* Available with KVM_CAP_PPC_GET_PAGE_SIZES */
+#define KVM_PPC_GET_PAGE_SIZES	  _IOR(KVMIO,  0xa5, struct kvm_ppc_page_sizes)
 
 /*
  * ioctls for vcpu fds