From patchwork Mon Mar 21 04:42:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 8629461 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id AB1A29F3D1 for ; Mon, 21 Mar 2016 04:42:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9CF9520172 for ; Mon, 21 Mar 2016 04:42:01 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8C51120155 for ; Mon, 21 Mar 2016 04:42:00 +0000 (UTC) Received: from localhost ([::1]:55561 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ahrfD-0006x1-VY for patchwork-qemu-devel@patchwork.kernel.org; Mon, 21 Mar 2016 00:42:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55847) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ahrez-0006tY-A1 for qemu-devel@nongnu.org; Mon, 21 Mar 2016 00:41:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ahrex-0007L9-HX for qemu-devel@nongnu.org; Mon, 21 Mar 2016 00:41:45 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:49565) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ahrew-0007Jl-Ux; Mon, 21 Mar 2016 00:41:43 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 3qT37n5tQzz9s9N; Mon, 21 Mar 2016 15:41:41 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1458535301; bh=pbwQEJC0XzuduEG4YADz7Y2JG08PfhYvlG8YXPCwRcY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ATQlr6V3l7mhg7QPn4Y+Vz+EEOMWb3haQNsMpEwlbjH7KeqZ31iM7AeOzj2uRvrt2 zNlYMXlFNrJfCMugUn/zm9F7spYnoMLPQ/OoO67dXRULFNiZsDRbD5B1hPyr1xKmJP 2jDrJK6/ZIREiNMPPdf+d4Vh/EJ6jHdS7LDNaM14= From: David Gibson To: paulus@samba.org, aik@ozlabs.ru Date: Mon, 21 Mar 2016 15:42:47 +1100 Message-Id: <1458535372-6757-2-git-send-email-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1458535372-6757-1-git-send-email-david@gibson.dropbear.id.au> References: <1458535372-6757-1-git-send-email-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Cc: agraf@suse.de, David Gibson , qemu-ppc@nongnu.org, qemu-devel@nongnu.org, bharata@linux.vnet.ibm.com Subject: [Qemu-devel] [RFC 1/6] pseries: Stubs for HPT resizing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This introduces stub implementations of the H_RESIZE_HPT_PREPARE and H_RESIZE_HPT_COMMIT hypercalls which we hope to add in a PAPR extension to allow run time resizing of a guest's hash page table. It also adds a new machine property for controlling whether this new facility is available. Finally, it adds a new string to the hypertas property in the device tree, advertising to the guest the availability of the HPT resizing hypercalls. This is a tentative suggested value, and would need to be standardized by PAPR before being merged. Signed-off-by: David Gibson --- hw/ppc/spapr.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ hw/ppc/spapr_hcall.c | 37 ++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 13 +++++++++- target-ppc/kvm.c | 12 ++++++++++ target-ppc/kvm_ppc.h | 6 +++++ trace-events | 2 ++ 6 files changed, 134 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d43d6d9..a027a80 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -318,6 +318,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, const char *kernel_cmdline, uint32_t epow_irq) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); void *fdt; uint32_t start_prop = cpu_to_be32(initrd_base); uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size); @@ -337,6 +338,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, add_str(hypertas, "hcall-splpar"); add_str(hypertas, "hcall-bulk"); add_str(hypertas, "hcall-set-mode"); + if (spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) { + add_str(hypertas, "hcall-hpt-resize"); + } add_str(qemu_hypertas, "hcall-memop1"); fdt = g_malloc0(FDT_MAX_SIZE); @@ -1733,6 +1737,7 @@ static void ppc_spapr_init(MachineState *machine) long load_limit, fw_size; bool kernel_le = false; char *filename; + Error *resize_hpt_err = NULL; msi_nonbroken = true; @@ -1740,6 +1745,25 @@ static void ppc_spapr_init(MachineState *machine) cpu_ppc_hypercall = emulate_spapr_hypercall; + /* Check HPT resizing availability */ + kvmppc_check_papr_resize_hpt(&resize_hpt_err); + if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DEFAULT) { + if (resize_hpt_err) { + spapr->resize_hpt = SPAPR_RESIZE_HPT_DISABLED; + error_free(resize_hpt_err); + resize_hpt_err = NULL; + } else { + spapr->resize_hpt = smc->resize_hpt_default; + } + } + + assert(spapr->resize_hpt != SPAPR_RESIZE_HPT_DEFAULT); + + if ((spapr->resize_hpt != SPAPR_RESIZE_HPT_DISABLED) && resize_hpt_err) { + error_report_err(resize_hpt_err); + exit(1); + } + /* Allocate RMA if necessary */ rma_alloc_size = kvmppc_alloc_rma(&rma); @@ -2093,6 +2117,40 @@ static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp) spapr->kvm_type = g_strdup(value); } +static char *spapr_get_resize_hpt(Object *obj, Error **errp) +{ + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + + switch (spapr->resize_hpt) { + case SPAPR_RESIZE_HPT_DEFAULT: + return g_strdup("default"); + case SPAPR_RESIZE_HPT_DISABLED: + return g_strdup("disabled"); + case SPAPR_RESIZE_HPT_ENABLED: + return g_strdup("enabled"); + case SPAPR_RESIZE_HPT_REQUIRED: + return g_strdup("required"); + } + assert(0); +} + +static void spapr_set_resize_hpt(Object *obj, const char *value, Error **errp) +{ + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + + if (strcmp(value, "default") == 0) { + spapr->resize_hpt = SPAPR_RESIZE_HPT_DEFAULT; + } else if (strcmp(value, "disabled") == 0) { + spapr->resize_hpt = SPAPR_RESIZE_HPT_DISABLED; + } else if (strcmp(value, "enabled") == 0) { + spapr->resize_hpt = SPAPR_RESIZE_HPT_ENABLED; + } else if (strcmp(value, "required") == 0) { + spapr->resize_hpt = SPAPR_RESIZE_HPT_REQUIRED; + } else { + error_setg(errp, "Bad value for \"resize-hpt\" property"); + } +} + static void spapr_machine_initfn(Object *obj) { sPAPRMachineState *spapr = SPAPR_MACHINE(obj); @@ -2103,6 +2161,12 @@ static void spapr_machine_initfn(Object *obj) object_property_set_description(obj, "kvm-type", "Specifies the KVM virtualization mode (HV, PR)", NULL); + + object_property_add_str(obj, "resize-hpt", + spapr_get_resize_hpt, spapr_set_resize_hpt, NULL); + object_property_set_description(obj, "resize-hpt", + "Resizing of the Hash Page Table (enabled, disabled, required)", + NULL); } static void spapr_machine_finalizefn(Object *obj) @@ -2296,6 +2360,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->cpu_index_to_socket_id = spapr_cpu_index_to_socket_id; smc->dr_lmb_enabled = true; + smc->resize_hpt_default = SPAPR_RESIZE_HPT_DISABLED; fwc->get_dev_path = spapr_get_fw_dev_path; nc->nmi_monitor_handler = spapr_nmi; } diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index b2b1b93..0f0675e 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -338,6 +338,38 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachineState *spapr, return H_SUCCESS; } +static target_ulong h_resize_hpt_prepare(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags = args[0]; + target_ulong shift = args[1]; + + if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED) { + return H_AUTHORITY; + } + + trace_spapr_h_resize_hpt_prepare(flags, shift); + return H_HARDWARE; +} + +static target_ulong h_resize_hpt_commit(PowerPCCPU *cpu, + sPAPRMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong flags = args[0]; + target_ulong shift = args[1]; + + if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DISABLED) { + return H_AUTHORITY; + } + + trace_spapr_h_resize_hpt_commit(flags, shift); + return H_HARDWARE; +} + static target_ulong h_set_sprg0(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { @@ -1096,6 +1128,11 @@ static void hypercall_register_types(void) /* hcall-bulk */ spapr_register_hypercall(H_BULK_REMOVE, h_bulk_remove); + /* hcall-hpt-resize */ + spapr_register_hypercall(KVMPPC_H_RESIZE_HPT_PREPARE, + h_resize_hpt_prepare); + spapr_register_hypercall(KVMPPC_H_RESIZE_HPT_COMMIT, h_resize_hpt_commit); + /* hcall-splpar */ spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); spapr_register_hypercall(H_CEDE, h_cede); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 098d85d..6de5135 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -27,6 +27,13 @@ typedef struct sPAPRMachineState sPAPRMachineState; #define SPAPR_MACHINE_CLASS(klass) \ OBJECT_CLASS_CHECK(sPAPRMachineClass, klass, TYPE_SPAPR_MACHINE) +typedef enum { + SPAPR_RESIZE_HPT_DEFAULT = 0, + SPAPR_RESIZE_HPT_DISABLED, + SPAPR_RESIZE_HPT_ENABLED, + SPAPR_RESIZE_HPT_REQUIRED, +} sPAPRResizeHPT; + /** * sPAPRMachineClass: */ @@ -37,6 +44,7 @@ struct sPAPRMachineClass { /*< public >*/ bool dr_lmb_enabled; /* enable dynamic-reconfig/hotplug of LMBs */ bool use_ohci_by_default; /* use USB-OHCI instead of XHCI */ + sPAPRResizeHPT resize_hpt_default; }; /** @@ -52,6 +60,7 @@ struct sPAPRMachineState { XICSState *icp; DeviceState *rtc; + sPAPRResizeHPT resize_hpt; void *htab; uint32_t htab_shift; hwaddr rma_size; @@ -351,7 +360,9 @@ struct sPAPRMachineState { #define KVMPPC_H_LOGICAL_MEMOP (KVMPPC_HCALL_BASE + 0x1) /* Client Architecture support */ #define KVMPPC_H_CAS (KVMPPC_HCALL_BASE + 0x2) -#define KVMPPC_HCALL_MAX KVMPPC_H_CAS +#define KVMPPC_H_RESIZE_HPT_PREPARE (KVMPPC_HCALL_BASE + 0x3) +#define KVMPPC_H_RESIZE_HPT_COMMIT (KVMPPC_HCALL_BASE + 0x4) +#define KVMPPC_HCALL_MAX KVMPPC_H_RESIZE_HPT_COMMIT typedef struct sPAPRDeviceTreeUpdateHeader { uint32_t version_id; diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index e5183db..989e1d1 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -2572,3 +2572,15 @@ int kvmppc_enable_hwrng(void) return kvmppc_enable_hcall(kvm_state, H_RANDOM); } + +void kvmppc_check_papr_resize_hpt(Error **errp) +{ + if (!kvm_enabled()) { + return; + } + + /* KVM will need to advertise capability for HPT resizing once + * implemented, for now we assume that it's not possible with + * KVM */ + error_setg(errp, "Hash page table resizing not available with KVM"); +} diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h index fc79312..5446d6f 100644 --- a/target-ppc/kvm_ppc.h +++ b/target-ppc/kvm_ppc.h @@ -56,6 +56,7 @@ void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index, bool kvmppc_has_cap_fixup_hcalls(void); int kvmppc_enable_hwrng(void); int kvmppc_put_books_sregs(PowerPCCPU *cpu); +void kvmppc_check_papr_resize_hpt(Error **errp); #else @@ -252,6 +253,11 @@ static inline int kvmppc_put_books_sregs(PowerPCCPU *cpu) { abort(); } + +static inline void kvmppc_check_papr_resize_hpt(Error **errp) +{ + return; +} #endif #ifndef CONFIG_KVM diff --git a/trace-events b/trace-events index d494de1..dfc263f 100644 --- a/trace-events +++ b/trace-events @@ -1419,6 +1419,8 @@ spapr_cas_continue(unsigned long n) "Copy changes to the guest: %ld bytes" # hw/ppc/spapr_hcall.c spapr_cas_pvr_try(uint32_t pvr) "%x" spapr_cas_pvr(uint32_t cur_pvr, bool cpu_match, uint32_t new_pvr, uint64_t pcr) "current=%x, cpu_match=%u, new=%x, compat flags=%"PRIx64 +spapr_h_resize_hpt_prepare(uint64_t flags, uint64_t shift) "flags=0x%"PRIx64", shift=%"PRIu64 +spapr_h_resize_hpt_commit(uint64_t flags, uint64_t shift) "flags=0x%"PRIx64", shift=%"PRIu64 # hw/ppc/spapr_iommu.c spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64