Patchwork [V4,1/7] kvm tools: PPC64, add HPT/SDR1 for -PR KVM

login
register
mail settings
Submitter Matt Evans
Date Jan. 31, 2012, 6:34 a.m.
Message ID <1327991682-18503-2-git-send-email-matt@ozlabs.org>
Download mbox | patch
Permalink /patch/138692/
State New
Headers show

Comments

Matt Evans - Jan. 31, 2012, 6:34 a.m.
Allocate a page table and point SDR1 to it in order to support the -PR
PPC64 KVM mode.  (The alternative, -HV mode, is available only on a small
set of machines.)

This patch also removes the previous dependency on mapping guest RAM with
huge pages; PR KVM doesn't require them so the user isn't forced to use them.

A new option, '--hugetlbfs default', uses a default path for 16M pages for
HV mode, if required.

Signed-off-by: Matt Evans <matt@ozlabs.org>
---
 tools/kvm/powerpc/include/kvm/kvm-arch.h |    2 ++
 tools/kvm/powerpc/kvm-cpu.c              |   24 +++++++++++++++++++++---
 tools/kvm/powerpc/kvm.c                  |   25 ++++++++++++++++++-------
 3 files changed, 41 insertions(+), 10 deletions(-)

Patch

diff --git a/tools/kvm/powerpc/include/kvm/kvm-arch.h b/tools/kvm/powerpc/include/kvm/kvm-arch.h
index c4b493c..8653871 100644
--- a/tools/kvm/powerpc/include/kvm/kvm-arch.h
+++ b/tools/kvm/powerpc/include/kvm/kvm-arch.h
@@ -52,6 +52,8 @@  struct kvm {
 	u64			ram_size;
 	void			*ram_start;
 
+	u64			sdr1;
+
 	bool			nmi_disabled;
 
 	bool			single_step;
diff --git a/tools/kvm/powerpc/kvm-cpu.c b/tools/kvm/powerpc/kvm-cpu.c
index ea99666..60379d0 100644
--- a/tools/kvm/powerpc/kvm-cpu.c
+++ b/tools/kvm/powerpc/kvm-cpu.c
@@ -76,7 +76,8 @@  struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id)
 	if (vcpu->kvm_run == MAP_FAILED)
 		die("unable to mmap vcpu fd");
 
-	ioctl(vcpu->vcpu_fd, KVM_ENABLE_CAP, &papr_cap);
+	if (ioctl(vcpu->vcpu_fd, KVM_ENABLE_CAP, &papr_cap) < 0)
+		die("unable to enable PAPR capability");
 
 	/*
 	 * We start all CPUs, directing non-primary threads into the kernel's
@@ -121,9 +122,26 @@  static void kvm_cpu__setup_regs(struct kvm_cpu *vcpu)
 static void kvm_cpu__setup_sregs(struct kvm_cpu *vcpu)
 {
 	/*
-	 * No sregs setup is required on PPC64/SPAPR (but there may be setup
-	 * required for non-paravirtualised platforms, e.g. TLB/SLB setup).
+	 * Some sregs setup to initialise SDR1/PVR/HIOR on PPC64 SPAPR
+	 * platforms using PR KVM.  (Technically, this is all ignored on
+	 * SPAPR HV KVM.)  Different setup is required for non-PV non-SPAPR
+	 * platforms!  (FIXME.)
 	 */
+	struct kvm_sregs sregs;
+	struct kvm_one_reg reg = {};
+
+	if (ioctl(vcpu->vcpu_fd, KVM_GET_SREGS, &sregs) < 0)
+		die("KVM_GET_SREGS failed");
+
+	sregs.u.s.sdr1 = vcpu->kvm->sdr1;
+
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_SREGS, &sregs) < 0)
+		die("KVM_SET_SREGS failed");
+
+	reg.id = KVM_ONE_REG_PPC_HIOR;
+	reg.u.reg64 = 0;
+	if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, &reg) < 0)
+		die("KVM_SET_ONE_REG failed");
 }
 
 /**
diff --git a/tools/kvm/powerpc/kvm.c b/tools/kvm/powerpc/kvm.c
index 58982ff..8bd1fe2 100644
--- a/tools/kvm/powerpc/kvm.c
+++ b/tools/kvm/powerpc/kvm.c
@@ -72,19 +72,24 @@  void kvm__arch_set_cmdline(char *cmdline, bool video)
 void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 {
 	int cap_ppc_rma;
+	unsigned long hpt;
 
 	kvm->ram_size		= ram_size;
 
 	/*
-	 * Currently, we must map from hugetlbfs; if --hugetlbfs not specified,
-	 * try a default path:
+	 * Currently, HV-mode PPC64 SPAPR requires that we map from hugetlfs.
+	 * Allow a 'default' option to assist.
+	 * PR-mode does not require this.
 	 */
-	if (!hugetlbfs_path) {
-		hugetlbfs_path = HUGETLBFS_PATH;
-		pr_info("Using default %s for memory", hugetlbfs_path);
+	if (hugetlbfs_path) {
+		if (!strcmp(hugetlbfs_path, "default"))
+			hugetlbfs_path = HUGETLBFS_PATH;
+		kvm->ram_start = mmap_hugetlbfs(hugetlbfs_path, kvm->ram_size);
+	} else {
+		kvm->ram_start = mmap(0, kvm->ram_size, PROT_READ | PROT_WRITE,
+				      MAP_ANON | MAP_PRIVATE,
+				      -1, 0);
 	}
-
-	kvm->ram_start = mmap_hugetlbfs(hugetlbfs_path, kvm->ram_size);
 	if (kvm->ram_start == MAP_FAILED)
 		die("Couldn't map %lld bytes for RAM (%d)\n",
 		    kvm->ram_size, errno);
@@ -95,6 +100,12 @@  void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
 	kvm->rtas_gra = kvm->fdt_gra - RTAS_MAX_SIZE;
 	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
 
+	/* FIXME:  SPAPR-PR specific; allocate a guest HPT. */
+	if (posix_memalign((void **)&hpt, (1<<HPT_ORDER), (1<<HPT_ORDER)))
+		die("Can't allocate %d bytes for HPT\n", (1<<HPT_ORDER));
+
+	kvm->sdr1 = ((hpt + 0x3ffffULL) & ~0x3ffffULL) | (HPT_ORDER-18);
+
 	/* FIXME: This is book3s-specific */
 	cap_ppc_rma = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_PPC_RMA);
 	if (cap_ppc_rma == 2)