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@xxxxxxxxxx> --- 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, ®) < 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" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html