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 <m...@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(-)

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)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to