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
