From nobody Sun Apr 28 19:59:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 14957764468841019.7906696310248; Thu, 25 May 2017 22:27:26 -0700 (PDT) Received: from localhost ([::1]:35020 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7mX-0002So-Al for importer@patchew.org; Fri, 26 May 2017 01:27:25 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56865) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7in-00081A-7e for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dE7ij-0007Tq-7X for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:33 -0400 Received: from ozlabs.org ([103.22.144.67]:35929) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dE7ii-0007R7-DH; Fri, 26 May 2017 01:23:29 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 3wYvfz5XrTz9sCZ; Fri, 26 May 2017 15:23:23 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1495776203; bh=nWlEln8qwY6T7ktvsSe6UdpqOj18NnALV4rv3GjSXsY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Yjgmfq/oD1S8/MDnQT8Pl3ry+jFE9GS++MtdIjLrn0XiSJ65BF5wLRg27FOXWRVGW Q4HBsQrCIqUuzxRhX3+sik79LugvsXVKEnFER7j+9eqdpgQox16mCD+r3415CezjRo ln3jWNpnAQARL1ac7uVbsCZFhiG/RisPRtihPIn4= From: David Gibson To: groug@kaod.org, clg@kaod.org, aik@ozlabs.ru, mdroth@linux.vnet.ibm.com, nikunj@linux.vnet.ibm.com Date: Fri, 26 May 2017 15:23:15 +1000 Message-Id: <20170526052319.28096-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170526052319.28096-1-david@gibson.dropbear.id.au> References: <20170526052319.28096-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 103.22.144.67 Subject: [Qemu-devel] [PATCHv4 1/5] qapi: add explicit null to string input and output visitors X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: agraf@suse.de, quintela@redhat.com, sursingh@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, qemu-ppc@nongnu.org, abologna@redhat.com, sbobroff@redhat.com, dgilbert@redhat.com, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Greg Kurz This may be used for deprecated object properties that are kept for backwards compatibility. Signed-off-by: Greg Kurz Reviewed-by: Markus Armbruster Signed-off-by: David Gibson --- qapi/string-input-visitor.c | 11 +++++++++++ qapi/string-output-visitor.c | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index c089491..63ae115 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -326,6 +326,16 @@ static void parse_type_number(Visitor *v, const char *= name, double *obj, *obj =3D val; } =20 +static void parse_type_null(Visitor *v, const char *name, Error **errp) +{ + StringInputVisitor *siv =3D to_siv(v); + + if (!siv->string || siv->string[0]) { + error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", + "null"); + } +} + static void string_input_free(Visitor *v) { StringInputVisitor *siv =3D to_siv(v); @@ -349,6 +359,7 @@ Visitor *string_input_visitor_new(const char *str) v->visitor.type_bool =3D parse_type_bool; v->visitor.type_str =3D parse_type_str; v->visitor.type_number =3D parse_type_number; + v->visitor.type_null =3D parse_type_null; v->visitor.start_list =3D start_list; v->visitor.next_list =3D next_list; v->visitor.check_list =3D check_list; diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c index 53c2175..af649e1 100644 --- a/qapi/string-output-visitor.c +++ b/qapi/string-output-visitor.c @@ -256,6 +256,19 @@ static void print_type_number(Visitor *v, const char *= name, double *obj, string_output_set(sov, g_strdup_printf("%f", *obj)); } =20 +static void print_type_null(Visitor *v, const char *name, Error **errp) +{ + StringOutputVisitor *sov =3D to_sov(v); + char *out; + + if (sov->human) { + out =3D g_strdup(""); + } else { + out =3D g_strdup(""); + } + string_output_set(sov, out); +} + static void start_list(Visitor *v, const char *name, GenericList **list, size_t size, Error **errp) @@ -341,6 +354,7 @@ Visitor *string_output_visitor_new(bool human, char **r= esult) v->visitor.type_bool =3D print_type_bool; v->visitor.type_str =3D print_type_str; v->visitor.type_number =3D print_type_number; + v->visitor.type_null =3D print_type_null; v->visitor.start_list =3D start_list; v->visitor.next_list =3D next_list; v->visitor.end_list =3D end_list; --=20 2.9.4 From nobody Sun Apr 28 19:59:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495776448583503.39469418101805; Thu, 25 May 2017 22:27:28 -0700 (PDT) Received: from localhost ([::1]:35021 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7mZ-0002TK-2V for importer@patchew.org; Fri, 26 May 2017 01:27:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56864) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7in-000819-7P for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dE7ij-0007Tp-7S for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:33 -0400 Received: from ozlabs.org ([103.22.144.67]:54419) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dE7ii-0007R6-DM; Fri, 26 May 2017 01:23:29 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 3wYvfz4bWjz9s8V; Fri, 26 May 2017 15:23:23 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1495776203; bh=uvk77LuddyCLUXc/t7I9VafGxm8kgsdSeaCEaG+P8tg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=or5a/tcRLJiOwnQY3Ts2Yr0R2C0AVEvuzFwjqAirTp+ouObvGQFEe5nQqoXFz5EzS hJY1HgbS1aLHe1hoJXt35EHQqsejrPJJfNPA2gS542vgw8f3UDmbfb/GSNXCtFkoxu YJRyvsXgK05xUphgvnV3xUiu9HUJGQLEbhZe5W10= From: David Gibson To: groug@kaod.org, clg@kaod.org, aik@ozlabs.ru, mdroth@linux.vnet.ibm.com, nikunj@linux.vnet.ibm.com Date: Fri, 26 May 2017 15:23:16 +1000 Message-Id: <20170526052319.28096-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170526052319.28096-1-david@gibson.dropbear.id.au> References: <20170526052319.28096-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 103.22.144.67 Subject: [Qemu-devel] [PATCHv4 2/5] migration: Mark CPU states dirty before incoming migration/loadvm X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: agraf@suse.de, quintela@redhat.com, sursingh@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, qemu-ppc@nongnu.org, abologna@redhat.com, sbobroff@redhat.com, dgilbert@redhat.com, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" As a rule, CPU internal state should never be updated when !cpu->kvm_vcpu_dirty (or the HAX equivalent). If that is done, then subsequent calls to cpu_synchronize_state() - usually safe and idempotent - will clobber state. However, we routinely do this during a loadvm or incoming migration. Usually this is called shortly after a reset, which will clear all the cpu dirty flags with cpu_synchronize_all_post_reset(). Nothing is expected to set the dirty flags again before the cpu state is loaded from the incoming stream. This means that it isn't safe to call cpu_synchronize_state() from a post_load handler, which is non-obvious and potentially inconvenient. We could cpu_synchronize_all_state() before the loadvm, but that would be overkill since a) we expect the state to already be synchronized from the reset and b) we expect to completely rewrite the state with a call to cpu_synchronize_all_post_init() at the end of qemu_loadvm_state(). To clear this up, this patch introduces cpu_synchronize_pre_loadvm() and associated helpers, which simply marks the cpu state as dirty without actually changing anything. i.e. it says we want to discard any existing KVM (or HAX) state and replace it with what we're going to load. Cc: Juan Quintela Cc: Dave Gilbert Signed-off-by: David Gibson --- cpus.c | 9 +++++++++ include/sysemu/cpus.h | 1 + include/sysemu/hax.h | 1 + include/sysemu/hw_accel.h | 10 ++++++++++ include/sysemu/kvm.h | 1 + kvm-all.c | 10 ++++++++++ migration/savevm.c | 2 ++ target/i386/hax-all.c | 10 ++++++++++ 8 files changed, 44 insertions(+) diff --git a/cpus.c b/cpus.c index 516e5cb..6398439 100644 --- a/cpus.c +++ b/cpus.c @@ -921,6 +921,15 @@ void cpu_synchronize_all_post_init(void) } } =20 +void cpu_synchronize_all_pre_loadvm(void) +{ + CPUState *cpu; + + CPU_FOREACH(cpu) { + cpu_synchronize_pre_loadvm(cpu); + } +} + static int do_vm_stop(RunState state) { int ret =3D 0; diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index a8053f1..731756d 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -27,6 +27,7 @@ void qemu_timer_notify_cb(void *opaque, QEMUClockType typ= e); void cpu_synchronize_all_states(void); void cpu_synchronize_all_post_reset(void); void cpu_synchronize_all_post_init(void); +void cpu_synchronize_all_pre_loadvm(void); =20 void qtest_clock_warp(int64_t dest); =20 diff --git a/include/sysemu/hax.h b/include/sysemu/hax.h index d9f0239..232a68a 100644 --- a/include/sysemu/hax.h +++ b/include/sysemu/hax.h @@ -33,6 +33,7 @@ int hax_populate_ram(uint64_t va, uint32_t size); void hax_cpu_synchronize_state(CPUState *cpu); void hax_cpu_synchronize_post_reset(CPUState *cpu); void hax_cpu_synchronize_post_init(CPUState *cpu); +void hax_cpu_synchronize_pre_loadvm(CPUState *cpu); =20 #ifdef CONFIG_HAX =20 diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h index c9b3105..469ffda 100644 --- a/include/sysemu/hw_accel.h +++ b/include/sysemu/hw_accel.h @@ -45,4 +45,14 @@ static inline void cpu_synchronize_post_init(CPUState *c= pu) } } =20 +static inline void cpu_synchronize_pre_loadvm(CPUState *cpu) +{ + if (kvm_enabled()) { + kvm_cpu_synchronize_pre_loadvm(cpu); + } + if (hax_enabled()) { + hax_cpu_synchronize_pre_loadvm(cpu); + } +} + #endif /* QEMU_HW_ACCEL_H */ diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index 5cc83f2..a45c145 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -459,6 +459,7 @@ int kvm_physical_memory_addr_from_host(KVMState *s, voi= d *ram_addr, void kvm_cpu_synchronize_state(CPUState *cpu); void kvm_cpu_synchronize_post_reset(CPUState *cpu); void kvm_cpu_synchronize_post_init(CPUState *cpu); +void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu); =20 void kvm_init_cpu_signals(CPUState *cpu); =20 diff --git a/kvm-all.c b/kvm-all.c index 90b8573..a8485bd 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1896,6 +1896,16 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu) run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, RUN_ON_CPU_NULL); } =20 +static void do_kvm_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_da= ta arg) +{ + cpu->kvm_vcpu_dirty =3D true; +} + +void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu) +{ + run_on_cpu(cpu, do_kvm_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL); +} + #ifdef KVM_HAVE_MCE_INJECTION static __thread void *pending_sigbus_addr; static __thread int pending_sigbus_code; diff --git a/migration/savevm.c b/migration/savevm.c index d971e5e..6391131 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -2011,6 +2011,8 @@ int qemu_loadvm_state(QEMUFile *f) } } =20 + cpu_synchronize_all_pre_loadvm(); + ret =3D qemu_loadvm_state_main(f, mis); qemu_event_set(&mis->main_thread_load_event); =20 diff --git a/target/i386/hax-all.c b/target/i386/hax-all.c index ef13015..1306722 100644 --- a/target/i386/hax-all.c +++ b/target/i386/hax-all.c @@ -635,6 +635,16 @@ void hax_cpu_synchronize_post_init(CPUState *cpu) run_on_cpu(cpu, do_hax_cpu_synchronize_post_init, RUN_ON_CPU_NULL); } =20 +static void do_hax_cpu_synchronize_pre_loadvm(CPUState *cpu, run_on_cpu_da= ta arg) +{ + cpu->hax_vcpu_dirty =3D true; +} + +void hax_cpu_synchronize_pre_loadvm(CPUState *cpu) +{ + run_on_cpu(cpu, do_hax_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL); +} + int hax_smp_cpu_exec(CPUState *cpu) { CPUArchState *env =3D (CPUArchState *) (cpu->env_ptr); --=20 2.9.4 From nobody Sun Apr 28 19:59:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495776453995849.6556540593286; Thu, 25 May 2017 22:27:33 -0700 (PDT) Received: from localhost ([::1]:35022 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7me-0002ax-Im for importer@patchew.org; Fri, 26 May 2017 01:27:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56849) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7im-000815-CY for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dE7ij-0007UD-PO for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:32 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:43705) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dE7ij-0007RE-2R; Fri, 26 May 2017 01:23:29 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 3wYvg00T86z9sDF; Fri, 26 May 2017 15:23:23 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1495776204; bh=SBJLmZZZdOWQVqSCwgagk46IlqIknfsyayf2KIwOFXI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L63y6r9/z4ki91PlcyF9BMZIiY61Z2r3ozOCs3gILijh7ZdKqXuAHFPxE/3oDZQB/ oifUp0U9SXbz889g54Pav6PouwoULw6qT9ldoMS9AjX11k9ZD1rdkEfr5yKsGfvxM3 0aVVRrPO+lOcA/rNMKsqfJ36ekRRLmEd9TFw+qDg= From: David Gibson To: groug@kaod.org, clg@kaod.org, aik@ozlabs.ru, mdroth@linux.vnet.ibm.com, nikunj@linux.vnet.ibm.com Date: Fri, 26 May 2017 15:23:17 +1000 Message-Id: <20170526052319.28096-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170526052319.28096-1-david@gibson.dropbear.id.au> References: <20170526052319.28096-1-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 Subject: [Qemu-devel] [PATCHv4 3/5] pseries: Move CPU compatibility property to machine X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: agraf@suse.de, quintela@redhat.com, sursingh@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, qemu-ppc@nongnu.org, abologna@redhat.com, sbobroff@redhat.com, dgilbert@redhat.com, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Server class POWER CPUs have a "compat" property, which is used to set the backwards compatibility mode for the processor. However, this only makes sense for machine types which don't give the guest access to hypervisor privilege - otherwise the compatibility level is under the guest's control. To reflect this, this removes the CPU 'compat' property and instead creates a 'max-cpu-compat' property on the pseries machine. Strictly speaking this breaks compatibility, but AFAIK the 'compat' option was never (directly) used with -device or device_add. The option was used with -cpu. So, to maintain compatibility, this patch adds a hack to the cpu option parsing to strip out any compat options supplied with -cpu and set them on the machine property instead of the now deprecated cpu property. Signed-off-by: David Gibson --- hw/ppc/spapr.c | 6 ++- hw/ppc/spapr_cpu_core.c | 56 +++++++++++++++++++++++- hw/ppc/spapr_hcall.c | 8 ++-- include/hw/ppc/spapr.h | 12 ++++-- target/ppc/compat.c | 102 ++++++++++++++++++++++++++++++++++++++++= ++++ target/ppc/cpu.h | 5 ++- target/ppc/translate_init.c | 86 +++++++++++-------------------------- 7 files changed, 202 insertions(+), 73 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index ab3aab1..3c4e88f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2134,7 +2134,7 @@ static void ppc_spapr_init(MachineState *machine) machine->cpu_model =3D kvm_enabled() ? "host" : smc->tcg_default_c= pu; } =20 - ppc_cpu_parse_features(machine->cpu_model); + spapr_cpu_parse_features(spapr); =20 spapr_init_cpus(spapr); =20 @@ -2497,6 +2497,10 @@ static void spapr_machine_initfn(Object *obj) " place of standard EPOW events when p= ossible" " (required for memory hot-unplug supp= ort)", NULL); + + ppc_compat_add_property(obj, "max-cpu-compat", &spapr->max_compat_pvr, + "Maximum permitted CPU compatibility mode", + &error_fatal); } =20 static void spapr_machine_finalizefn(Object *obj) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index ff7058e..ab4102b 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -20,6 +20,58 @@ #include "sysemu/numa.h" #include "qemu/error-report.h" =20 +void spapr_cpu_parse_features(sPAPRMachineState *spapr) +{ + /* + * Backwards compatibility hack: + * + * CPUs had a "compat=3D" property which didn't make sense for + * anything except pseries. It was replaced by "max-cpu-compat" + * machine option. This supports old command lines like + * -cpu POWER8,compat=3Dpower7 + * By stripping the compat option and applying it to the machine + * before passing it on to the cpu level parser. + */ + gchar **inpieces; + int i, j; + gchar *compat_str =3D NULL; + + inpieces =3D g_strsplit(MACHINE(spapr)->cpu_model, ",", 0); + + /* inpieces[0] is the actual model string */ + i =3D 1; + j =3D 1; + while (inpieces[i]) { + if (g_str_has_prefix(inpieces[i], "compat=3D")) { + /* in case of multiple compat=3D optipons */ + g_free(compat_str); + compat_str =3D inpieces[i]; + } else { + j++; + } + + /* Excise compat options from list */ + inpieces[j] =3D inpieces[i]; + i++; + } + inpieces[j] =3D NULL; + + if (compat_str) { + char *val =3D compat_str + strlen("compat=3D"); + gchar *newprops =3D g_strjoinv(",", inpieces); + + object_property_set_str(OBJECT(spapr), val, "max-cpu-compat", + &error_fatal); + + ppc_cpu_parse_features(newprops); + g_free(newprops); + } else { + ppc_cpu_parse_features(MACHINE(spapr)->cpu_model); + } + + g_strfreev(inpieces); +} + static void spapr_cpu_reset(void *opaque) { sPAPRMachineState *spapr =3D SPAPR_MACHINE(qdev_get_machine()); @@ -70,10 +122,10 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, P= owerPCCPU *cpu, /* Enable PAPR mode in TCG or KVM */ cpu_ppc_set_papr(cpu, PPC_VIRTUAL_HYPERVISOR(spapr)); =20 - if (cpu->max_compat) { + if (spapr->max_compat_pvr) { Error *local_err =3D NULL; =20 - ppc_set_compat(cpu, cpu->max_compat, &local_err); + ppc_set_compat(cpu, spapr->max_compat_pvr, &local_err); if (local_err) { error_propagate(errp, local_err); return; diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 77d2d66..8129959 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1044,11 +1044,11 @@ static target_ulong h_signal_sys_reset(PowerPCCPU *= cpu, } } =20 -static uint32_t cas_check_pvr(PowerPCCPU *cpu, target_ulong *addr, - Error **errp) +static uint32_t cas_check_pvr(sPAPRMachineState *spapr, PowerPCCPU *cpu, + target_ulong *addr, Error **errp) { bool explicit_match =3D false; /* Matched the CPU's real PVR */ - uint32_t max_compat =3D cpu->max_compat; + uint32_t max_compat =3D spapr->max_compat_pvr; uint32_t best_compat =3D 0; int i; =20 @@ -1104,7 +1104,7 @@ static target_ulong h_client_architecture_support(Pow= erPCCPU *cpu, bool guest_radix; Error *local_err =3D NULL; =20 - cas_pvr =3D cas_check_pvr(cpu, &addr, &local_err); + cas_pvr =3D cas_check_pvr(spapr, cpu, &addr, &local_err); if (local_err) { error_report_err(local_err); return H_HARDWARE; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 98fb78b..4da92e2 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -87,16 +87,19 @@ struct sPAPRMachineState { uint64_t rtc_offset; /* Now used only during incoming migration */ struct PPCTimebase tb; bool has_graphics; - sPAPROptionVector *ov5; /* QEMU-supported option vectors */ - sPAPROptionVector *ov5_cas; /* negotiated (via CAS) option vectors= */ - bool cas_reboot; - bool cas_legacy_guest_workaround; =20 Notifier epow_notifier; QTAILQ_HEAD(, sPAPREventLogEntry) pending_events; bool use_hotplug_event_source; sPAPREventSource *event_sources; =20 + /* ibm,client-architecture-support option negotiation */ + bool cas_reboot; + bool cas_legacy_guest_workaround; + sPAPROptionVector *ov5; /* QEMU-supported option vectors */ + sPAPROptionVector *ov5_cas; /* negotiated (via CAS) option vectors= */ + uint32_t max_compat_pvr; + /* Migration state */ int htab_save_index; bool htab_first_pass; @@ -639,6 +642,7 @@ void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConn= ectorType drc_type, uint32_t count, uint32_t index= ); void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_ty= pe, uint32_t count, uint32_t in= dex); +void spapr_cpu_parse_features(sPAPRMachineState *spapr); void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset, sPAPRMachineState *spapr); =20 diff --git a/target/ppc/compat.c b/target/ppc/compat.c index e8ec1e1..e72839f 100644 --- a/target/ppc/compat.c +++ b/target/ppc/compat.c @@ -24,9 +24,11 @@ #include "sysemu/cpus.h" #include "qemu/error-report.h" #include "qapi/error.h" +#include "qapi/visitor.h" #include "cpu-models.h" =20 typedef struct { + const char *name; uint32_t pvr; uint64_t pcr; uint64_t pcr_level; @@ -38,6 +40,7 @@ static const CompatInfo compat_table[] =3D { * Ordered from oldest to newest - the code relies on this */ { /* POWER6, ISA2.05 */ + .name =3D "power6", .pvr =3D CPU_POWERPC_LOGICAL_2_05, .pcr =3D PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05 | PCR_TM_DIS | PCR_VSX_DIS, @@ -45,24 +48,28 @@ static const CompatInfo compat_table[] =3D { .max_threads =3D 2, }, { /* POWER7, ISA2.06 */ + .name =3D "power7", .pvr =3D CPU_POWERPC_LOGICAL_2_06, .pcr =3D PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR= _TM_DIS, .pcr_level =3D PCR_COMPAT_2_06, .max_threads =3D 4, }, { + .name =3D "power7+", .pvr =3D CPU_POWERPC_LOGICAL_2_06_PLUS, .pcr =3D PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR= _TM_DIS, .pcr_level =3D PCR_COMPAT_2_06, .max_threads =3D 4, }, { /* POWER8, ISA2.07 */ + .name =3D "power8", .pvr =3D CPU_POWERPC_LOGICAL_2_07, .pcr =3D PCR_COMPAT_3_00 | PCR_COMPAT_2_07, .pcr_level =3D PCR_COMPAT_2_07, .max_threads =3D 8, }, { /* POWER9, ISA3.00 */ + .name =3D "power9", .pvr =3D CPU_POWERPC_LOGICAL_3_00, .pcr =3D PCR_COMPAT_3_00, .pcr_level =3D PCR_COMPAT_3_00, @@ -189,3 +196,98 @@ int ppc_compat_max_threads(PowerPCCPU *cpu) =20 return n_threads; } + +static void ppc_compat_prop_get(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint32_t compat_pvr =3D *((uint32_t *)opaque); + const char *value; + + if (!compat_pvr) { + value =3D ""; + } else { + const CompatInfo *compat =3D compat_by_pvr(compat_pvr); + + g_assert(compat); + + value =3D compat->name; + } + + visit_type_str(v, name, (char **)&value, errp); +} + +static void ppc_compat_prop_set(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + Error *error =3D NULL; + char *value; + uint32_t compat_pvr; + + visit_type_str(v, name, &value, &error); + if (error) { + error_propagate(errp, error); + return; + } + + if (strcmp(value, "") =3D=3D 0) { + compat_pvr =3D 0; + } else { + int i; + const CompatInfo *compat =3D NULL; + + for (i =3D 0; i < ARRAY_SIZE(compat_table); i++) { + if (strcmp(value, compat_table[i].name) =3D=3D 0) { + compat =3D &compat_table[i]; + break; + + } + } + + if (!compat) { + error_setg(errp, "Invalid compatibility mode \"%s\"", value); + goto out; + } + compat_pvr =3D compat->pvr; + } + + *((uint32_t *)opaque) =3D compat_pvr; + +out: + g_free(value); +} + +void ppc_compat_add_property(Object *obj, const char *name, + uint32_t *compat_pvr, const char *basedesc, + Error **errp) +{ + Error *local_err =3D NULL; + gchar *namesv[ARRAY_SIZE(compat_table) + 1]; + gchar *names, *desc; + int i; + + object_property_add(obj, name, "string", + ppc_compat_prop_get, ppc_compat_prop_set, NULL, + compat_pvr, &local_err); + if (local_err) { + goto out; + } + + for (i =3D 0; i < ARRAY_SIZE(compat_table); i++) { + /* + * Have to discard const here, because g_strjoinv() takes + * (gchar **), not (const gchar **) :( + */ + namesv[i] =3D (gchar *)compat_table[i].name; + } + namesv[ARRAY_SIZE(compat_table)] =3D NULL; + + names =3D g_strjoinv(", ", namesv); + desc =3D g_strdup_printf("%s. Valid values are %s.", basedesc, names); + object_property_set_description(obj, name, desc, &local_err); + + g_free(names); + g_free(desc); + +out: + error_propagate(errp, local_err); +} diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 401e10e..4517b4b 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1189,7 +1189,6 @@ typedef struct PPCVirtualHypervisorClass PPCVirtualHy= pervisorClass; * PowerPCCPU: * @env: #CPUPPCState * @cpu_dt_id: CPU index used in the device tree. KVM uses this index too - * @max_compat: Maximal supported logical PVR from the command line * @compat_pvr: Current logical PVR, zero if in "raw" mode * * A PowerPC CPU. @@ -1201,7 +1200,6 @@ struct PowerPCCPU { =20 CPUPPCState env; int cpu_dt_id; - uint32_t max_compat; uint32_t compat_pvr; PPCVirtualHypervisor *vhyp; Object *intc; @@ -1374,6 +1372,9 @@ void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_= pvr, Error **errp); void ppc_set_compat_all(uint32_t compat_pvr, Error **errp); #endif int ppc_compat_max_threads(PowerPCCPU *cpu); +void ppc_compat_add_property(Object *obj, const char *name, + uint32_t *compat_pvr, const char *basedesc, + Error **errp); #endif /* defined(TARGET_PPC64) */ =20 #include "exec/cpu-all.h" diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c index 56a0ab2..e837cd2 100644 --- a/target/ppc/translate_init.c +++ b/target/ppc/translate_init.c @@ -33,6 +33,7 @@ #include "hw/qdev-properties.h" #include "hw/ppc/ppc.h" #include "mmu-book3s-v3.h" +#include "sysemu/qtest.h" =20 //#define PPC_DUMP_CPU //#define PPC_DEBUG_SPR @@ -8413,73 +8414,38 @@ POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data) pcc->l1_icache_size =3D 0x10000; } =20 -static void powerpc_get_compat(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) -{ - char *value =3D (char *)""; - Property *prop =3D opaque; - uint32_t *max_compat =3D qdev_get_prop_ptr(DEVICE(obj), prop); - - switch (*max_compat) { - case CPU_POWERPC_LOGICAL_2_05: - value =3D (char *)"power6"; - break; - case CPU_POWERPC_LOGICAL_2_06: - value =3D (char *)"power7"; - break; - case CPU_POWERPC_LOGICAL_2_07: - value =3D (char *)"power8"; - break; - case 0: - break; - default: - error_report("Internal error: compat is set to %x", *max_compat); - abort(); - break; - } - - visit_type_str(v, name, &value, errp); -} - -static void powerpc_set_compat(Object *obj, Visitor *v, const char *name, - void *opaque, Error **errp) +/* + * The CPU used to have a "compat" property which set the + * compatibility mode PVR. However, this was conceptually broken - it + * only makes sense on the pseries machine type (otherwise the guest + * owns the PCR and can control the compatibility mode itself). It's + * been replaced with the 'max-cpu-compat' property on the pseries + * machine type. For backwards compatibility, pseries specially + * parses the -cpu parameter and converts old compat=3D parameters into + * the appropriate machine parameters. This stub implementation of + * the parameter catches any uses on explicitly created CPUs. + */ +static void getset_compat_deprecated(Object *obj, Visitor *v, const char *= name, + void *opaque, Error **errp) { - Error *error =3D NULL; - char *value =3D NULL; - Property *prop =3D opaque; - uint32_t *max_compat =3D qdev_get_prop_ptr(DEVICE(obj), prop); - - visit_type_str(v, name, &value, &error); - if (error) { - error_propagate(errp, error); - return; - } - - if (strcmp(value, "power6") =3D=3D 0) { - *max_compat =3D CPU_POWERPC_LOGICAL_2_05; - } else if (strcmp(value, "power7") =3D=3D 0) { - *max_compat =3D CPU_POWERPC_LOGICAL_2_06; - } else if (strcmp(value, "power8") =3D=3D 0) { - *max_compat =3D CPU_POWERPC_LOGICAL_2_07; - } else { - error_setg(errp, "Invalid compatibility mode \"%s\"", value); + if (!qtest_enabled()) { + error_report("CPU 'compat' property is deprecated and has no effec= t; " + "use max-cpu-compat machine property instead"); } - - g_free(value); + visit_type_null(v, name, NULL); } =20 -static PropertyInfo powerpc_compat_propinfo =3D { +static PropertyInfo ppc_compat_deprecated_propinfo =3D { .name =3D "str", - .description =3D "compatibility mode, power6/power7/power8", - .get =3D powerpc_get_compat, - .set =3D powerpc_set_compat, + .description =3D "compatibility mode (deprecated)", + .get =3D getset_compat_deprecated, + .set =3D getset_compat_deprecated, }; - -#define DEFINE_PROP_POWERPC_COMPAT(_n, _s, _f) \ - DEFINE_PROP(_n, _s, _f, powerpc_compat_propinfo, uint32_t) - static Property powerpc_servercpu_properties[] =3D { - DEFINE_PROP_POWERPC_COMPAT("compat", PowerPCCPU, max_compat), + { + .name =3D "compat", + .info =3D &ppc_compat_deprecated_propinfo, + }, DEFINE_PROP_END_OF_LIST(), }; =20 --=20 2.9.4 From nobody Sun Apr 28 19:59:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495776306096567.9626626730371; Thu, 25 May 2017 22:25:06 -0700 (PDT) Received: from localhost ([::1]:35008 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7kF-0000YY-Gg for importer@patchew.org; Fri, 26 May 2017 01:25:03 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56821) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7ik-00080v-J6 for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dE7ij-0007U2-EC for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:30 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:50891) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dE7ij-0007RC-1D; Fri, 26 May 2017 01:23:29 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 3wYvfz6gm0z9s9Y; Fri, 26 May 2017 15:23:23 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1495776203; bh=Gi3GASOsxVvVgsP4ZuNDH0XX3tZQYlx6u90V5xEdidg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LBC0dsx4brY7UplcM/vTQxFBA0TBmblDvl7kjDHJvkpSGR8Q0gSQfo1Dbaui4z6UZ dK6WsGSEXyG5OYqoabKmJ4wTH8JJnI6Zm4S20JzFUNWk+hI6hId/Ez72hAToVs/8Kj KRKqbWqvYgg4Xr+7OqLLo7oA1ZvpOAukCMju7kkI= From: David Gibson To: groug@kaod.org, clg@kaod.org, aik@ozlabs.ru, mdroth@linux.vnet.ibm.com, nikunj@linux.vnet.ibm.com Date: Fri, 26 May 2017 15:23:18 +1000 Message-Id: <20170526052319.28096-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170526052319.28096-1-david@gibson.dropbear.id.au> References: <20170526052319.28096-1-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 Subject: [Qemu-devel] [PATCHv4 4/5] pseries: Reset CPU compatibility mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: agraf@suse.de, quintela@redhat.com, sursingh@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, qemu-ppc@nongnu.org, abologna@redhat.com, sbobroff@redhat.com, dgilbert@redhat.com, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Currently, the CPU compatibility mode is set when the cpu is initialized, then again when the guest negotiates features. This means if a guest negotiates a compatibility mode, then reboots, that compatibility mode will be retained across the reset. Usually that will get overridden when features are negotiated on the next boot, but it's still not really correct. This patch moves the initial set up of the compatibility mode from cpu init to reset time. The mode *is* retained if the reboot was caused by the feature negotiation (it might be important in that case, though it's unlikely). Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy Reviewed-by: Michael Roth --- hw/ppc/spapr.c | 2 ++ hw/ppc/spapr_cpu_core.c | 10 ---------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3c4e88f..2821b7e 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1348,6 +1348,8 @@ static void ppc_spapr_reset(void) if (!spapr->cas_reboot) { spapr_ovec_cleanup(spapr->ov5_cas); spapr->ov5_cas =3D spapr_ovec_new(); + + ppc_set_compat_all(spapr->max_compat_pvr, &error_abort); } =20 fdt =3D spapr_build_fdt(spapr, rtas_addr, spapr->rtas_size); diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index ab4102b..7cc7320 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -122,16 +122,6 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, P= owerPCCPU *cpu, /* Enable PAPR mode in TCG or KVM */ cpu_ppc_set_papr(cpu, PPC_VIRTUAL_HYPERVISOR(spapr)); =20 - if (spapr->max_compat_pvr) { - Error *local_err =3D NULL; - - ppc_set_compat(cpu, spapr->max_compat_pvr, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - } - qemu_register_reset(spapr_cpu_reset, cpu); spapr_cpu_reset(cpu); } --=20 2.9.4 From nobody Sun Apr 28 19:59:07 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1495776308704264.3359196541876; Thu, 25 May 2017 22:25:08 -0700 (PDT) Received: from localhost ([::1]:35009 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7kJ-0000b0-6u for importer@patchew.org; Fri, 26 May 2017 01:25:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56870) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dE7in-00081I-IR for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dE7im-0007Un-4o for qemu-devel@nongnu.org; Fri, 26 May 2017 01:23:33 -0400 Received: from ozlabs.org ([103.22.144.67]:42941) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dE7il-0007U9-O7; Fri, 26 May 2017 01:23:32 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 3wYvg01DPRz9sDB; Fri, 26 May 2017 15:23:23 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1495776204; bh=yPP32CARnAH4WRY59Ze0KODUg8jAwA2djHmb2SHMDdY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eBp6MWsInijEofULBSHzrFXqLm11G4XjFf/SMp7ajXbSQK5n46qWv6yYSpHtu0+Mx pytqjL2Q0A0BeAcbFyAogkBPErXk6ycc6EhxpRLO/c8LleCotEo/JB/3bYLKcBLNWk +vyL60cUaDZgYN0+tDt+fJPcTpvvvPrjCnfzZBqM= From: David Gibson To: groug@kaod.org, clg@kaod.org, aik@ozlabs.ru, mdroth@linux.vnet.ibm.com, nikunj@linux.vnet.ibm.com Date: Fri, 26 May 2017 15:23:19 +1000 Message-Id: <20170526052319.28096-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.4 In-Reply-To: <20170526052319.28096-1-david@gibson.dropbear.id.au> References: <20170526052319.28096-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 103.22.144.67 Subject: [Qemu-devel] [PATCHv4 5/5] ppc: Rework CPU compatibility testing across migration X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: agraf@suse.de, quintela@redhat.com, sursingh@redhat.com, qemu-devel@nongnu.org, armbru@redhat.com, qemu-ppc@nongnu.org, abologna@redhat.com, sbobroff@redhat.com, dgilbert@redhat.com, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Migrating between different CPU versions is a bit complicated for ppc. A long time ago, we ensured identical CPU versions at either end by checking the PVR had the same value. However, this breaks under KVM HV, because we always have to use the host's PVR - it's not virtualized. That would mean we couldn't migrate between hosts with different PVRs, even if the CPUs are close enough to compatible in practice (sometimes identical cores with different surrounding logic have different PVRs, so this happens in practice quite often). So, we removed the PVR check, but instead checked that several flags indicating supported instructions matched. This turns out to be a bad idea, because those instruction masks are not architected information, but essentially a TCG implementation detail. So changes to qemu internal CPU modelling can break migration - this happened between qemu-2.6 and qemu-2.7. That was addressed by 146c11f1 "target-ppc: Allow eventual removal of old migration mistakes". Now, verification of CPU compatibility across a migration basically doesn't happen. We simply ignore the PVR of the incoming migration, and hope the cpu on the destination is close enough to work. Now that we've cleaned up handling of processor compatibility modes for pseries machine type, we can do better. We allow migration if: * The source and destination PVRs are for the same type of CPU, as determined by CPU class's pvr_match function OR * When the source was in a compatibility mode, and the destination CPU supports the same compatibility mode Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Suraj Jitindar Singh --- target/ppc/machine.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++= +--- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/target/ppc/machine.c b/target/ppc/machine.c index 6cb3a48..2c6d9dc 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -8,6 +8,7 @@ #include "helper_regs.h" #include "mmu-hash64.h" #include "migration/cpu.h" +#include "qapi/error.h" =20 static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) { @@ -195,6 +196,30 @@ static void cpu_pre_save(void *opaque) } } =20 +/* + * Determine if a given PVR is a "close enough" match to the CPU + * object. For TCG and KVM PR it would probably be sufficient to + * require an exact PVR match. However for KVM HV the user is + * restricted to a PVR exactly matching the host CPU. The correct way + * to handle this is to put the guest into an architected + * compatibility mode. However, to allow a more forgiving transition + * and migration from before this was widely done, we allow migration + * between sufficiently similar PVRs, as determined by the CPU class's + * pvr_match() hook. + */ +static bool pvr_match(PowerPCCPU *cpu, uint32_t pvr) +{ + PowerPCCPUClass *pcc =3D POWERPC_CPU_GET_CLASS(cpu); + + if (pvr =3D=3D pcc->pvr) { + return true; + } + if (pcc->pvr_match) { + return pcc->pvr_match(pcc, pvr); + } + return false; +} + static int cpu_post_load(void *opaque, int version_id) { PowerPCCPU *cpu =3D opaque; @@ -203,10 +228,31 @@ static int cpu_post_load(void *opaque, int version_id) target_ulong msr; =20 /* - * We always ignore the source PVR. The user or management - * software has to take care of running QEMU in a compatible mode. + * If we're operating in compat mode, we should be ok as long as + * the destination supports the same compatiblity mode. + * + * Otherwise, however, we require that the destination has exactly + * the same CPU model as the source. */ - env->spr[SPR_PVR] =3D env->spr_cb[SPR_PVR].default_value; + +#if defined(TARGET_PPC64) + if (cpu->compat_pvr) { + Error *local_err =3D NULL; + + ppc_set_compat(cpu, cpu->compat_pvr, &local_err); + if (local_err) { + error_report_err(local_err); + error_free(local_err); + return -1; + } + } else +#endif + { + if (!pvr_match(cpu, env->spr[SPR_PVR])) { + return -1; + } + } + env->lr =3D env->spr[SPR_LR]; env->ctr =3D env->spr[SPR_CTR]; cpu_write_xer(env, env->spr[SPR_XER]); @@ -560,6 +606,25 @@ static const VMStateDescription vmstate_tlbmas =3D { } }; =20 +static bool compat_needed(void *opaque) +{ + PowerPCCPU *cpu =3D opaque; + + assert(!(cpu->compat_pvr && !cpu->vhyp)); + return (cpu->compat_pvr !=3D 0); +} + +static const VMStateDescription vmstate_compat =3D { + .name =3D "cpu/compat", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D compat_needed, + .fields =3D (VMStateField[]) { + VMSTATE_UINT32(compat_pvr, PowerPCCPU), + VMSTATE_END_OF_LIST() + } +}; + const VMStateDescription vmstate_ppc_cpu =3D { .name =3D "cpu", .version_id =3D 5, @@ -613,6 +678,7 @@ const VMStateDescription vmstate_ppc_cpu =3D { &vmstate_tlb6xx, &vmstate_tlbemb, &vmstate_tlbmas, + &vmstate_compat, NULL } }; --=20 2.9.4