From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333116; cv=none; d=zohomail.com; s=zohoarc; b=BUfkbmh2gj/ZaZ8nRC0sEJOVJvukA3IwWqTFYX/Lmc/4ykmM1RjiP/IhfjT50empXO9PihqpSDVXuuMSIzDbunlzi6JK9VT5qdTaMWk1x8DmAWh1lxuCqoOwn6iRDj3bIH3/WzIFdV7UO/DvqVsZK4J50pgx6BfPywp7ydWi7+o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333116; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=jgw5HjdVn1bzJIanZal4Sgki/vEZ4tY4bQBTDWdYOjY=; b=ZP2274j56kiVDQdlR44A5PXRnxZwn10FOiyvB3rK8viOkYSlAN7heioMR2DBEJGfWL03w2dsQrdHhGJwb6UVd41cwhGyGPG4H6Ki1NViphGpyBH4Jwpp2qgg65nML9NttaT7mOAb9pwofpWJFoTfFRwj2P91ZUg2NE56VNC9B6g= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333116680627.1192615432409; Fri, 26 Feb 2021 01:51:56 -0800 (PST) Received: from localhost ([::1]:44662 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZmt-0006fs-Ea for importer@patchew.org; Fri, 26 Feb 2021 04:51:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36304) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkp-0004nK-Pg for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:47 -0500 Received: from mx2.suse.de ([195.135.220.15]:42954) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkl-0004mj-2I for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:47 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id C841AAF33; Fri, 26 Feb 2021 09:49:41 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 01/18] i386: split cpu accelerators from cpu.c, using AccelCPUClass Date: Fri, 26 Feb 2021 10:49:22 +0100 Message-Id: <20210226094939.11087-2-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" i386 is the first user of AccelCPUClass, allowing to split cpu.c into: cpu.c cpuid and common x86 cpu functionality host-cpu.c host x86 cpu functions and "host" cpu type kvm/kvm-cpu.c KVM x86 AccelCPUClass hvf/hvf-cpu.c HVF x86 AccelCPUClass tcg/tcg-cpu.c TCG x86 AccelCPUClass Signed-off-by: Claudio Fontana Reviewed-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- target/i386/cpu.h | 20 +- target/i386/host-cpu.h | 19 ++ target/i386/kvm/kvm-cpu.h | 41 ++++ target/i386/tcg/tcg-cpu.h | 15 -- hw/i386/pc_piix.c | 1 + target/i386/cpu.c | 390 ++++-------------------------------- target/i386/host-cpu.c | 201 +++++++++++++++++++ target/i386/hvf/hvf-cpu.c | 68 +++++++ target/i386/kvm/kvm-cpu.c | 151 ++++++++++++++ target/i386/kvm/kvm.c | 3 +- target/i386/tcg/tcg-cpu.c | 113 ++++++++++- MAINTAINERS | 2 +- target/i386/hvf/meson.build | 1 + target/i386/kvm/meson.build | 7 +- target/i386/meson.build | 6 +- 15 files changed, 651 insertions(+), 387 deletions(-) create mode 100644 target/i386/host-cpu.h create mode 100644 target/i386/kvm/kvm-cpu.h delete mode 100644 target/i386/tcg/tcg-cpu.h create mode 100644 target/i386/host-cpu.c create mode 100644 target/i386/hvf/hvf-cpu.c create mode 100644 target/i386/kvm/kvm-cpu.c diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 8be39cfb62..c8a84a9033 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1925,13 +1925,20 @@ int cpu_x86_signal_handler(int host_signum, void *p= info, void *puc); =20 /* cpu.c */ +void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, + uint32_t vendor2, uint32_t vendor3); +typedef struct PropValue { + const char *prop, *value; +} PropValue; +void x86_cpu_apply_props(X86CPU *cpu, PropValue *props); + +/* cpu.c other functions (cpuid) */ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx); void cpu_clear_apic_feature(CPUX86State *env); void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx= ); -void host_vendor_fms(char *vendor, int *family, int *model, int *stepping); =20 /* helper.c */ void x86_cpu_set_a20(X86CPU *cpu, int a20_state); @@ -2136,17 +2143,6 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAcce= ss access); void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip, TPRAccess access); =20 - -/* Change the value of a KVM-specific default - * - * If value is NULL, no default will be set and the original - * value from the CPU model table will be kept. - * - * It is valid to call this function only for properties that - * are already present in the kvm_default_props table. - */ -void x86_cpu_change_kvm_default(const char *prop, const char *value); - /* Special values for X86CPUVersion: */ =20 /* Resolve to latest CPU version */ diff --git a/target/i386/host-cpu.h b/target/i386/host-cpu.h new file mode 100644 index 0000000000..b47bc0943f --- /dev/null +++ b/target/i386/host-cpu.h @@ -0,0 +1,19 @@ +/* + * x86 host CPU type initialization and host CPU functions + * + * Copyright 2021 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef HOST_CPU_H +#define HOST_CPU_H + +void host_cpu_instance_init(X86CPU *cpu); +void host_cpu_max_instance_init(X86CPU *cpu); +void host_cpu_realizefn(CPUState *cs, Error **errp); + +void host_cpu_vendor_fms(char *vendor, int *family, int *model, int *stepp= ing); + +#endif /* HOST_CPU_H */ diff --git a/target/i386/kvm/kvm-cpu.h b/target/i386/kvm/kvm-cpu.h new file mode 100644 index 0000000000..e858ca21e5 --- /dev/null +++ b/target/i386/kvm/kvm-cpu.h @@ -0,0 +1,41 @@ +/* + * i386 KVM CPU type and functions + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef KVM_CPU_H +#define KVM_CPU_H + +#ifdef CONFIG_KVM +/* + * Change the value of a KVM-specific default + * + * If value is NULL, no default will be set and the original + * value from the CPU model table will be kept. + * + * It is valid to call this function only for properties that + * are already present in the kvm_default_props table. + */ +void x86_cpu_change_kvm_default(const char *prop, const char *value); + +#else /* !CONFIG_KVM */ + +#define x86_cpu_change_kvm_default(a, b) + +#endif /* CONFIG_KVM */ + +#endif /* KVM_CPU_H */ diff --git a/target/i386/tcg/tcg-cpu.h b/target/i386/tcg/tcg-cpu.h deleted file mode 100644 index 81f02e562e..0000000000 --- a/target/i386/tcg/tcg-cpu.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * i386 TCG CPU class initialization - * - * Copyright 2020 SUSE LLC - * - * This work is licensed under the terms of the GNU GPL, version 2 or late= r. - * See the COPYING file in the top-level directory. - */ - -#ifndef TCG_CPU_H -#define TCG_CPU_H - -void tcg_cpu_common_class_init(CPUClass *cc); - -#endif /* TCG_CPU_H */ diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 2904b40163..7772880c04 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -64,6 +64,7 @@ #include "hw/hyperv/vmbus-bridge.h" #include "hw/mem/nvdimm.h" #include "hw/i386/acpi-build.h" +#include "kvm/kvm-cpu.h" =20 #define MAX_IDE_BUS 2 =20 diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6a53446e6a..648e41791f 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -22,38 +22,25 @@ #include "qemu/cutils.h" #include "qemu/bitops.h" #include "qemu/qemu-print.h" - #include "cpu.h" -#include "tcg/tcg-cpu.h" #include "tcg/helper-tcg.h" #include "exec/exec-all.h" #include "sysemu/kvm.h" #include "sysemu/reset.h" #include "sysemu/hvf.h" -#include "sysemu/cpus.h" +#include "hw/core/accel-cpu.h" #include "sysemu/xen.h" #include "sysemu/whpx.h" #include "kvm/kvm_i386.h" #include "sev_i386.h" - -#include "qemu/error-report.h" #include "qemu/module.h" -#include "qemu/option.h" -#include "qemu/config-file.h" -#include "qapi/error.h" #include "qapi/qapi-visit-machine.h" #include "qapi/qapi-visit-run-state.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qerror.h" -#include "qapi/visitor.h" #include "qom/qom-qobject.h" -#include "sysemu/arch_init.h" #include "qapi/qapi-commands-machine-target.h" - #include "standard-headers/asm-x86/kvm_para.h" - -#include "sysemu/sysemu.h" -#include "sysemu/tcg.h" #include "hw/qdev-properties.h" #include "hw/i386/topology.h" #ifndef CONFIG_USER_ONLY @@ -595,8 +582,8 @@ static CPUCacheInfo legacy_l3_cache =3D { #define INTEL_PT_CYCLE_BITMAP 0x1fff /* Support 0,2^(0~11) */ #define INTEL_PT_PSB_BITMAP (0x003f << 16) /* Support 2K,4K,8K,16K,32= K,64K */ =20 -static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, - uint32_t vendor2, uint32_t vendor3) +void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, + uint32_t vendor2, uint32_t vendor3) { int i; for (i =3D 0; i < 4; i++) { @@ -1589,25 +1576,6 @@ void host_cpuid(uint32_t function, uint32_t count, *edx =3D vec[3]; } =20 -void host_vendor_fms(char *vendor, int *family, int *model, int *stepping) -{ - uint32_t eax, ebx, ecx, edx; - - host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx); - x86_cpu_vendor_words2str(vendor, ebx, edx, ecx); - - host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx); - if (family) { - *family =3D ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF); - } - if (model) { - *model =3D ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12); - } - if (stepping) { - *stepping =3D eax & 0x0F; - } -} - /* CPU class name definitions: */ =20 /* Return type name for a given CPU model name @@ -1632,10 +1600,6 @@ static char *x86_cpu_class_get_model_name(X86CPUClas= s *cc) strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX)); } =20 -typedef struct PropValue { - const char *prop, *value; -} PropValue; - typedef struct X86CPUVersionDefinition { X86CPUVersion version; const char *alias; @@ -4237,32 +4201,6 @@ static X86CPUDefinition builtin_x86_defs[] =3D { }, }; =20 -/* KVM-specific features that are automatically added/removed - * from all CPU models when KVM is enabled. - */ -static PropValue kvm_default_props[] =3D { - { "kvmclock", "on" }, - { "kvm-nopiodelay", "on" }, - { "kvm-asyncpf", "on" }, - { "kvm-steal-time", "on" }, - { "kvm-pv-eoi", "on" }, - { "kvmclock-stable-bit", "on" }, - { "x2apic", "on" }, - { "kvm-msi-ext-dest-id", "off" }, - { "acpi", "off" }, - { "monitor", "off" }, - { "svm", "off" }, - { NULL, NULL }, -}; - -/* TCG-specific defaults that override all CPU models when using TCG - */ -static PropValue tcg_default_props[] =3D { - { "vme", "off" }, - { NULL, NULL }, -}; - - /* * We resolve CPU model aliases using -v1 when using "-machine * none", but this is just for compatibility while libvirt isn't @@ -4304,61 +4242,6 @@ static X86CPUVersion x86_cpu_model_resolve_version(c= onst X86CPUModel *model) return v; } =20 -void x86_cpu_change_kvm_default(const char *prop, const char *value) -{ - PropValue *pv; - for (pv =3D kvm_default_props; pv->prop; pv++) { - if (!strcmp(pv->prop, prop)) { - pv->value =3D value; - break; - } - } - - /* It is valid to call this function only for properties that - * are already present in the kvm_default_props table. - */ - assert(pv->prop); -} - -static bool lmce_supported(void) -{ - uint64_t mce_cap =3D 0; - -#ifdef CONFIG_KVM - if (kvm_ioctl(kvm_state, KVM_X86_GET_MCE_CAP_SUPPORTED, &mce_cap) < 0)= { - return false; - } -#endif - - return !!(mce_cap & MCG_LMCE_P); -} - -#define CPUID_MODEL_ID_SZ 48 - -/** - * cpu_x86_fill_model_id: - * Get CPUID model ID string from host CPU. - * - * @str should have at least CPUID_MODEL_ID_SZ bytes - * - * The function does NOT add a null terminator to the string - * automatically. - */ -static int cpu_x86_fill_model_id(char *str) -{ - uint32_t eax =3D 0, ebx =3D 0, ecx =3D 0, edx =3D 0; - int i; - - for (i =3D 0; i < 3; i++) { - host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx); - memcpy(str + i * 16 + 0, &eax, 4); - memcpy(str + i * 16 + 4, &ebx, 4); - memcpy(str + i * 16 + 8, &ecx, 4); - memcpy(str + i * 16 + 12, &edx, 4); - } - return 0; -} - static Property max_x86_cpu_properties[] =3D { DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true), DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, fa= lse), @@ -4381,62 +4264,25 @@ static void max_x86_cpu_class_init(ObjectClass *oc,= void *data) static void max_x86_cpu_initfn(Object *obj) { X86CPU *cpu =3D X86_CPU(obj); - CPUX86State *env =3D &cpu->env; - KVMState *s =3D kvm_state; =20 /* We can't fill the features array here because we don't know yet if * "migratable" is true or false. */ cpu->max_features =3D true; - - if (accel_uses_host_cpuid()) { - char vendor[CPUID_VENDOR_SZ + 1] =3D { 0 }; - char model_id[CPUID_MODEL_ID_SZ + 1] =3D { 0 }; - int family, model, stepping; - - host_vendor_fms(vendor, &family, &model, &stepping); - cpu_x86_fill_model_id(model_id); - - object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abor= t); - object_property_set_int(OBJECT(cpu), "family", family, &error_abor= t); - object_property_set_int(OBJECT(cpu), "model", model, &error_abort); - object_property_set_int(OBJECT(cpu), "stepping", stepping, - &error_abort); - object_property_set_str(OBJECT(cpu), "model-id", model_id, - &error_abort); - - if (kvm_enabled()) { - env->cpuid_min_level =3D - kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX); - env->cpuid_min_xlevel =3D - kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX); - env->cpuid_min_xlevel2 =3D - kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX); - } else { - env->cpuid_min_level =3D - hvf_get_supported_cpuid(0x0, 0, R_EAX); - env->cpuid_min_xlevel =3D - hvf_get_supported_cpuid(0x80000000, 0, R_EAX); - env->cpuid_min_xlevel2 =3D - hvf_get_supported_cpuid(0xC0000000, 0, R_EAX); - } - - if (lmce_supported()) { - object_property_set_bool(OBJECT(cpu), "lmce", true, &error_abo= rt); - } - object_property_set_bool(OBJECT(cpu), "host-phys-bits", true, &err= or_abort); - } else { - object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD, - &error_abort); - object_property_set_int(OBJECT(cpu), "family", 6, &error_abort); - object_property_set_int(OBJECT(cpu), "model", 6, &error_abort); - object_property_set_int(OBJECT(cpu), "stepping", 3, &error_abort); - object_property_set_str(OBJECT(cpu), "model-id", - "QEMU TCG CPU version " QEMU_HW_VERSION, - &error_abort); - } - object_property_set_bool(OBJECT(cpu), "pmu", true, &error_abort); + + /* + * these defaults are used for TCG and all other accelerators + * besides KVM and HVF, which overwrite these values + */ + object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD, + &error_abort); + object_property_set_int(OBJECT(cpu), "family", 6, &error_abort); + object_property_set_int(OBJECT(cpu), "model", 6, &error_abort); + object_property_set_int(OBJECT(cpu), "stepping", 3, &error_abort); + object_property_set_str(OBJECT(cpu), "model-id", + "QEMU TCG CPU version " QEMU_HW_VERSION, + &error_abort); } =20 static const TypeInfo max_x86_cpu_type_info =3D { @@ -4446,31 +4292,6 @@ static const TypeInfo max_x86_cpu_type_info =3D { .class_init =3D max_x86_cpu_class_init, }; =20 -#if defined(CONFIG_KVM) || defined(CONFIG_HVF) -static void host_x86_cpu_class_init(ObjectClass *oc, void *data) -{ - X86CPUClass *xcc =3D X86_CPU_CLASS(oc); - - xcc->host_cpuid_required =3D true; - xcc->ordering =3D 8; - -#if defined(CONFIG_KVM) - xcc->model_description =3D - "KVM processor with all supported host features "; -#elif defined(CONFIG_HVF) - xcc->model_description =3D - "HVF processor with all supported host features "; -#endif -} - -static const TypeInfo host_x86_cpu_type_info =3D { - .name =3D X86_CPU_TYPE_NAME("host"), - .parent =3D X86_CPU_TYPE_NAME("max"), - .class_init =3D host_x86_cpu_class_init, -}; - -#endif - static char *feature_word_description(FeatureWordInfo *f, uint32_t bit) { assert(f->type =3D=3D CPUID_FEATURE_WORD || f->type =3D=3D MSR_FEATURE= _WORD); @@ -5189,7 +5010,7 @@ static uint64_t x86_cpu_get_supported_feature_word(Fe= atureWord w, return r; } =20 -static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props) +void x86_cpu_apply_props(X86CPU *cpu, PropValue *props) { PropValue *pv; for (pv =3D props; pv->prop; pv++) { @@ -5236,8 +5057,6 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUMod= el *model) { X86CPUDefinition *def =3D model->cpudef; CPUX86State *env =3D &cpu->env; - const char *vendor; - char host_vendor[CPUID_VENDOR_SZ + 1]; FeatureWord w; =20 /*NOTE: any property set by this function should be returned by @@ -5264,20 +5083,6 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUMo= del *model) /* legacy-cache defaults to 'off' if CPU model provides cache info */ cpu->legacy_cache =3D !def->cache_info; =20 - /* Special cases not set in the X86CPUDefinition structs: */ - /* TODO: in-kernel irqchip for hvf */ - if (kvm_enabled()) { - if (!kvm_irqchip_in_kernel()) { - x86_cpu_change_kvm_default("x2apic", "off"); - } else if (kvm_irqchip_is_split() && kvm_enable_x2apic()) { - x86_cpu_change_kvm_default("kvm-msi-ext-dest-id", "on"); - } - - x86_cpu_apply_props(cpu, kvm_default_props); - } else if (tcg_enabled()) { - x86_cpu_apply_props(cpu, tcg_default_props); - } - env->features[FEAT_1_ECX] |=3D CPUID_EXT_HYPERVISOR; =20 /* sysenter isn't supported in compatibility mode on AMD, @@ -5287,15 +5092,12 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUM= odel *model) * KVM's sysenter/syscall emulation in compatibility mode and * when doing cross vendor migration */ - vendor =3D def->vendor; - if (accel_uses_host_cpuid()) { - uint32_t ebx =3D 0, ecx =3D 0, edx =3D 0; - host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); - x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx); - vendor =3D host_vendor; - } =20 - object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort); + /* + * vendor property is set here but then overloaded with the + * host cpu vendor for KVM and HVF. + */ + object_property_set_str(OBJECT(cpu), "vendor", def->vendor, &error_abo= rt); =20 x86_cpu_apply_version_props(cpu, model); =20 @@ -6326,53 +6128,12 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error= **errp) apic_mmio_map_once =3D true; } } - -static void x86_cpu_machine_done(Notifier *n, void *unused) -{ - X86CPU *cpu =3D container_of(n, X86CPU, machine_done); - MemoryRegion *smram =3D - (MemoryRegion *) object_resolve_path("/machine/smram", NULL); - - if (smram) { - cpu->smram =3D g_new(MemoryRegion, 1); - memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram", - smram, 0, 4 * GiB); - memory_region_set_enabled(cpu->smram, true); - memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smra= m, 1); - } -} #else static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) { } #endif =20 -/* Note: Only safe for use on x86(-64) hosts */ -static uint32_t x86_host_phys_bits(void) -{ - uint32_t eax; - uint32_t host_phys_bits; - - host_cpuid(0x80000000, 0, &eax, NULL, NULL, NULL); - if (eax >=3D 0x80000008) { - host_cpuid(0x80000008, 0, &eax, NULL, NULL, NULL); - /* Note: According to AMD doc 25481 rev 2.34 they have a field - * at 23:16 that can specify a maximum physical address bits for - * the guest that can override this value; but I've not seen - * anything with that set. - */ - host_phys_bits =3D eax & 0xff; - } else { - /* It's an odd 64 bit machine that doesn't have the leaf for - * physical address bits; fall back to 36 that's most older - * Intel. - */ - host_phys_bits =3D 36; - } - - return host_phys_bits; -} - static void x86_cpu_adjust_level(X86CPU *cpu, uint32_t *min, uint32_t valu= e) { if (*min < value) { @@ -6684,33 +6445,22 @@ static void x86_cpu_hyperv_realize(X86CPU *cpu) static void x86_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs =3D CPU(dev); + CPUClass *cc =3D CPU_GET_CLASS(cs); X86CPU *cpu =3D X86_CPU(dev); X86CPUClass *xcc =3D X86_CPU_GET_CLASS(dev); CPUX86State *env =3D &cpu->env; Error *local_err =3D NULL; static bool ht_warned; =20 - if (xcc->host_cpuid_required) { - if (!accel_uses_host_cpuid()) { - g_autofree char *name =3D x86_cpu_class_get_model_name(xcc); - error_setg(&local_err, "CPU model '%s' requires KVM", name); - goto out; - } + /* The accelerator realizefn needs to be called first. */ + if (cc->accel_cpu) { + cc->accel_cpu->cpu_realizefn(cs, errp); } =20 - if (cpu->max_features && accel_uses_host_cpuid()) { - if (enable_cpu_pm) { - host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx, - &cpu->mwait.ecx, &cpu->mwait.edx); - env->features[FEAT_1_ECX] |=3D CPUID_EXT_MONITOR; - if (kvm_enabled() && kvm_has_waitpkg()) { - env->features[FEAT_7_0_ECX] |=3D CPUID_7_0_ECX_WAITPKG; - } - } - if (kvm_enabled() && cpu->ucode_rev =3D=3D 0) { - cpu->ucode_rev =3D kvm_arch_get_supported_msr_feature(kvm_stat= e, - MSR_IA32_U= CODE_REV); - } + if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) { + g_autofree char *name =3D x86_cpu_class_get_model_name(xcc); + error_setg(&local_err, "CPU model '%s' requires KVM or HVF", name); + goto out; } =20 if (cpu->ucode_rev =3D=3D 0) { @@ -6762,39 +6512,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Erro= r **errp) * consumer AMD devices but nothing else. */ if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { - if (accel_uses_host_cpuid()) { - uint32_t host_phys_bits =3D x86_host_phys_bits(); - static bool warned; - - /* Print a warning if the user set it to a value that's not the - * host value. - */ - if (cpu->phys_bits !=3D host_phys_bits && cpu->phys_bits !=3D = 0 && - !warned) { - warn_report("Host physical bits (%u)" - " does not match phys-bits property (%u)", - host_phys_bits, cpu->phys_bits); - warned =3D true; - } - - if (cpu->host_phys_bits) { - /* The user asked for us to use the host physical bits */ - cpu->phys_bits =3D host_phys_bits; - if (cpu->host_phys_bits_limit && - cpu->phys_bits > cpu->host_phys_bits_limit) { - cpu->phys_bits =3D cpu->host_phys_bits_limit; - } - } - - if (cpu->phys_bits && - (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS || - cpu->phys_bits < 32)) { - error_setg(errp, "phys-bits should be between 32 and %u " - " (but is %u)", - TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bi= ts); - return; - } - } else { + if (!accel_uses_host_cpuid()) { if (cpu->phys_bits && cpu->phys_bits !=3D TCG_PHYS_ADDR_BITS) { error_setg(errp, "TCG only supports phys-bits=3D%u", TCG_PHYS_ADDR_BITS); @@ -6802,8 +6520,8 @@ static void x86_cpu_realizefn(DeviceState *dev, Error= **errp) } } /* 0 means it was not explicitly set by the user (or by machine - * compat_props or by the host code above). In this case, the defa= ult - * is the value used by TCG (40). + * compat_props or by the host code in host-cpu.c). + * In this case, the default is the value used by TCG (40). */ if (cpu->phys_bits =3D=3D 0) { cpu->phys_bits =3D TCG_PHYS_ADDR_BITS; @@ -6875,33 +6593,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Erro= r **errp) =20 mce_init(cpu); =20 -#ifndef CONFIG_USER_ONLY - if (tcg_enabled()) { - cpu->cpu_as_mem =3D g_new(MemoryRegion, 1); - cpu->cpu_as_root =3D g_new(MemoryRegion, 1); - - /* Outer container... */ - memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull); - memory_region_set_enabled(cpu->cpu_as_root, true); - - /* ... with two regions inside: normal system memory with low - * priority, and... - */ - memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory", - get_system_memory(), 0, ~0ull); - memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_= as_mem, 0); - memory_region_set_enabled(cpu->cpu_as_mem, true); - - cs->num_ases =3D 2; - cpu_address_space_init(cs, 0, "cpu-memory", cs->memory); - cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root); - - /* ... SMRAM with higher priority, linked from /machine/smram. */ - cpu->machine_done.notify =3D x86_cpu_machine_done; - qemu_add_machine_init_done_notifier(&cpu->machine_done); - } -#endif - qemu_init_vcpu(cs); =20 /* @@ -7101,6 +6792,8 @@ static void x86_cpu_initfn(Object *obj) { X86CPU *cpu =3D X86_CPU(obj); X86CPUClass *xcc =3D X86_CPU_GET_CLASS(obj); + CPUClass *cc =3D CPU_CLASS(xcc); + CPUX86State *env =3D &cpu->env; =20 env->nr_dies =3D 1; @@ -7148,6 +6841,11 @@ static void x86_cpu_initfn(Object *obj) if (xcc->model) { x86_cpu_load_model(cpu, xcc->model); } + + /* if required, do the accelerator-specific cpu initialization */ + if (cc->accel_cpu) { + cc->accel_cpu->cpu_instance_init(CPU(obj)); + } } =20 static int64_t x86_cpu_get_arch_id(CPUState *cs) @@ -7405,11 +7103,6 @@ static void x86_cpu_common_class_init(ObjectClass *o= c, void *data) cc->class_by_name =3D x86_cpu_class_by_name; cc->parse_features =3D x86_cpu_parse_featurestr; cc->has_work =3D x86_cpu_has_work; - -#ifdef CONFIG_TCG - tcg_cpu_common_class_init(cc); -#endif /* CONFIG_TCG */ - cc->dump_state =3D x86_cpu_dump_state; cc->set_pc =3D x86_cpu_set_pc; cc->gdb_read_register =3D x86_cpu_gdb_read_register; @@ -7520,9 +7213,6 @@ static void x86_cpu_register_types(void) } type_register_static(&max_x86_cpu_type_info); type_register_static(&x86_base_cpu_type_info); -#if defined(CONFIG_KVM) || defined(CONFIG_HVF) - type_register_static(&host_x86_cpu_type_info); -#endif } =20 type_init(x86_cpu_register_types) diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c new file mode 100644 index 0000000000..9cfe56ce41 --- /dev/null +++ b/target/i386/host-cpu.c @@ -0,0 +1,201 @@ +/* + * x86 host CPU functions, and "host" cpu type initialization + * + * Copyright 2021 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "host-cpu.h" +#include "qapi/error.h" +#include "sysemu/sysemu.h" + +/* Note: Only safe for use on x86(-64) hosts */ +static uint32_t host_cpu_phys_bits(void) +{ + uint32_t eax; + uint32_t host_phys_bits; + + host_cpuid(0x80000000, 0, &eax, NULL, NULL, NULL); + if (eax >=3D 0x80000008) { + host_cpuid(0x80000008, 0, &eax, NULL, NULL, NULL); + /* + * Note: According to AMD doc 25481 rev 2.34 they have a field + * at 23:16 that can specify a maximum physical address bits for + * the guest that can override this value; but I've not seen + * anything with that set. + */ + host_phys_bits =3D eax & 0xff; + } else { + /* + * It's an odd 64 bit machine that doesn't have the leaf for + * physical address bits; fall back to 36 that's most older + * Intel. + */ + host_phys_bits =3D 36; + } + + return host_phys_bits; +} + +static void host_cpu_enable_cpu_pm(X86CPU *cpu) +{ + CPUX86State *env =3D &cpu->env; + + host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx, + &cpu->mwait.ecx, &cpu->mwait.edx); + env->features[FEAT_1_ECX] |=3D CPUID_EXT_MONITOR; +} + +static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu, Error **errp) +{ + uint32_t host_phys_bits =3D host_cpu_phys_bits(); + uint32_t phys_bits =3D cpu->phys_bits; + static bool warned; + + /* + * Print a warning if the user set it to a value that's not the + * host value. + */ + if (phys_bits !=3D host_phys_bits && phys_bits !=3D 0 && + !warned) { + warn_report("Host physical bits (%u)" + " does not match phys-bits property (%u)", + host_phys_bits, phys_bits); + warned =3D true; + } + + if (cpu->host_phys_bits) { + /* The user asked for us to use the host physical bits */ + phys_bits =3D host_phys_bits; + if (cpu->host_phys_bits_limit && + phys_bits > cpu->host_phys_bits_limit) { + phys_bits =3D cpu->host_phys_bits_limit; + } + } + + if (phys_bits && + (phys_bits > TARGET_PHYS_ADDR_SPACE_BITS || + phys_bits < 32)) { + error_setg(errp, "phys-bits should be between 32 and %u " + " (but is %u)", + TARGET_PHYS_ADDR_SPACE_BITS, phys_bits); + } + + return phys_bits; +} + +void host_cpu_realizefn(CPUState *cs, Error **errp) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + if (cpu->max_features && enable_cpu_pm) { + host_cpu_enable_cpu_pm(cpu); + } + if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { + cpu->phys_bits =3D host_cpu_adjust_phys_bits(cpu, errp); + } +} + +#define CPUID_MODEL_ID_SZ 48 +/** + * cpu_x86_fill_model_id: + * Get CPUID model ID string from host CPU. + * + * @str should have at least CPUID_MODEL_ID_SZ bytes + * + * The function does NOT add a null terminator to the string + * automatically. + */ +static int host_cpu_fill_model_id(char *str) +{ + uint32_t eax =3D 0, ebx =3D 0, ecx =3D 0, edx =3D 0; + int i; + + for (i =3D 0; i < 3; i++) { + host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx); + memcpy(str + i * 16 + 0, &eax, 4); + memcpy(str + i * 16 + 4, &ebx, 4); + memcpy(str + i * 16 + 8, &ecx, 4); + memcpy(str + i * 16 + 12, &edx, 4); + } + return 0; +} + +void host_cpu_vendor_fms(char *vendor, int *family, int *model, int *stepp= ing) +{ + uint32_t eax, ebx, ecx, edx; + + host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx); + x86_cpu_vendor_words2str(vendor, ebx, edx, ecx); + + host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx); + if (family) { + *family =3D ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF); + } + if (model) { + *model =3D ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12); + } + if (stepping) { + *stepping =3D eax & 0x0F; + } +} + +void host_cpu_instance_init(X86CPU *cpu) +{ + uint32_t ebx =3D 0, ecx =3D 0, edx =3D 0; + char vendor[CPUID_VENDOR_SZ + 1]; + + host_cpuid(0, 0, NULL, &ebx, &ecx, &edx); + x86_cpu_vendor_words2str(vendor, ebx, edx, ecx); + + object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort); +} + +void host_cpu_max_instance_init(X86CPU *cpu) +{ + char vendor[CPUID_VENDOR_SZ + 1] =3D { 0 }; + char model_id[CPUID_MODEL_ID_SZ + 1] =3D { 0 }; + int family, model, stepping; + + /* Use max host physical address bits if -cpu max option is applied */ + object_property_set_bool(OBJECT(cpu), "host-phys-bits", true, &error_a= bort); + + host_cpu_vendor_fms(vendor, &family, &model, &stepping); + host_cpu_fill_model_id(model_id); + + object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort); + object_property_set_int(OBJECT(cpu), "family", family, &error_abort); + object_property_set_int(OBJECT(cpu), "model", model, &error_abort); + object_property_set_int(OBJECT(cpu), "stepping", stepping, + &error_abort); + object_property_set_str(OBJECT(cpu), "model-id", model_id, + &error_abort); +} + +static void host_cpu_class_init(ObjectClass *oc, void *data) +{ + X86CPUClass *xcc =3D X86_CPU_CLASS(oc); + + xcc->host_cpuid_required =3D true; + xcc->ordering =3D 8; + xcc->model_description =3D + g_strdup_printf("processor with all supported host features "); +} + +static const TypeInfo host_cpu_type_info =3D { + .name =3D X86_CPU_TYPE_NAME("host"), + .parent =3D X86_CPU_TYPE_NAME("max"), + .class_init =3D host_cpu_class_init, +}; + +static void host_cpu_type_init(void) +{ + type_register_static(&host_cpu_type_info); +} + +type_init(host_cpu_type_init); diff --git a/target/i386/hvf/hvf-cpu.c b/target/i386/hvf/hvf-cpu.c new file mode 100644 index 0000000000..8fbc423888 --- /dev/null +++ b/target/i386/hvf/hvf-cpu.c @@ -0,0 +1,68 @@ +/* + * x86 HVF CPU type initialization + * + * Copyright 2021 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "host-cpu.h" +#include "qapi/error.h" +#include "sysemu/sysemu.h" +#include "hw/boards.h" +#include "sysemu/hvf.h" +#include "hw/core/accel-cpu.h" + +static void hvf_cpu_max_instance_init(X86CPU *cpu) +{ + CPUX86State *env =3D &cpu->env; + + host_cpu_max_instance_init(cpu); + + env->cpuid_min_level =3D + hvf_get_supported_cpuid(0x0, 0, R_EAX); + env->cpuid_min_xlevel =3D + hvf_get_supported_cpuid(0x80000000, 0, R_EAX); + env->cpuid_min_xlevel2 =3D + hvf_get_supported_cpuid(0xC0000000, 0, R_EAX); +} + +static void hvf_cpu_instance_init(CPUState *cs) +{ + X86CPU *cpu =3D X86_CPU(cs); + + host_cpu_instance_init(cpu); + + /* Special cases not set in the X86CPUDefinition structs: */ + /* TODO: in-kernel irqchip for hvf */ + + if (cpu->max_features) { + hvf_cpu_max_instance_init(cpu); + } +} + +static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data) +{ + AccelCPUClass *acc =3D ACCEL_CPU_CLASS(oc); + + acc->cpu_realizefn =3D host_cpu_realizefn; + acc->cpu_instance_init =3D hvf_cpu_instance_init; +} + +static const TypeInfo hvf_cpu_accel_type_info =3D { + .name =3D ACCEL_CPU_NAME("hvf"), + + .parent =3D TYPE_ACCEL_CPU, + .class_init =3D hvf_cpu_accel_class_init, + .abstract =3D true, +}; + +static void hvf_cpu_accel_register_types(void) +{ + type_register_static(&hvf_cpu_accel_type_info); +} + +type_init(hvf_cpu_accel_register_types); diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c new file mode 100644 index 0000000000..c23bbe6c50 --- /dev/null +++ b/target/i386/kvm/kvm-cpu.c @@ -0,0 +1,151 @@ +/* + * x86 KVM CPU type initialization + * + * Copyright 2021 SUSE LLC + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "host-cpu.h" +#include "kvm-cpu.h" +#include "qapi/error.h" +#include "sysemu/sysemu.h" +#include "hw/boards.h" + +#include "kvm_i386.h" +#include "hw/core/accel-cpu.h" + +static void kvm_cpu_realizefn(CPUState *cs, Error **errp) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + /* + * The realize order is important, since x86_cpu_realize() checks if + * nothing else has been set by the user (or by accelerators) in + * cpu->ucode_rev and cpu->phys_bits. + * + * realize order: + * kvm_cpu -> host_cpu -> x86_cpu + */ + if (cpu->max_features) { + if (enable_cpu_pm && kvm_has_waitpkg()) { + env->features[FEAT_7_0_ECX] |=3D CPUID_7_0_ECX_WAITPKG; + } + if (cpu->ucode_rev =3D=3D 0) { + cpu->ucode_rev =3D + kvm_arch_get_supported_msr_feature(kvm_state, + MSR_IA32_UCODE_REV); + } + } + host_cpu_realizefn(cs, errp); +} + +/* + * KVM-specific features that are automatically added/removed + * from all CPU models when KVM is enabled. + */ +static PropValue kvm_default_props[] =3D { + { "kvmclock", "on" }, + { "kvm-nopiodelay", "on" }, + { "kvm-asyncpf", "on" }, + { "kvm-steal-time", "on" }, + { "kvm-pv-eoi", "on" }, + { "kvmclock-stable-bit", "on" }, + { "x2apic", "on" }, + { "kvm-msi-ext-dest-id", "off" }, + { "acpi", "off" }, + { "monitor", "off" }, + { "svm", "off" }, + { NULL, NULL }, +}; + +void x86_cpu_change_kvm_default(const char *prop, const char *value) +{ + PropValue *pv; + for (pv =3D kvm_default_props; pv->prop; pv++) { + if (!strcmp(pv->prop, prop)) { + pv->value =3D value; + break; + } + } + + /* + * It is valid to call this function only for properties that + * are already present in the kvm_default_props table. + */ + assert(pv->prop); +} + +static bool lmce_supported(void) +{ + uint64_t mce_cap =3D 0; + + if (kvm_ioctl(kvm_state, KVM_X86_GET_MCE_CAP_SUPPORTED, &mce_cap) < 0)= { + return false; + } + return !!(mce_cap & MCG_LMCE_P); +} + +static void kvm_cpu_max_instance_init(X86CPU *cpu) +{ + CPUX86State *env =3D &cpu->env; + KVMState *s =3D kvm_state; + + host_cpu_max_instance_init(cpu); + + if (lmce_supported()) { + object_property_set_bool(OBJECT(cpu), "lmce", true, &error_abort); + } + + env->cpuid_min_level =3D + kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX); + env->cpuid_min_xlevel =3D + kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX); + env->cpuid_min_xlevel2 =3D + kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX); +} + +static void kvm_cpu_instance_init(CPUState *cs) +{ + X86CPU *cpu =3D X86_CPU(cs); + + host_cpu_instance_init(cpu); + + if (!kvm_irqchip_in_kernel()) { + x86_cpu_change_kvm_default("x2apic", "off"); + } else if (kvm_irqchip_is_split() && kvm_enable_x2apic()) { + x86_cpu_change_kvm_default("kvm-msi-ext-dest-id", "on"); + } + + /* Special cases not set in the X86CPUDefinition structs: */ + + x86_cpu_apply_props(cpu, kvm_default_props); + + if (cpu->max_features) { + kvm_cpu_max_instance_init(cpu); + } +} + +static void kvm_cpu_accel_class_init(ObjectClass *oc, void *data) +{ + AccelCPUClass *acc =3D ACCEL_CPU_CLASS(oc); + + acc->cpu_realizefn =3D kvm_cpu_realizefn; + acc->cpu_instance_init =3D kvm_cpu_instance_init; +} +static const TypeInfo kvm_cpu_accel_type_info =3D { + .name =3D ACCEL_CPU_NAME("kvm"), + + .parent =3D TYPE_ACCEL_CPU, + .class_init =3D kvm_cpu_accel_class_init, + .abstract =3D true, +}; +static void kvm_cpu_accel_register_types(void) +{ + type_register_static(&kvm_cpu_accel_type_info); +} +type_init(kvm_cpu_accel_register_types); diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 0b5755e42b..5064f904c5 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -22,6 +22,7 @@ #include "standard-headers/asm-x86/kvm_para.h" =20 #include "cpu.h" +#include "host-cpu.h" #include "sysemu/sysemu.h" #include "sysemu/hw_accel.h" #include "sysemu/kvm_int.h" @@ -288,7 +289,7 @@ static bool host_tsx_broken(void) int family, model, stepping;\ char vendor[CPUID_VENDOR_SZ + 1]; =20 - host_vendor_fms(vendor, &family, &model, &stepping); + host_cpu_vendor_fms(vendor, &family, &model, &stepping); =20 /* Check if we are running on a Haswell host known to have broken TSX = */ return !strcmp(vendor, CPUID_VENDOR_INTEL) && diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c index 1e125d2175..1d3d6d1c6a 100644 --- a/target/i386/tcg/tcg-cpu.c +++ b/target/i386/tcg/tcg-cpu.c @@ -19,13 +19,14 @@ =20 #include "qemu/osdep.h" #include "cpu.h" -#include "tcg-cpu.h" -#include "exec/exec-all.h" -#include "sysemu/runstate.h" #include "helper-tcg.h" +#include "qemu/accel.h" +#include "hw/core/accel-cpu.h" =20 -#if !defined(CONFIG_USER_ONLY) -#include "hw/i386/apic.h" +#ifndef CONFIG_USER_ONLY +#include "sysemu/sysemu.h" +#include "qemu/units.h" +#include "exec/address-spaces.h" #endif =20 /* Frob eflags into and out of the CPU temporary format. */ @@ -72,7 +73,107 @@ static struct TCGCPUOps x86_tcg_ops =3D { #endif /* !CONFIG_USER_ONLY */ }; =20 -void tcg_cpu_common_class_init(CPUClass *cc) +static void tcg_cpu_class_init(CPUClass *cc) { cc->tcg_ops =3D &x86_tcg_ops; } + +#ifndef CONFIG_USER_ONLY + +static void x86_cpu_machine_done(Notifier *n, void *unused) +{ + X86CPU *cpu =3D container_of(n, X86CPU, machine_done); + MemoryRegion *smram =3D + (MemoryRegion *) object_resolve_path("/machine/smram", NULL); + + if (smram) { + cpu->smram =3D g_new(MemoryRegion, 1); + memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram", + smram, 0, 4 * GiB); + memory_region_set_enabled(cpu->smram, true); + memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, + cpu->smram, 1); + } +} + +static void tcg_cpu_realizefn(CPUState *cs, Error **errp) +{ + X86CPU *cpu =3D X86_CPU(cs); + + /* + * The realize order is important, since x86_cpu_realize() checks if + * nothing else has been set by the user (or by accelerators) in + * cpu->ucode_rev and cpu->phys_bits, and the memory regions + * initialized here are needed for the vcpu initialization. + * + * realize order: + * tcg_cpu -> host_cpu -> x86_cpu + */ + cpu->cpu_as_mem =3D g_new(MemoryRegion, 1); + cpu->cpu_as_root =3D g_new(MemoryRegion, 1); + + /* Outer container... */ + memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull); + memory_region_set_enabled(cpu->cpu_as_root, true); + + /* + * ... with two regions inside: normal system memory with low + * priority, and... + */ + memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory", + get_system_memory(), 0, ~0ull); + memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_m= em, 0); + memory_region_set_enabled(cpu->cpu_as_mem, true); + + cs->num_ases =3D 2; + cpu_address_space_init(cs, 0, "cpu-memory", cs->memory); + cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root); + + /* ... SMRAM with higher priority, linked from /machine/smram. */ + cpu->machine_done.notify =3D x86_cpu_machine_done; + qemu_add_machine_init_done_notifier(&cpu->machine_done); +} + +#else /* CONFIG_USER_ONLY */ + +static void tcg_cpu_realizefn(CPUState *cs, Error **errp) +{ +} + +#endif /* !CONFIG_USER_ONLY */ + +/* + * TCG-specific defaults that override all CPU models when using TCG + */ +static PropValue tcg_default_props[] =3D { + { "vme", "off" }, + { NULL, NULL }, +}; + +static void tcg_cpu_instance_init(CPUState *cs) +{ + X86CPU *cpu =3D X86_CPU(cs); + /* Special cases not set in the X86CPUDefinition structs: */ + x86_cpu_apply_props(cpu, tcg_default_props); +} + +static void tcg_cpu_accel_class_init(ObjectClass *oc, void *data) +{ + AccelCPUClass *acc =3D ACCEL_CPU_CLASS(oc); + + acc->cpu_realizefn =3D tcg_cpu_realizefn; + acc->cpu_class_init =3D tcg_cpu_class_init; + acc->cpu_instance_init =3D tcg_cpu_instance_init; +} +static const TypeInfo tcg_cpu_accel_type_info =3D { + .name =3D ACCEL_CPU_NAME("tcg"), + + .parent =3D TYPE_ACCEL_CPU, + .class_init =3D tcg_cpu_accel_class_init, + .abstract =3D true, +}; +static void tcg_cpu_accel_register_types(void) +{ + type_register_static(&tcg_cpu_accel_type_info); +} +type_init(tcg_cpu_accel_register_types); diff --git a/MAINTAINERS b/MAINTAINERS index 9b2aa18e1f..ac7b0d6c6a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -350,7 +350,7 @@ M: Paolo Bonzini M: Richard Henderson M: Eduardo Habkost S: Maintained -F: target/i386/ +F: target/i386/tcg/ F: tests/tcg/i386/ F: tests/tcg/x86_64/ F: hw/i386/ diff --git a/target/i386/hvf/meson.build b/target/i386/hvf/meson.build index e9eb5a5da8..d253d5fd10 100644 --- a/target/i386/hvf/meson.build +++ b/target/i386/hvf/meson.build @@ -10,4 +10,5 @@ i386_softmmu_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: f= iles( 'x86_mmu.c', 'x86_task.c', 'x86hvf.c', + 'hvf-cpu.c', )) diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build index 1d66559187..0a533411ca 100644 --- a/target/i386/kvm/meson.build +++ b/target/i386/kvm/meson.build @@ -1,3 +1,8 @@ i386_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c')) -i386_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c')) + +i386_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files( + 'kvm.c', + 'kvm-cpu.c', +)) + i386_softmmu_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_= false: files('hyperv-stub.c')) diff --git a/target/i386/meson.build b/target/i386/meson.build index c4bf20b319..fd24479590 100644 --- a/target/i386/meson.build +++ b/target/i386/meson.build @@ -6,7 +6,11 @@ i386_ss.add(files( 'xsave_helper.c', 'cpu-dump.c', )) -i386_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('= sev-stub.c')) +i386_ss.add(when: 'CONFIG_SEV', if_true: files('host-cpu.c', 'sev.c'), if_= false: files('sev-stub.c')) + +# x86 cpu type +i386_ss.add(when: 'CONFIG_KVM', if_true: files('host-cpu.c')) +i386_ss.add(when: 'CONFIG_HVF', if_true: files('host-cpu.c')) =20 i386_softmmu_ss =3D ss.source_set() i386_softmmu_ss.add(files( --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333117; cv=none; d=zohomail.com; s=zohoarc; b=YaOQhtF9VvfawTjG0c32iC4ZaxmMbtWQeiyO1B/+FcijtL0M50241VP69NgwoY4xDMT5LA7ORADaYFr8DiXu8FUefH3HY/YdJUVejgVmJRnel1iE9XjQdDY3TW9Dhb+xD6lAOoyOkMgqR/XsClUD/wsWJBiOCQ1D+282hTeJCG4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333117; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=r5BgG6UEMJ6DX3y/kU8CHsZDdmgfdoszUx2yW2oL0I4=; b=f3IiPIxyiL40MB0WpcMYxBZvnOe8N1lPl3WlkEjH5NJ+k2u5iaxxgYpEg1VyHTMFm6ljWaMggvzehlrHDIXNEH9kFPDwup1a9G0bk/AajsHUE8l/X7RyPY6BRufDX9bM2TpGG0ev9M8E2HVXhnxkJuALai1HIGbgNS6yxZZMV3Q= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333117002238.37424572776695; Fri, 26 Feb 2021 01:51:57 -0800 (PST) Received: from localhost ([::1]:44858 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZmt-0006kW-K0 for importer@patchew.org; Fri, 26 Feb 2021 04:51:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36322) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkq-0004oE-Jo for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:48 -0500 Received: from mx2.suse.de ([195.135.220.15]:42970) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkl-0004mo-I8 for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:48 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 564B3AF37; Fri, 26 Feb 2021 09:49:42 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 02/18] cpu: call AccelCPUClass::cpu_realizefn in cpu_exec_realizefn Date: Fri, 26 Feb 2021 10:49:23 +0100 Message-Id: <20210226094939.11087-3-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" move the call to accel_cpu->cpu_realizefn to the general cpu_exec_realizefn from target/i386, so it does not need to be called for every target explicitly as we enable more targets. Signed-off-by: Claudio Fontana Reviewed-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- cpu.c | 6 ++++++ target/i386/cpu.c | 20 +++++++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cpu.c b/cpu.c index bfbe5a66f9..ba5d272c1e 100644 --- a/cpu.c +++ b/cpu.c @@ -36,6 +36,7 @@ #include "sysemu/replay.h" #include "exec/translate-all.h" #include "exec/log.h" +#include "hw/core/accel-cpu.h" =20 uintptr_t qemu_host_page_size; intptr_t qemu_host_page_mask; @@ -130,6 +131,11 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp) =20 cpu_list_add(cpu); =20 + if (cc->accel_cpu) { + /* NB: errp parameter is unused currently */ + cc->accel_cpu->cpu_realizefn(cpu, errp); + } + #ifdef CONFIG_TCG /* NB: errp parameter is unused currently */ if (tcg_enabled()) { diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 648e41791f..6e2b5d7e59 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -6445,16 +6445,19 @@ static void x86_cpu_hyperv_realize(X86CPU *cpu) static void x86_cpu_realizefn(DeviceState *dev, Error **errp) { CPUState *cs =3D CPU(dev); - CPUClass *cc =3D CPU_GET_CLASS(cs); X86CPU *cpu =3D X86_CPU(dev); X86CPUClass *xcc =3D X86_CPU_GET_CLASS(dev); CPUX86State *env =3D &cpu->env; Error *local_err =3D NULL; static bool ht_warned; =20 - /* The accelerator realizefn needs to be called first. */ - if (cc->accel_cpu) { - cc->accel_cpu->cpu_realizefn(cs, errp); + /* Process Hyper-V enlightenments */ + x86_cpu_hyperv_realize(cpu); + + cpu_exec_realizefn(cs, &local_err); + if (local_err !=3D NULL) { + error_propagate(errp, local_err); + return; } =20 if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) { @@ -6570,15 +6573,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Erro= r **errp) env->cache_info_amd.l3_cache =3D &legacy_l3_cache; } =20 - /* Process Hyper-V enlightenments */ - x86_cpu_hyperv_realize(cpu); - - cpu_exec_realizefn(cs, &local_err); - if (local_err !=3D NULL) { - error_propagate(errp, local_err); - return; - } - #ifndef CONFIG_USER_ONLY MachineState *ms =3D MACHINE(qdev_get_machine()); qemu_register_reset(x86_cpu_machine_reset_cb, cpu); --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333230; cv=none; d=zohomail.com; s=zohoarc; b=dIuB2OuaF66e54uh6tW/+i4q6lcbDshDfNerbcjHnPuOk1GbCLtVNlIA3SjTYH5IJkteEhi5+xL/uTuL4XElAdLPFZRoGWuGO+hC/6Vy9BuszGi356ZKcbyE8I2/5rfwLV04gUecxIfYPoTAzYRQbYRZ6IOJF5KcUZonFX0gKVM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333230; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=5jo8V82jnDZd5YGqrZ7f3tuZsRyr20GKQGu1bcK0KWo=; b=fd9P1hJLHzlPUBx6puZzYBPJr4yjdhO2uCJIEuSOR577+VNjsOp7IxSouadHR5St0i/iKecsPm3cT+fJuEWKNDKU1WvYMm4uYrswl4Tq5UBtUT9906yO2KFzPe02Hdhez4CVBT1EKIqP92VtXf0ysLNUT/OxMevefd2NAhxebOA= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 161433323091642.56081374459768; Fri, 26 Feb 2021 01:53:50 -0800 (PST) Received: from localhost ([::1]:52792 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZoj-0001V8-QB for importer@patchew.org; Fri, 26 Feb 2021 04:53:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36326) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkq-0004oS-PC for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:48 -0500 Received: from mx2.suse.de ([195.135.220.15]:42986) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkm-0004nS-5d for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:48 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id D5EDAAF3F; Fri, 26 Feb 2021 09:49:42 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 03/18] accel: introduce new accessor functions Date: Fri, 26 Feb 2021 10:49:24 +0100 Message-Id: <20210226094939.11087-4-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" avoid open coding the accesses to cpu->accel_cpu interfaces, and instead introduce: accel_cpu_instance_init, accel_cpu_realizefn to be used by the targets/ initfn code, and by cpu_exec_realizefn respectively. Signed-off-by: Claudio Fontana Reviewed-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- include/qemu/accel.h | 13 +++++++++++++ accel/accel-common.c | 19 +++++++++++++++++++ cpu.c | 6 +----- target/i386/cpu.c | 9 ++------- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/include/qemu/accel.h b/include/qemu/accel.h index b9d6d69eb8..da0c8ab523 100644 --- a/include/qemu/accel.h +++ b/include/qemu/accel.h @@ -78,4 +78,17 @@ int accel_init_machine(AccelState *accel, MachineState *= ms); void accel_setup_post(MachineState *ms); #endif /* !CONFIG_USER_ONLY */ =20 +/** + * accel_cpu_instance_init: + * @cpu: The CPU that needs to do accel-specific object initializations. + */ +void accel_cpu_instance_init(CPUState *cpu); + +/** + * accel_cpu_realizefn: + * @cpu: The CPU that needs to call accel-specific cpu realization. + * @errp: currently unused. + */ +void accel_cpu_realizefn(CPUState *cpu, Error **errp); + #endif /* QEMU_ACCEL_H */ diff --git a/accel/accel-common.c b/accel/accel-common.c index 9901b0531c..0f6fb4fb66 100644 --- a/accel/accel-common.c +++ b/accel/accel-common.c @@ -89,6 +89,25 @@ void accel_init_interfaces(AccelClass *ac) accel_init_cpu_interfaces(ac); } =20 +void accel_cpu_instance_init(CPUState *cpu) +{ + CPUClass *cc =3D CPU_GET_CLASS(cpu); + + if (cc->accel_cpu && cc->accel_cpu->cpu_instance_init) { + cc->accel_cpu->cpu_instance_init(cpu); + } +} + +void accel_cpu_realizefn(CPUState *cpu, Error **errp) +{ + CPUClass *cc =3D CPU_GET_CLASS(cpu); + + if (cc->accel_cpu && cc->accel_cpu->cpu_realizefn) { + /* NB: errp parameter is unused currently */ + cc->accel_cpu->cpu_realizefn(cpu, errp); + } +} + static const TypeInfo accel_cpu_type =3D { .name =3D TYPE_ACCEL_CPU, .parent =3D TYPE_OBJECT, diff --git a/cpu.c b/cpu.c index ba5d272c1e..25e6fbfa2c 100644 --- a/cpu.c +++ b/cpu.c @@ -130,11 +130,7 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp) CPUClass *cc =3D CPU_GET_CLASS(cpu); =20 cpu_list_add(cpu); - - if (cc->accel_cpu) { - /* NB: errp parameter is unused currently */ - cc->accel_cpu->cpu_realizefn(cpu, errp); - } + accel_cpu_realizefn(cpu, errp); =20 #ifdef CONFIG_TCG /* NB: errp parameter is unused currently */ diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6e2b5d7e59..14e2a60ee5 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -28,7 +28,6 @@ #include "sysemu/kvm.h" #include "sysemu/reset.h" #include "sysemu/hvf.h" -#include "hw/core/accel-cpu.h" #include "sysemu/xen.h" #include "sysemu/whpx.h" #include "kvm/kvm_i386.h" @@ -6786,8 +6785,6 @@ static void x86_cpu_initfn(Object *obj) { X86CPU *cpu =3D X86_CPU(obj); X86CPUClass *xcc =3D X86_CPU_GET_CLASS(obj); - CPUClass *cc =3D CPU_CLASS(xcc); - CPUX86State *env =3D &cpu->env; =20 env->nr_dies =3D 1; @@ -6836,10 +6833,8 @@ static void x86_cpu_initfn(Object *obj) x86_cpu_load_model(cpu, xcc->model); } =20 - /* if required, do the accelerator-specific cpu initialization */ - if (cc->accel_cpu) { - cc->accel_cpu->cpu_instance_init(CPU(obj)); - } + /* if required, do accelerator-specific cpu initializations */ + accel_cpu_instance_init(CPU(obj)); } =20 static int64_t x86_cpu_get_arch_id(CPUState *cs) --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333103; cv=none; d=zohomail.com; s=zohoarc; b=GtC4OvfIQd3olC7qVD7E/65wgeu3zm/0ZNUld8e1cVfui1kvqXy20sQKsLHri0zo/qJSgGYa3YpzTAyUZgpfUuT/OgsCTM9ZZOp9EGqlnRKFJrtekIFl02US7ijczAX2jmey77HqxIxWBn+Q1eAk7R3IjVF0QMY222toZX9DjfM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333103; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=NQQdIZa/3er1Zp0zXPINX2O3WpMMpk0krSDt8zj84ug=; b=mlXtcNi1XlRQdwxiVp66gu5Bk5zqlY8jGWkrzYCOJ6AUv0eDO7J348WmlWEN692VIwWvw/Z/dccpNeFuG5RTkUOG4dosQxL6026bE4M54v9SG7jFEXWCOZiU3HGYda7mFqYb9nDQ+mIjZEo5KI67MLczpPRC+8RxLbZVQTL8Pzc= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333103966278.7306734374598; Fri, 26 Feb 2021 01:51:43 -0800 (PST) Received: from localhost ([::1]:44472 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZmg-0006af-R3 for importer@patchew.org; Fri, 26 Feb 2021 04:51:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36310) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkq-0004nl-7K for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:48 -0500 Received: from mx2.suse.de ([195.135.220.15]:43002) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkm-0004na-Rk for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:47 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 64B1EAF44; Fri, 26 Feb 2021 09:49:43 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 04/18] target/i386: fix host_cpu_adjust_phys_bits error handling Date: Fri, 26 Feb 2021 10:49:25 +0100 Message-Id: <20210226094939.11087-5-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" move the check for phys_bits outside of host_cpu_adjust_phys_bits, because otherwise it is impossible to return an error condition explicitly. Signed-off-by: Claudio Fontana Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- target/i386/host-cpu.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c index 9cfe56ce41..d07d41c34c 100644 --- a/target/i386/host-cpu.c +++ b/target/i386/host-cpu.c @@ -50,7 +50,7 @@ static void host_cpu_enable_cpu_pm(X86CPU *cpu) env->features[FEAT_1_ECX] |=3D CPUID_EXT_MONITOR; } =20 -static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu, Error **errp) +static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu) { uint32_t host_phys_bits =3D host_cpu_phys_bits(); uint32_t phys_bits =3D cpu->phys_bits; @@ -77,14 +77,6 @@ static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu, E= rror **errp) } } =20 - if (phys_bits && - (phys_bits > TARGET_PHYS_ADDR_SPACE_BITS || - phys_bits < 32)) { - error_setg(errp, "phys-bits should be between 32 and %u " - " (but is %u)", - TARGET_PHYS_ADDR_SPACE_BITS, phys_bits); - } - return phys_bits; } =20 @@ -97,7 +89,17 @@ void host_cpu_realizefn(CPUState *cs, Error **errp) host_cpu_enable_cpu_pm(cpu); } if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { - cpu->phys_bits =3D host_cpu_adjust_phys_bits(cpu, errp); + uint32_t phys_bits =3D host_cpu_adjust_phys_bits(cpu); + + if (phys_bits && + (phys_bits > TARGET_PHYS_ADDR_SPACE_BITS || + phys_bits < 32)) { + error_setg(errp, "phys-bits should be between 32 and %u " + " (but is %u)", + TARGET_PHYS_ADDR_SPACE_BITS, phys_bits); + return; + } + cpu->phys_bits =3D phys_bits; } } =20 --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333251; cv=none; d=zohomail.com; s=zohoarc; b=XatTMaqeSSeSGBZjArCqQ+S9uciAG+fAD6OVaYqnOPovMAGgBpDWHBLatPpBFW+JG94cJECiIjjcyEvaMS3jRSwbEIRvoVh3PxLA94lyvZy/UANWorxFR/fKOUTNfLEMNzP7mfvh+AofS2OR0HY/WXyCDtafKxJJbOx0IdD5ucc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333251; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=aXXpf7fDvSt5bmrGHwRml8EMttBMsHQtedULjTY0fQY=; b=PJIWrfl75u2kh34ZRqdNTopwX3ia0Gi1hph5b9UIAsqxFPeztecSILvTmOX7POhVx10a/+pgNKlVntWli0IBJH3lUlpTf81kle/sP3Bcb95LxhX76XG4WG+4P4DIiY1OVQGOtymx3AThcpEpXn2jvUX2X1X4CUN70qF/xLvZ8uk= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 161433325183796.53389422245868; Fri, 26 Feb 2021 01:54:11 -0800 (PST) Received: from localhost ([::1]:53448 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZp4-0001md-LA for importer@patchew.org; Fri, 26 Feb 2021 04:54:10 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36342) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkr-0004ov-5I for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:49 -0500 Received: from mx2.suse.de ([195.135.220.15]:43068) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZko-0004oz-RV for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:48 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id E3958AF47; Fri, 26 Feb 2021 09:49:43 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 05/18] accel-cpu: make cpu_realizefn return a bool Date: Fri, 26 Feb 2021 10:49:26 +0100 Message-Id: <20210226094939.11087-6-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" overall, all devices' realize functions take an Error **errp, but return vo= id. hw/core/qdev.c code, which realizes devices, therefore does: local_err =3D NULL; dc->realize(dev, &local_err); if (local_err !=3D NULL) { goto fail; } However, we can improve at least accel_cpu to return a meaningful bool valu= e. Signed-off-by: Claudio Fontana Reviewed-by: Philippe Mathieu-Daud=C3=A9 Reviewed-by: Alex Benn=C3=A9e Reviewed-by: Richard Henderson --- include/hw/core/accel-cpu.h | 2 +- include/qemu/accel.h | 2 +- target/i386/host-cpu.h | 2 +- accel/accel-common.c | 6 +++--- cpu.c | 5 +++-- target/i386/host-cpu.c | 5 +++-- target/i386/kvm/kvm-cpu.c | 4 ++-- target/i386/tcg/tcg-cpu.c | 6 ++++-- 8 files changed, 18 insertions(+), 14 deletions(-) diff --git a/include/hw/core/accel-cpu.h b/include/hw/core/accel-cpu.h index 24a6697412..5dbfd79955 100644 --- a/include/hw/core/accel-cpu.h +++ b/include/hw/core/accel-cpu.h @@ -32,7 +32,7 @@ typedef struct AccelCPUClass { =20 void (*cpu_class_init)(CPUClass *cc); void (*cpu_instance_init)(CPUState *cpu); - void (*cpu_realizefn)(CPUState *cpu, Error **errp); + bool (*cpu_realizefn)(CPUState *cpu, Error **errp); } AccelCPUClass; =20 #endif /* ACCEL_CPU_H */ diff --git a/include/qemu/accel.h b/include/qemu/accel.h index da0c8ab523..4f4c283f6f 100644 --- a/include/qemu/accel.h +++ b/include/qemu/accel.h @@ -89,6 +89,6 @@ void accel_cpu_instance_init(CPUState *cpu); * @cpu: The CPU that needs to call accel-specific cpu realization. * @errp: currently unused. */ -void accel_cpu_realizefn(CPUState *cpu, Error **errp); +bool accel_cpu_realizefn(CPUState *cpu, Error **errp); =20 #endif /* QEMU_ACCEL_H */ diff --git a/target/i386/host-cpu.h b/target/i386/host-cpu.h index b47bc0943f..6a9bc918ba 100644 --- a/target/i386/host-cpu.h +++ b/target/i386/host-cpu.h @@ -12,7 +12,7 @@ =20 void host_cpu_instance_init(X86CPU *cpu); void host_cpu_max_instance_init(X86CPU *cpu); -void host_cpu_realizefn(CPUState *cs, Error **errp); +bool host_cpu_realizefn(CPUState *cs, Error **errp); =20 void host_cpu_vendor_fms(char *vendor, int *family, int *model, int *stepp= ing); =20 diff --git a/accel/accel-common.c b/accel/accel-common.c index 0f6fb4fb66..d77c09d7b5 100644 --- a/accel/accel-common.c +++ b/accel/accel-common.c @@ -98,14 +98,14 @@ void accel_cpu_instance_init(CPUState *cpu) } } =20 -void accel_cpu_realizefn(CPUState *cpu, Error **errp) +bool accel_cpu_realizefn(CPUState *cpu, Error **errp) { CPUClass *cc =3D CPU_GET_CLASS(cpu); =20 if (cc->accel_cpu && cc->accel_cpu->cpu_realizefn) { - /* NB: errp parameter is unused currently */ - cc->accel_cpu->cpu_realizefn(cpu, errp); + return cc->accel_cpu->cpu_realizefn(cpu, errp); } + return true; } =20 static const TypeInfo accel_cpu_type =3D { diff --git a/cpu.c b/cpu.c index 25e6fbfa2c..34a0484bf4 100644 --- a/cpu.c +++ b/cpu.c @@ -130,8 +130,9 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp) CPUClass *cc =3D CPU_GET_CLASS(cpu); =20 cpu_list_add(cpu); - accel_cpu_realizefn(cpu, errp); - + if (!accel_cpu_realizefn(cpu, errp)) { + return; + } #ifdef CONFIG_TCG /* NB: errp parameter is unused currently */ if (tcg_enabled()) { diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c index d07d41c34c..4ea9e354ea 100644 --- a/target/i386/host-cpu.c +++ b/target/i386/host-cpu.c @@ -80,7 +80,7 @@ static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu) return phys_bits; } =20 -void host_cpu_realizefn(CPUState *cs, Error **errp) +bool host_cpu_realizefn(CPUState *cs, Error **errp) { X86CPU *cpu =3D X86_CPU(cs); CPUX86State *env =3D &cpu->env; @@ -97,10 +97,11 @@ void host_cpu_realizefn(CPUState *cs, Error **errp) error_setg(errp, "phys-bits should be between 32 and %u " " (but is %u)", TARGET_PHYS_ADDR_SPACE_BITS, phys_bits); - return; + return false; } cpu->phys_bits =3D phys_bits; } + return true; } =20 #define CPUID_MODEL_ID_SZ 48 diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c index c23bbe6c50..c660ad4293 100644 --- a/target/i386/kvm/kvm-cpu.c +++ b/target/i386/kvm/kvm-cpu.c @@ -18,7 +18,7 @@ #include "kvm_i386.h" #include "hw/core/accel-cpu.h" =20 -static void kvm_cpu_realizefn(CPUState *cs, Error **errp) +static bool kvm_cpu_realizefn(CPUState *cs, Error **errp) { X86CPU *cpu =3D X86_CPU(cs); CPUX86State *env =3D &cpu->env; @@ -41,7 +41,7 @@ static void kvm_cpu_realizefn(CPUState *cs, Error **errp) MSR_IA32_UCODE_REV); } } - host_cpu_realizefn(cs, errp); + return host_cpu_realizefn(cs, errp); } =20 /* diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c index 1d3d6d1c6a..23e1f5f0c3 100644 --- a/target/i386/tcg/tcg-cpu.c +++ b/target/i386/tcg/tcg-cpu.c @@ -96,7 +96,7 @@ static void x86_cpu_machine_done(Notifier *n, void *unuse= d) } } =20 -static void tcg_cpu_realizefn(CPUState *cs, Error **errp) +static bool tcg_cpu_realizefn(CPUState *cs, Error **errp) { X86CPU *cpu =3D X86_CPU(cs); =20 @@ -132,12 +132,14 @@ static void tcg_cpu_realizefn(CPUState *cs, Error **e= rrp) /* ... SMRAM with higher priority, linked from /machine/smram. */ cpu->machine_done.notify =3D x86_cpu_machine_done; qemu_add_machine_init_done_notifier(&cpu->machine_done); + return true; } =20 #else /* CONFIG_USER_ONLY */ =20 -static void tcg_cpu_realizefn(CPUState *cs, Error **errp) +static bool tcg_cpu_realizefn(CPUState *cs, Error **errp) { + return true; } =20 #endif /* !CONFIG_USER_ONLY */ --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333234; cv=none; d=zohomail.com; s=zohoarc; b=gZWbTZk13qjczT+1zXNZjIHzVAZwebbEUMwWqlXRAb7KQp29+oLSBFC4kzCAoHVYrNHSKiFRrfmrGXEzbdZklBJDcAdUVItm2bRdHXZ4Z5W4SU8svLBPVyiqeQchZljhg0l8AFkzwDmZKRckBd+6lXozaccjYZ/yizUmBxp92Jw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333234; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=v3n3oTRxe1l8F4RWF5V/NG2HwUC2qBIhFTbBEXSH17Q=; b=Bu3wJFfkUfeEUr7Gijj0l9HjEuV4hpBO6eTI0BisK9eZWe+p5KXoVBWYdJYN8Zs2W4I/WLlSbeTN0TEdlhgvu2jIuuo+Z9EDVasqfpfR19BxrjLf0NI1xQ4KNH935Err47ng9uXDIso3e+r5XSBt6UvyMTGjGcMk//jWsYD4hec= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333234300428.95306500732613; Fri, 26 Feb 2021 01:53:54 -0800 (PST) Received: from localhost ([::1]:52926 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZol-0001YW-Hn for importer@patchew.org; Fri, 26 Feb 2021 04:53:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36354) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkr-0004px-O4 for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:49 -0500 Received: from mx2.suse.de ([195.135.220.15]:43066) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZko-0004p0-Rv for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:49 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 72E1DAF49; Fri, 26 Feb 2021 09:49:44 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 06/18] meson: add target_user_arch Date: Fri, 26 Feb 2021 10:49:27 +0100 Message-Id: <20210226094939.11087-7-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" the lack of target_user_arch makes it hard to fully leverage the build system in order to separate user code from sysemu code. Provide it, so that we can avoid the proliferation of #ifdef in target code. Signed-off-by: Claudio Fontana Reviewed-by: Alex Benn=C3=A9e [claudio: added changes for new target hexagon] Signed-off-by: Claudio Fontana --- meson.build | 5 +++++ target/alpha/meson.build | 3 +++ target/arm/meson.build | 2 ++ target/cris/meson.build | 3 +++ target/hexagon/meson.build | 3 +++ target/hppa/meson.build | 3 +++ target/i386/meson.build | 2 ++ target/m68k/meson.build | 3 +++ target/microblaze/meson.build | 3 +++ target/mips/meson.build | 3 +++ target/nios2/meson.build | 3 +++ target/openrisc/meson.build | 3 +++ target/ppc/meson.build | 3 +++ target/riscv/meson.build | 3 +++ target/s390x/meson.build | 3 +++ target/sh4/meson.build | 3 +++ target/sparc/meson.build | 3 +++ target/tilegx/meson.build | 3 +++ target/tricore/meson.build | 3 +++ target/xtensa/meson.build | 3 +++ 20 files changed, 60 insertions(+) diff --git a/meson.build b/meson.build index 05a67c20d9..5be4e5f38c 100644 --- a/meson.build +++ b/meson.build @@ -1735,6 +1735,7 @@ modules =3D {} hw_arch =3D {} target_arch =3D {} target_softmmu_arch =3D {} +target_user_arch =3D {} =20 ############### # Trace files # @@ -2132,6 +2133,10 @@ foreach target : target_dirs abi =3D config_target['TARGET_ABI_DIR'] target_type=3D'user' qemu_target_name =3D 'qemu-' + target_name + t =3D target_user_arch[arch].apply(config_target, strict: false) + arch_srcs +=3D t.sources() + arch_deps +=3D t.dependencies() + if 'CONFIG_LINUX_USER' in config_target base_dir =3D 'linux-user' target_inc +=3D include_directories('linux-user/host/' / config_host= ['ARCH']) diff --git a/target/alpha/meson.build b/target/alpha/meson.build index 1aec55abb4..1b0555d3ee 100644 --- a/target/alpha/meson.build +++ b/target/alpha/meson.build @@ -14,5 +14,8 @@ alpha_ss.add(files( alpha_softmmu_ss =3D ss.source_set() alpha_softmmu_ss.add(files('machine.c')) =20 +alpha_user_ss =3D ss.source_set() + target_arch +=3D {'alpha': alpha_ss} target_softmmu_arch +=3D {'alpha': alpha_softmmu_ss} +target_user_arch +=3D {'alpha': alpha_user_ss} diff --git a/target/arm/meson.build b/target/arm/meson.build index 15b936c101..a96af5ee1b 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -53,6 +53,8 @@ arm_softmmu_ss.add(files( 'monitor.c', 'psci.c', )) +arm_user_ss =3D ss.source_set() =20 target_arch +=3D {'arm': arm_ss} target_softmmu_arch +=3D {'arm': arm_softmmu_ss} +target_user_arch +=3D {'arm': arm_user_ss} diff --git a/target/cris/meson.build b/target/cris/meson.build index 67c3793c85..7fd81e0348 100644 --- a/target/cris/meson.build +++ b/target/cris/meson.build @@ -10,5 +10,8 @@ cris_ss.add(files( cris_softmmu_ss =3D ss.source_set() cris_softmmu_ss.add(files('mmu.c', 'machine.c')) =20 +cris_user_ss =3D ss.source_set() + target_arch +=3D {'cris': cris_ss} target_softmmu_arch +=3D {'cris': cris_softmmu_ss} +target_user_arch +=3D {'cris': cris_user_ss} diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build index 15318a6fa7..e92d45400d 100644 --- a/target/hexagon/meson.build +++ b/target/hexagon/meson.build @@ -188,4 +188,7 @@ hexagon_ss.add(files( 'conv_emu.c', )) =20 +hexagon_user_ss =3D ss.source_set() + target_arch +=3D {'hexagon': hexagon_ss} +target_user_arch +=3D {'hexagon': hexagon_user_ss} diff --git a/target/hppa/meson.build b/target/hppa/meson.build index 8a7ff82efc..85ad314671 100644 --- a/target/hppa/meson.build +++ b/target/hppa/meson.build @@ -15,5 +15,8 @@ hppa_ss.add(files( hppa_softmmu_ss =3D ss.source_set() hppa_softmmu_ss.add(files('machine.c')) =20 +hppa_user_ss =3D ss.source_set() + target_arch +=3D {'hppa': hppa_ss} target_softmmu_arch +=3D {'hppa': hppa_softmmu_ss} +target_user_arch +=3D {'hppa': hppa_user_ss} diff --git a/target/i386/meson.build b/target/i386/meson.build index fd24479590..cac26a4581 100644 --- a/target/i386/meson.build +++ b/target/i386/meson.build @@ -19,6 +19,7 @@ i386_softmmu_ss.add(files( 'machine.c', 'monitor.c', )) +i386_user_ss =3D ss.source_set() =20 subdir('kvm') subdir('hax') @@ -28,3 +29,4 @@ subdir('tcg') =20 target_arch +=3D {'i386': i386_ss} target_softmmu_arch +=3D {'i386': i386_softmmu_ss} +target_user_arch +=3D {'i386': i386_user_ss} diff --git a/target/m68k/meson.build b/target/m68k/meson.build index 05cd9fbd1e..b507682684 100644 --- a/target/m68k/meson.build +++ b/target/m68k/meson.build @@ -13,5 +13,8 @@ m68k_ss.add(files( m68k_softmmu_ss =3D ss.source_set() m68k_softmmu_ss.add(files('monitor.c')) =20 +m68k_user_ss =3D ss.source_set() + target_arch +=3D {'m68k': m68k_ss} target_softmmu_arch +=3D {'m68k': m68k_softmmu_ss} +target_user_arch +=3D {'m68k': m68k_user_ss} diff --git a/target/microblaze/meson.build b/target/microblaze/meson.build index 05ee0ec163..52d8fcb0a3 100644 --- a/target/microblaze/meson.build +++ b/target/microblaze/meson.build @@ -16,5 +16,8 @@ microblaze_softmmu_ss.add(files( 'machine.c', )) =20 +microblaze_user_ss =3D ss.source_set() + target_arch +=3D {'microblaze': microblaze_ss} target_softmmu_arch +=3D {'microblaze': microblaze_softmmu_ss} +target_user_arch +=3D {'microblaze': microblaze_user_ss} diff --git a/target/mips/meson.build b/target/mips/meson.build index 9741545440..30843c1521 100644 --- a/target/mips/meson.build +++ b/target/mips/meson.build @@ -36,5 +36,8 @@ mips_softmmu_ss.add(when: 'CONFIG_TCG', if_true: files( 'cp0_helper.c', )) =20 +mips_user_ss =3D ss.source_set() + target_arch +=3D {'mips': mips_ss} target_softmmu_arch +=3D {'mips': mips_softmmu_ss} +target_user_arch +=3D {'mips': mips_user_ss} diff --git a/target/nios2/meson.build b/target/nios2/meson.build index e643917db1..00367056fa 100644 --- a/target/nios2/meson.build +++ b/target/nios2/meson.build @@ -11,5 +11,8 @@ nios2_ss.add(files( nios2_softmmu_ss =3D ss.source_set() nios2_softmmu_ss.add(files('monitor.c')) =20 +nios2_user_ss =3D ss.source_set() + target_arch +=3D {'nios2': nios2_ss} target_softmmu_arch +=3D {'nios2': nios2_softmmu_ss} +target_user_arch +=3D {'nios2': nios2_user_ss} diff --git a/target/openrisc/meson.build b/target/openrisc/meson.build index 9774a58306..794a9e8161 100644 --- a/target/openrisc/meson.build +++ b/target/openrisc/meson.build @@ -19,5 +19,8 @@ openrisc_ss.add(files( openrisc_softmmu_ss =3D ss.source_set() openrisc_softmmu_ss.add(files('machine.c')) =20 +openrisc_user_ss =3D ss.source_set() + target_arch +=3D {'openrisc': openrisc_ss} target_softmmu_arch +=3D {'openrisc': openrisc_softmmu_ss} +target_user_arch +=3D {'openrisc': openrisc_user_ss} diff --git a/target/ppc/meson.build b/target/ppc/meson.build index bbfef90e08..cdd69bf989 100644 --- a/target/ppc/meson.build +++ b/target/ppc/meson.build @@ -33,5 +33,8 @@ ppc_softmmu_ss.add(when: 'TARGET_PPC64', if_true: files( 'mmu-radix64.c', )) =20 +ppc_user_ss =3D ss.source_set() + target_arch +=3D {'ppc': ppc_ss} target_softmmu_arch +=3D {'ppc': ppc_softmmu_ss} +target_user_arch +=3D {'ppc': ppc_user_ss} diff --git a/target/riscv/meson.build b/target/riscv/meson.build index 14a5c62dac..a55851336b 100644 --- a/target/riscv/meson.build +++ b/target/riscv/meson.build @@ -31,5 +31,8 @@ riscv_softmmu_ss.add(files( 'machine.c' )) =20 +riscv_user_ss =3D ss.source_set() + target_arch +=3D {'riscv': riscv_ss} target_softmmu_arch +=3D {'riscv': riscv_softmmu_ss} +target_user_arch +=3D {'riscv': riscv_user_ss} diff --git a/target/s390x/meson.build b/target/s390x/meson.build index c42eadb7d2..1219f64112 100644 --- a/target/s390x/meson.build +++ b/target/s390x/meson.build @@ -58,5 +58,8 @@ if host_machine.cpu_family() =3D=3D 's390x' and cc.has_li= nk_argument('-Wl,--s390-pgs if_true: declare_dependency(link_args: ['-Wl,--s390= -pgste'])) endif =20 +s390x_user_ss =3D ss.source_set() + target_arch +=3D {'s390x': s390x_ss} target_softmmu_arch +=3D {'s390x': s390x_softmmu_ss} +target_user_arch +=3D {'s390x': s390x_user_ss} diff --git a/target/sh4/meson.build b/target/sh4/meson.build index 56a57576da..5a05729bc1 100644 --- a/target/sh4/meson.build +++ b/target/sh4/meson.build @@ -10,5 +10,8 @@ sh4_ss.add(files( sh4_softmmu_ss =3D ss.source_set() sh4_softmmu_ss.add(files('monitor.c')) =20 +sh4_user_ss =3D ss.source_set() + target_arch +=3D {'sh4': sh4_ss} target_softmmu_arch +=3D {'sh4': sh4_softmmu_ss} +target_user_arch +=3D {'sh4': sh4_user_ss} diff --git a/target/sparc/meson.build b/target/sparc/meson.build index a3638b9503..cc77a77064 100644 --- a/target/sparc/meson.build +++ b/target/sparc/meson.build @@ -19,5 +19,8 @@ sparc_softmmu_ss.add(files( 'monitor.c', )) =20 +sparc_user_ss =3D ss.source_set() + target_arch +=3D {'sparc': sparc_ss} target_softmmu_arch +=3D {'sparc': sparc_softmmu_ss} +target_user_arch +=3D {'sparc': sparc_user_ss} diff --git a/target/tilegx/meson.build b/target/tilegx/meson.build index 678590439c..23dab8b9a1 100644 --- a/target/tilegx/meson.build +++ b/target/tilegx/meson.build @@ -9,5 +9,8 @@ tilegx_ss.add(zlib) =20 tilegx_softmmu_ss =3D ss.source_set() =20 +tilegx_user_ss =3D ss.source_set() + target_arch +=3D {'tilegx': tilegx_ss} target_softmmu_arch +=3D {'tilegx': tilegx_softmmu_ss} +target_user_arch +=3D {'tilegx': tilegx_user_ss} diff --git a/target/tricore/meson.build b/target/tricore/meson.build index 0ccc829517..7086ae1a22 100644 --- a/target/tricore/meson.build +++ b/target/tricore/meson.build @@ -11,5 +11,8 @@ tricore_ss.add(zlib) =20 tricore_softmmu_ss =3D ss.source_set() =20 +tricore_user_ss =3D ss.source_set() + target_arch +=3D {'tricore': tricore_ss} target_softmmu_arch +=3D {'tricore': tricore_softmmu_ss} +target_user_arch +=3D {'tricore': tricore_user_ss} diff --git a/target/xtensa/meson.build b/target/xtensa/meson.build index dd750a977e..949b2c8334 100644 --- a/target/xtensa/meson.build +++ b/target/xtensa/meson.build @@ -28,5 +28,8 @@ xtensa_softmmu_ss.add(files( 'xtensa-semi.c', )) =20 +xtensa_user_ss =3D ss.source_set() + target_arch +=3D {'xtensa': xtensa_ss} target_softmmu_arch +=3D {'xtensa': xtensa_softmmu_ss} +target_user_arch +=3D {'xtensa': xtensa_user_ss} --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333252; cv=none; d=zohomail.com; s=zohoarc; b=IEAF6Z7fK0uoXDwC5wwWv48imEXXMgBS3LzQ+k9gLgpPFIg/OKDmvbtERkIsJGSEFeVUVkNGBAefEK7qHcyTxyFMqrWsxDMv6D9tNHSby6rus2kxiAefU+7CDDIp6/kZcLtD8FzBTmquKr4Smfe4Dm47m+fwmFodAacS/6x3z2Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333252; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=zX71/9lH7hxNs/uP5HTPDrP2pIoLHBjTgYqnD/qPOu8=; b=BfkRpUCxe7QcM99CjWnDtFWFKrnRJYDYWa+1Em2ksPr54UKzJDgbhPshAUlT+e6zOVYJLRsQYqKR5Sf/wHUhOtjCifKNF22Liz/RHGkx6FmXalHCvhoTbDCo7ExsEMpeKtELWUlrZXxUQzQYYG+QtQvd4ZrWmw3QdjP7V6fwVEI= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333252241766.588103275933; Fri, 26 Feb 2021 01:54:12 -0800 (PST) Received: from localhost ([::1]:53346 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZp4-0001k5-MU for importer@patchew.org; Fri, 26 Feb 2021 04:54:10 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36382) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZku-0004uM-FY for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:52 -0500 Received: from mx2.suse.de ([195.135.220.15]:43186) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkq-0004qy-Qn for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:52 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 01891AAAE; Fri, 26 Feb 2021 09:49:45 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 07/18] i386: split off sysemu-only functionality in tcg-cpu Date: Fri, 26 Feb 2021 10:49:28 +0100 Message-Id: <20210226094939.11087-8-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson --- target/i386/tcg/tcg-cpu.h | 24 +++++++++ target/i386/tcg/sysemu/tcg-cpu.c | 83 ++++++++++++++++++++++++++++++ target/i386/tcg/tcg-cpu.c | 75 ++------------------------- target/i386/tcg/meson.build | 3 ++ target/i386/tcg/sysemu/meson.build | 3 ++ target/i386/tcg/user/meson.build | 2 + 6 files changed, 119 insertions(+), 71 deletions(-) create mode 100644 target/i386/tcg/tcg-cpu.h create mode 100644 target/i386/tcg/sysemu/tcg-cpu.c create mode 100644 target/i386/tcg/sysemu/meson.build create mode 100644 target/i386/tcg/user/meson.build diff --git a/target/i386/tcg/tcg-cpu.h b/target/i386/tcg/tcg-cpu.h new file mode 100644 index 0000000000..36bd300af0 --- /dev/null +++ b/target/i386/tcg/tcg-cpu.h @@ -0,0 +1,24 @@ +/* + * i386 TCG cpu class initialization functions + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ +#ifndef TCG_CPU_H +#define TCG_CPU_H + +bool tcg_cpu_realizefn(CPUState *cs, Error **errp); + +#endif /* TCG_CPU_H */ diff --git a/target/i386/tcg/sysemu/tcg-cpu.c b/target/i386/tcg/sysemu/tcg-= cpu.c new file mode 100644 index 0000000000..c223c0fe9b --- /dev/null +++ b/target/i386/tcg/sysemu/tcg-cpu.c @@ -0,0 +1,83 @@ +/* + * i386 TCG cpu class initialization functions specific to sysemu + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "tcg/helper-tcg.h" + +#include "sysemu/sysemu.h" +#include "qemu/units.h" +#include "exec/address-spaces.h" + +#include "tcg/tcg-cpu.h" + +static void tcg_cpu_machine_done(Notifier *n, void *unused) +{ + X86CPU *cpu =3D container_of(n, X86CPU, machine_done); + MemoryRegion *smram =3D + (MemoryRegion *) object_resolve_path("/machine/smram", NULL); + + if (smram) { + cpu->smram =3D g_new(MemoryRegion, 1); + memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram", + smram, 0, 4 * GiB); + memory_region_set_enabled(cpu->smram, true); + memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, + cpu->smram, 1); + } +} + +bool tcg_cpu_realizefn(CPUState *cs, Error **errp) +{ + X86CPU *cpu =3D X86_CPU(cs); + + /* + * The realize order is important, since x86_cpu_realize() checks if + * nothing else has been set by the user (or by accelerators) in + * cpu->ucode_rev and cpu->phys_bits, and the memory regions + * initialized here are needed for the vcpu initialization. + * + * realize order: + * tcg_cpu -> host_cpu -> x86_cpu + */ + cpu->cpu_as_mem =3D g_new(MemoryRegion, 1); + cpu->cpu_as_root =3D g_new(MemoryRegion, 1); + + /* Outer container... */ + memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull); + memory_region_set_enabled(cpu->cpu_as_root, true); + + /* + * ... with two regions inside: normal system memory with low + * priority, and... + */ + memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory", + get_system_memory(), 0, ~0ull); + memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_m= em, 0); + memory_region_set_enabled(cpu->cpu_as_mem, true); + + cs->num_ases =3D 2; + cpu_address_space_init(cs, 0, "cpu-memory", cs->memory); + cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root); + + /* ... SMRAM with higher priority, linked from /machine/smram. */ + cpu->machine_done.notify =3D tcg_cpu_machine_done; + qemu_add_machine_init_done_notifier(&cpu->machine_done); + return true; +} diff --git a/target/i386/tcg/tcg-cpu.c b/target/i386/tcg/tcg-cpu.c index 23e1f5f0c3..e311f52855 100644 --- a/target/i386/tcg/tcg-cpu.c +++ b/target/i386/tcg/tcg-cpu.c @@ -23,11 +23,7 @@ #include "qemu/accel.h" #include "hw/core/accel-cpu.h" =20 -#ifndef CONFIG_USER_ONLY -#include "sysemu/sysemu.h" -#include "qemu/units.h" -#include "exec/address-spaces.h" -#endif +#include "tcg-cpu.h" =20 /* Frob eflags into and out of the CPU temporary format. */ =20 @@ -78,72 +74,6 @@ static void tcg_cpu_class_init(CPUClass *cc) cc->tcg_ops =3D &x86_tcg_ops; } =20 -#ifndef CONFIG_USER_ONLY - -static void x86_cpu_machine_done(Notifier *n, void *unused) -{ - X86CPU *cpu =3D container_of(n, X86CPU, machine_done); - MemoryRegion *smram =3D - (MemoryRegion *) object_resolve_path("/machine/smram", NULL); - - if (smram) { - cpu->smram =3D g_new(MemoryRegion, 1); - memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram", - smram, 0, 4 * GiB); - memory_region_set_enabled(cpu->smram, true); - memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, - cpu->smram, 1); - } -} - -static bool tcg_cpu_realizefn(CPUState *cs, Error **errp) -{ - X86CPU *cpu =3D X86_CPU(cs); - - /* - * The realize order is important, since x86_cpu_realize() checks if - * nothing else has been set by the user (or by accelerators) in - * cpu->ucode_rev and cpu->phys_bits, and the memory regions - * initialized here are needed for the vcpu initialization. - * - * realize order: - * tcg_cpu -> host_cpu -> x86_cpu - */ - cpu->cpu_as_mem =3D g_new(MemoryRegion, 1); - cpu->cpu_as_root =3D g_new(MemoryRegion, 1); - - /* Outer container... */ - memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull); - memory_region_set_enabled(cpu->cpu_as_root, true); - - /* - * ... with two regions inside: normal system memory with low - * priority, and... - */ - memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory", - get_system_memory(), 0, ~0ull); - memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_m= em, 0); - memory_region_set_enabled(cpu->cpu_as_mem, true); - - cs->num_ases =3D 2; - cpu_address_space_init(cs, 0, "cpu-memory", cs->memory); - cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root); - - /* ... SMRAM with higher priority, linked from /machine/smram. */ - cpu->machine_done.notify =3D x86_cpu_machine_done; - qemu_add_machine_init_done_notifier(&cpu->machine_done); - return true; -} - -#else /* CONFIG_USER_ONLY */ - -static bool tcg_cpu_realizefn(CPUState *cs, Error **errp) -{ - return true; -} - -#endif /* !CONFIG_USER_ONLY */ - /* * TCG-specific defaults that override all CPU models when using TCG */ @@ -163,7 +93,10 @@ static void tcg_cpu_accel_class_init(ObjectClass *oc, v= oid *data) { AccelCPUClass *acc =3D ACCEL_CPU_CLASS(oc); =20 +#ifndef CONFIG_USER_ONLY acc->cpu_realizefn =3D tcg_cpu_realizefn; +#endif /* CONFIG_USER_ONLY */ + acc->cpu_class_init =3D tcg_cpu_class_init; acc->cpu_instance_init =3D tcg_cpu_instance_init; } diff --git a/target/i386/tcg/meson.build b/target/i386/tcg/meson.build index 6a1a73cdbf..320bcd1e46 100644 --- a/target/i386/tcg/meson.build +++ b/target/i386/tcg/meson.build @@ -12,3 +12,6 @@ i386_ss.add(when: 'CONFIG_TCG', if_true: files( 'svm_helper.c', 'tcg-cpu.c', 'translate.c'), if_false: files('tcg-stub.c')) + +subdir('sysemu') +subdir('user') diff --git a/target/i386/tcg/sysemu/meson.build b/target/i386/tcg/sysemu/me= son.build new file mode 100644 index 0000000000..4ab30cc32e --- /dev/null +++ b/target/i386/tcg/sysemu/meson.build @@ -0,0 +1,3 @@ +i386_softmmu_ss.add(when: ['CONFIG_TCG', 'CONFIG_SOFTMMU'], if_true: files( + 'tcg-cpu.c', +)) diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.= build new file mode 100644 index 0000000000..7aecc53155 --- /dev/null +++ b/target/i386/tcg/user/meson.build @@ -0,0 +1,2 @@ +i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], if_true: files( +)) --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333372; cv=none; d=zohomail.com; s=zohoarc; b=OqB7nT5Obbhv3fBWB+Ba9ygaqE+VE0ep0xCtUehwriZH9fekvqhS9MnPLYxjSg6XaIlLdZhA2NOp64jjk0/5smQWAOVu1gVXBUuodKF6cR8Nj7Eu/2WW6PJ3QZeVKRG3nhp0wos1n0cTlOm8mNqED4GzG+hUouronJvxhRhLRvY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333372; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=oSkWwDnBIJ+fyCKSCgILoQthWYXjWlEIyqT+mpBCpbA=; b=Jx5r3fc2RJ0ySygI9AyrskR5MoW3AgsXADA9JwwuETuQHUiNVgabWRG7okmEdaTkdgTYFgAxPnPo/CJ6OcdctonEhmZRCWPzOOOjrQ6k3dkMjKbbmuuxGCK4uA2LRlvsKb26MC7EVn4ycOUo/NC4/DGKKEpOISclfnmj5Xtem2c= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333372422460.16374104304214; Fri, 26 Feb 2021 01:56:12 -0800 (PST) Received: from localhost ([::1]:32968 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZr1-00051C-9S for importer@patchew.org; Fri, 26 Feb 2021 04:56:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36380) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkt-0004tT-Vo for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:52 -0500 Received: from mx2.suse.de ([195.135.220.15]:43184) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkq-0004qx-Qg for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:51 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 7F1C9AF4E; Fri, 26 Feb 2021 09:49:45 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 08/18] i386: split smm helper (sysemu) Date: Fri, 26 Feb 2021 10:49:29 +0100 Message-Id: <20210226094939.11087-9-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" smm is only really useful for sysemu, split in two modules around the CONFIG_USER_ONLY, in order to remove the ifdef and use the build system instead. add cpu_abort() when detecting attempts to enter SMM mode via SMI interrupt in user-mode, and assert that the cpu is not in SMM mode while translating RSM instructions. Signed-off-by: Claudio Fontana Cc: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/helper.h | 4 ++++ target/i386/tcg/seg_helper.c | 4 ++++ target/i386/tcg/{ =3D> sysemu}/smm_helper.c | 19 ++----------------- target/i386/tcg/translate.c | 5 +++++ target/i386/tcg/meson.build | 1 - target/i386/tcg/sysemu/meson.build | 1 + 6 files changed, 16 insertions(+), 18 deletions(-) rename target/i386/tcg/{ =3D> sysemu}/smm_helper.c (98%) diff --git a/target/i386/helper.h b/target/i386/helper.h index c2ae2f7e61..8ffda4cdc6 100644 --- a/target/i386/helper.h +++ b/target/i386/helper.h @@ -70,7 +70,11 @@ DEF_HELPER_1(clac, void, env) DEF_HELPER_1(stac, void, env) DEF_HELPER_3(boundw, void, env, tl, int) DEF_HELPER_3(boundl, void, env, tl, int) + +#ifndef CONFIG_USER_ONLY DEF_HELPER_1(rsm, void, env) +#endif /* !CONFIG_USER_ONLY */ + DEF_HELPER_2(into, void, env, int) DEF_HELPER_2(cmpxchg8b_unlocked, void, env, tl) DEF_HELPER_2(cmpxchg8b, void, env, tl) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 180d47f0e9..d04fbdd7cd 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -1351,7 +1351,11 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interr= upt_request) case CPU_INTERRUPT_SMI: cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0, 0); cs->interrupt_request &=3D ~CPU_INTERRUPT_SMI; +#ifdef CONFIG_USER_ONLY + cpu_abort(CPU(cpu), "SMI interrupt: cannot enter SMM in user-mode"= ); +#else do_smm_enter(cpu); +#endif /* CONFIG_USER_ONLY */ break; case CPU_INTERRUPT_NMI: cpu_svm_check_intercept_param(env, SVM_EXIT_NMI, 0, 0); diff --git a/target/i386/tcg/smm_helper.c b/target/i386/tcg/sysemu/smm_help= er.c similarity index 98% rename from target/i386/tcg/smm_helper.c rename to target/i386/tcg/sysemu/smm_helper.c index 62d027abd3..a45b5651c3 100644 --- a/target/i386/tcg/smm_helper.c +++ b/target/i386/tcg/sysemu/smm_helper.c @@ -1,5 +1,5 @@ /* - * x86 SMM helpers + * x86 SMM helpers (sysemu-only) * * Copyright (c) 2003 Fabrice Bellard * @@ -18,27 +18,14 @@ */ =20 #include "qemu/osdep.h" -#include "qemu/main-loop.h" #include "cpu.h" #include "exec/helper-proto.h" #include "exec/log.h" -#include "helper-tcg.h" +#include "tcg/helper-tcg.h" =20 =20 /* SMM support */ =20 -#if defined(CONFIG_USER_ONLY) - -void do_smm_enter(X86CPU *cpu) -{ -} - -void helper_rsm(CPUX86State *env) -{ -} - -#else - #ifdef TARGET_X86_64 #define SMM_REVISION_ID 0x00020064 #else @@ -330,5 +317,3 @@ void helper_rsm(CPUX86State *env) qemu_log_mask(CPU_LOG_INT, "SMM: after RSM\n"); log_cpu_state_mask(CPU_LOG_INT, CPU(cpu), CPU_DUMP_CCOP); } - -#endif /* !CONFIG_USER_ONLY */ diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index af1faf9342..b882041ef0 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -8319,9 +8319,14 @@ static target_ulong disas_insn(DisasContext *s, CPUS= tate *cpu) gen_svm_check_intercept(s, pc_start, SVM_EXIT_RSM); if (!(s->flags & HF_SMM_MASK)) goto illegal_op; +#ifdef CONFIG_USER_ONLY + /* we should not be in SMM mode */ + g_assert_not_reached(); +#else gen_update_cc_op(s); gen_jmp_im(s, s->pc - s->cs_base); gen_helper_rsm(cpu_env); +#endif /* CONFIG_USER_ONLY */ gen_eob(s); break; case 0x1b8: /* SSE4.2 popcnt */ diff --git a/target/i386/tcg/meson.build b/target/i386/tcg/meson.build index 320bcd1e46..449d9719ef 100644 --- a/target/i386/tcg/meson.build +++ b/target/i386/tcg/meson.build @@ -8,7 +8,6 @@ i386_ss.add(when: 'CONFIG_TCG', if_true: files( 'misc_helper.c', 'mpx_helper.c', 'seg_helper.c', - 'smm_helper.c', 'svm_helper.c', 'tcg-cpu.c', 'translate.c'), if_false: files('tcg-stub.c')) diff --git a/target/i386/tcg/sysemu/meson.build b/target/i386/tcg/sysemu/me= son.build index 4ab30cc32e..35ba16dc3d 100644 --- a/target/i386/tcg/sysemu/meson.build +++ b/target/i386/tcg/sysemu/meson.build @@ -1,3 +1,4 @@ i386_softmmu_ss.add(when: ['CONFIG_TCG', 'CONFIG_SOFTMMU'], if_true: files( 'tcg-cpu.c', + 'smm_helper.c', )) --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333588; cv=none; d=zohomail.com; s=zohoarc; b=S4gpW24U8acS1V3AbOnQYPypIssJGJE/jaBtp6WznUlyKu0Uz2rR4IRVSVshBDEVvA+P925Xw4uE9RsG9S0ynV6rUbLsHDOK8eUh539PwF6GBqAVeOswh1hCQ0TWCuRm4NPq4Yn3inSI+tKJk5eenWzAEPuisnhLDLLZEDOPuzs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333588; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=ncjMp4E4zev3b8VcxrD0qNmouCr6rzxQIlBE1cxMgOc=; b=DSCR3w2y6zyH+higqF8yefdseRmJcyQX8jqBZGGuMeypsctOssYyWOIO1Oia72mexl2FJgny5e84Fe/Mk/U8D+aGayJehIFPY05VdGPnvPeudYd5sNg+DJTH6jOqusdJQ9TUVgfLyDDApnC2mGrKXjWsRtGKZrJrcKECtYBRkNc= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333588174553.8870993278125; Fri, 26 Feb 2021 01:59:48 -0800 (PST) Received: from localhost ([::1]:42282 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZuU-0000TU-Re for importer@patchew.org; Fri, 26 Feb 2021 04:59:46 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36434) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl5-0005Kh-RD for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:03 -0500 Received: from mx2.suse.de ([195.135.220.15]:43210) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl1-0004r6-3Q for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:03 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 0D7CCAF31; Fri, 26 Feb 2021 09:49:46 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 09/18] i386: split tcg excp_helper into sysemu and user parts Date: Fri, 26 Feb 2021 10:49:30 +0100 Message-Id: <20210226094939.11087-10-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson --- target/i386/tcg/excp_helper.c | 572 -------------------------- target/i386/tcg/sysemu/excp_helper.c | 581 +++++++++++++++++++++++++++ target/i386/tcg/user/excp_helper.c | 39 ++ target/i386/tcg/sysemu/meson.build | 1 + target/i386/tcg/user/meson.build | 1 + 5 files changed, 622 insertions(+), 572 deletions(-) create mode 100644 target/i386/tcg/sysemu/excp_helper.c create mode 100644 target/i386/tcg/user/excp_helper.c diff --git a/target/i386/tcg/excp_helper.c b/target/i386/tcg/excp_helper.c index b7d6259e4a..0183f3932e 100644 --- a/target/i386/tcg/excp_helper.c +++ b/target/i386/tcg/excp_helper.c @@ -137,575 +137,3 @@ void raise_exception_ra(CPUX86State *env, int excepti= on_index, uintptr_t retaddr { raise_interrupt2(env, exception_index, 0, 0, 0, retaddr); } - -#if !defined(CONFIG_USER_ONLY) -static hwaddr get_hphys(CPUState *cs, hwaddr gphys, MMUAccessType access_t= ype, - int *prot) -{ - CPUX86State *env =3D &X86_CPU(cs)->env; - uint64_t rsvd_mask =3D PG_HI_RSVD_MASK; - uint64_t ptep, pte; - uint64_t exit_info_1 =3D 0; - target_ulong pde_addr, pte_addr; - uint32_t page_offset; - int page_size; - - if (likely(!(env->hflags2 & HF2_NPT_MASK))) { - return gphys; - } - - if (!(env->nested_pg_mode & SVM_NPT_NXE)) { - rsvd_mask |=3D PG_NX_MASK; - } - - if (env->nested_pg_mode & SVM_NPT_PAE) { - uint64_t pde, pdpe; - target_ulong pdpe_addr; - -#ifdef TARGET_X86_64 - if (env->nested_pg_mode & SVM_NPT_LMA) { - uint64_t pml5e; - uint64_t pml4e_addr, pml4e; - - pml5e =3D env->nested_cr3; - ptep =3D PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; - - pml4e_addr =3D (pml5e & PG_ADDRESS_MASK) + - (((gphys >> 39) & 0x1ff) << 3); - pml4e =3D x86_ldq_phys(cs, pml4e_addr); - if (!(pml4e & PG_PRESENT_MASK)) { - goto do_fault; - } - if (pml4e & (rsvd_mask | PG_PSE_MASK)) { - goto do_fault_rsvd; - } - if (!(pml4e & PG_ACCESSED_MASK)) { - pml4e |=3D PG_ACCESSED_MASK; - x86_stl_phys_notdirty(cs, pml4e_addr, pml4e); - } - ptep &=3D pml4e ^ PG_NX_MASK; - pdpe_addr =3D (pml4e & PG_ADDRESS_MASK) + - (((gphys >> 30) & 0x1ff) << 3); - pdpe =3D x86_ldq_phys(cs, pdpe_addr); - if (!(pdpe & PG_PRESENT_MASK)) { - goto do_fault; - } - if (pdpe & rsvd_mask) { - goto do_fault_rsvd; - } - ptep &=3D pdpe ^ PG_NX_MASK; - if (!(pdpe & PG_ACCESSED_MASK)) { - pdpe |=3D PG_ACCESSED_MASK; - x86_stl_phys_notdirty(cs, pdpe_addr, pdpe); - } - if (pdpe & PG_PSE_MASK) { - /* 1 GB page */ - page_size =3D 1024 * 1024 * 1024; - pte_addr =3D pdpe_addr; - pte =3D pdpe; - goto do_check_protect; - } - } else -#endif - { - pdpe_addr =3D (env->nested_cr3 & ~0x1f) + ((gphys >> 27) & 0x1= 8); - pdpe =3D x86_ldq_phys(cs, pdpe_addr); - if (!(pdpe & PG_PRESENT_MASK)) { - goto do_fault; - } - rsvd_mask |=3D PG_HI_USER_MASK; - if (pdpe & (rsvd_mask | PG_NX_MASK)) { - goto do_fault_rsvd; - } - ptep =3D PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; - } - - pde_addr =3D (pdpe & PG_ADDRESS_MASK) + (((gphys >> 21) & 0x1ff) <= < 3); - pde =3D x86_ldq_phys(cs, pde_addr); - if (!(pde & PG_PRESENT_MASK)) { - goto do_fault; - } - if (pde & rsvd_mask) { - goto do_fault_rsvd; - } - ptep &=3D pde ^ PG_NX_MASK; - if (pde & PG_PSE_MASK) { - /* 2 MB page */ - page_size =3D 2048 * 1024; - pte_addr =3D pde_addr; - pte =3D pde; - goto do_check_protect; - } - /* 4 KB page */ - if (!(pde & PG_ACCESSED_MASK)) { - pde |=3D PG_ACCESSED_MASK; - x86_stl_phys_notdirty(cs, pde_addr, pde); - } - pte_addr =3D (pde & PG_ADDRESS_MASK) + (((gphys >> 12) & 0x1ff) <<= 3); - pte =3D x86_ldq_phys(cs, pte_addr); - if (!(pte & PG_PRESENT_MASK)) { - goto do_fault; - } - if (pte & rsvd_mask) { - goto do_fault_rsvd; - } - /* combine pde and pte nx, user and rw protections */ - ptep &=3D pte ^ PG_NX_MASK; - page_size =3D 4096; - } else { - uint32_t pde; - - /* page directory entry */ - pde_addr =3D (env->nested_cr3 & ~0xfff) + ((gphys >> 20) & 0xffc); - pde =3D x86_ldl_phys(cs, pde_addr); - if (!(pde & PG_PRESENT_MASK)) { - goto do_fault; - } - ptep =3D pde | PG_NX_MASK; - - /* if host cr4 PSE bit is set, then we use a 4MB page */ - if ((pde & PG_PSE_MASK) && (env->nested_pg_mode & SVM_NPT_PSE)) { - page_size =3D 4096 * 1024; - pte_addr =3D pde_addr; - - /* Bits 20-13 provide bits 39-32 of the address, bit 21 is res= erved. - * Leave bits 20-13 in place for setting accessed/dirty bits b= elow. - */ - pte =3D pde | ((pde & 0x1fe000LL) << (32 - 13)); - rsvd_mask =3D 0x200000; - goto do_check_protect_pse36; - } - - if (!(pde & PG_ACCESSED_MASK)) { - pde |=3D PG_ACCESSED_MASK; - x86_stl_phys_notdirty(cs, pde_addr, pde); - } - - /* page directory entry */ - pte_addr =3D (pde & ~0xfff) + ((gphys >> 10) & 0xffc); - pte =3D x86_ldl_phys(cs, pte_addr); - if (!(pte & PG_PRESENT_MASK)) { - goto do_fault; - } - /* combine pde and pte user and rw protections */ - ptep &=3D pte | PG_NX_MASK; - page_size =3D 4096; - rsvd_mask =3D 0; - } - - do_check_protect: - rsvd_mask |=3D (page_size - 1) & PG_ADDRESS_MASK & ~PG_PSE_PAT_MASK; - do_check_protect_pse36: - if (pte & rsvd_mask) { - goto do_fault_rsvd; - } - ptep ^=3D PG_NX_MASK; - - if (!(ptep & PG_USER_MASK)) { - goto do_fault_protect; - } - if (ptep & PG_NX_MASK) { - if (access_type =3D=3D MMU_INST_FETCH) { - goto do_fault_protect; - } - *prot &=3D ~PAGE_EXEC; - } - if (!(ptep & PG_RW_MASK)) { - if (access_type =3D=3D MMU_DATA_STORE) { - goto do_fault_protect; - } - *prot &=3D ~PAGE_WRITE; - } - - pte &=3D PG_ADDRESS_MASK & ~(page_size - 1); - page_offset =3D gphys & (page_size - 1); - return pte + page_offset; - - do_fault_rsvd: - exit_info_1 |=3D SVM_NPTEXIT_RSVD; - do_fault_protect: - exit_info_1 |=3D SVM_NPTEXIT_P; - do_fault: - x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.exit_inf= o_2), - gphys); - exit_info_1 |=3D SVM_NPTEXIT_US; - if (access_type =3D=3D MMU_DATA_STORE) { - exit_info_1 |=3D SVM_NPTEXIT_RW; - } else if (access_type =3D=3D MMU_INST_FETCH) { - exit_info_1 |=3D SVM_NPTEXIT_ID; - } - if (prot) { - exit_info_1 |=3D SVM_NPTEXIT_GPA; - } else { /* page table access */ - exit_info_1 |=3D SVM_NPTEXIT_GPT; - } - cpu_vmexit(env, SVM_EXIT_NPF, exit_info_1, env->retaddr); -} - -/* return value: - * -1 =3D cannot handle fault - * 0 =3D nothing more to do - * 1 =3D generate PF fault - */ -static int handle_mmu_fault(CPUState *cs, vaddr addr, int size, - int is_write1, int mmu_idx) -{ - X86CPU *cpu =3D X86_CPU(cs); - CPUX86State *env =3D &cpu->env; - uint64_t ptep, pte; - int32_t a20_mask; - target_ulong pde_addr, pte_addr; - int error_code =3D 0; - int is_dirty, prot, page_size, is_write, is_user; - hwaddr paddr; - uint64_t rsvd_mask =3D PG_HI_RSVD_MASK; - uint32_t page_offset; - target_ulong vaddr; - uint32_t pkr; - - is_user =3D mmu_idx =3D=3D MMU_USER_IDX; -#if defined(DEBUG_MMU) - printf("MMU fault: addr=3D%" VADDR_PRIx " w=3D%d u=3D%d eip=3D" TARGET= _FMT_lx "\n", - addr, is_write1, is_user, env->eip); -#endif - is_write =3D is_write1 & 1; - - a20_mask =3D x86_get_a20_mask(env); - if (!(env->cr[0] & CR0_PG_MASK)) { - pte =3D addr; -#ifdef TARGET_X86_64 - if (!(env->hflags & HF_LMA_MASK)) { - /* Without long mode we can only address 32bits in real mode */ - pte =3D (uint32_t)pte; - } -#endif - prot =3D PAGE_READ | PAGE_WRITE | PAGE_EXEC; - page_size =3D 4096; - goto do_mapping; - } - - if (!(env->efer & MSR_EFER_NXE)) { - rsvd_mask |=3D PG_NX_MASK; - } - - if (env->cr[4] & CR4_PAE_MASK) { - uint64_t pde, pdpe; - target_ulong pdpe_addr; - -#ifdef TARGET_X86_64 - if (env->hflags & HF_LMA_MASK) { - bool la57 =3D env->cr[4] & CR4_LA57_MASK; - uint64_t pml5e_addr, pml5e; - uint64_t pml4e_addr, pml4e; - int32_t sext; - - /* test virtual address sign extension */ - sext =3D la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47; - if (sext !=3D 0 && sext !=3D -1) { - env->error_code =3D 0; - cs->exception_index =3D EXCP0D_GPF; - return 1; - } - - if (la57) { - pml5e_addr =3D ((env->cr[3] & ~0xfff) + - (((addr >> 48) & 0x1ff) << 3)) & a20_mask; - pml5e_addr =3D get_hphys(cs, pml5e_addr, MMU_DATA_STORE, N= ULL); - pml5e =3D x86_ldq_phys(cs, pml5e_addr); - if (!(pml5e & PG_PRESENT_MASK)) { - goto do_fault; - } - if (pml5e & (rsvd_mask | PG_PSE_MASK)) { - goto do_fault_rsvd; - } - if (!(pml5e & PG_ACCESSED_MASK)) { - pml5e |=3D PG_ACCESSED_MASK; - x86_stl_phys_notdirty(cs, pml5e_addr, pml5e); - } - ptep =3D pml5e ^ PG_NX_MASK; - } else { - pml5e =3D env->cr[3]; - ptep =3D PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; - } - - pml4e_addr =3D ((pml5e & PG_ADDRESS_MASK) + - (((addr >> 39) & 0x1ff) << 3)) & a20_mask; - pml4e_addr =3D get_hphys(cs, pml4e_addr, MMU_DATA_STORE, false= ); - pml4e =3D x86_ldq_phys(cs, pml4e_addr); - if (!(pml4e & PG_PRESENT_MASK)) { - goto do_fault; - } - if (pml4e & (rsvd_mask | PG_PSE_MASK)) { - goto do_fault_rsvd; - } - if (!(pml4e & PG_ACCESSED_MASK)) { - pml4e |=3D PG_ACCESSED_MASK; - x86_stl_phys_notdirty(cs, pml4e_addr, pml4e); - } - ptep &=3D pml4e ^ PG_NX_MASK; - pdpe_addr =3D ((pml4e & PG_ADDRESS_MASK) + (((addr >> 30) & 0x= 1ff) << 3)) & - a20_mask; - pdpe_addr =3D get_hphys(cs, pdpe_addr, MMU_DATA_STORE, NULL); - pdpe =3D x86_ldq_phys(cs, pdpe_addr); - if (!(pdpe & PG_PRESENT_MASK)) { - goto do_fault; - } - if (pdpe & rsvd_mask) { - goto do_fault_rsvd; - } - ptep &=3D pdpe ^ PG_NX_MASK; - if (!(pdpe & PG_ACCESSED_MASK)) { - pdpe |=3D PG_ACCESSED_MASK; - x86_stl_phys_notdirty(cs, pdpe_addr, pdpe); - } - if (pdpe & PG_PSE_MASK) { - /* 1 GB page */ - page_size =3D 1024 * 1024 * 1024; - pte_addr =3D pdpe_addr; - pte =3D pdpe; - goto do_check_protect; - } - } else -#endif - { - /* XXX: load them when cr3 is loaded ? */ - pdpe_addr =3D ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) & - a20_mask; - pdpe_addr =3D get_hphys(cs, pdpe_addr, MMU_DATA_STORE, false); - pdpe =3D x86_ldq_phys(cs, pdpe_addr); - if (!(pdpe & PG_PRESENT_MASK)) { - goto do_fault; - } - rsvd_mask |=3D PG_HI_USER_MASK; - if (pdpe & (rsvd_mask | PG_NX_MASK)) { - goto do_fault_rsvd; - } - ptep =3D PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; - } - - pde_addr =3D ((pdpe & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) <= < 3)) & - a20_mask; - pde_addr =3D get_hphys(cs, pde_addr, MMU_DATA_STORE, NULL); - pde =3D x86_ldq_phys(cs, pde_addr); - if (!(pde & PG_PRESENT_MASK)) { - goto do_fault; - } - if (pde & rsvd_mask) { - goto do_fault_rsvd; - } - ptep &=3D pde ^ PG_NX_MASK; - if (pde & PG_PSE_MASK) { - /* 2 MB page */ - page_size =3D 2048 * 1024; - pte_addr =3D pde_addr; - pte =3D pde; - goto do_check_protect; - } - /* 4 KB page */ - if (!(pde & PG_ACCESSED_MASK)) { - pde |=3D PG_ACCESSED_MASK; - x86_stl_phys_notdirty(cs, pde_addr, pde); - } - pte_addr =3D ((pde & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) <<= 3)) & - a20_mask; - pte_addr =3D get_hphys(cs, pte_addr, MMU_DATA_STORE, NULL); - pte =3D x86_ldq_phys(cs, pte_addr); - if (!(pte & PG_PRESENT_MASK)) { - goto do_fault; - } - if (pte & rsvd_mask) { - goto do_fault_rsvd; - } - /* combine pde and pte nx, user and rw protections */ - ptep &=3D pte ^ PG_NX_MASK; - page_size =3D 4096; - } else { - uint32_t pde; - - /* page directory entry */ - pde_addr =3D ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & - a20_mask; - pde_addr =3D get_hphys(cs, pde_addr, MMU_DATA_STORE, NULL); - pde =3D x86_ldl_phys(cs, pde_addr); - if (!(pde & PG_PRESENT_MASK)) { - goto do_fault; - } - ptep =3D pde | PG_NX_MASK; - - /* if PSE bit is set, then we use a 4MB page */ - if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { - page_size =3D 4096 * 1024; - pte_addr =3D pde_addr; - - /* Bits 20-13 provide bits 39-32 of the address, bit 21 is res= erved. - * Leave bits 20-13 in place for setting accessed/dirty bits b= elow. - */ - pte =3D pde | ((pde & 0x1fe000LL) << (32 - 13)); - rsvd_mask =3D 0x200000; - goto do_check_protect_pse36; - } - - if (!(pde & PG_ACCESSED_MASK)) { - pde |=3D PG_ACCESSED_MASK; - x86_stl_phys_notdirty(cs, pde_addr, pde); - } - - /* page directory entry */ - pte_addr =3D ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & - a20_mask; - pte_addr =3D get_hphys(cs, pte_addr, MMU_DATA_STORE, NULL); - pte =3D x86_ldl_phys(cs, pte_addr); - if (!(pte & PG_PRESENT_MASK)) { - goto do_fault; - } - /* combine pde and pte user and rw protections */ - ptep &=3D pte | PG_NX_MASK; - page_size =3D 4096; - rsvd_mask =3D 0; - } - -do_check_protect: - rsvd_mask |=3D (page_size - 1) & PG_ADDRESS_MASK & ~PG_PSE_PAT_MASK; -do_check_protect_pse36: - if (pte & rsvd_mask) { - goto do_fault_rsvd; - } - ptep ^=3D PG_NX_MASK; - - /* can the page can be put in the TLB? prot will tell us */ - if (is_user && !(ptep & PG_USER_MASK)) { - goto do_fault_protect; - } - - prot =3D 0; - if (mmu_idx !=3D MMU_KSMAP_IDX || !(ptep & PG_USER_MASK)) { - prot |=3D PAGE_READ; - if ((ptep & PG_RW_MASK) || (!is_user && !(env->cr[0] & CR0_WP_MASK= ))) { - prot |=3D PAGE_WRITE; - } - } - if (!(ptep & PG_NX_MASK) && - (mmu_idx =3D=3D MMU_USER_IDX || - !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) { - prot |=3D PAGE_EXEC; - } - - if (!(env->hflags & HF_LMA_MASK)) { - pkr =3D 0; - } else if (ptep & PG_USER_MASK) { - pkr =3D env->cr[4] & CR4_PKE_MASK ? env->pkru : 0; - } else { - pkr =3D env->cr[4] & CR4_PKS_MASK ? env->pkrs : 0; - } - if (pkr) { - uint32_t pk =3D (pte & PG_PKRU_MASK) >> PG_PKRU_BIT; - uint32_t pkr_ad =3D (pkr >> pk * 2) & 1; - uint32_t pkr_wd =3D (pkr >> pk * 2) & 2; - uint32_t pkr_prot =3D PAGE_READ | PAGE_WRITE | PAGE_EXEC; - - if (pkr_ad) { - pkr_prot &=3D ~(PAGE_READ | PAGE_WRITE); - } else if (pkr_wd && (is_user || env->cr[0] & CR0_WP_MASK)) { - pkr_prot &=3D ~PAGE_WRITE; - } - - prot &=3D pkr_prot; - if ((pkr_prot & (1 << is_write1)) =3D=3D 0) { - assert(is_write1 !=3D 2); - error_code |=3D PG_ERROR_PK_MASK; - goto do_fault_protect; - } - } - - if ((prot & (1 << is_write1)) =3D=3D 0) { - goto do_fault_protect; - } - - /* yes, it can! */ - is_dirty =3D is_write && !(pte & PG_DIRTY_MASK); - if (!(pte & PG_ACCESSED_MASK) || is_dirty) { - pte |=3D PG_ACCESSED_MASK; - if (is_dirty) { - pte |=3D PG_DIRTY_MASK; - } - x86_stl_phys_notdirty(cs, pte_addr, pte); - } - - if (!(pte & PG_DIRTY_MASK)) { - /* only set write access if already dirty... otherwise wait - for dirty access */ - assert(!is_write); - prot &=3D ~PAGE_WRITE; - } - - do_mapping: - pte =3D pte & a20_mask; - - /* align to page_size */ - pte &=3D PG_ADDRESS_MASK & ~(page_size - 1); - page_offset =3D addr & (page_size - 1); - paddr =3D get_hphys(cs, pte + page_offset, is_write1, &prot); - - /* Even if 4MB pages, we map only one 4KB page in the cache to - avoid filling it too fast */ - vaddr =3D addr & TARGET_PAGE_MASK; - paddr &=3D TARGET_PAGE_MASK; - - assert(prot & (1 << is_write1)); - tlb_set_page_with_attrs(cs, vaddr, paddr, cpu_get_mem_attrs(env), - prot, mmu_idx, page_size); - return 0; - do_fault_rsvd: - error_code |=3D PG_ERROR_RSVD_MASK; - do_fault_protect: - error_code |=3D PG_ERROR_P_MASK; - do_fault: - error_code |=3D (is_write << PG_ERROR_W_BIT); - if (is_user) - error_code |=3D PG_ERROR_U_MASK; - if (is_write1 =3D=3D 2 && - (((env->efer & MSR_EFER_NXE) && - (env->cr[4] & CR4_PAE_MASK)) || - (env->cr[4] & CR4_SMEP_MASK))) - error_code |=3D PG_ERROR_I_D_MASK; - if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) { - /* cr2 is not modified in case of exceptions */ - x86_stq_phys(cs, - env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), - addr); - } else { - env->cr[2] =3D addr; - } - env->error_code =3D error_code; - cs->exception_index =3D EXCP0E_PAGE; - return 1; -} -#endif - -bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, - MMUAccessType access_type, int mmu_idx, - bool probe, uintptr_t retaddr) -{ - X86CPU *cpu =3D X86_CPU(cs); - CPUX86State *env =3D &cpu->env; - -#ifdef CONFIG_USER_ONLY - /* user mode only emulation */ - env->cr[2] =3D addr; - env->error_code =3D (access_type =3D=3D MMU_DATA_STORE) << PG_ERROR_W_= BIT; - env->error_code |=3D PG_ERROR_U_MASK; - cs->exception_index =3D EXCP0E_PAGE; - env->exception_is_int =3D 0; - env->exception_next_eip =3D -1; - cpu_loop_exit_restore(cs, retaddr); -#else - env->retaddr =3D retaddr; - if (handle_mmu_fault(cs, addr, size, access_type, mmu_idx)) { - /* FIXME: On error in get_hphys we have already jumped out. */ - g_assert(!probe); - raise_exception_err_ra(env, cs->exception_index, - env->error_code, retaddr); - } - return true; -#endif -} diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/= excp_helper.c new file mode 100644 index 0000000000..37e6eead05 --- /dev/null +++ b/target/i386/tcg/sysemu/excp_helper.c @@ -0,0 +1,581 @@ +/* + * x86 exception helpers - sysemu code + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "tcg/helper-tcg.h" + +static hwaddr get_hphys(CPUState *cs, hwaddr gphys, MMUAccessType access_t= ype, + int *prot) +{ + CPUX86State *env =3D &X86_CPU(cs)->env; + uint64_t rsvd_mask =3D PG_HI_RSVD_MASK; + uint64_t ptep, pte; + uint64_t exit_info_1 =3D 0; + target_ulong pde_addr, pte_addr; + uint32_t page_offset; + int page_size; + + if (likely(!(env->hflags2 & HF2_NPT_MASK))) { + return gphys; + } + + if (!(env->nested_pg_mode & SVM_NPT_NXE)) { + rsvd_mask |=3D PG_NX_MASK; + } + + if (env->nested_pg_mode & SVM_NPT_PAE) { + uint64_t pde, pdpe; + target_ulong pdpe_addr; + +#ifdef TARGET_X86_64 + if (env->nested_pg_mode & SVM_NPT_LMA) { + uint64_t pml5e; + uint64_t pml4e_addr, pml4e; + + pml5e =3D env->nested_cr3; + ptep =3D PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; + + pml4e_addr =3D (pml5e & PG_ADDRESS_MASK) + + (((gphys >> 39) & 0x1ff) << 3); + pml4e =3D x86_ldq_phys(cs, pml4e_addr); + if (!(pml4e & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pml4e & (rsvd_mask | PG_PSE_MASK)) { + goto do_fault_rsvd; + } + if (!(pml4e & PG_ACCESSED_MASK)) { + pml4e |=3D PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pml4e_addr, pml4e); + } + ptep &=3D pml4e ^ PG_NX_MASK; + pdpe_addr =3D (pml4e & PG_ADDRESS_MASK) + + (((gphys >> 30) & 0x1ff) << 3); + pdpe =3D x86_ldq_phys(cs, pdpe_addr); + if (!(pdpe & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pdpe & rsvd_mask) { + goto do_fault_rsvd; + } + ptep &=3D pdpe ^ PG_NX_MASK; + if (!(pdpe & PG_ACCESSED_MASK)) { + pdpe |=3D PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pdpe_addr, pdpe); + } + if (pdpe & PG_PSE_MASK) { + /* 1 GB page */ + page_size =3D 1024 * 1024 * 1024; + pte_addr =3D pdpe_addr; + pte =3D pdpe; + goto do_check_protect; + } + } else +#endif + { + pdpe_addr =3D (env->nested_cr3 & ~0x1f) + ((gphys >> 27) & 0x1= 8); + pdpe =3D x86_ldq_phys(cs, pdpe_addr); + if (!(pdpe & PG_PRESENT_MASK)) { + goto do_fault; + } + rsvd_mask |=3D PG_HI_USER_MASK; + if (pdpe & (rsvd_mask | PG_NX_MASK)) { + goto do_fault_rsvd; + } + ptep =3D PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; + } + + pde_addr =3D (pdpe & PG_ADDRESS_MASK) + (((gphys >> 21) & 0x1ff) <= < 3); + pde =3D x86_ldq_phys(cs, pde_addr); + if (!(pde & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pde & rsvd_mask) { + goto do_fault_rsvd; + } + ptep &=3D pde ^ PG_NX_MASK; + if (pde & PG_PSE_MASK) { + /* 2 MB page */ + page_size =3D 2048 * 1024; + pte_addr =3D pde_addr; + pte =3D pde; + goto do_check_protect; + } + /* 4 KB page */ + if (!(pde & PG_ACCESSED_MASK)) { + pde |=3D PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pde_addr, pde); + } + pte_addr =3D (pde & PG_ADDRESS_MASK) + (((gphys >> 12) & 0x1ff) <<= 3); + pte =3D x86_ldq_phys(cs, pte_addr); + if (!(pte & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pte & rsvd_mask) { + goto do_fault_rsvd; + } + /* combine pde and pte nx, user and rw protections */ + ptep &=3D pte ^ PG_NX_MASK; + page_size =3D 4096; + } else { + uint32_t pde; + + /* page directory entry */ + pde_addr =3D (env->nested_cr3 & ~0xfff) + ((gphys >> 20) & 0xffc); + pde =3D x86_ldl_phys(cs, pde_addr); + if (!(pde & PG_PRESENT_MASK)) { + goto do_fault; + } + ptep =3D pde | PG_NX_MASK; + + /* if host cr4 PSE bit is set, then we use a 4MB page */ + if ((pde & PG_PSE_MASK) && (env->nested_pg_mode & SVM_NPT_PSE)) { + page_size =3D 4096 * 1024; + pte_addr =3D pde_addr; + + /* Bits 20-13 provide bits 39-32 of the address, bit 21 is res= erved. + * Leave bits 20-13 in place for setting accessed/dirty bits b= elow. + */ + pte =3D pde | ((pde & 0x1fe000LL) << (32 - 13)); + rsvd_mask =3D 0x200000; + goto do_check_protect_pse36; + } + + if (!(pde & PG_ACCESSED_MASK)) { + pde |=3D PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pde_addr, pde); + } + + /* page directory entry */ + pte_addr =3D (pde & ~0xfff) + ((gphys >> 10) & 0xffc); + pte =3D x86_ldl_phys(cs, pte_addr); + if (!(pte & PG_PRESENT_MASK)) { + goto do_fault; + } + /* combine pde and pte user and rw protections */ + ptep &=3D pte | PG_NX_MASK; + page_size =3D 4096; + rsvd_mask =3D 0; + } + + do_check_protect: + rsvd_mask |=3D (page_size - 1) & PG_ADDRESS_MASK & ~PG_PSE_PAT_MASK; + do_check_protect_pse36: + if (pte & rsvd_mask) { + goto do_fault_rsvd; + } + ptep ^=3D PG_NX_MASK; + + if (!(ptep & PG_USER_MASK)) { + goto do_fault_protect; + } + if (ptep & PG_NX_MASK) { + if (access_type =3D=3D MMU_INST_FETCH) { + goto do_fault_protect; + } + *prot &=3D ~PAGE_EXEC; + } + if (!(ptep & PG_RW_MASK)) { + if (access_type =3D=3D MMU_DATA_STORE) { + goto do_fault_protect; + } + *prot &=3D ~PAGE_WRITE; + } + + pte &=3D PG_ADDRESS_MASK & ~(page_size - 1); + page_offset =3D gphys & (page_size - 1); + return pte + page_offset; + + do_fault_rsvd: + exit_info_1 |=3D SVM_NPTEXIT_RSVD; + do_fault_protect: + exit_info_1 |=3D SVM_NPTEXIT_P; + do_fault: + x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, control.exit_inf= o_2), + gphys); + exit_info_1 |=3D SVM_NPTEXIT_US; + if (access_type =3D=3D MMU_DATA_STORE) { + exit_info_1 |=3D SVM_NPTEXIT_RW; + } else if (access_type =3D=3D MMU_INST_FETCH) { + exit_info_1 |=3D SVM_NPTEXIT_ID; + } + if (prot) { + exit_info_1 |=3D SVM_NPTEXIT_GPA; + } else { /* page table access */ + exit_info_1 |=3D SVM_NPTEXIT_GPT; + } + cpu_vmexit(env, SVM_EXIT_NPF, exit_info_1, env->retaddr); +} + +/* return value: + * -1 =3D cannot handle fault + * 0 =3D nothing more to do + * 1 =3D generate PF fault + */ +static int handle_mmu_fault(CPUState *cs, vaddr addr, int size, + int is_write1, int mmu_idx) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + uint64_t ptep, pte; + int32_t a20_mask; + target_ulong pde_addr, pte_addr; + int error_code =3D 0; + int is_dirty, prot, page_size, is_write, is_user; + hwaddr paddr; + uint64_t rsvd_mask =3D PG_HI_RSVD_MASK; + uint32_t page_offset; + target_ulong vaddr; + uint32_t pkr; + + is_user =3D mmu_idx =3D=3D MMU_USER_IDX; +#if defined(DEBUG_MMU) + printf("MMU fault: addr=3D%" VADDR_PRIx " w=3D%d u=3D%d eip=3D" TARGET= _FMT_lx "\n", + addr, is_write1, is_user, env->eip); +#endif + is_write =3D is_write1 & 1; + + a20_mask =3D x86_get_a20_mask(env); + if (!(env->cr[0] & CR0_PG_MASK)) { + pte =3D addr; +#ifdef TARGET_X86_64 + if (!(env->hflags & HF_LMA_MASK)) { + /* Without long mode we can only address 32bits in real mode */ + pte =3D (uint32_t)pte; + } +#endif + prot =3D PAGE_READ | PAGE_WRITE | PAGE_EXEC; + page_size =3D 4096; + goto do_mapping; + } + + if (!(env->efer & MSR_EFER_NXE)) { + rsvd_mask |=3D PG_NX_MASK; + } + + if (env->cr[4] & CR4_PAE_MASK) { + uint64_t pde, pdpe; + target_ulong pdpe_addr; + +#ifdef TARGET_X86_64 + if (env->hflags & HF_LMA_MASK) { + bool la57 =3D env->cr[4] & CR4_LA57_MASK; + uint64_t pml5e_addr, pml5e; + uint64_t pml4e_addr, pml4e; + int32_t sext; + + /* test virtual address sign extension */ + sext =3D la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47; + if (sext !=3D 0 && sext !=3D -1) { + env->error_code =3D 0; + cs->exception_index =3D EXCP0D_GPF; + return 1; + } + + if (la57) { + pml5e_addr =3D ((env->cr[3] & ~0xfff) + + (((addr >> 48) & 0x1ff) << 3)) & a20_mask; + pml5e_addr =3D get_hphys(cs, pml5e_addr, MMU_DATA_STORE, N= ULL); + pml5e =3D x86_ldq_phys(cs, pml5e_addr); + if (!(pml5e & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pml5e & (rsvd_mask | PG_PSE_MASK)) { + goto do_fault_rsvd; + } + if (!(pml5e & PG_ACCESSED_MASK)) { + pml5e |=3D PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pml5e_addr, pml5e); + } + ptep =3D pml5e ^ PG_NX_MASK; + } else { + pml5e =3D env->cr[3]; + ptep =3D PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; + } + + pml4e_addr =3D ((pml5e & PG_ADDRESS_MASK) + + (((addr >> 39) & 0x1ff) << 3)) & a20_mask; + pml4e_addr =3D get_hphys(cs, pml4e_addr, MMU_DATA_STORE, false= ); + pml4e =3D x86_ldq_phys(cs, pml4e_addr); + if (!(pml4e & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pml4e & (rsvd_mask | PG_PSE_MASK)) { + goto do_fault_rsvd; + } + if (!(pml4e & PG_ACCESSED_MASK)) { + pml4e |=3D PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pml4e_addr, pml4e); + } + ptep &=3D pml4e ^ PG_NX_MASK; + pdpe_addr =3D ((pml4e & PG_ADDRESS_MASK) + (((addr >> 30) & 0x= 1ff) << 3)) & + a20_mask; + pdpe_addr =3D get_hphys(cs, pdpe_addr, MMU_DATA_STORE, NULL); + pdpe =3D x86_ldq_phys(cs, pdpe_addr); + if (!(pdpe & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pdpe & rsvd_mask) { + goto do_fault_rsvd; + } + ptep &=3D pdpe ^ PG_NX_MASK; + if (!(pdpe & PG_ACCESSED_MASK)) { + pdpe |=3D PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pdpe_addr, pdpe); + } + if (pdpe & PG_PSE_MASK) { + /* 1 GB page */ + page_size =3D 1024 * 1024 * 1024; + pte_addr =3D pdpe_addr; + pte =3D pdpe; + goto do_check_protect; + } + } else +#endif + { + /* XXX: load them when cr3 is loaded ? */ + pdpe_addr =3D ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) & + a20_mask; + pdpe_addr =3D get_hphys(cs, pdpe_addr, MMU_DATA_STORE, false); + pdpe =3D x86_ldq_phys(cs, pdpe_addr); + if (!(pdpe & PG_PRESENT_MASK)) { + goto do_fault; + } + rsvd_mask |=3D PG_HI_USER_MASK; + if (pdpe & (rsvd_mask | PG_NX_MASK)) { + goto do_fault_rsvd; + } + ptep =3D PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; + } + + pde_addr =3D ((pdpe & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) <= < 3)) & + a20_mask; + pde_addr =3D get_hphys(cs, pde_addr, MMU_DATA_STORE, NULL); + pde =3D x86_ldq_phys(cs, pde_addr); + if (!(pde & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pde & rsvd_mask) { + goto do_fault_rsvd; + } + ptep &=3D pde ^ PG_NX_MASK; + if (pde & PG_PSE_MASK) { + /* 2 MB page */ + page_size =3D 2048 * 1024; + pte_addr =3D pde_addr; + pte =3D pde; + goto do_check_protect; + } + /* 4 KB page */ + if (!(pde & PG_ACCESSED_MASK)) { + pde |=3D PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pde_addr, pde); + } + pte_addr =3D ((pde & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) <<= 3)) & + a20_mask; + pte_addr =3D get_hphys(cs, pte_addr, MMU_DATA_STORE, NULL); + pte =3D x86_ldq_phys(cs, pte_addr); + if (!(pte & PG_PRESENT_MASK)) { + goto do_fault; + } + if (pte & rsvd_mask) { + goto do_fault_rsvd; + } + /* combine pde and pte nx, user and rw protections */ + ptep &=3D pte ^ PG_NX_MASK; + page_size =3D 4096; + } else { + uint32_t pde; + + /* page directory entry */ + pde_addr =3D ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & + a20_mask; + pde_addr =3D get_hphys(cs, pde_addr, MMU_DATA_STORE, NULL); + pde =3D x86_ldl_phys(cs, pde_addr); + if (!(pde & PG_PRESENT_MASK)) { + goto do_fault; + } + ptep =3D pde | PG_NX_MASK; + + /* if PSE bit is set, then we use a 4MB page */ + if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { + page_size =3D 4096 * 1024; + pte_addr =3D pde_addr; + + /* Bits 20-13 provide bits 39-32 of the address, bit 21 is res= erved. + * Leave bits 20-13 in place for setting accessed/dirty bits b= elow. + */ + pte =3D pde | ((pde & 0x1fe000LL) << (32 - 13)); + rsvd_mask =3D 0x200000; + goto do_check_protect_pse36; + } + + if (!(pde & PG_ACCESSED_MASK)) { + pde |=3D PG_ACCESSED_MASK; + x86_stl_phys_notdirty(cs, pde_addr, pde); + } + + /* page directory entry */ + pte_addr =3D ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & + a20_mask; + pte_addr =3D get_hphys(cs, pte_addr, MMU_DATA_STORE, NULL); + pte =3D x86_ldl_phys(cs, pte_addr); + if (!(pte & PG_PRESENT_MASK)) { + goto do_fault; + } + /* combine pde and pte user and rw protections */ + ptep &=3D pte | PG_NX_MASK; + page_size =3D 4096; + rsvd_mask =3D 0; + } + +do_check_protect: + rsvd_mask |=3D (page_size - 1) & PG_ADDRESS_MASK & ~PG_PSE_PAT_MASK; +do_check_protect_pse36: + if (pte & rsvd_mask) { + goto do_fault_rsvd; + } + ptep ^=3D PG_NX_MASK; + + /* can the page can be put in the TLB? prot will tell us */ + if (is_user && !(ptep & PG_USER_MASK)) { + goto do_fault_protect; + } + + prot =3D 0; + if (mmu_idx !=3D MMU_KSMAP_IDX || !(ptep & PG_USER_MASK)) { + prot |=3D PAGE_READ; + if ((ptep & PG_RW_MASK) || (!is_user && !(env->cr[0] & CR0_WP_MASK= ))) { + prot |=3D PAGE_WRITE; + } + } + if (!(ptep & PG_NX_MASK) && + (mmu_idx =3D=3D MMU_USER_IDX || + !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) { + prot |=3D PAGE_EXEC; + } + + if (!(env->hflags & HF_LMA_MASK)) { + pkr =3D 0; + } else if (ptep & PG_USER_MASK) { + pkr =3D env->cr[4] & CR4_PKE_MASK ? env->pkru : 0; + } else { + pkr =3D env->cr[4] & CR4_PKS_MASK ? env->pkrs : 0; + } + if (pkr) { + uint32_t pk =3D (pte & PG_PKRU_MASK) >> PG_PKRU_BIT; + uint32_t pkr_ad =3D (pkr >> pk * 2) & 1; + uint32_t pkr_wd =3D (pkr >> pk * 2) & 2; + uint32_t pkr_prot =3D PAGE_READ | PAGE_WRITE | PAGE_EXEC; + + if (pkr_ad) { + pkr_prot &=3D ~(PAGE_READ | PAGE_WRITE); + } else if (pkr_wd && (is_user || env->cr[0] & CR0_WP_MASK)) { + pkr_prot &=3D ~PAGE_WRITE; + } + + prot &=3D pkr_prot; + if ((pkr_prot & (1 << is_write1)) =3D=3D 0) { + assert(is_write1 !=3D 2); + error_code |=3D PG_ERROR_PK_MASK; + goto do_fault_protect; + } + } + + if ((prot & (1 << is_write1)) =3D=3D 0) { + goto do_fault_protect; + } + + /* yes, it can! */ + is_dirty =3D is_write && !(pte & PG_DIRTY_MASK); + if (!(pte & PG_ACCESSED_MASK) || is_dirty) { + pte |=3D PG_ACCESSED_MASK; + if (is_dirty) { + pte |=3D PG_DIRTY_MASK; + } + x86_stl_phys_notdirty(cs, pte_addr, pte); + } + + if (!(pte & PG_DIRTY_MASK)) { + /* only set write access if already dirty... otherwise wait + for dirty access */ + assert(!is_write); + prot &=3D ~PAGE_WRITE; + } + + do_mapping: + pte =3D pte & a20_mask; + + /* align to page_size */ + pte &=3D PG_ADDRESS_MASK & ~(page_size - 1); + page_offset =3D addr & (page_size - 1); + paddr =3D get_hphys(cs, pte + page_offset, is_write1, &prot); + + /* Even if 4MB pages, we map only one 4KB page in the cache to + avoid filling it too fast */ + vaddr =3D addr & TARGET_PAGE_MASK; + paddr &=3D TARGET_PAGE_MASK; + + assert(prot & (1 << is_write1)); + tlb_set_page_with_attrs(cs, vaddr, paddr, cpu_get_mem_attrs(env), + prot, mmu_idx, page_size); + return 0; + do_fault_rsvd: + error_code |=3D PG_ERROR_RSVD_MASK; + do_fault_protect: + error_code |=3D PG_ERROR_P_MASK; + do_fault: + error_code |=3D (is_write << PG_ERROR_W_BIT); + if (is_user) + error_code |=3D PG_ERROR_U_MASK; + if (is_write1 =3D=3D 2 && + (((env->efer & MSR_EFER_NXE) && + (env->cr[4] & CR4_PAE_MASK)) || + (env->cr[4] & CR4_SMEP_MASK))) + error_code |=3D PG_ERROR_I_D_MASK; + if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) { + /* cr2 is not modified in case of exceptions */ + x86_stq_phys(cs, + env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), + addr); + } else { + env->cr[2] =3D addr; + } + env->error_code =3D error_code; + cs->exception_index =3D EXCP0E_PAGE; + return 1; +} + +bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + env->retaddr =3D retaddr; + if (handle_mmu_fault(cs, addr, size, access_type, mmu_idx)) { + /* FIXME: On error in get_hphys we have already jumped out. */ + g_assert(!probe); + raise_exception_err_ra(env, cs->exception_index, + env->error_code, retaddr); + } + return true; +} diff --git a/target/i386/tcg/user/excp_helper.c b/target/i386/tcg/user/excp= _helper.c new file mode 100644 index 0000000000..a89b5228fd --- /dev/null +++ b/target/i386/tcg/user/excp_helper.c @@ -0,0 +1,39 @@ +/* + * x86 exception helpers - user-mode specific code + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/exec-all.h" +#include "tcg/helper-tcg.h" + +bool x86_cpu_tlb_fill(CPUState *cs, vaddr addr, int size, + MMUAccessType access_type, int mmu_idx, + bool probe, uintptr_t retaddr) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + env->cr[2] =3D addr; + env->error_code =3D (access_type =3D=3D MMU_DATA_STORE) << PG_ERROR_W_= BIT; + env->error_code |=3D PG_ERROR_U_MASK; + cs->exception_index =3D EXCP0E_PAGE; + env->exception_is_int =3D 0; + env->exception_next_eip =3D -1; + cpu_loop_exit_restore(cs, retaddr); +} diff --git a/target/i386/tcg/sysemu/meson.build b/target/i386/tcg/sysemu/me= son.build index 35ba16dc3d..6d0a0a0fee 100644 --- a/target/i386/tcg/sysemu/meson.build +++ b/target/i386/tcg/sysemu/meson.build @@ -1,4 +1,5 @@ i386_softmmu_ss.add(when: ['CONFIG_TCG', 'CONFIG_SOFTMMU'], if_true: files( 'tcg-cpu.c', 'smm_helper.c', + 'excp_helper.c', )) diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.= build index 7aecc53155..e0ef0f02e2 100644 --- a/target/i386/tcg/user/meson.build +++ b/target/i386/tcg/user/meson.build @@ -1,2 +1,3 @@ i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], if_true: files( + 'excp_helper.c', )) --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333577; cv=none; d=zohomail.com; s=zohoarc; b=MYC3n/pelSG4wdNBu6/nBW7pJ2qxIizSA9lVs6ThextU0dgN8+IY0lXVdZClAqbNf2RdOr41z9nc2o3Y8k+SEjTH240aW7uIg0i6iDjt8o53gYsJpAU9VMwsE/mWZPreoNA89Ly/bzFl5mmBk0kIVGCEo3W79+jKU2hwayaCaGo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333577; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=VHZzumt863I6hmpUGXS49uWyaFDhL8tJQv9wzLrjazA=; b=haYBlmuEAZdGH46cMqGkWEzaNkVBNnzHU7753zoj8HxlpWU/ETJYn4KL0PMaM8onzyZ+SnXFMPdsZTPjKzO9vRW1Dfgazc863+Jxx+Zhrg0xTTD9kKW7OOLWTDXruOXsPAdx/0U1Ng+uce8fMgarWxhedINYz6lcx8V585AUH74= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333577424998.6148426014535; Fri, 26 Feb 2021 01:59:37 -0800 (PST) Received: from localhost ([::1]:41658 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZuK-0000Cv-4Z for importer@patchew.org; Fri, 26 Feb 2021 04:59:36 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36384) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkw-0004xc-0D for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:54 -0500 Received: from mx2.suse.de ([195.135.220.15]:43212) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZkr-0004r7-2c for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:49:53 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 9795BAF84; Fri, 26 Feb 2021 09:49:46 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 10/18] i386: move TCG btp_helper into sysemu/ Date: Fri, 26 Feb 2021 10:49:31 +0100 Message-Id: <20210226094939.11087-11-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" for user-mode, assert that the hidden IOBPT flags are not set while attempting to generate io_bpt helpers. Signed-off-by: Claudio Fontana Cc: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/helper.h | 7 + target/i386/tcg/helper-tcg.h | 3 + target/i386/tcg/bpt_helper.c | 276 -------------------------- target/i386/tcg/sysemu/bpt_helper.c | 293 ++++++++++++++++++++++++++++ target/i386/tcg/translate.c | 8 +- target/i386/tcg/sysemu/meson.build | 1 + 6 files changed, 311 insertions(+), 277 deletions(-) create mode 100644 target/i386/tcg/sysemu/bpt_helper.c diff --git a/target/i386/helper.h b/target/i386/helper.h index 8ffda4cdc6..095520f81f 100644 --- a/target/i386/helper.h +++ b/target/i386/helper.h @@ -46,7 +46,11 @@ DEF_HELPER_2(read_crN, tl, env, int) DEF_HELPER_3(write_crN, void, env, int, tl) DEF_HELPER_2(lmsw, void, env, tl) DEF_HELPER_1(clts, void, env) + +#ifndef CONFIG_USER_ONLY DEF_HELPER_FLAGS_3(set_dr, TCG_CALL_NO_WG, void, env, int, tl) +#endif /* !CONFIG_USER_ONLY */ + DEF_HELPER_FLAGS_2(get_dr, TCG_CALL_NO_WG, tl, env, int) DEF_HELPER_2(invlpg, void, env, tl) =20 @@ -100,7 +104,10 @@ DEF_HELPER_3(outw, void, env, i32, i32) DEF_HELPER_2(inw, tl, env, i32) DEF_HELPER_3(outl, void, env, i32, i32) DEF_HELPER_2(inl, tl, env, i32) + +#ifndef CONFIG_USER_ONLY DEF_HELPER_FLAGS_4(bpt_io, TCG_CALL_NO_WG, void, env, i32, i32, tl) +#endif /* !CONFIG_USER_ONLY */ =20 DEF_HELPER_3(svm_check_intercept_param, void, env, i32, i64) DEF_HELPER_4(svm_check_io, void, env, i32, i32, i32) diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h index c133c63555..b420b3356d 100644 --- a/target/i386/tcg/helper-tcg.h +++ b/target/i386/tcg/helper-tcg.h @@ -92,4 +92,7 @@ void do_interrupt_x86_hardirq(CPUX86State *env, int intno= , int is_hw); /* smm_helper.c */ void do_smm_enter(X86CPU *cpu); =20 +/* bpt_helper.c */ +bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update); + #endif /* I386_HELPER_TCG_H */ diff --git a/target/i386/tcg/bpt_helper.c b/target/i386/tcg/bpt_helper.c index 979230ac12..fb2a65ac9c 100644 --- a/target/i386/tcg/bpt_helper.c +++ b/target/i386/tcg/bpt_helper.c @@ -19,223 +19,9 @@ =20 #include "qemu/osdep.h" #include "cpu.h" -#include "exec/exec-all.h" #include "exec/helper-proto.h" #include "helper-tcg.h" =20 - -#ifndef CONFIG_USER_ONLY -static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int inde= x) -{ - return (dr7 >> (index * 2)) & 1; -} - -static inline bool hw_global_breakpoint_enabled(unsigned long dr7, int ind= ex) -{ - return (dr7 >> (index * 2)) & 2; - -} -static inline bool hw_breakpoint_enabled(unsigned long dr7, int index) -{ - return hw_global_breakpoint_enabled(dr7, index) || - hw_local_breakpoint_enabled(dr7, index); -} - -static inline int hw_breakpoint_type(unsigned long dr7, int index) -{ - return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3; -} - -static inline int hw_breakpoint_len(unsigned long dr7, int index) -{ - int len =3D ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3); - return (len =3D=3D 2) ? 8 : len + 1; -} - -static int hw_breakpoint_insert(CPUX86State *env, int index) -{ - CPUState *cs =3D env_cpu(env); - target_ulong dr7 =3D env->dr[7]; - target_ulong drN =3D env->dr[index]; - int err =3D 0; - - switch (hw_breakpoint_type(dr7, index)) { - case DR7_TYPE_BP_INST: - if (hw_breakpoint_enabled(dr7, index)) { - err =3D cpu_breakpoint_insert(cs, drN, BP_CPU, - &env->cpu_breakpoint[index]); - } - break; - - case DR7_TYPE_IO_RW: - /* Notice when we should enable calls to bpt_io. */ - return hw_breakpoint_enabled(env->dr[7], index) - ? HF_IOBPT_MASK : 0; - - case DR7_TYPE_DATA_WR: - if (hw_breakpoint_enabled(dr7, index)) { - err =3D cpu_watchpoint_insert(cs, drN, - hw_breakpoint_len(dr7, index), - BP_CPU | BP_MEM_WRITE, - &env->cpu_watchpoint[index]); - } - break; - - case DR7_TYPE_DATA_RW: - if (hw_breakpoint_enabled(dr7, index)) { - err =3D cpu_watchpoint_insert(cs, drN, - hw_breakpoint_len(dr7, index), - BP_CPU | BP_MEM_ACCESS, - &env->cpu_watchpoint[index]); - } - break; - } - if (err) { - env->cpu_breakpoint[index] =3D NULL; - } - return 0; -} - -static void hw_breakpoint_remove(CPUX86State *env, int index) -{ - CPUState *cs =3D env_cpu(env); - - switch (hw_breakpoint_type(env->dr[7], index)) { - case DR7_TYPE_BP_INST: - if (env->cpu_breakpoint[index]) { - cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]); - env->cpu_breakpoint[index] =3D NULL; - } - break; - - case DR7_TYPE_DATA_WR: - case DR7_TYPE_DATA_RW: - if (env->cpu_breakpoint[index]) { - cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]); - env->cpu_breakpoint[index] =3D NULL; - } - break; - - case DR7_TYPE_IO_RW: - /* HF_IOBPT_MASK cleared elsewhere. */ - break; - } -} - -void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7) -{ - target_ulong old_dr7 =3D env->dr[7]; - int iobpt =3D 0; - int i; - - new_dr7 |=3D DR7_FIXED_1; - - /* If nothing is changing except the global/local enable bits, - then we can make the change more efficient. */ - if (((old_dr7 ^ new_dr7) & ~0xff) =3D=3D 0) { - /* Fold the global and local enable bits together into the - global fields, then xor to show which registers have - changed collective enable state. */ - int mod =3D ((old_dr7 | old_dr7 * 2) ^ (new_dr7 | new_dr7 * 2)) & = 0xff; - - for (i =3D 0; i < DR7_MAX_BP; i++) { - if ((mod & (2 << i * 2)) && !hw_breakpoint_enabled(new_dr7, i)= ) { - hw_breakpoint_remove(env, i); - } - } - env->dr[7] =3D new_dr7; - for (i =3D 0; i < DR7_MAX_BP; i++) { - if (mod & (2 << i * 2) && hw_breakpoint_enabled(new_dr7, i)) { - iobpt |=3D hw_breakpoint_insert(env, i); - } else if (hw_breakpoint_type(new_dr7, i) =3D=3D DR7_TYPE_IO_RW - && hw_breakpoint_enabled(new_dr7, i)) { - iobpt |=3D HF_IOBPT_MASK; - } - } - } else { - for (i =3D 0; i < DR7_MAX_BP; i++) { - hw_breakpoint_remove(env, i); - } - env->dr[7] =3D new_dr7; - for (i =3D 0; i < DR7_MAX_BP; i++) { - iobpt |=3D hw_breakpoint_insert(env, i); - } - } - - env->hflags =3D (env->hflags & ~HF_IOBPT_MASK) | iobpt; -} - -static bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update) -{ - target_ulong dr6; - int reg; - bool hit_enabled =3D false; - - dr6 =3D env->dr[6] & ~0xf; - for (reg =3D 0; reg < DR7_MAX_BP; reg++) { - bool bp_match =3D false; - bool wp_match =3D false; - - switch (hw_breakpoint_type(env->dr[7], reg)) { - case DR7_TYPE_BP_INST: - if (env->dr[reg] =3D=3D env->eip) { - bp_match =3D true; - } - break; - case DR7_TYPE_DATA_WR: - case DR7_TYPE_DATA_RW: - if (env->cpu_watchpoint[reg] && - env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) { - wp_match =3D true; - } - break; - case DR7_TYPE_IO_RW: - break; - } - if (bp_match || wp_match) { - dr6 |=3D 1 << reg; - if (hw_breakpoint_enabled(env->dr[7], reg)) { - hit_enabled =3D true; - } - } - } - - if (hit_enabled || force_dr6_update) { - env->dr[6] =3D dr6; - } - - return hit_enabled; -} - -void breakpoint_handler(CPUState *cs) -{ - X86CPU *cpu =3D X86_CPU(cs); - CPUX86State *env =3D &cpu->env; - CPUBreakpoint *bp; - - if (cs->watchpoint_hit) { - if (cs->watchpoint_hit->flags & BP_CPU) { - cs->watchpoint_hit =3D NULL; - if (check_hw_breakpoints(env, false)) { - raise_exception(env, EXCP01_DB); - } else { - cpu_loop_exit_noexc(cs); - } - } - } else { - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { - if (bp->pc =3D=3D env->eip) { - if (bp->flags & BP_CPU) { - check_hw_breakpoints(env, true); - raise_exception(env, EXCP01_DB); - } - break; - } - } - } -} -#endif - void helper_single_step(CPUX86State *env) { #ifndef CONFIG_USER_ONLY @@ -252,41 +38,6 @@ void helper_rechecking_single_step(CPUX86State *env) } } =20 -void helper_set_dr(CPUX86State *env, int reg, target_ulong t0) -{ -#ifndef CONFIG_USER_ONLY - switch (reg) { - case 0: case 1: case 2: case 3: - if (hw_breakpoint_enabled(env->dr[7], reg) - && hw_breakpoint_type(env->dr[7], reg) !=3D DR7_TYPE_IO_RW) { - hw_breakpoint_remove(env, reg); - env->dr[reg] =3D t0; - hw_breakpoint_insert(env, reg); - } else { - env->dr[reg] =3D t0; - } - return; - case 4: - if (env->cr[4] & CR4_DE_MASK) { - break; - } - /* fallthru */ - case 6: - env->dr[6] =3D t0 | DR6_FIXED_1; - return; - case 5: - if (env->cr[4] & CR4_DE_MASK) { - break; - } - /* fallthru */ - case 7: - cpu_x86_update_dr7(env, t0); - return; - } - raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); -#endif -} - target_ulong helper_get_dr(CPUX86State *env, int reg) { switch (reg) { @@ -307,30 +58,3 @@ target_ulong helper_get_dr(CPUX86State *env, int reg) } raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); } - -/* Check if Port I/O is trapped by a breakpoint. */ -void helper_bpt_io(CPUX86State *env, uint32_t port, - uint32_t size, target_ulong next_eip) -{ -#ifndef CONFIG_USER_ONLY - target_ulong dr7 =3D env->dr[7]; - int i, hit =3D 0; - - for (i =3D 0; i < DR7_MAX_BP; ++i) { - if (hw_breakpoint_type(dr7, i) =3D=3D DR7_TYPE_IO_RW - && hw_breakpoint_enabled(dr7, i)) { - int bpt_len =3D hw_breakpoint_len(dr7, i); - if (port + size - 1 >=3D env->dr[i] - && port <=3D env->dr[i] + bpt_len - 1) { - hit |=3D 1 << i; - } - } - } - - if (hit) { - env->dr[6] =3D (env->dr[6] & ~0xf) | hit; - env->eip =3D next_eip; - raise_exception(env, EXCP01_DB); - } -#endif -} diff --git a/target/i386/tcg/sysemu/bpt_helper.c b/target/i386/tcg/sysemu/b= pt_helper.c new file mode 100644 index 0000000000..9bdf7e170b --- /dev/null +++ b/target/i386/tcg/sysemu/bpt_helper.c @@ -0,0 +1,293 @@ +/* + * i386 breakpoint helpers - sysemu code + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/exec-all.h" +#include "exec/helper-proto.h" +#include "tcg/helper-tcg.h" + + +static inline bool hw_local_breakpoint_enabled(unsigned long dr7, int inde= x) +{ + return (dr7 >> (index * 2)) & 1; +} + +static inline bool hw_global_breakpoint_enabled(unsigned long dr7, int ind= ex) +{ + return (dr7 >> (index * 2)) & 2; + +} +static inline bool hw_breakpoint_enabled(unsigned long dr7, int index) +{ + return hw_global_breakpoint_enabled(dr7, index) || + hw_local_breakpoint_enabled(dr7, index); +} + +static inline int hw_breakpoint_type(unsigned long dr7, int index) +{ + return (dr7 >> (DR7_TYPE_SHIFT + (index * 4))) & 3; +} + +static inline int hw_breakpoint_len(unsigned long dr7, int index) +{ + int len =3D ((dr7 >> (DR7_LEN_SHIFT + (index * 4))) & 3); + return (len =3D=3D 2) ? 8 : len + 1; +} + +static int hw_breakpoint_insert(CPUX86State *env, int index) +{ + CPUState *cs =3D env_cpu(env); + target_ulong dr7 =3D env->dr[7]; + target_ulong drN =3D env->dr[index]; + int err =3D 0; + + switch (hw_breakpoint_type(dr7, index)) { + case DR7_TYPE_BP_INST: + if (hw_breakpoint_enabled(dr7, index)) { + err =3D cpu_breakpoint_insert(cs, drN, BP_CPU, + &env->cpu_breakpoint[index]); + } + break; + + case DR7_TYPE_IO_RW: + /* Notice when we should enable calls to bpt_io. */ + return hw_breakpoint_enabled(env->dr[7], index) + ? HF_IOBPT_MASK : 0; + + case DR7_TYPE_DATA_WR: + if (hw_breakpoint_enabled(dr7, index)) { + err =3D cpu_watchpoint_insert(cs, drN, + hw_breakpoint_len(dr7, index), + BP_CPU | BP_MEM_WRITE, + &env->cpu_watchpoint[index]); + } + break; + + case DR7_TYPE_DATA_RW: + if (hw_breakpoint_enabled(dr7, index)) { + err =3D cpu_watchpoint_insert(cs, drN, + hw_breakpoint_len(dr7, index), + BP_CPU | BP_MEM_ACCESS, + &env->cpu_watchpoint[index]); + } + break; + } + if (err) { + env->cpu_breakpoint[index] =3D NULL; + } + return 0; +} + +static void hw_breakpoint_remove(CPUX86State *env, int index) +{ + CPUState *cs =3D env_cpu(env); + + switch (hw_breakpoint_type(env->dr[7], index)) { + case DR7_TYPE_BP_INST: + if (env->cpu_breakpoint[index]) { + cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]); + env->cpu_breakpoint[index] =3D NULL; + } + break; + + case DR7_TYPE_DATA_WR: + case DR7_TYPE_DATA_RW: + if (env->cpu_breakpoint[index]) { + cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]); + env->cpu_breakpoint[index] =3D NULL; + } + break; + + case DR7_TYPE_IO_RW: + /* HF_IOBPT_MASK cleared elsewhere. */ + break; + } +} + +void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7) +{ + target_ulong old_dr7 =3D env->dr[7]; + int iobpt =3D 0; + int i; + + new_dr7 |=3D DR7_FIXED_1; + + /* If nothing is changing except the global/local enable bits, + then we can make the change more efficient. */ + if (((old_dr7 ^ new_dr7) & ~0xff) =3D=3D 0) { + /* Fold the global and local enable bits together into the + global fields, then xor to show which registers have + changed collective enable state. */ + int mod =3D ((old_dr7 | old_dr7 * 2) ^ (new_dr7 | new_dr7 * 2)) & = 0xff; + + for (i =3D 0; i < DR7_MAX_BP; i++) { + if ((mod & (2 << i * 2)) && !hw_breakpoint_enabled(new_dr7, i)= ) { + hw_breakpoint_remove(env, i); + } + } + env->dr[7] =3D new_dr7; + for (i =3D 0; i < DR7_MAX_BP; i++) { + if (mod & (2 << i * 2) && hw_breakpoint_enabled(new_dr7, i)) { + iobpt |=3D hw_breakpoint_insert(env, i); + } else if (hw_breakpoint_type(new_dr7, i) =3D=3D DR7_TYPE_IO_RW + && hw_breakpoint_enabled(new_dr7, i)) { + iobpt |=3D HF_IOBPT_MASK; + } + } + } else { + for (i =3D 0; i < DR7_MAX_BP; i++) { + hw_breakpoint_remove(env, i); + } + env->dr[7] =3D new_dr7; + for (i =3D 0; i < DR7_MAX_BP; i++) { + iobpt |=3D hw_breakpoint_insert(env, i); + } + } + + env->hflags =3D (env->hflags & ~HF_IOBPT_MASK) | iobpt; +} + +bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update) +{ + target_ulong dr6; + int reg; + bool hit_enabled =3D false; + + dr6 =3D env->dr[6] & ~0xf; + for (reg =3D 0; reg < DR7_MAX_BP; reg++) { + bool bp_match =3D false; + bool wp_match =3D false; + + switch (hw_breakpoint_type(env->dr[7], reg)) { + case DR7_TYPE_BP_INST: + if (env->dr[reg] =3D=3D env->eip) { + bp_match =3D true; + } + break; + case DR7_TYPE_DATA_WR: + case DR7_TYPE_DATA_RW: + if (env->cpu_watchpoint[reg] && + env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) { + wp_match =3D true; + } + break; + case DR7_TYPE_IO_RW: + break; + } + if (bp_match || wp_match) { + dr6 |=3D 1 << reg; + if (hw_breakpoint_enabled(env->dr[7], reg)) { + hit_enabled =3D true; + } + } + } + + if (hit_enabled || force_dr6_update) { + env->dr[6] =3D dr6; + } + + return hit_enabled; +} + +void breakpoint_handler(CPUState *cs) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + CPUBreakpoint *bp; + + if (cs->watchpoint_hit) { + if (cs->watchpoint_hit->flags & BP_CPU) { + cs->watchpoint_hit =3D NULL; + if (check_hw_breakpoints(env, false)) { + raise_exception(env, EXCP01_DB); + } else { + cpu_loop_exit_noexc(cs); + } + } + } else { + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { + if (bp->pc =3D=3D env->eip) { + if (bp->flags & BP_CPU) { + check_hw_breakpoints(env, true); + raise_exception(env, EXCP01_DB); + } + break; + } + } + } +} + +void helper_set_dr(CPUX86State *env, int reg, target_ulong t0) +{ + switch (reg) { + case 0: case 1: case 2: case 3: + if (hw_breakpoint_enabled(env->dr[7], reg) + && hw_breakpoint_type(env->dr[7], reg) !=3D DR7_TYPE_IO_RW) { + hw_breakpoint_remove(env, reg); + env->dr[reg] =3D t0; + hw_breakpoint_insert(env, reg); + } else { + env->dr[reg] =3D t0; + } + return; + case 4: + if (env->cr[4] & CR4_DE_MASK) { + break; + } + /* fallthru */ + case 6: + env->dr[6] =3D t0 | DR6_FIXED_1; + return; + case 5: + if (env->cr[4] & CR4_DE_MASK) { + break; + } + /* fallthru */ + case 7: + cpu_x86_update_dr7(env, t0); + return; + } + raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); +} + +/* Check if Port I/O is trapped by a breakpoint. */ +void helper_bpt_io(CPUX86State *env, uint32_t port, + uint32_t size, target_ulong next_eip) +{ + target_ulong dr7 =3D env->dr[7]; + int i, hit =3D 0; + + for (i =3D 0; i < DR7_MAX_BP; ++i) { + if (hw_breakpoint_type(dr7, i) =3D=3D DR7_TYPE_IO_RW + && hw_breakpoint_enabled(dr7, i)) { + int bpt_len =3D hw_breakpoint_len(dr7, i); + if (port + size - 1 >=3D env->dr[i] + && port <=3D env->dr[i] + bpt_len - 1) { + hit |=3D 1 << i; + } + } + } + + if (hit) { + env->dr[6] =3D (env->dr[6] & ~0xf) | hit; + env->eip =3D next_eip; + raise_exception(env, EXCP01_DB); + } +} diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index b882041ef0..60fd9d3885 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -1117,16 +1117,20 @@ static inline void gen_cmps(DisasContext *s, MemOp = ot) static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot) { if (s->flags & HF_IOBPT_MASK) { +#ifdef CONFIG_USER_ONLY + /* user-mode cpu should not be in IOBPT mode */ + g_assert_not_reached(); +#else TCGv_i32 t_size =3D tcg_const_i32(1 << ot); TCGv t_next =3D tcg_const_tl(s->pc - s->cs_base); =20 gen_helper_bpt_io(cpu_env, t_port, t_size, t_next); tcg_temp_free_i32(t_size); tcg_temp_free(t_next); +#endif /* CONFIG_USER_ONLY */ } } =20 - static inline void gen_ins(DisasContext *s, MemOp ot) { gen_string_movl_A0_EDI(s); @@ -8054,6 +8058,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) case 0x123: /* mov drN, reg */ if (s->cpl !=3D 0) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); +#ifndef CONFIG_USER_ONLY } else { modrm =3D x86_ldub_code(env, s); /* Ignore the mod bits (assume (modrm&0xc0)=3D=3D0xc0). @@ -8083,6 +8088,7 @@ static target_ulong disas_insn(DisasContext *s, CPUSt= ate *cpu) gen_helper_get_dr(s->T0, cpu_env, s->tmp2_i32); gen_op_mov_reg_v(s, ot, rm, s->T0); } +#endif /* CONFIG_USER_ONLY */ } break; case 0x106: /* clts */ diff --git a/target/i386/tcg/sysemu/meson.build b/target/i386/tcg/sysemu/me= son.build index 6d0a0a0fee..1580950141 100644 --- a/target/i386/tcg/sysemu/meson.build +++ b/target/i386/tcg/sysemu/meson.build @@ -2,4 +2,5 @@ i386_softmmu_ss.add(when: ['CONFIG_TCG', 'CONFIG_SOFTMMU'],= if_true: files( 'tcg-cpu.c', 'smm_helper.c', 'excp_helper.c', + 'bpt_helper.c', )) --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333740; cv=none; d=zohomail.com; s=zohoarc; b=iefAtEKeK8HU7XolXHEXSCdL855iAp5j+Ixdtma+Wn7mY+a+5FyLp+ZreaKi6RWcak+pTnXte4BbBavZmT1UlAqc5aVemVn+2LWXuUJ9127bsYmZlxYIIZpCXVXjPgjPPQfSUnVe2RegTnCWVkiW7ehm+RiTdu35MHyB+orZmT8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333740; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=T6IRT5uR7C4aawd1H4i0A1elk1qwPqonPG9HmG1eA9U=; b=mL+gwZ2PmfBr1LIEm0FTZ2JEEeIf+18Dja2iaN3oXCf4d7rXaHJJyVo4be3RW9ZEbhdy7QgpC4icVdMZ/Q1PjtG/Cy4069Fis9gKVPSSm4XXGGByOQBq2NgBOzzi2p4Os7gSxegHGAuUQVQXb1mNjta0ecOuPQRtrqRyBqluX9w= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 161433374081071.01542784903131; Fri, 26 Feb 2021 02:02:20 -0800 (PST) Received: from localhost ([::1]:47510 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZwx-0002jO-7H for importer@patchew.org; Fri, 26 Feb 2021 05:02:19 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36502) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl9-0005Sx-PK for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:07 -0500 Received: from mx2.suse.de ([195.135.220.15]:43230) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl1-0004rK-Hx for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:07 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 2354EAF9A; Fri, 26 Feb 2021 09:49:47 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 11/18] i386: split misc helper user stubs and sysemu part Date: Fri, 26 Feb 2021 10:49:32 +0100 Message-Id: <20210226094939.11087-12-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson --- target/i386/tcg/misc_helper.c | 463 --------------------------- target/i386/tcg/sysemu/misc_helper.c | 438 +++++++++++++++++++++++++ target/i386/tcg/user/misc_stubs.c | 75 +++++ target/i386/tcg/sysemu/meson.build | 1 + target/i386/tcg/user/meson.build | 1 + 5 files changed, 515 insertions(+), 463 deletions(-) create mode 100644 target/i386/tcg/sysemu/misc_helper.c create mode 100644 target/i386/tcg/user/misc_stubs.c diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c index f02e4fd400..82fb7037ac 100644 --- a/target/i386/tcg/misc_helper.c +++ b/target/i386/tcg/misc_helper.c @@ -18,12 +18,9 @@ */ =20 #include "qemu/osdep.h" -#include "qemu/main-loop.h" #include "cpu.h" #include "exec/helper-proto.h" #include "exec/exec-all.h" -#include "exec/cpu_ldst.h" -#include "exec/address-spaces.h" #include "helper-tcg.h" =20 /* @@ -39,69 +36,6 @@ void cpu_load_eflags(CPUX86State *env, int eflags, int u= pdate_mask) (eflags & update_mask) | 0x2; } =20 -void helper_outb(CPUX86State *env, uint32_t port, uint32_t data) -{ -#ifdef CONFIG_USER_ONLY - fprintf(stderr, "outb: port=3D0x%04x, data=3D%02x\n", port, data); -#else - address_space_stb(&address_space_io, port, data, - cpu_get_mem_attrs(env), NULL); -#endif -} - -target_ulong helper_inb(CPUX86State *env, uint32_t port) -{ -#ifdef CONFIG_USER_ONLY - fprintf(stderr, "inb: port=3D0x%04x\n", port); - return 0; -#else - return address_space_ldub(&address_space_io, port, - cpu_get_mem_attrs(env), NULL); -#endif -} - -void helper_outw(CPUX86State *env, uint32_t port, uint32_t data) -{ -#ifdef CONFIG_USER_ONLY - fprintf(stderr, "outw: port=3D0x%04x, data=3D%04x\n", port, data); -#else - address_space_stw(&address_space_io, port, data, - cpu_get_mem_attrs(env), NULL); -#endif -} - -target_ulong helper_inw(CPUX86State *env, uint32_t port) -{ -#ifdef CONFIG_USER_ONLY - fprintf(stderr, "inw: port=3D0x%04x\n", port); - return 0; -#else - return address_space_lduw(&address_space_io, port, - cpu_get_mem_attrs(env), NULL); -#endif -} - -void helper_outl(CPUX86State *env, uint32_t port, uint32_t data) -{ -#ifdef CONFIG_USER_ONLY - fprintf(stderr, "outl: port=3D0x%04x, data=3D%08x\n", port, data); -#else - address_space_stl(&address_space_io, port, data, - cpu_get_mem_attrs(env), NULL); -#endif -} - -target_ulong helper_inl(CPUX86State *env, uint32_t port) -{ -#ifdef CONFIG_USER_ONLY - fprintf(stderr, "inl: port=3D0x%04x\n", port); - return 0; -#else - return address_space_ldl(&address_space_io, port, - cpu_get_mem_attrs(env), NULL); -#endif -} - void helper_into(CPUX86State *env, int next_eip_addend) { int eflags; @@ -126,64 +60,6 @@ void helper_cpuid(CPUX86State *env) env->regs[R_EDX] =3D edx; } =20 -#if defined(CONFIG_USER_ONLY) -target_ulong helper_read_crN(CPUX86State *env, int reg) -{ - return 0; -} - -void helper_write_crN(CPUX86State *env, int reg, target_ulong t0) -{ -} -#else -target_ulong helper_read_crN(CPUX86State *env, int reg) -{ - target_ulong val; - - cpu_svm_check_intercept_param(env, SVM_EXIT_READ_CR0 + reg, 0, GETPC()= ); - switch (reg) { - default: - val =3D env->cr[reg]; - break; - case 8: - if (!(env->hflags2 & HF2_VINTR_MASK)) { - val =3D cpu_get_apic_tpr(env_archcpu(env)->apic_state); - } else { - val =3D env->v_tpr; - } - break; - } - return val; -} - -void helper_write_crN(CPUX86State *env, int reg, target_ulong t0) -{ - cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0, GETPC(= )); - switch (reg) { - case 0: - cpu_x86_update_cr0(env, t0); - break; - case 3: - cpu_x86_update_cr3(env, t0); - break; - case 4: - cpu_x86_update_cr4(env, t0); - break; - case 8: - if (!(env->hflags2 & HF2_VINTR_MASK)) { - qemu_mutex_lock_iothread(); - cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0); - qemu_mutex_unlock_iothread(); - } - env->v_tpr =3D t0 & 0x0f; - break; - default: - env->cr[reg] =3D t0; - break; - } -} -#endif - void helper_lmsw(CPUX86State *env, target_ulong t0) { /* only 4 lower bits of CR0 are modified. PE cannot be set to zero @@ -232,345 +108,6 @@ void helper_rdpmc(CPUX86State *env) raise_exception_err(env, EXCP06_ILLOP, 0); } =20 -#if defined(CONFIG_USER_ONLY) -void helper_wrmsr(CPUX86State *env) -{ -} - -void helper_rdmsr(CPUX86State *env) -{ -} -#else -void helper_wrmsr(CPUX86State *env) -{ - uint64_t val; - CPUState *cs =3D env_cpu(env); - - cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC()); - - val =3D ((uint32_t)env->regs[R_EAX]) | - ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32); - - switch ((uint32_t)env->regs[R_ECX]) { - case MSR_IA32_SYSENTER_CS: - env->sysenter_cs =3D val & 0xffff; - break; - case MSR_IA32_SYSENTER_ESP: - env->sysenter_esp =3D val; - break; - case MSR_IA32_SYSENTER_EIP: - env->sysenter_eip =3D val; - break; - case MSR_IA32_APICBASE: - cpu_set_apic_base(env_archcpu(env)->apic_state, val); - break; - case MSR_EFER: - { - uint64_t update_mask; - - update_mask =3D 0; - if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) { - update_mask |=3D MSR_EFER_SCE; - } - if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { - update_mask |=3D MSR_EFER_LME; - } - if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) { - update_mask |=3D MSR_EFER_FFXSR; - } - if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) { - update_mask |=3D MSR_EFER_NXE; - } - if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { - update_mask |=3D MSR_EFER_SVME; - } - if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) { - update_mask |=3D MSR_EFER_FFXSR; - } - cpu_load_efer(env, (env->efer & ~update_mask) | - (val & update_mask)); - } - break; - case MSR_STAR: - env->star =3D val; - break; - case MSR_PAT: - env->pat =3D val; - break; - case MSR_IA32_PKRS: - if (val & 0xFFFFFFFF00000000ull) { - goto error; - } - env->pkrs =3D val; - tlb_flush(cs); - break; - case MSR_VM_HSAVE_PA: - env->vm_hsave =3D val; - break; -#ifdef TARGET_X86_64 - case MSR_LSTAR: - env->lstar =3D val; - break; - case MSR_CSTAR: - env->cstar =3D val; - break; - case MSR_FMASK: - env->fmask =3D val; - break; - case MSR_FSBASE: - env->segs[R_FS].base =3D val; - break; - case MSR_GSBASE: - env->segs[R_GS].base =3D val; - break; - case MSR_KERNELGSBASE: - env->kernelgsbase =3D val; - break; -#endif - case MSR_MTRRphysBase(0): - case MSR_MTRRphysBase(1): - case MSR_MTRRphysBase(2): - case MSR_MTRRphysBase(3): - case MSR_MTRRphysBase(4): - case MSR_MTRRphysBase(5): - case MSR_MTRRphysBase(6): - case MSR_MTRRphysBase(7): - env->mtrr_var[((uint32_t)env->regs[R_ECX] - - MSR_MTRRphysBase(0)) / 2].base =3D val; - break; - case MSR_MTRRphysMask(0): - case MSR_MTRRphysMask(1): - case MSR_MTRRphysMask(2): - case MSR_MTRRphysMask(3): - case MSR_MTRRphysMask(4): - case MSR_MTRRphysMask(5): - case MSR_MTRRphysMask(6): - case MSR_MTRRphysMask(7): - env->mtrr_var[((uint32_t)env->regs[R_ECX] - - MSR_MTRRphysMask(0)) / 2].mask =3D val; - break; - case MSR_MTRRfix64K_00000: - env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - - MSR_MTRRfix64K_00000] =3D val; - break; - case MSR_MTRRfix16K_80000: - case MSR_MTRRfix16K_A0000: - env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - - MSR_MTRRfix16K_80000 + 1] =3D val; - break; - case MSR_MTRRfix4K_C0000: - case MSR_MTRRfix4K_C8000: - case MSR_MTRRfix4K_D0000: - case MSR_MTRRfix4K_D8000: - case MSR_MTRRfix4K_E0000: - case MSR_MTRRfix4K_E8000: - case MSR_MTRRfix4K_F0000: - case MSR_MTRRfix4K_F8000: - env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - - MSR_MTRRfix4K_C0000 + 3] =3D val; - break; - case MSR_MTRRdefType: - env->mtrr_deftype =3D val; - break; - case MSR_MCG_STATUS: - env->mcg_status =3D val; - break; - case MSR_MCG_CTL: - if ((env->mcg_cap & MCG_CTL_P) - && (val =3D=3D 0 || val =3D=3D ~(uint64_t)0)) { - env->mcg_ctl =3D val; - } - break; - case MSR_TSC_AUX: - env->tsc_aux =3D val; - break; - case MSR_IA32_MISC_ENABLE: - env->msr_ia32_misc_enable =3D val; - break; - case MSR_IA32_BNDCFGS: - /* FIXME: #GP if reserved bits are set. */ - /* FIXME: Extend highest implemented bit of linear address. */ - env->msr_bndcfgs =3D val; - cpu_sync_bndcs_hflags(env); - break; - default: - if ((uint32_t)env->regs[R_ECX] >=3D MSR_MC0_CTL - && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + - (4 * env->mcg_cap & 0xff)) { - uint32_t offset =3D (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL; - if ((offset & 0x3) !=3D 0 - || (val =3D=3D 0 || val =3D=3D ~(uint64_t)0)) { - env->mce_banks[offset] =3D val; - } - break; - } - /* XXX: exception? */ - break; - } - return; -error: - raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); -} - -void helper_rdmsr(CPUX86State *env) -{ - X86CPU *x86_cpu =3D env_archcpu(env); - uint64_t val; - - cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC()); - - switch ((uint32_t)env->regs[R_ECX]) { - case MSR_IA32_SYSENTER_CS: - val =3D env->sysenter_cs; - break; - case MSR_IA32_SYSENTER_ESP: - val =3D env->sysenter_esp; - break; - case MSR_IA32_SYSENTER_EIP: - val =3D env->sysenter_eip; - break; - case MSR_IA32_APICBASE: - val =3D cpu_get_apic_base(env_archcpu(env)->apic_state); - break; - case MSR_EFER: - val =3D env->efer; - break; - case MSR_STAR: - val =3D env->star; - break; - case MSR_PAT: - val =3D env->pat; - break; - case MSR_IA32_PKRS: - val =3D env->pkrs; - break; - case MSR_VM_HSAVE_PA: - val =3D env->vm_hsave; - break; - case MSR_IA32_PERF_STATUS: - /* tsc_increment_by_tick */ - val =3D 1000ULL; - /* CPU multiplier */ - val |=3D (((uint64_t)4ULL) << 40); - break; -#ifdef TARGET_X86_64 - case MSR_LSTAR: - val =3D env->lstar; - break; - case MSR_CSTAR: - val =3D env->cstar; - break; - case MSR_FMASK: - val =3D env->fmask; - break; - case MSR_FSBASE: - val =3D env->segs[R_FS].base; - break; - case MSR_GSBASE: - val =3D env->segs[R_GS].base; - break; - case MSR_KERNELGSBASE: - val =3D env->kernelgsbase; - break; - case MSR_TSC_AUX: - val =3D env->tsc_aux; - break; -#endif - case MSR_SMI_COUNT: - val =3D env->msr_smi_count; - break; - case MSR_MTRRphysBase(0): - case MSR_MTRRphysBase(1): - case MSR_MTRRphysBase(2): - case MSR_MTRRphysBase(3): - case MSR_MTRRphysBase(4): - case MSR_MTRRphysBase(5): - case MSR_MTRRphysBase(6): - case MSR_MTRRphysBase(7): - val =3D env->mtrr_var[((uint32_t)env->regs[R_ECX] - - MSR_MTRRphysBase(0)) / 2].base; - break; - case MSR_MTRRphysMask(0): - case MSR_MTRRphysMask(1): - case MSR_MTRRphysMask(2): - case MSR_MTRRphysMask(3): - case MSR_MTRRphysMask(4): - case MSR_MTRRphysMask(5): - case MSR_MTRRphysMask(6): - case MSR_MTRRphysMask(7): - val =3D env->mtrr_var[((uint32_t)env->regs[R_ECX] - - MSR_MTRRphysMask(0)) / 2].mask; - break; - case MSR_MTRRfix64K_00000: - val =3D env->mtrr_fixed[0]; - break; - case MSR_MTRRfix16K_80000: - case MSR_MTRRfix16K_A0000: - val =3D env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - - MSR_MTRRfix16K_80000 + 1]; - break; - case MSR_MTRRfix4K_C0000: - case MSR_MTRRfix4K_C8000: - case MSR_MTRRfix4K_D0000: - case MSR_MTRRfix4K_D8000: - case MSR_MTRRfix4K_E0000: - case MSR_MTRRfix4K_E8000: - case MSR_MTRRfix4K_F0000: - case MSR_MTRRfix4K_F8000: - val =3D env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - - MSR_MTRRfix4K_C0000 + 3]; - break; - case MSR_MTRRdefType: - val =3D env->mtrr_deftype; - break; - case MSR_MTRRcap: - if (env->features[FEAT_1_EDX] & CPUID_MTRR) { - val =3D MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | - MSR_MTRRcap_WC_SUPPORTED; - } else { - /* XXX: exception? */ - val =3D 0; - } - break; - case MSR_MCG_CAP: - val =3D env->mcg_cap; - break; - case MSR_MCG_CTL: - if (env->mcg_cap & MCG_CTL_P) { - val =3D env->mcg_ctl; - } else { - val =3D 0; - } - break; - case MSR_MCG_STATUS: - val =3D env->mcg_status; - break; - case MSR_IA32_MISC_ENABLE: - val =3D env->msr_ia32_misc_enable; - break; - case MSR_IA32_BNDCFGS: - val =3D env->msr_bndcfgs; - break; - case MSR_IA32_UCODE_REV: - val =3D x86_cpu->ucode_rev; - break; - default: - if ((uint32_t)env->regs[R_ECX] >=3D MSR_MC0_CTL - && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + - (4 * env->mcg_cap & 0xff)) { - uint32_t offset =3D (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL; - val =3D env->mce_banks[offset]; - break; - } - /* XXX: exception? */ - val =3D 0; - break; - } - env->regs[R_EAX] =3D (uint32_t)(val); - env->regs[R_EDX] =3D (uint32_t)(val >> 32); -} -#endif - static void do_pause(X86CPU *cpu) { CPUState *cs =3D CPU(cpu); diff --git a/target/i386/tcg/sysemu/misc_helper.c b/target/i386/tcg/sysemu/= misc_helper.c new file mode 100644 index 0000000000..6a88840cf2 --- /dev/null +++ b/target/i386/tcg/sysemu/misc_helper.c @@ -0,0 +1,438 @@ +/* + * x86 misc helpers - sysemu code + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/main-loop.h" +#include "cpu.h" +#include "exec/helper-proto.h" +#include "exec/cpu_ldst.h" +#include "exec/address-spaces.h" +#include "tcg/helper-tcg.h" + +void helper_outb(CPUX86State *env, uint32_t port, uint32_t data) +{ + address_space_stb(&address_space_io, port, data, + cpu_get_mem_attrs(env), NULL); +} + +target_ulong helper_inb(CPUX86State *env, uint32_t port) +{ + return address_space_ldub(&address_space_io, port, + cpu_get_mem_attrs(env), NULL); +} + +void helper_outw(CPUX86State *env, uint32_t port, uint32_t data) +{ + address_space_stw(&address_space_io, port, data, + cpu_get_mem_attrs(env), NULL); +} + +target_ulong helper_inw(CPUX86State *env, uint32_t port) +{ + return address_space_lduw(&address_space_io, port, + cpu_get_mem_attrs(env), NULL); +} + +void helper_outl(CPUX86State *env, uint32_t port, uint32_t data) +{ + address_space_stl(&address_space_io, port, data, + cpu_get_mem_attrs(env), NULL); +} + +target_ulong helper_inl(CPUX86State *env, uint32_t port) +{ + return address_space_ldl(&address_space_io, port, + cpu_get_mem_attrs(env), NULL); +} + +target_ulong helper_read_crN(CPUX86State *env, int reg) +{ + target_ulong val; + + cpu_svm_check_intercept_param(env, SVM_EXIT_READ_CR0 + reg, 0, GETPC()= ); + switch (reg) { + default: + val =3D env->cr[reg]; + break; + case 8: + if (!(env->hflags2 & HF2_VINTR_MASK)) { + val =3D cpu_get_apic_tpr(env_archcpu(env)->apic_state); + } else { + val =3D env->v_tpr; + } + break; + } + return val; +} + +void helper_write_crN(CPUX86State *env, int reg, target_ulong t0) +{ + cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0, GETPC(= )); + switch (reg) { + case 0: + cpu_x86_update_cr0(env, t0); + break; + case 3: + cpu_x86_update_cr3(env, t0); + break; + case 4: + cpu_x86_update_cr4(env, t0); + break; + case 8: + if (!(env->hflags2 & HF2_VINTR_MASK)) { + qemu_mutex_lock_iothread(); + cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0); + qemu_mutex_unlock_iothread(); + } + env->v_tpr =3D t0 & 0x0f; + break; + default: + env->cr[reg] =3D t0; + break; + } +} + +void helper_wrmsr(CPUX86State *env) +{ + uint64_t val; + CPUState *cs =3D env_cpu(env); + + cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC()); + + val =3D ((uint32_t)env->regs[R_EAX]) | + ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32); + + switch ((uint32_t)env->regs[R_ECX]) { + case MSR_IA32_SYSENTER_CS: + env->sysenter_cs =3D val & 0xffff; + break; + case MSR_IA32_SYSENTER_ESP: + env->sysenter_esp =3D val; + break; + case MSR_IA32_SYSENTER_EIP: + env->sysenter_eip =3D val; + break; + case MSR_IA32_APICBASE: + cpu_set_apic_base(env_archcpu(env)->apic_state, val); + break; + case MSR_EFER: + { + uint64_t update_mask; + + update_mask =3D 0; + if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) { + update_mask |=3D MSR_EFER_SCE; + } + if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { + update_mask |=3D MSR_EFER_LME; + } + if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) { + update_mask |=3D MSR_EFER_FFXSR; + } + if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) { + update_mask |=3D MSR_EFER_NXE; + } + if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) { + update_mask |=3D MSR_EFER_SVME; + } + if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) { + update_mask |=3D MSR_EFER_FFXSR; + } + cpu_load_efer(env, (env->efer & ~update_mask) | + (val & update_mask)); + } + break; + case MSR_STAR: + env->star =3D val; + break; + case MSR_PAT: + env->pat =3D val; + break; + case MSR_IA32_PKRS: + if (val & 0xFFFFFFFF00000000ull) { + goto error; + } + env->pkrs =3D val; + tlb_flush(cs); + break; + case MSR_VM_HSAVE_PA: + env->vm_hsave =3D val; + break; +#ifdef TARGET_X86_64 + case MSR_LSTAR: + env->lstar =3D val; + break; + case MSR_CSTAR: + env->cstar =3D val; + break; + case MSR_FMASK: + env->fmask =3D val; + break; + case MSR_FSBASE: + env->segs[R_FS].base =3D val; + break; + case MSR_GSBASE: + env->segs[R_GS].base =3D val; + break; + case MSR_KERNELGSBASE: + env->kernelgsbase =3D val; + break; +#endif + case MSR_MTRRphysBase(0): + case MSR_MTRRphysBase(1): + case MSR_MTRRphysBase(2): + case MSR_MTRRphysBase(3): + case MSR_MTRRphysBase(4): + case MSR_MTRRphysBase(5): + case MSR_MTRRphysBase(6): + case MSR_MTRRphysBase(7): + env->mtrr_var[((uint32_t)env->regs[R_ECX] - + MSR_MTRRphysBase(0)) / 2].base =3D val; + break; + case MSR_MTRRphysMask(0): + case MSR_MTRRphysMask(1): + case MSR_MTRRphysMask(2): + case MSR_MTRRphysMask(3): + case MSR_MTRRphysMask(4): + case MSR_MTRRphysMask(5): + case MSR_MTRRphysMask(6): + case MSR_MTRRphysMask(7): + env->mtrr_var[((uint32_t)env->regs[R_ECX] - + MSR_MTRRphysMask(0)) / 2].mask =3D val; + break; + case MSR_MTRRfix64K_00000: + env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - + MSR_MTRRfix64K_00000] =3D val; + break; + case MSR_MTRRfix16K_80000: + case MSR_MTRRfix16K_A0000: + env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - + MSR_MTRRfix16K_80000 + 1] =3D val; + break; + case MSR_MTRRfix4K_C0000: + case MSR_MTRRfix4K_C8000: + case MSR_MTRRfix4K_D0000: + case MSR_MTRRfix4K_D8000: + case MSR_MTRRfix4K_E0000: + case MSR_MTRRfix4K_E8000: + case MSR_MTRRfix4K_F0000: + case MSR_MTRRfix4K_F8000: + env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - + MSR_MTRRfix4K_C0000 + 3] =3D val; + break; + case MSR_MTRRdefType: + env->mtrr_deftype =3D val; + break; + case MSR_MCG_STATUS: + env->mcg_status =3D val; + break; + case MSR_MCG_CTL: + if ((env->mcg_cap & MCG_CTL_P) + && (val =3D=3D 0 || val =3D=3D ~(uint64_t)0)) { + env->mcg_ctl =3D val; + } + break; + case MSR_TSC_AUX: + env->tsc_aux =3D val; + break; + case MSR_IA32_MISC_ENABLE: + env->msr_ia32_misc_enable =3D val; + break; + case MSR_IA32_BNDCFGS: + /* FIXME: #GP if reserved bits are set. */ + /* FIXME: Extend highest implemented bit of linear address. */ + env->msr_bndcfgs =3D val; + cpu_sync_bndcs_hflags(env); + break; + default: + if ((uint32_t)env->regs[R_ECX] >=3D MSR_MC0_CTL + && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + + (4 * env->mcg_cap & 0xff)) { + uint32_t offset =3D (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL; + if ((offset & 0x3) !=3D 0 + || (val =3D=3D 0 || val =3D=3D ~(uint64_t)0)) { + env->mce_banks[offset] =3D val; + } + break; + } + /* XXX: exception? */ + break; + } + return; +error: + raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); +} + +void helper_rdmsr(CPUX86State *env) +{ + X86CPU *x86_cpu =3D env_archcpu(env); + uint64_t val; + + cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC()); + + switch ((uint32_t)env->regs[R_ECX]) { + case MSR_IA32_SYSENTER_CS: + val =3D env->sysenter_cs; + break; + case MSR_IA32_SYSENTER_ESP: + val =3D env->sysenter_esp; + break; + case MSR_IA32_SYSENTER_EIP: + val =3D env->sysenter_eip; + break; + case MSR_IA32_APICBASE: + val =3D cpu_get_apic_base(env_archcpu(env)->apic_state); + break; + case MSR_EFER: + val =3D env->efer; + break; + case MSR_STAR: + val =3D env->star; + break; + case MSR_PAT: + val =3D env->pat; + break; + case MSR_IA32_PKRS: + val =3D env->pkrs; + break; + case MSR_VM_HSAVE_PA: + val =3D env->vm_hsave; + break; + case MSR_IA32_PERF_STATUS: + /* tsc_increment_by_tick */ + val =3D 1000ULL; + /* CPU multiplier */ + val |=3D (((uint64_t)4ULL) << 40); + break; +#ifdef TARGET_X86_64 + case MSR_LSTAR: + val =3D env->lstar; + break; + case MSR_CSTAR: + val =3D env->cstar; + break; + case MSR_FMASK: + val =3D env->fmask; + break; + case MSR_FSBASE: + val =3D env->segs[R_FS].base; + break; + case MSR_GSBASE: + val =3D env->segs[R_GS].base; + break; + case MSR_KERNELGSBASE: + val =3D env->kernelgsbase; + break; + case MSR_TSC_AUX: + val =3D env->tsc_aux; + break; +#endif + case MSR_SMI_COUNT: + val =3D env->msr_smi_count; + break; + case MSR_MTRRphysBase(0): + case MSR_MTRRphysBase(1): + case MSR_MTRRphysBase(2): + case MSR_MTRRphysBase(3): + case MSR_MTRRphysBase(4): + case MSR_MTRRphysBase(5): + case MSR_MTRRphysBase(6): + case MSR_MTRRphysBase(7): + val =3D env->mtrr_var[((uint32_t)env->regs[R_ECX] - + MSR_MTRRphysBase(0)) / 2].base; + break; + case MSR_MTRRphysMask(0): + case MSR_MTRRphysMask(1): + case MSR_MTRRphysMask(2): + case MSR_MTRRphysMask(3): + case MSR_MTRRphysMask(4): + case MSR_MTRRphysMask(5): + case MSR_MTRRphysMask(6): + case MSR_MTRRphysMask(7): + val =3D env->mtrr_var[((uint32_t)env->regs[R_ECX] - + MSR_MTRRphysMask(0)) / 2].mask; + break; + case MSR_MTRRfix64K_00000: + val =3D env->mtrr_fixed[0]; + break; + case MSR_MTRRfix16K_80000: + case MSR_MTRRfix16K_A0000: + val =3D env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - + MSR_MTRRfix16K_80000 + 1]; + break; + case MSR_MTRRfix4K_C0000: + case MSR_MTRRfix4K_C8000: + case MSR_MTRRfix4K_D0000: + case MSR_MTRRfix4K_D8000: + case MSR_MTRRfix4K_E0000: + case MSR_MTRRfix4K_E8000: + case MSR_MTRRfix4K_F0000: + case MSR_MTRRfix4K_F8000: + val =3D env->mtrr_fixed[(uint32_t)env->regs[R_ECX] - + MSR_MTRRfix4K_C0000 + 3]; + break; + case MSR_MTRRdefType: + val =3D env->mtrr_deftype; + break; + case MSR_MTRRcap: + if (env->features[FEAT_1_EDX] & CPUID_MTRR) { + val =3D MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT | + MSR_MTRRcap_WC_SUPPORTED; + } else { + /* XXX: exception? */ + val =3D 0; + } + break; + case MSR_MCG_CAP: + val =3D env->mcg_cap; + break; + case MSR_MCG_CTL: + if (env->mcg_cap & MCG_CTL_P) { + val =3D env->mcg_ctl; + } else { + val =3D 0; + } + break; + case MSR_MCG_STATUS: + val =3D env->mcg_status; + break; + case MSR_IA32_MISC_ENABLE: + val =3D env->msr_ia32_misc_enable; + break; + case MSR_IA32_BNDCFGS: + val =3D env->msr_bndcfgs; + break; + case MSR_IA32_UCODE_REV: + val =3D x86_cpu->ucode_rev; + break; + default: + if ((uint32_t)env->regs[R_ECX] >=3D MSR_MC0_CTL + && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + + (4 * env->mcg_cap & 0xff)) { + uint32_t offset =3D (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL; + val =3D env->mce_banks[offset]; + break; + } + /* XXX: exception? */ + val =3D 0; + break; + } + env->regs[R_EAX] =3D (uint32_t)(val); + env->regs[R_EDX] =3D (uint32_t)(val >> 32); +} diff --git a/target/i386/tcg/user/misc_stubs.c b/target/i386/tcg/user/misc_= stubs.c new file mode 100644 index 0000000000..84df4e65ff --- /dev/null +++ b/target/i386/tcg/user/misc_stubs.c @@ -0,0 +1,75 @@ +/* + * x86 misc helpers + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" + +void helper_outb(CPUX86State *env, uint32_t port, uint32_t data) +{ + g_assert_not_reached(); +} + +target_ulong helper_inb(CPUX86State *env, uint32_t port) +{ + g_assert_not_reached(); + return 0; +} + +void helper_outw(CPUX86State *env, uint32_t port, uint32_t data) +{ + g_assert_not_reached(); +} + +target_ulong helper_inw(CPUX86State *env, uint32_t port) +{ + g_assert_not_reached(); + return 0; +} + +void helper_outl(CPUX86State *env, uint32_t port, uint32_t data) +{ + g_assert_not_reached(); +} + +target_ulong helper_inl(CPUX86State *env, uint32_t port) +{ + g_assert_not_reached(); + return 0; +} + +target_ulong helper_read_crN(CPUX86State *env, int reg) +{ + g_assert_not_reached(); +} + +void helper_write_crN(CPUX86State *env, int reg, target_ulong t0) +{ + g_assert_not_reached(); +} + +void helper_wrmsr(CPUX86State *env) +{ + g_assert_not_reached(); +} + +void helper_rdmsr(CPUX86State *env) +{ + g_assert_not_reached(); +} diff --git a/target/i386/tcg/sysemu/meson.build b/target/i386/tcg/sysemu/me= son.build index 1580950141..b2aaab6eef 100644 --- a/target/i386/tcg/sysemu/meson.build +++ b/target/i386/tcg/sysemu/meson.build @@ -3,4 +3,5 @@ i386_softmmu_ss.add(when: ['CONFIG_TCG', 'CONFIG_SOFTMMU'],= if_true: files( 'smm_helper.c', 'excp_helper.c', 'bpt_helper.c', + 'misc_helper.c', )) diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.= build index e0ef0f02e2..2ab8bd903c 100644 --- a/target/i386/tcg/user/meson.build +++ b/target/i386/tcg/user/meson.build @@ -1,3 +1,4 @@ i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], if_true: files( 'excp_helper.c', + 'misc_stubs.c', )) --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333379; cv=none; d=zohomail.com; s=zohoarc; b=Wa1vV4KBgZ6gimJM3WP+hbkXxzSQttdn4SSrkCvLv7Mc9aSNBk0zFEQn/Lp+XnXEDfwA2sAqjw3CIL7x1wETuEW+oPnDt4/bEelqz+tDvp6pKnIDFcO8dB4xNwtBa0altZc3O+BbzcNN/0kVORDvMzp2iYOjjci4/EJlvqfxUTM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333379; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=9Jd9NzexeFUb4f6SaKcN436zrtaenzVxujQbhJEz0pk=; b=IQeSUcf+AsDHjA/OdejvRscuXkwFbZFZQCRvyJbQy7Q+UwDlZDSCoCTZQYmxjvqMDEJdHEPYLpuE2WZBxv1EQbZC+OYs9todoFinP3YAAh1i3h0hctHn/RXnRlYMPHh4zYVcXnm64uI8mw1MM9XuH7+0+LpVt78s007SViUe9rU= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333379384597.5449498518915; Fri, 26 Feb 2021 01:56:19 -0800 (PST) Received: from localhost ([::1]:33622 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZr7-0005HI-4b for importer@patchew.org; Fri, 26 Feb 2021 04:56:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36412) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl4-0005HE-15 for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:02 -0500 Received: from mx2.suse.de ([195.135.220.15]:43228) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl1-0004rJ-F9 for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:01 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id A38D6AF33; Fri, 26 Feb 2021 09:49:47 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 12/18] i386: separate fpu_helper into user and sysemu parts Date: Fri, 26 Feb 2021 10:49:33 +0100 Message-Id: <20210226094939.11087-13-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Claudio Fontana Reviewed-by: Alex Benn=C3=A9e [claudio: removed unused return value] Signed-off-by: Claudio Fontana --- target/i386/cpu.h | 3 ++ target/i386/tcg/fpu_helper.c | 65 +---------------------------- target/i386/tcg/sysemu/fpu_helper.c | 57 +++++++++++++++++++++++++ target/i386/tcg/user/fpu_helper.c | 58 +++++++++++++++++++++++++ target/i386/tcg/sysemu/meson.build | 1 + target/i386/tcg/user/meson.build | 1 + 6 files changed, 122 insertions(+), 63 deletions(-) create mode 100644 target/i386/tcg/sysemu/fpu_helper.c create mode 100644 target/i386/tcg/user/fpu_helper.c diff --git a/target/i386/cpu.h b/target/i386/cpu.h index c8a84a9033..3797789dc2 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1816,7 +1816,10 @@ int cpu_x86_support_mca_broadcast(CPUX86State *env); int cpu_get_pic_interrupt(CPUX86State *s); /* MSDOS compatibility mode FPU exception support */ void x86_register_ferr_irq(qemu_irq irq); +void fpu_check_raise_ferr_irq(CPUX86State *s); void cpu_set_ignne(void); +void cpu_clear_ignne(void); + /* mpx_helper.c */ void cpu_sync_bndcs_hflags(CPUX86State *env); =20 diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c index 60ed93520a..ade18aa13c 100644 --- a/target/i386/tcg/fpu_helper.c +++ b/target/i386/tcg/fpu_helper.c @@ -21,17 +21,10 @@ #include #include "cpu.h" #include "exec/helper-proto.h" -#include "qemu/host-utils.h" -#include "exec/exec-all.h" -#include "exec/cpu_ldst.h" #include "fpu/softfloat.h" #include "fpu/softfloat-macros.h" #include "helper-tcg.h" =20 -#ifdef CONFIG_SOFTMMU -#include "hw/irq.h" -#endif - /* float macros */ #define FT0 (env->ft0) #define ST0 (env->fpregs[env->fpstt].d) @@ -75,36 +68,6 @@ #define floatx80_ln2_d make_floatx80(0x3ffe, 0xb17217f7d1cf79abLL) #define floatx80_pi_d make_floatx80(0x4000, 0xc90fdaa22168c234LL) =20 -#if !defined(CONFIG_USER_ONLY) -static qemu_irq ferr_irq; - -void x86_register_ferr_irq(qemu_irq irq) -{ - ferr_irq =3D irq; -} - -static void cpu_clear_ignne(void) -{ - CPUX86State *env =3D &X86_CPU(first_cpu)->env; - env->hflags2 &=3D ~HF2_IGNNE_MASK; -} - -void cpu_set_ignne(void) -{ - CPUX86State *env =3D &X86_CPU(first_cpu)->env; - env->hflags2 |=3D HF2_IGNNE_MASK; - /* - * We get here in response to a write to port F0h. The chipset should - * deassert FP_IRQ and FERR# instead should stay signaled until FPSW_S= E is - * cleared, because FERR# and FP_IRQ are two separate pins on real - * hardware. However, we don't model FERR# as a qemu_irq, so we just - * do directly what the chipset would do, i.e. deassert FP_IRQ. - */ - qemu_irq_lower(ferr_irq); -} -#endif - - static inline void fpush(CPUX86State *env) { env->fpstt =3D (env->fpstt - 1) & 7; @@ -203,8 +166,8 @@ static void fpu_raise_exception(CPUX86State *env, uintp= tr_t retaddr) raise_exception_ra(env, EXCP10_COPR, retaddr); } #if !defined(CONFIG_USER_ONLY) - else if (ferr_irq && !(env->hflags2 & HF2_IGNNE_MASK)) { - qemu_irq_raise(ferr_irq); + else { + fpu_check_raise_ferr_irq(env); } #endif } @@ -2501,18 +2464,6 @@ void helper_frstor(CPUX86State *env, target_ulong pt= r, int data32) } } =20 -#if defined(CONFIG_USER_ONLY) -void cpu_x86_fsave(CPUX86State *env, target_ulong ptr, int data32) -{ - helper_fsave(env, ptr, data32); -} - -void cpu_x86_frstor(CPUX86State *env, target_ulong ptr, int data32) -{ - helper_frstor(env, ptr, data32); -} -#endif - #define XO(X) offsetof(X86XSaveArea, X) =20 static void do_xsave_fpu(CPUX86State *env, target_ulong ptr, uintptr_t ra) @@ -2780,18 +2731,6 @@ void helper_fxrstor(CPUX86State *env, target_ulong p= tr) } } =20 -#if defined(CONFIG_USER_ONLY) -void cpu_x86_fxsave(CPUX86State *env, target_ulong ptr) -{ - helper_fxsave(env, ptr); -} - -void cpu_x86_fxrstor(CPUX86State *env, target_ulong ptr) -{ - helper_fxrstor(env, ptr); -} -#endif - void helper_xrstor(CPUX86State *env, target_ulong ptr, uint64_t rfbm) { uintptr_t ra =3D GETPC(); diff --git a/target/i386/tcg/sysemu/fpu_helper.c b/target/i386/tcg/sysemu/f= pu_helper.c new file mode 100644 index 0000000000..1c3610da3b --- /dev/null +++ b/target/i386/tcg/sysemu/fpu_helper.c @@ -0,0 +1,57 @@ +/* + * x86 FPU, MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI helpers (sysemu code) + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "hw/irq.h" + +static qemu_irq ferr_irq; + +void x86_register_ferr_irq(qemu_irq irq) +{ + ferr_irq =3D irq; +} + +void fpu_check_raise_ferr_irq(CPUX86State *env) +{ + if (ferr_irq && !(env->hflags2 & HF2_IGNNE_MASK)) { + qemu_irq_raise(ferr_irq); + return; + } +} + +void cpu_clear_ignne(void) +{ + CPUX86State *env =3D &X86_CPU(first_cpu)->env; + env->hflags2 &=3D ~HF2_IGNNE_MASK; +} + +void cpu_set_ignne(void) +{ + CPUX86State *env =3D &X86_CPU(first_cpu)->env; + env->hflags2 |=3D HF2_IGNNE_MASK; + /* + * We get here in response to a write to port F0h. The chipset should + * deassert FP_IRQ and FERR# instead should stay signaled until FPSW_S= E is + * cleared, because FERR# and FP_IRQ are two separate pins on real + * hardware. However, we don't model FERR# as a qemu_irq, so we just + * do directly what the chipset would do, i.e. deassert FP_IRQ. + */ + qemu_irq_lower(ferr_irq); +} diff --git a/target/i386/tcg/user/fpu_helper.c b/target/i386/tcg/user/fpu_h= elper.c new file mode 100644 index 0000000000..a1b96dc51c --- /dev/null +++ b/target/i386/tcg/user/fpu_helper.c @@ -0,0 +1,58 @@ +/* + * x86 FPU, MMX/3DNow!/SSE/SSE2/SSE3/SSSE3/SSE4/PNI helpers (user-mode) + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" + +/* + * XXX in helper_fsave() we reference GETPC(). Which is only valid when + * directly called from code_gen_buffer. + * + * The signature of cpu_x86_foo should be changed to add a "uintptr_t reta= ddr" + * argument, the callers from linux-user/i386/signal.c must pass 0 for this + * new argument (no unwind required), and the helpers must do + * + * void helper_fsave(CPUX86State *env, target_ulong ptr, int data32) + * { + * cpu_x86_fsave(env, ptr, data32, GETPC()); + * } + * + * etc. + */ + +void cpu_x86_fsave(CPUX86State *env, target_ulong ptr, int data32) +{ + helper_fsave(env, ptr, data32); +} + +void cpu_x86_frstor(CPUX86State *env, target_ulong ptr, int data32) +{ + helper_frstor(env, ptr, data32); +} + +void cpu_x86_fxsave(CPUX86State *env, target_ulong ptr) +{ + helper_fxsave(env, ptr); +} + +void cpu_x86_fxrstor(CPUX86State *env, target_ulong ptr) +{ + helper_fxrstor(env, ptr); +} diff --git a/target/i386/tcg/sysemu/meson.build b/target/i386/tcg/sysemu/me= son.build index b2aaab6eef..f84519a213 100644 --- a/target/i386/tcg/sysemu/meson.build +++ b/target/i386/tcg/sysemu/meson.build @@ -4,4 +4,5 @@ i386_softmmu_ss.add(when: ['CONFIG_TCG', 'CONFIG_SOFTMMU'],= if_true: files( 'excp_helper.c', 'bpt_helper.c', 'misc_helper.c', + 'fpu_helper.c', )) diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.= build index 2ab8bd903c..7d919d3bc8 100644 --- a/target/i386/tcg/user/meson.build +++ b/target/i386/tcg/user/meson.build @@ -1,4 +1,5 @@ i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], if_true: files( 'excp_helper.c', 'misc_stubs.c', + 'fpu_helper.c', )) --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333837; cv=none; d=zohomail.com; s=zohoarc; b=Z34BfUezCOjK8aGx9j+JwcpPUEq8wpcJYk3pcqVnomgV/bBnp39v2I0FUsPXY41Za4ZF3suHMhaz967LszD2fR3Evzj8gJyHgtPHjN0l0lH8fp7Oxp3r6MWrPhYOigI/XQohby/aDZ+Luv2ytWSIikjijm0oJ1AlAoa51Qg7JgQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333837; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=p0urcC0GCfaTmWv0HLz2S3HwJlIJOL1Zz0HcBi4FDFg=; b=bR+P0iLi1+qXI37tJA55Cxl7P1KZ6/DyqUoPKzZ8drwIYWNG43zF8GbNwmQNVa/2PURPvZ7Oz19hiq0wUZmjKn8dQr9HYYByt8UueiWv5P2WtvONEPwcoJ+GJO2mg2wVA+tAqLKXgXkblDOwi4WBkZ8aA9Ljaul20VSJo7nrOPg= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333837857957.6109276800955; Fri, 26 Feb 2021 02:03:57 -0800 (PST) Received: from localhost ([::1]:51034 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZyW-0004HS-Op for importer@patchew.org; Fri, 26 Feb 2021 05:03:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36446) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl6-0005Lm-6y for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:04 -0500 Received: from mx2.suse.de ([195.135.220.15]:43238) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl1-0004rR-QF for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:03 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 32FFFAF44; Fri, 26 Feb 2021 09:49:48 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 13/18] i386: split svm_helper into sysemu and stub-only user Date: Fri, 26 Feb 2021 10:49:34 +0100 Message-Id: <20210226094939.11087-14-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" For now we just copy over the previous user stubs, but really, everything that requires s->cpl =3D=3D 0 should be impossible to trigger from user-mode emulation. Later on we should add a check that asserts this easily f.e.: static bool check_cpl0(DisasContext *s) { int cpl =3D s->cpl; #ifdef CONFIG_USER_ONLY assert(cpl =3D=3D 3); #endif if (cpl !=3D 0) { gen_exception(s, EXCP0D_GPF, s->pc_start - s->cs_base); return false; } return true; } Signed-off-by: Claudio Fontana Cc: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/tcg/{ =3D> sysemu}/svm_helper.c | 62 +----------------- target/i386/tcg/user/svm_stubs.c | 76 +++++++++++++++++++++++ target/i386/tcg/meson.build | 1 - target/i386/tcg/sysemu/meson.build | 1 + target/i386/tcg/user/meson.build | 1 + 5 files changed, 80 insertions(+), 61 deletions(-) rename target/i386/tcg/{ =3D> sysemu}/svm_helper.c (96%) create mode 100644 target/i386/tcg/user/svm_stubs.c diff --git a/target/i386/tcg/svm_helper.c b/target/i386/tcg/sysemu/svm_help= er.c similarity index 96% rename from target/i386/tcg/svm_helper.c rename to target/i386/tcg/sysemu/svm_helper.c index 097bb9b83d..5b9c6f18be 100644 --- a/target/i386/tcg/svm_helper.c +++ b/target/i386/tcg/sysemu/svm_helper.c @@ -1,5 +1,5 @@ /* - * x86 SVM helpers + * x86 SVM helpers (sysemu only) * * Copyright (c) 2003 Fabrice Bellard * @@ -22,66 +22,10 @@ #include "exec/helper-proto.h" #include "exec/exec-all.h" #include "exec/cpu_ldst.h" -#include "helper-tcg.h" +#include "tcg/helper-tcg.h" =20 /* Secure Virtual Machine helpers */ =20 -#if defined(CONFIG_USER_ONLY) - -void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend) -{ -} - -void helper_vmmcall(CPUX86State *env) -{ -} - -void helper_vmload(CPUX86State *env, int aflag) -{ -} - -void helper_vmsave(CPUX86State *env, int aflag) -{ -} - -void helper_stgi(CPUX86State *env) -{ -} - -void helper_clgi(CPUX86State *env) -{ -} - -void helper_skinit(CPUX86State *env) -{ -} - -void helper_invlpga(CPUX86State *env, int aflag) -{ -} - -void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_= 1, - uintptr_t retaddr) -{ - assert(0); -} - -void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type, - uint64_t param) -{ -} - -void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type, - uint64_t param, uintptr_t retaddr) -{ -} - -void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param, - uint32_t next_eip_addend) -{ -} -#else - static inline void svm_save_seg(CPUX86State *env, hwaddr addr, const SegmentCache *sc) { @@ -797,5 +741,3 @@ void do_vmexit(CPUX86State *env, uint32_t exit_code, ui= nt64_t exit_info_1) host's code segment or non-canonical (in the case of long mode), a #GP fault is delivered inside the host. */ } - -#endif diff --git a/target/i386/tcg/user/svm_stubs.c b/target/i386/tcg/user/svm_st= ubs.c new file mode 100644 index 0000000000..97528b56ad --- /dev/null +++ b/target/i386/tcg/user/svm_stubs.c @@ -0,0 +1,76 @@ +/* + * x86 SVM helpers (user-mode) + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" +#include "tcg/helper-tcg.h" + +void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend) +{ +} + +void helper_vmmcall(CPUX86State *env) +{ +} + +void helper_vmload(CPUX86State *env, int aflag) +{ +} + +void helper_vmsave(CPUX86State *env, int aflag) +{ +} + +void helper_stgi(CPUX86State *env) +{ +} + +void helper_clgi(CPUX86State *env) +{ +} + +void helper_skinit(CPUX86State *env) +{ +} + +void helper_invlpga(CPUX86State *env, int aflag) +{ +} + +void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_= 1, + uintptr_t retaddr) +{ + assert(0); +} + +void helper_svm_check_intercept_param(CPUX86State *env, uint32_t type, + uint64_t param) +{ +} + +void cpu_svm_check_intercept_param(CPUX86State *env, uint32_t type, + uint64_t param, uintptr_t retaddr) +{ +} + +void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param, + uint32_t next_eip_addend) +{ +} diff --git a/target/i386/tcg/meson.build b/target/i386/tcg/meson.build index 449d9719ef..f9110e890c 100644 --- a/target/i386/tcg/meson.build +++ b/target/i386/tcg/meson.build @@ -8,7 +8,6 @@ i386_ss.add(when: 'CONFIG_TCG', if_true: files( 'misc_helper.c', 'mpx_helper.c', 'seg_helper.c', - 'svm_helper.c', 'tcg-cpu.c', 'translate.c'), if_false: files('tcg-stub.c')) =20 diff --git a/target/i386/tcg/sysemu/meson.build b/target/i386/tcg/sysemu/me= son.build index f84519a213..126528d0c9 100644 --- a/target/i386/tcg/sysemu/meson.build +++ b/target/i386/tcg/sysemu/meson.build @@ -5,4 +5,5 @@ i386_softmmu_ss.add(when: ['CONFIG_TCG', 'CONFIG_SOFTMMU'],= if_true: files( 'bpt_helper.c', 'misc_helper.c', 'fpu_helper.c', + 'svm_helper.c', )) diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.= build index 7d919d3bc8..f891cc8d76 100644 --- a/target/i386/tcg/user/meson.build +++ b/target/i386/tcg/user/meson.build @@ -2,4 +2,5 @@ i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], = if_true: files( 'excp_helper.c', 'misc_stubs.c', 'fpu_helper.c', + 'svm_stubs.c', )) --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333375; cv=none; d=zohomail.com; s=zohoarc; b=amMSPAe1iNvmVBvv3wCdYVWn3TjQ3zkc9KuCMsMswKlIxUcQbM+KyegeQGwu11DfbCl0fuYzLzD1vE0g/FK2GxX397no2abVQwjLYU11eaxalSFXpvQme7TvO8CEnx6+TM4/Y0IcypikLDmRH51CjdSHoSKsnnFYrpHq0Pl9NgQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333375; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=kGju8NqNLeuy20sCLDXsrphEc8FwU/TqzeFaVfwHEfc=; b=VxvOCCV7b97tsA3pO8FNP9/VJvQ2gkg3h5SZCBlAfJvbqkNY4F2OaxsnEqYLwX8F+r4dWIw65tKsed3SIlYbBbO0jYNVE5v+lK99Qq4dQVR5tAXdhykJ91m2TMFzQYH6x/IpS6ZpbhiMm85Vf9wGXlP1Sfvyrrd4KDyGInl2YiA= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333375792873.2204143982152; Fri, 26 Feb 2021 01:56:15 -0800 (PST) Received: from localhost ([::1]:33170 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZr3-000569-Go for importer@patchew.org; Fri, 26 Feb 2021 04:56:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36478) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl7-0005Or-IG for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:05 -0500 Received: from mx2.suse.de ([195.135.220.15]:43252) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl2-0004ra-0Y for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:05 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id B7631AF37; Fri, 26 Feb 2021 09:49:48 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 14/18] i386: split seg_helper into user-only and sysemu parts Date: Fri, 26 Feb 2021 10:49:35 +0100 Message-Id: <20210226094939.11087-15-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson --- target/i386/tcg/helper-tcg.h | 5 + target/i386/tcg/seg_helper.h | 66 ++++++++ target/i386/tcg/seg_helper.c | 233 +--------------------------- target/i386/tcg/sysemu/seg_helper.c | 125 +++++++++++++++ target/i386/tcg/user/seg_helper.c | 109 +++++++++++++ target/i386/tcg/sysemu/meson.build | 1 + target/i386/tcg/user/meson.build | 1 + 7 files changed, 311 insertions(+), 229 deletions(-) create mode 100644 target/i386/tcg/seg_helper.h create mode 100644 target/i386/tcg/sysemu/seg_helper.c create mode 100644 target/i386/tcg/user/seg_helper.c diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h index b420b3356d..30eacdbbc9 100644 --- a/target/i386/tcg/helper-tcg.h +++ b/target/i386/tcg/helper-tcg.h @@ -88,6 +88,11 @@ void do_vmexit(CPUX86State *env, uint32_t exit_code, uin= t64_t exit_info_1); =20 /* seg_helper.c */ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw); +void do_interrupt_all(X86CPU *cpu, int intno, int is_int, + int error_code, target_ulong next_eip, int is_hw); +void handle_even_inj(CPUX86State *env, int intno, int is_int, + int error_code, int is_hw, int rm); +int exception_has_error_code(int intno); =20 /* smm_helper.c */ void do_smm_enter(X86CPU *cpu); diff --git a/target/i386/tcg/seg_helper.h b/target/i386/tcg/seg_helper.h new file mode 100644 index 0000000000..ebf1035277 --- /dev/null +++ b/target/i386/tcg/seg_helper.h @@ -0,0 +1,66 @@ +/* + * x86 segmentation related helpers macros + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef SEG_HELPER_H +#define SEG_HELPER_H + +//#define DEBUG_PCALL + +#ifdef DEBUG_PCALL +# define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__) +# define LOG_PCALL_STATE(cpu) \ + log_cpu_state_mask(CPU_LOG_PCALL, (cpu), CPU_DUMP_CCOP) +#else +# define LOG_PCALL(...) do { } while (0) +# define LOG_PCALL_STATE(cpu) do { } while (0) +#endif + +/* + * TODO: Convert callers to compute cpu_mmu_index_kernel once + * and use *_mmuidx_ra directly. + */ +#define cpu_ldub_kernel_ra(e, p, r) \ + cpu_ldub_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) +#define cpu_lduw_kernel_ra(e, p, r) \ + cpu_lduw_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) +#define cpu_ldl_kernel_ra(e, p, r) \ + cpu_ldl_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) +#define cpu_ldq_kernel_ra(e, p, r) \ + cpu_ldq_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) + +#define cpu_stb_kernel_ra(e, p, v, r) \ + cpu_stb_mmuidx_ra(e, p, v, cpu_mmu_index_kernel(e), r) +#define cpu_stw_kernel_ra(e, p, v, r) \ + cpu_stw_mmuidx_ra(e, p, v, cpu_mmu_index_kernel(e), r) +#define cpu_stl_kernel_ra(e, p, v, r) \ + cpu_stl_mmuidx_ra(e, p, v, cpu_mmu_index_kernel(e), r) +#define cpu_stq_kernel_ra(e, p, v, r) \ + cpu_stq_mmuidx_ra(e, p, v, cpu_mmu_index_kernel(e), r) + +#define cpu_ldub_kernel(e, p) cpu_ldub_kernel_ra(e, p, 0) +#define cpu_lduw_kernel(e, p) cpu_lduw_kernel_ra(e, p, 0) +#define cpu_ldl_kernel(e, p) cpu_ldl_kernel_ra(e, p, 0) +#define cpu_ldq_kernel(e, p) cpu_ldq_kernel_ra(e, p, 0) + +#define cpu_stb_kernel(e, p, v) cpu_stb_kernel_ra(e, p, v, 0) +#define cpu_stw_kernel(e, p, v) cpu_stw_kernel_ra(e, p, v, 0) +#define cpu_stl_kernel(e, p, v) cpu_stl_kernel_ra(e, p, v, 0) +#define cpu_stq_kernel(e, p, v) cpu_stq_kernel_ra(e, p, v, 0) + +#endif /* SEG_HELPER_H */ diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index d04fbdd7cd..cf3f051524 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -26,49 +26,7 @@ #include "exec/cpu_ldst.h" #include "exec/log.h" #include "helper-tcg.h" - -//#define DEBUG_PCALL - -#ifdef DEBUG_PCALL -# define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__) -# define LOG_PCALL_STATE(cpu) \ - log_cpu_state_mask(CPU_LOG_PCALL, (cpu), CPU_DUMP_CCOP) -#else -# define LOG_PCALL(...) do { } while (0) -# define LOG_PCALL_STATE(cpu) do { } while (0) -#endif - -/* - * TODO: Convert callers to compute cpu_mmu_index_kernel once - * and use *_mmuidx_ra directly. - */ -#define cpu_ldub_kernel_ra(e, p, r) \ - cpu_ldub_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) -#define cpu_lduw_kernel_ra(e, p, r) \ - cpu_lduw_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) -#define cpu_ldl_kernel_ra(e, p, r) \ - cpu_ldl_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) -#define cpu_ldq_kernel_ra(e, p, r) \ - cpu_ldq_mmuidx_ra(e, p, cpu_mmu_index_kernel(e), r) - -#define cpu_stb_kernel_ra(e, p, v, r) \ - cpu_stb_mmuidx_ra(e, p, v, cpu_mmu_index_kernel(e), r) -#define cpu_stw_kernel_ra(e, p, v, r) \ - cpu_stw_mmuidx_ra(e, p, v, cpu_mmu_index_kernel(e), r) -#define cpu_stl_kernel_ra(e, p, v, r) \ - cpu_stl_mmuidx_ra(e, p, v, cpu_mmu_index_kernel(e), r) -#define cpu_stq_kernel_ra(e, p, v, r) \ - cpu_stq_mmuidx_ra(e, p, v, cpu_mmu_index_kernel(e), r) - -#define cpu_ldub_kernel(e, p) cpu_ldub_kernel_ra(e, p, 0) -#define cpu_lduw_kernel(e, p) cpu_lduw_kernel_ra(e, p, 0) -#define cpu_ldl_kernel(e, p) cpu_ldl_kernel_ra(e, p, 0) -#define cpu_ldq_kernel(e, p) cpu_ldq_kernel_ra(e, p, 0) - -#define cpu_stb_kernel(e, p, v) cpu_stb_kernel_ra(e, p, v, 0) -#define cpu_stw_kernel(e, p, v) cpu_stw_kernel_ra(e, p, v, 0) -#define cpu_stl_kernel(e, p, v) cpu_stl_kernel_ra(e, p, v, 0) -#define cpu_stq_kernel(e, p, v) cpu_stq_kernel_ra(e, p, v, 0) +#include "seg_helper.h" =20 /* return non zero if error */ static inline int load_segment_ra(CPUX86State *env, uint32_t *e1_ptr, @@ -531,7 +489,7 @@ static inline unsigned int get_sp_mask(unsigned int e2) } } =20 -static int exception_has_error_code(int intno) +int exception_has_error_code(int intno) { switch (intno) { case 8: @@ -976,72 +934,6 @@ static void do_interrupt64(CPUX86State *env, int intno= , int is_int, } #endif =20 -#ifdef TARGET_X86_64 -#if defined(CONFIG_USER_ONLY) -void helper_syscall(CPUX86State *env, int next_eip_addend) -{ - CPUState *cs =3D env_cpu(env); - - cs->exception_index =3D EXCP_SYSCALL; - env->exception_is_int =3D 0; - env->exception_next_eip =3D env->eip + next_eip_addend; - cpu_loop_exit(cs); -} -#else -void helper_syscall(CPUX86State *env, int next_eip_addend) -{ - int selector; - - if (!(env->efer & MSR_EFER_SCE)) { - raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); - } - selector =3D (env->star >> 32) & 0xffff; - if (env->hflags & HF_LMA_MASK) { - int code64; - - env->regs[R_ECX] =3D env->eip + next_eip_addend; - env->regs[11] =3D cpu_compute_eflags(env) & ~RF_MASK; - - code64 =3D env->hflags & HF_CS64_MASK; - - env->eflags &=3D ~(env->fmask | RF_MASK); - cpu_load_eflags(env, env->eflags, 0); - cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | - DESC_L_MASK); - cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_W_MASK | DESC_A_MASK); - if (code64) { - env->eip =3D env->lstar; - } else { - env->eip =3D env->cstar; - } - } else { - env->regs[R_ECX] =3D (uint32_t)(env->eip + next_eip_addend); - - env->eflags &=3D ~(IF_MASK | RF_MASK | VM_MASK); - cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); - cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc, - 0, 0xffffffff, - DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | - DESC_S_MASK | - DESC_W_MASK | DESC_A_MASK); - env->eip =3D (uint32_t)env->star; - } -} -#endif -#endif - #ifdef TARGET_X86_64 void helper_sysret(CPUX86State *env, int dflag) { @@ -1136,84 +1028,13 @@ static void do_interrupt_real(CPUX86State *env, int= intno, int is_int, env->eflags &=3D ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK); } =20 -#if defined(CONFIG_USER_ONLY) -/* fake user mode interrupt. is_int is TRUE if coming from the int - * instruction. next_eip is the env->eip value AFTER the interrupt - * instruction. It is only relevant if is_int is TRUE or if intno - * is EXCP_SYSCALL. - */ -static void do_interrupt_user(CPUX86State *env, int intno, int is_int, - int error_code, target_ulong next_eip) -{ - if (is_int) { - SegmentCache *dt; - target_ulong ptr; - int dpl, cpl, shift; - uint32_t e2; - - dt =3D &env->idt; - if (env->hflags & HF_LMA_MASK) { - shift =3D 4; - } else { - shift =3D 3; - } - ptr =3D dt->base + (intno << shift); - e2 =3D cpu_ldl_kernel(env, ptr + 4); - - dpl =3D (e2 >> DESC_DPL_SHIFT) & 3; - cpl =3D env->hflags & HF_CPL_MASK; - /* check privilege if software int */ - if (dpl < cpl) { - raise_exception_err(env, EXCP0D_GPF, (intno << shift) + 2); - } - } - - /* Since we emulate only user space, we cannot do more than - exiting the emulation with the suitable exception and error - code. So update EIP for INT 0x80 and EXCP_SYSCALL. */ - if (is_int || intno =3D=3D EXCP_SYSCALL) { - env->eip =3D next_eip; - } -} - -#else - -static void handle_even_inj(CPUX86State *env, int intno, int is_int, - int error_code, int is_hw, int rm) -{ - CPUState *cs =3D env_cpu(env); - uint32_t event_inj =3D x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct= vmcb, - control.event_in= j)); - - if (!(event_inj & SVM_EVTINJ_VALID)) { - int type; - - if (is_int) { - type =3D SVM_EVTINJ_TYPE_SOFT; - } else { - type =3D SVM_EVTINJ_TYPE_EXEPT; - } - event_inj =3D intno | type | SVM_EVTINJ_VALID; - if (!rm && exception_has_error_code(intno)) { - event_inj |=3D SVM_EVTINJ_VALID_ERR; - x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, - control.event_inj_err), - error_code); - } - x86_stl_phys(cs, - env->vm_vmcb + offsetof(struct vmcb, control.event_inj), - event_inj); - } -} -#endif - /* * Begin execution of an interruption. is_int is TRUE if coming from * the int instruction. next_eip is the env->eip value AFTER the interrupt * instruction. It is only relevant if is_int is TRUE. */ -static void do_interrupt_all(X86CPU *cpu, int intno, int is_int, - int error_code, target_ulong next_eip, int is= _hw) +void do_interrupt_all(X86CPU *cpu, int intno, int is_int, + int error_code, target_ulong next_eip, int is_hw) { CPUX86State *env =3D &cpu->env; =20 @@ -1289,36 +1110,6 @@ static void do_interrupt_all(X86CPU *cpu, int intno,= int is_int, #endif } =20 -void x86_cpu_do_interrupt(CPUState *cs) -{ - X86CPU *cpu =3D X86_CPU(cs); - CPUX86State *env =3D &cpu->env; - -#if defined(CONFIG_USER_ONLY) - /* if user mode only, we simulate a fake exception - which will be handled outside the cpu execution - loop */ - do_interrupt_user(env, cs->exception_index, - env->exception_is_int, - env->error_code, - env->exception_next_eip); - /* successfully delivered */ - env->old_exception =3D -1; -#else - if (cs->exception_index >=3D EXCP_VMEXIT) { - assert(env->old_exception =3D=3D -1); - do_vmexit(env, cs->exception_index - EXCP_VMEXIT, env->error_code); - } else { - do_interrupt_all(cpu, cs->exception_index, - env->exception_is_int, - env->error_code, - env->exception_next_eip, 0); - /* successfully delivered */ - env->old_exception =3D -1; - } -#endif -} - void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw) { do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw); @@ -2626,22 +2417,6 @@ void helper_verw(CPUX86State *env, target_ulong sele= ctor1) CC_SRC =3D eflags | CC_Z; } =20 -#if defined(CONFIG_USER_ONLY) -void cpu_x86_load_seg(CPUX86State *env, X86Seg seg_reg, int selector) -{ - if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { - int dpl =3D (env->eflags & VM_MASK) ? 3 : 0; - selector &=3D 0xffff; - cpu_x86_load_seg_cache(env, seg_reg, selector, - (selector << 4), 0xffff, - DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | - DESC_A_MASK | (dpl << DESC_DPL_SHIFT)); - } else { - helper_load_seg(env, seg_reg, selector); - } -} -#endif - /* check if Port I/O is allowed in TSS */ static inline void check_io(CPUX86State *env, int addr, int size, uintptr_t retaddr) diff --git a/target/i386/tcg/sysemu/seg_helper.c b/target/i386/tcg/sysemu/s= eg_helper.c new file mode 100644 index 0000000000..10076d1341 --- /dev/null +++ b/target/i386/tcg/sysemu/seg_helper.c @@ -0,0 +1,125 @@ +/* + * x86 segmentation related helpers: (sysemu-only code) + * TSS, interrupts, system calls, jumps and call/task gates, descriptors + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" +#include "exec/cpu_ldst.h" +#include "tcg/helper-tcg.h" + +#ifdef TARGET_X86_64 +void helper_syscall(CPUX86State *env, int next_eip_addend) +{ + int selector; + + if (!(env->efer & MSR_EFER_SCE)) { + raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC()); + } + selector =3D (env->star >> 32) & 0xffff; + if (env->hflags & HF_LMA_MASK) { + int code64; + + env->regs[R_ECX] =3D env->eip + next_eip_addend; + env->regs[11] =3D cpu_compute_eflags(env) & ~RF_MASK; + + code64 =3D env->hflags & HF_CS64_MASK; + + env->eflags &=3D ~(env->fmask | RF_MASK); + cpu_load_eflags(env, env->eflags, 0); + cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, + 0, 0xffffffff, + DESC_G_MASK | DESC_P_MASK | + DESC_S_MASK | + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | + DESC_L_MASK); + cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc, + 0, 0xffffffff, + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | + DESC_S_MASK | + DESC_W_MASK | DESC_A_MASK); + if (code64) { + env->eip =3D env->lstar; + } else { + env->eip =3D env->cstar; + } + } else { + env->regs[R_ECX] =3D (uint32_t)(env->eip + next_eip_addend); + + env->eflags &=3D ~(IF_MASK | RF_MASK | VM_MASK); + cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc, + 0, 0xffffffff, + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | + DESC_S_MASK | + DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK); + cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc, + 0, 0xffffffff, + DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | + DESC_S_MASK | + DESC_W_MASK | DESC_A_MASK); + env->eip =3D (uint32_t)env->star; + } +} +#endif /* TARGET_X86_64 */ + +void handle_even_inj(CPUX86State *env, int intno, int is_int, + int error_code, int is_hw, int rm) +{ + CPUState *cs =3D env_cpu(env); + uint32_t event_inj =3D x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct= vmcb, + control.event_in= j)); + + if (!(event_inj & SVM_EVTINJ_VALID)) { + int type; + + if (is_int) { + type =3D SVM_EVTINJ_TYPE_SOFT; + } else { + type =3D SVM_EVTINJ_TYPE_EXEPT; + } + event_inj =3D intno | type | SVM_EVTINJ_VALID; + if (!rm && exception_has_error_code(intno)) { + event_inj |=3D SVM_EVTINJ_VALID_ERR; + x86_stl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, + control.event_inj_err), + error_code); + } + x86_stl_phys(cs, + env->vm_vmcb + offsetof(struct vmcb, control.event_inj), + event_inj); + } +} + +void x86_cpu_do_interrupt(CPUState *cs) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + if (cs->exception_index >=3D EXCP_VMEXIT) { + assert(env->old_exception =3D=3D -1); + do_vmexit(env, cs->exception_index - EXCP_VMEXIT, env->error_code); + } else { + do_interrupt_all(cpu, cs->exception_index, + env->exception_is_int, + env->error_code, + env->exception_next_eip, 0); + /* successfully delivered */ + env->old_exception =3D -1; + } +} diff --git a/target/i386/tcg/user/seg_helper.c b/target/i386/tcg/user/seg_h= elper.c new file mode 100644 index 0000000000..67481b0aa8 --- /dev/null +++ b/target/i386/tcg/user/seg_helper.c @@ -0,0 +1,109 @@ +/* + * x86 segmentation related helpers (user-mode code): + * TSS, interrupts, system calls, jumps and call/task gates, descriptors + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" +#include "exec/exec-all.h" +#include "exec/cpu_ldst.h" +#include "tcg/helper-tcg.h" +#include "tcg/seg_helper.h" + +#ifdef TARGET_X86_64 +void helper_syscall(CPUX86State *env, int next_eip_addend) +{ + CPUState *cs =3D env_cpu(env); + + cs->exception_index =3D EXCP_SYSCALL; + env->exception_is_int =3D 0; + env->exception_next_eip =3D env->eip + next_eip_addend; + cpu_loop_exit(cs); +} +#endif /* TARGET_X86_64 */ + +/* + * fake user mode interrupt. is_int is TRUE if coming from the int + * instruction. next_eip is the env->eip value AFTER the interrupt + * instruction. It is only relevant if is_int is TRUE or if intno + * is EXCP_SYSCALL. + */ +static void do_interrupt_user(CPUX86State *env, int intno, int is_int, + int error_code, target_ulong next_eip) +{ + if (is_int) { + SegmentCache *dt; + target_ulong ptr; + int dpl, cpl, shift; + uint32_t e2; + + dt =3D &env->idt; + if (env->hflags & HF_LMA_MASK) { + shift =3D 4; + } else { + shift =3D 3; + } + ptr =3D dt->base + (intno << shift); + e2 =3D cpu_ldl_kernel(env, ptr + 4); + + dpl =3D (e2 >> DESC_DPL_SHIFT) & 3; + cpl =3D env->hflags & HF_CPL_MASK; + /* check privilege if software int */ + if (dpl < cpl) { + raise_exception_err(env, EXCP0D_GPF, (intno << shift) + 2); + } + } + + /* Since we emulate only user space, we cannot do more than + exiting the emulation with the suitable exception and error + code. So update EIP for INT 0x80 and EXCP_SYSCALL. */ + if (is_int || intno =3D=3D EXCP_SYSCALL) { + env->eip =3D next_eip; + } +} + +void x86_cpu_do_interrupt(CPUState *cs) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + + /* if user mode only, we simulate a fake exception + which will be handled outside the cpu execution + loop */ + do_interrupt_user(env, cs->exception_index, + env->exception_is_int, + env->error_code, + env->exception_next_eip); + /* successfully delivered */ + env->old_exception =3D -1; +} + +void cpu_x86_load_seg(CPUX86State *env, X86Seg seg_reg, int selector) +{ + if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { + int dpl =3D (env->eflags & VM_MASK) ? 3 : 0; + selector &=3D 0xffff; + cpu_x86_load_seg_cache(env, seg_reg, selector, + (selector << 4), 0xffff, + DESC_P_MASK | DESC_S_MASK | DESC_W_MASK | + DESC_A_MASK | (dpl << DESC_DPL_SHIFT)); + } else { + helper_load_seg(env, seg_reg, selector); + } +} diff --git a/target/i386/tcg/sysemu/meson.build b/target/i386/tcg/sysemu/me= son.build index 126528d0c9..2e444e766a 100644 --- a/target/i386/tcg/sysemu/meson.build +++ b/target/i386/tcg/sysemu/meson.build @@ -6,4 +6,5 @@ i386_softmmu_ss.add(when: ['CONFIG_TCG', 'CONFIG_SOFTMMU'],= if_true: files( 'misc_helper.c', 'fpu_helper.c', 'svm_helper.c', + 'seg_helper.c', )) diff --git a/target/i386/tcg/user/meson.build b/target/i386/tcg/user/meson.= build index f891cc8d76..345294c096 100644 --- a/target/i386/tcg/user/meson.build +++ b/target/i386/tcg/user/meson.build @@ -3,4 +3,5 @@ i386_user_ss.add(when: ['CONFIG_TCG', 'CONFIG_USER_ONLY'], = if_true: files( 'misc_stubs.c', 'fpu_helper.c', 'svm_stubs.c', + 'seg_helper.c', )) --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333830; cv=none; d=zohomail.com; s=zohoarc; b=g4ngnxB5evoT0wERgS272KHsJnkasyxfklyd2DuT7CPF7ajSyzRzZSYqoKiJW1tsOfg5fkMzkwDULACO79WnzzZ7+Y8dSsoOF6JranJcB5ip7TisGryF/Tjx01rrA7ov8lUyVfe/FZRIU6UeQabvF5a7qz062R1EKsUqbdhGQh4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333830; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=/6n6rBd/e4/uy5RjOh8ZbajAW7qjYlfVvmRiIcI0fv4=; b=dT9uGvJKeTOZmlEk3Tt7F4JfVENzrNJTtxNqNo/Ky4S+cfoxdpIj2eVRkWnuO3NwiX3y11llWPr5thN22aKN3COOcAJMTsXglkOwqYdha/u6OjRMQelxRT0FgTANHRf+U657W1cFryul89IapOHrpsyiHx7PHIIfks+OAQoWdrw= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333830971904.6213531710983; Fri, 26 Feb 2021 02:03:50 -0800 (PST) Received: from localhost ([::1]:50226 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZyP-0003vV-Ex for importer@patchew.org; Fri, 26 Feb 2021 05:03:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36498) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl9-0005S0-0W for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:07 -0500 Received: from mx2.suse.de ([195.135.220.15]:43274) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl2-0004rn-Hu for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:06 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 45D39AF47; Fri, 26 Feb 2021 09:49:49 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 15/18] i386: split off sysemu part of cpu.c Date: Fri, 26 Feb 2021 10:49:36 +0100 Message-Id: <20210226094939.11087-16-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson --- target/i386/cpu-internal.h | 70 +++++++ target/i386/cpu-sysemu.c | 352 +++++++++++++++++++++++++++++++++ target/i386/cpu.c | 385 +------------------------------------ target/i386/meson.build | 1 + 4 files changed, 429 insertions(+), 379 deletions(-) create mode 100644 target/i386/cpu-internal.h create mode 100644 target/i386/cpu-sysemu.c diff --git a/target/i386/cpu-internal.h b/target/i386/cpu-internal.h new file mode 100644 index 0000000000..9baac5c0b4 --- /dev/null +++ b/target/i386/cpu-internal.h @@ -0,0 +1,70 @@ +/* + * i386 CPU internal definitions to be shared between cpu.c and cpu-sysemu= .c + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#ifndef I386_CPU_INTERNAL_H +#define I386_CPU_INTERNAL_H + +typedef enum FeatureWordType { + CPUID_FEATURE_WORD, + MSR_FEATURE_WORD, +} FeatureWordType; + +typedef struct FeatureWordInfo { + FeatureWordType type; + /* feature flags names are taken from "Intel Processor Identification = and + * the CPUID Instruction" and AMD's "CPUID Specification". + * In cases of disagreement between feature naming conventions, + * aliases may be added. + */ + const char *feat_names[64]; + union { + /* If type=3D=3DCPUID_FEATURE_WORD */ + struct { + uint32_t eax; /* Input EAX for CPUID */ + bool needs_ecx; /* CPUID instruction uses ECX as input */ + uint32_t ecx; /* Input ECX value for CPUID */ + int reg; /* output register (R_* constant) */ + } cpuid; + /* If type=3D=3DMSR_FEATURE_WORD */ + struct { + uint32_t index; + } msr; + }; + uint64_t tcg_features; /* Feature flags supported by TCG */ + uint64_t unmigratable_flags; /* Feature flags known to be unmigratable= */ + uint64_t migratable_flags; /* Feature flags known to be migratable */ + /* Features that shouldn't be auto-enabled by "-cpu host" */ + uint64_t no_autoenable_flags; +} FeatureWordInfo; + +extern FeatureWordInfo feature_word_info[]; + +void x86_cpu_expand_features(X86CPU *cpu, Error **errp); + +#ifndef CONFIG_USER_ONLY +GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs); +void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v, + const char *name, void *opaque, Error **er= rp); + +void x86_cpu_apic_create(X86CPU *cpu, Error **errp); +void x86_cpu_apic_realize(X86CPU *cpu, Error **errp); +void x86_cpu_machine_reset_cb(void *opaque); +#endif /* !CONFIG_USER_ONLY */ + +#endif /* I386_CPU_INTERNAL_H */ diff --git a/target/i386/cpu-sysemu.c b/target/i386/cpu-sysemu.c new file mode 100644 index 0000000000..6477584313 --- /dev/null +++ b/target/i386/cpu-sysemu.c @@ -0,0 +1,352 @@ +/* + * i386 CPUID, CPU class, definitions, models: sysemu-only code + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "sysemu/xen.h" +#include "sysemu/whpx.h" +#include "kvm/kvm_i386.h" +#include "qapi/error.h" +#include "qapi/qapi-visit-run-state.h" +#include "qapi/qmp/qdict.h" +#include "qom/qom-qobject.h" +#include "qapi/qapi-commands-machine-target.h" +#include "hw/qdev-properties.h" + +#include "exec/address-spaces.h" +#include "hw/i386/apic_internal.h" + +#include "cpu-internal.h" + +/* Return a QDict containing keys for all properties that can be included + * in static expansion of CPU models. All properties set by x86_cpu_load_m= odel() + * must be included in the dictionary. + */ +static QDict *x86_cpu_static_props(void) +{ + FeatureWord w; + int i; + static const char *props[] =3D { + "min-level", + "min-xlevel", + "family", + "model", + "stepping", + "model-id", + "vendor", + "lmce", + NULL, + }; + static QDict *d; + + if (d) { + return d; + } + + d =3D qdict_new(); + for (i =3D 0; props[i]; i++) { + qdict_put_null(d, props[i]); + } + + for (w =3D 0; w < FEATURE_WORDS; w++) { + FeatureWordInfo *fi =3D &feature_word_info[w]; + int bit; + for (bit =3D 0; bit < 64; bit++) { + if (!fi->feat_names[bit]) { + continue; + } + qdict_put_null(d, fi->feat_names[bit]); + } + } + + return d; +} + +/* Add an entry to @props dict, with the value for property. */ +static void x86_cpu_expand_prop(X86CPU *cpu, QDict *props, const char *pro= p) +{ + QObject *value =3D object_property_get_qobject(OBJECT(cpu), prop, + &error_abort); + + qdict_put_obj(props, prop, value); +} + +/* Convert CPU model data from X86CPU object to a property dictionary + * that can recreate exactly the same CPU model. + */ +static void x86_cpu_to_dict(X86CPU *cpu, QDict *props) +{ + QDict *sprops =3D x86_cpu_static_props(); + const QDictEntry *e; + + for (e =3D qdict_first(sprops); e; e =3D qdict_next(sprops, e)) { + const char *prop =3D qdict_entry_key(e); + x86_cpu_expand_prop(cpu, props, prop); + } +} + +/* Convert CPU model data from X86CPU object to a property dictionary + * that can recreate exactly the same CPU model, including every + * writeable QOM property. + */ +static void x86_cpu_to_dict_full(X86CPU *cpu, QDict *props) +{ + ObjectPropertyIterator iter; + ObjectProperty *prop; + + object_property_iter_init(&iter, OBJECT(cpu)); + while ((prop =3D object_property_iter_next(&iter))) { + /* skip read-only or write-only properties */ + if (!prop->get || !prop->set) { + continue; + } + + /* "hotplugged" is the only property that is configurable + * on the command-line but will be set differently on CPUs + * created using "-cpu ... -smp ..." and by CPUs created + * on the fly by x86_cpu_from_model() for querying. Skip it. + */ + if (!strcmp(prop->name, "hotplugged")) { + continue; + } + x86_cpu_expand_prop(cpu, props, prop->name); + } +} + +static void object_apply_props(Object *obj, QDict *props, Error **errp) +{ + const QDictEntry *prop; + + for (prop =3D qdict_first(props); prop; prop =3D qdict_next(props, pro= p)) { + if (!object_property_set_qobject(obj, qdict_entry_key(prop), + qdict_entry_value(prop), errp)) { + break; + } + } +} + +/* Create X86CPU object according to model+props specification */ +static X86CPU *x86_cpu_from_model(const char *model, QDict *props, Error *= *errp) +{ + X86CPU *xc =3D NULL; + X86CPUClass *xcc; + Error *err =3D NULL; + + xcc =3D X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model)); + if (xcc =3D=3D NULL) { + error_setg(&err, "CPU model '%s' not found", model); + goto out; + } + + xc =3D X86_CPU(object_new_with_class(OBJECT_CLASS(xcc))); + if (props) { + object_apply_props(OBJECT(xc), props, &err); + if (err) { + goto out; + } + } + + x86_cpu_expand_features(xc, &err); + if (err) { + goto out; + } + +out: + if (err) { + error_propagate(errp, err); + object_unref(OBJECT(xc)); + xc =3D NULL; + } + return xc; +} + +CpuModelExpansionInfo * +qmp_query_cpu_model_expansion(CpuModelExpansionType type, + CpuModelInfo *model, + Error **errp) +{ + X86CPU *xc =3D NULL; + Error *err =3D NULL; + CpuModelExpansionInfo *ret =3D g_new0(CpuModelExpansionInfo, 1); + QDict *props =3D NULL; + const char *base_name; + + xc =3D x86_cpu_from_model(model->name, + model->has_props ? + qobject_to(QDict, model->props) : + NULL, &err); + if (err) { + goto out; + } + + props =3D qdict_new(); + ret->model =3D g_new0(CpuModelInfo, 1); + ret->model->props =3D QOBJECT(props); + ret->model->has_props =3D true; + + switch (type) { + case CPU_MODEL_EXPANSION_TYPE_STATIC: + /* Static expansion will be based on "base" only */ + base_name =3D "base"; + x86_cpu_to_dict(xc, props); + break; + case CPU_MODEL_EXPANSION_TYPE_FULL: + /* As we don't return every single property, full expansion needs + * to keep the original model name+props, and add extra + * properties on top of that. + */ + base_name =3D model->name; + x86_cpu_to_dict_full(xc, props); + break; + default: + error_setg(&err, "Unsupported expansion type"); + goto out; + } + + x86_cpu_to_dict(xc, props); + + ret->model->name =3D g_strdup(base_name); + +out: + object_unref(OBJECT(xc)); + if (err) { + error_propagate(errp, err); + qapi_free_CpuModelExpansionInfo(ret); + ret =3D NULL; + } + return ret; +} + +void cpu_clear_apic_feature(CPUX86State *env) +{ + env->features[FEAT_1_EDX] &=3D ~CPUID_APIC; +} + +bool cpu_is_bsp(X86CPU *cpu) +{ + return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP; +} + +/* TODO: remove me, when reset over QOM tree is implemented */ +void x86_cpu_machine_reset_cb(void *opaque) +{ + X86CPU *cpu =3D opaque; + cpu_reset(CPU(cpu)); +} + +APICCommonClass *apic_get_class(void) +{ + const char *apic_type =3D "apic"; + + /* TODO: in-kernel irqchip for hvf */ + if (kvm_apic_in_kernel()) { + apic_type =3D "kvm-apic"; + } else if (xen_enabled()) { + apic_type =3D "xen-apic"; + } else if (whpx_apic_in_platform()) { + apic_type =3D "whpx-apic"; + } + + return APIC_COMMON_CLASS(object_class_by_name(apic_type)); +} + +void x86_cpu_apic_create(X86CPU *cpu, Error **errp) +{ + APICCommonState *apic; + ObjectClass *apic_class =3D OBJECT_CLASS(apic_get_class()); + + cpu->apic_state =3D DEVICE(object_new_with_class(apic_class)); + + object_property_add_child(OBJECT(cpu), "lapic", + OBJECT(cpu->apic_state)); + object_unref(OBJECT(cpu->apic_state)); + + qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id); + /* TODO: convert to link<> */ + apic =3D APIC_COMMON(cpu->apic_state); + apic->cpu =3D cpu; + apic->apicbase =3D APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE; +} + +void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) +{ + APICCommonState *apic; + static bool apic_mmio_map_once; + + if (cpu->apic_state =3D=3D NULL) { + return; + } + qdev_realize(DEVICE(cpu->apic_state), NULL, errp); + + /* Map APIC MMIO area */ + apic =3D APIC_COMMON(cpu->apic_state); + if (!apic_mmio_map_once) { + memory_region_add_subregion_overlap(get_system_memory(), + apic->apicbase & + MSR_IA32_APICBASE_BASE, + &apic->io_memory, + 0x1000); + apic_mmio_map_once =3D true; + } +} + +GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs) +{ + X86CPU *cpu =3D X86_CPU(cs); + CPUX86State *env =3D &cpu->env; + GuestPanicInformation *panic_info =3D NULL; + + if (env->features[FEAT_HYPERV_EDX] & HV_GUEST_CRASH_MSR_AVAILABLE) { + panic_info =3D g_malloc0(sizeof(GuestPanicInformation)); + + panic_info->type =3D GUEST_PANIC_INFORMATION_TYPE_HYPER_V; + + assert(HV_CRASH_PARAMS >=3D 5); + panic_info->u.hyper_v.arg1 =3D env->msr_hv_crash_params[0]; + panic_info->u.hyper_v.arg2 =3D env->msr_hv_crash_params[1]; + panic_info->u.hyper_v.arg3 =3D env->msr_hv_crash_params[2]; + panic_info->u.hyper_v.arg4 =3D env->msr_hv_crash_params[3]; + panic_info->u.hyper_v.arg5 =3D env->msr_hv_crash_params[4]; + } + + return panic_info; +} +void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + CPUState *cs =3D CPU(obj); + GuestPanicInformation *panic_info; + + if (!cs->crash_occurred) { + error_setg(errp, "No crash occured"); + return; + } + + panic_info =3D x86_cpu_get_crash_info(cs); + if (panic_info =3D=3D NULL) { + error_setg(errp, "No crash information"); + return; + } + + visit_type_GuestPanicInformation(v, "crash-information", &panic_info, + errp); + qapi_free_GuestPanicInformation(panic_info); +} + diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 14e2a60ee5..4da7b2f7a9 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1,5 +1,5 @@ /* - * i386 CPUID helper functions + * i386 CPUID, CPU class, definitions, models * * Copyright (c) 2003 Fabrice Bellard * @@ -20,35 +20,26 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qemu/cutils.h" -#include "qemu/bitops.h" #include "qemu/qemu-print.h" #include "cpu.h" #include "tcg/helper-tcg.h" -#include "exec/exec-all.h" -#include "sysemu/kvm.h" #include "sysemu/reset.h" #include "sysemu/hvf.h" -#include "sysemu/xen.h" -#include "sysemu/whpx.h" #include "kvm/kvm_i386.h" #include "sev_i386.h" -#include "qemu/module.h" #include "qapi/qapi-visit-machine.h" -#include "qapi/qapi-visit-run-state.h" -#include "qapi/qmp/qdict.h" #include "qapi/qmp/qerror.h" -#include "qom/qom-qobject.h" #include "qapi/qapi-commands-machine-target.h" #include "standard-headers/asm-x86/kvm_para.h" #include "hw/qdev-properties.h" #include "hw/i386/topology.h" #ifndef CONFIG_USER_ONLY #include "exec/address-spaces.h" -#include "hw/i386/apic_internal.h" #include "hw/boards.h" #endif =20 #include "disas/capstone.h" +#include "cpu-internal.h" =20 /* Helpers for building CPUID[2] descriptors: */ =20 @@ -663,40 +654,7 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vend= or1, CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */ #define TCG_14_0_ECX_FEATURES 0 =20 -typedef enum FeatureWordType { - CPUID_FEATURE_WORD, - MSR_FEATURE_WORD, -} FeatureWordType; - -typedef struct FeatureWordInfo { - FeatureWordType type; - /* feature flags names are taken from "Intel Processor Identification = and - * the CPUID Instruction" and AMD's "CPUID Specification". - * In cases of disagreement between feature naming conventions, - * aliases may be added. - */ - const char *feat_names[64]; - union { - /* If type=3D=3DCPUID_FEATURE_WORD */ - struct { - uint32_t eax; /* Input EAX for CPUID */ - bool needs_ecx; /* CPUID instruction uses ECX as input */ - uint32_t ecx; /* Input ECX value for CPUID */ - int reg; /* output register (R_* constant) */ - } cpuid; - /* If type=3D=3DMSR_FEATURE_WORD */ - struct { - uint32_t index; - } msr; - }; - uint64_t tcg_features; /* Feature flags supported by TCG */ - uint64_t unmigratable_flags; /* Feature flags known to be unmigratable= */ - uint64_t migratable_flags; /* Feature flags known to be migratable */ - /* Features that shouldn't be auto-enabled by "-cpu host" */ - uint64_t no_autoenable_flags; -} FeatureWordInfo; - -static FeatureWordInfo feature_word_info[FEATURE_WORDS] =3D { +FeatureWordInfo feature_word_info[FEATURE_WORDS] =3D { [FEAT_1_EDX] =3D { .type =3D CPUID_FEATURE_WORD, .feat_names =3D { @@ -4738,7 +4696,6 @@ static void x86_cpu_parse_featurestr(const char *type= name, char *features, } } =20 -static void x86_cpu_expand_features(X86CPU *cpu, Error **errp); static void x86_cpu_filter_features(X86CPU *cpu, bool verbose); =20 /* Build a list with the name of all features on a feature word array */ @@ -5108,207 +5065,6 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUM= odel *model) memset(&env->user_features, 0, sizeof(env->user_features)); } =20 -#ifndef CONFIG_USER_ONLY -/* Return a QDict containing keys for all properties that can be included - * in static expansion of CPU models. All properties set by x86_cpu_load_m= odel() - * must be included in the dictionary. - */ -static QDict *x86_cpu_static_props(void) -{ - FeatureWord w; - int i; - static const char *props[] =3D { - "min-level", - "min-xlevel", - "family", - "model", - "stepping", - "model-id", - "vendor", - "lmce", - NULL, - }; - static QDict *d; - - if (d) { - return d; - } - - d =3D qdict_new(); - for (i =3D 0; props[i]; i++) { - qdict_put_null(d, props[i]); - } - - for (w =3D 0; w < FEATURE_WORDS; w++) { - FeatureWordInfo *fi =3D &feature_word_info[w]; - int bit; - for (bit =3D 0; bit < 64; bit++) { - if (!fi->feat_names[bit]) { - continue; - } - qdict_put_null(d, fi->feat_names[bit]); - } - } - - return d; -} - -/* Add an entry to @props dict, with the value for property. */ -static void x86_cpu_expand_prop(X86CPU *cpu, QDict *props, const char *pro= p) -{ - QObject *value =3D object_property_get_qobject(OBJECT(cpu), prop, - &error_abort); - - qdict_put_obj(props, prop, value); -} - -/* Convert CPU model data from X86CPU object to a property dictionary - * that can recreate exactly the same CPU model. - */ -static void x86_cpu_to_dict(X86CPU *cpu, QDict *props) -{ - QDict *sprops =3D x86_cpu_static_props(); - const QDictEntry *e; - - for (e =3D qdict_first(sprops); e; e =3D qdict_next(sprops, e)) { - const char *prop =3D qdict_entry_key(e); - x86_cpu_expand_prop(cpu, props, prop); - } -} - -/* Convert CPU model data from X86CPU object to a property dictionary - * that can recreate exactly the same CPU model, including every - * writeable QOM property. - */ -static void x86_cpu_to_dict_full(X86CPU *cpu, QDict *props) -{ - ObjectPropertyIterator iter; - ObjectProperty *prop; - - object_property_iter_init(&iter, OBJECT(cpu)); - while ((prop =3D object_property_iter_next(&iter))) { - /* skip read-only or write-only properties */ - if (!prop->get || !prop->set) { - continue; - } - - /* "hotplugged" is the only property that is configurable - * on the command-line but will be set differently on CPUs - * created using "-cpu ... -smp ..." and by CPUs created - * on the fly by x86_cpu_from_model() for querying. Skip it. - */ - if (!strcmp(prop->name, "hotplugged")) { - continue; - } - x86_cpu_expand_prop(cpu, props, prop->name); - } -} - -static void object_apply_props(Object *obj, QDict *props, Error **errp) -{ - const QDictEntry *prop; - - for (prop =3D qdict_first(props); prop; prop =3D qdict_next(props, pro= p)) { - if (!object_property_set_qobject(obj, qdict_entry_key(prop), - qdict_entry_value(prop), errp)) { - break; - } - } -} - -/* Create X86CPU object according to model+props specification */ -static X86CPU *x86_cpu_from_model(const char *model, QDict *props, Error *= *errp) -{ - X86CPU *xc =3D NULL; - X86CPUClass *xcc; - Error *err =3D NULL; - - xcc =3D X86_CPU_CLASS(cpu_class_by_name(TYPE_X86_CPU, model)); - if (xcc =3D=3D NULL) { - error_setg(&err, "CPU model '%s' not found", model); - goto out; - } - - xc =3D X86_CPU(object_new_with_class(OBJECT_CLASS(xcc))); - if (props) { - object_apply_props(OBJECT(xc), props, &err); - if (err) { - goto out; - } - } - - x86_cpu_expand_features(xc, &err); - if (err) { - goto out; - } - -out: - if (err) { - error_propagate(errp, err); - object_unref(OBJECT(xc)); - xc =3D NULL; - } - return xc; -} - -CpuModelExpansionInfo * -qmp_query_cpu_model_expansion(CpuModelExpansionType type, - CpuModelInfo *model, - Error **errp) -{ - X86CPU *xc =3D NULL; - Error *err =3D NULL; - CpuModelExpansionInfo *ret =3D g_new0(CpuModelExpansionInfo, 1); - QDict *props =3D NULL; - const char *base_name; - - xc =3D x86_cpu_from_model(model->name, - model->has_props ? - qobject_to(QDict, model->props) : - NULL, &err); - if (err) { - goto out; - } - - props =3D qdict_new(); - ret->model =3D g_new0(CpuModelInfo, 1); - ret->model->props =3D QOBJECT(props); - ret->model->has_props =3D true; - - switch (type) { - case CPU_MODEL_EXPANSION_TYPE_STATIC: - /* Static expansion will be based on "base" only */ - base_name =3D "base"; - x86_cpu_to_dict(xc, props); - break; - case CPU_MODEL_EXPANSION_TYPE_FULL: - /* As we don't return every single property, full expansion needs - * to keep the original model name+props, and add extra - * properties on top of that. - */ - base_name =3D model->name; - x86_cpu_to_dict_full(xc, props); - break; - default: - error_setg(&err, "Unsupported expansion type"); - goto out; - } - - x86_cpu_to_dict(xc, props); - - ret->model->name =3D g_strdup(base_name); - -out: - object_unref(OBJECT(xc)); - if (err) { - error_propagate(errp, err); - qapi_free_CpuModelExpansionInfo(ret); - ret =3D NULL; - } - return ret; -} -#endif /* !CONFIG_USER_ONLY */ - static gchar *x86_gdb_arch_name(CPUState *cs) { #ifdef TARGET_X86_64 @@ -5383,15 +5139,6 @@ static void x86_register_cpudef_types(X86CPUDefiniti= on *def) =20 } =20 -#if !defined(CONFIG_USER_ONLY) - -void cpu_clear_apic_feature(CPUX86State *env) -{ - env->features[FEAT_1_EDX] &=3D ~CPUID_APIC; -} - -#endif /* !CONFIG_USER_ONLY */ - void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) @@ -6040,20 +5787,6 @@ static void x86_cpu_reset(DeviceState *dev) #endif } =20 -#ifndef CONFIG_USER_ONLY -bool cpu_is_bsp(X86CPU *cpu) -{ - return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP; -} - -/* TODO: remove me, when reset over QOM tree is implemented */ -static void x86_cpu_machine_reset_cb(void *opaque) -{ - X86CPU *cpu =3D opaque; - cpu_reset(CPU(cpu)); -} -#endif - static void mce_init(X86CPU *cpu) { CPUX86State *cenv =3D &cpu->env; @@ -6071,68 +5804,6 @@ static void mce_init(X86CPU *cpu) } } =20 -#ifndef CONFIG_USER_ONLY -APICCommonClass *apic_get_class(void) -{ - const char *apic_type =3D "apic"; - - /* TODO: in-kernel irqchip for hvf */ - if (kvm_apic_in_kernel()) { - apic_type =3D "kvm-apic"; - } else if (xen_enabled()) { - apic_type =3D "xen-apic"; - } else if (whpx_apic_in_platform()) { - apic_type =3D "whpx-apic"; - } - - return APIC_COMMON_CLASS(object_class_by_name(apic_type)); -} - -static void x86_cpu_apic_create(X86CPU *cpu, Error **errp) -{ - APICCommonState *apic; - ObjectClass *apic_class =3D OBJECT_CLASS(apic_get_class()); - - cpu->apic_state =3D DEVICE(object_new_with_class(apic_class)); - - object_property_add_child(OBJECT(cpu), "lapic", - OBJECT(cpu->apic_state)); - object_unref(OBJECT(cpu->apic_state)); - - qdev_prop_set_uint32(cpu->apic_state, "id", cpu->apic_id); - /* TODO: convert to link<> */ - apic =3D APIC_COMMON(cpu->apic_state); - apic->cpu =3D cpu; - apic->apicbase =3D APIC_DEFAULT_ADDRESS | MSR_IA32_APICBASE_ENABLE; -} - -static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) -{ - APICCommonState *apic; - static bool apic_mmio_map_once; - - if (cpu->apic_state =3D=3D NULL) { - return; - } - qdev_realize(DEVICE(cpu->apic_state), NULL, errp); - - /* Map APIC MMIO area */ - apic =3D APIC_COMMON(cpu->apic_state); - if (!apic_mmio_map_once) { - memory_region_add_subregion_overlap(get_system_memory(), - apic->apicbase & - MSR_IA32_APICBASE_BASE, - &apic->io_memory, - 0x1000); - apic_mmio_map_once =3D true; - } -} -#else -static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp) -{ -} -#endif - static void x86_cpu_adjust_level(X86CPU *cpu, uint32_t *min, uint32_t valu= e) { if (*min < value) { @@ -6236,7 +5907,7 @@ static void x86_cpu_enable_xsave_components(X86CPU *c= pu) /* Expand CPU configuration data, based on configured features * and host/accelerator capabilities when appropriate. */ -static void x86_cpu_expand_features(X86CPU *cpu, Error **errp) +void x86_cpu_expand_features(X86CPU *cpu, Error **errp) { CPUX86State *env =3D &cpu->env; FeatureWord w; @@ -6608,10 +6279,12 @@ static void x86_cpu_realizefn(DeviceState *dev, Err= or **errp) ht_warned =3D true; } =20 +#ifndef CONFIG_USER_ONLY x86_cpu_apic_realize(cpu, &local_err); if (local_err !=3D NULL) { goto out; } +#endif /* !CONFIG_USER_ONLY */ cpu_reset(cs); =20 xcc->parent_realize(dev, &local_err); @@ -6735,52 +6408,6 @@ static void x86_cpu_register_feature_bit_props(X86CP= UClass *xcc, x86_cpu_register_bit_prop(xcc, name, w, bitnr); } =20 -#if !defined(CONFIG_USER_ONLY) -static GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs) -{ - X86CPU *cpu =3D X86_CPU(cs); - CPUX86State *env =3D &cpu->env; - GuestPanicInformation *panic_info =3D NULL; - - if (env->features[FEAT_HYPERV_EDX] & HV_GUEST_CRASH_MSR_AVAILABLE) { - panic_info =3D g_malloc0(sizeof(GuestPanicInformation)); - - panic_info->type =3D GUEST_PANIC_INFORMATION_TYPE_HYPER_V; - - assert(HV_CRASH_PARAMS >=3D 5); - panic_info->u.hyper_v.arg1 =3D env->msr_hv_crash_params[0]; - panic_info->u.hyper_v.arg2 =3D env->msr_hv_crash_params[1]; - panic_info->u.hyper_v.arg3 =3D env->msr_hv_crash_params[2]; - panic_info->u.hyper_v.arg4 =3D env->msr_hv_crash_params[3]; - panic_info->u.hyper_v.arg5 =3D env->msr_hv_crash_params[4]; - } - - return panic_info; -} -static void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) -{ - CPUState *cs =3D CPU(obj); - GuestPanicInformation *panic_info; - - if (!cs->crash_occurred) { - error_setg(errp, "No crash occured"); - return; - } - - panic_info =3D x86_cpu_get_crash_info(cs); - if (panic_info =3D=3D NULL) { - error_setg(errp, "No crash information"); - return; - } - - visit_type_GuestPanicInformation(v, "crash-information", &panic_info, - errp); - qapi_free_GuestPanicInformation(panic_info); -} -#endif /* !CONFIG_USER_ONLY */ - static void x86_cpu_initfn(Object *obj) { X86CPU *cpu =3D X86_CPU(obj); diff --git a/target/i386/meson.build b/target/i386/meson.build index cac26a4581..0f50f32b33 100644 --- a/target/i386/meson.build +++ b/target/i386/meson.build @@ -18,6 +18,7 @@ i386_softmmu_ss.add(files( 'arch_memory_mapping.c', 'machine.c', 'monitor.c', + 'cpu-sysemu.c', )) i386_user_ss =3D ss.source_set() =20 --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333536; cv=none; d=zohomail.com; s=zohoarc; b=EpkgopLbOGB6GLW1YRyvj9IeynEBmDOq4qtLPB18iphAunx3gYvTa51qdAVkgSB5FQlvkTTZ/o6O7wygxNJ/Jv3aiT8jGypg4SQR/MKTR8tqrmK/P+FuJtjf8NJF/LQ0Xvj5SflgCuxknEwseKG4cCwgKtL5hLYgm9h1aHFtAeg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333536; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=3KSrfB+r4sFMlCn0t9J+/JNtjucNFThDYemrM1LdYQA=; b=bG4760GM08ScSD5IJTcHJHwWNMa+aNkFGh3DXBLoakHaYwVtXqqPTc/d+xpNqICRlwcp2Ges6HDGZS9VA3cw+H01/WLAXSJM3GKvHTc2KEHNQ7MVQKAG/RzVLk4oEGfmkXwDSY+zjh3URGbi2Jx//nFZ+v2+oIkFqgasqiJkXuU= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 161433353692940.655610218769425; Fri, 26 Feb 2021 01:58:56 -0800 (PST) Received: from localhost ([::1]:38912 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZte-0007Or-9g for importer@patchew.org; Fri, 26 Feb 2021 04:58:54 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36488) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl8-0005QQ-7r for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:06 -0500 Received: from mx2.suse.de ([195.135.220.15]:43290) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl3-0004ry-2P for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:05 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id C8F6CAF3F; Fri, 26 Feb 2021 09:49:49 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 16/18] target/i386: gdbstub: introduce aux functions to read/write CS64 regs Date: Fri, 26 Feb 2021 10:49:37 +0100 Message-Id: <20210226094939.11087-17-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" a number of registers are read as 64bit under the condition that (hflags & HF_CS64_MASK) || TARGET_X86_64) and a number of registers are written as 64bit under the condition that (hflags & HF_CS64_MASK). Provide some auxiliary functions that do that. Signed-off-by: Claudio Fontana Cc: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/gdbstub.c | 155 ++++++++++++++---------------------------- 1 file changed, 51 insertions(+), 104 deletions(-) diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c index 41e265fc67..4ad1295425 100644 --- a/target/i386/gdbstub.c +++ b/target/i386/gdbstub.c @@ -78,6 +78,23 @@ static const int gpr_map32[8] =3D { 0, 1, 2, 3, 4, 5, 6,= 7 }; #define GDB_FORCE_64 0 #endif =20 +static int gdb_read_reg_cs64(uint32_t hflags, GByteArray *buf, target_ulon= g val) +{ + if ((hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(buf, val); + } + return gdb_get_reg32(buf, val); +} + +static int gdb_write_reg_cs64(uint32_t hflags, uint8_t *buf, target_ulong = *val) +{ + if (hflags & HF_CS64_MASK) { + *val =3D ldq_p(buf); + return 8; + } + *val =3D ldl_p(buf); + return 4; +} =20 int x86_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n) { @@ -142,25 +159,14 @@ int x86_cpu_gdb_read_register(CPUState *cs, GByteArra= y *mem_buf, int n) return gdb_get_reg32(mem_buf, env->segs[R_FS].selector); case IDX_SEG_REGS + 5: return gdb_get_reg32(mem_buf, env->segs[R_GS].selector); - case IDX_SEG_REGS + 6: - if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { - return gdb_get_reg64(mem_buf, env->segs[R_FS].base); - } - return gdb_get_reg32(mem_buf, env->segs[R_FS].base); - + return gdb_read_reg_cs64(env->hflags, mem_buf, env->segs[R_FS]= .base); case IDX_SEG_REGS + 7: - if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { - return gdb_get_reg64(mem_buf, env->segs[R_GS].base); - } - return gdb_get_reg32(mem_buf, env->segs[R_GS].base); + return gdb_read_reg_cs64(env->hflags, mem_buf, env->segs[R_GS]= .base); =20 case IDX_SEG_REGS + 8: #ifdef TARGET_X86_64 - if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { - return gdb_get_reg64(mem_buf, env->kernelgsbase); - } - return gdb_get_reg32(mem_buf, env->kernelgsbase); + return gdb_read_reg_cs64(env->hflags, mem_buf, env->kernelgsba= se); #else return gdb_get_reg32(mem_buf, 0); #endif @@ -188,45 +194,23 @@ int x86_cpu_gdb_read_register(CPUState *cs, GByteArra= y *mem_buf, int n) return gdb_get_reg32(mem_buf, env->mxcsr); =20 case IDX_CTL_CR0_REG: - if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { - return gdb_get_reg64(mem_buf, env->cr[0]); - } - return gdb_get_reg32(mem_buf, env->cr[0]); - + return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[0]); case IDX_CTL_CR2_REG: - if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { - return gdb_get_reg64(mem_buf, env->cr[2]); - } - return gdb_get_reg32(mem_buf, env->cr[2]); - + return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[2]); case IDX_CTL_CR3_REG: - if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { - return gdb_get_reg64(mem_buf, env->cr[3]); - } - return gdb_get_reg32(mem_buf, env->cr[3]); - + return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[3]); case IDX_CTL_CR4_REG: - if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { - return gdb_get_reg64(mem_buf, env->cr[4]); - } - return gdb_get_reg32(mem_buf, env->cr[4]); - + return gdb_read_reg_cs64(env->hflags, mem_buf, env->cr[4]); case IDX_CTL_CR8_REG: -#ifdef CONFIG_SOFTMMU +#ifndef CONFIG_USER_ONLY tpr =3D cpu_get_apic_tpr(cpu->apic_state); #else tpr =3D 0; #endif - if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { - return gdb_get_reg64(mem_buf, tpr); - } - return gdb_get_reg32(mem_buf, tpr); + return gdb_read_reg_cs64(env->hflags, mem_buf, tpr); =20 case IDX_CTL_EFER_REG: - if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { - return gdb_get_reg64(mem_buf, env->efer); - } - return gdb_get_reg32(mem_buf, env->efer); + return gdb_read_reg_cs64(env->hflags, mem_buf, env->efer); } } return 0; @@ -266,7 +250,8 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *m= em_buf, int n) { X86CPU *cpu =3D X86_CPU(cs); CPUX86State *env =3D &cpu->env; - uint32_t tmp; + target_ulong tmp; + int len; =20 /* N.B. GDB can't deal with changes in registers or sizes in the middle of a session. So if we're in 32-bit mode on a 64-bit cpu, still act @@ -329,30 +314,13 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t = *mem_buf, int n) return x86_cpu_gdb_load_seg(cpu, R_FS, mem_buf); case IDX_SEG_REGS + 5: return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf); - case IDX_SEG_REGS + 6: - if (env->hflags & HF_CS64_MASK) { - env->segs[R_FS].base =3D ldq_p(mem_buf); - return 8; - } - env->segs[R_FS].base =3D ldl_p(mem_buf); - return 4; - + return gdb_write_reg_cs64(env->hflags, mem_buf, &env->segs[R_F= S].base); case IDX_SEG_REGS + 7: - if (env->hflags & HF_CS64_MASK) { - env->segs[R_GS].base =3D ldq_p(mem_buf); - return 8; - } - env->segs[R_GS].base =3D ldl_p(mem_buf); - return 4; - + return gdb_write_reg_cs64(env->hflags, mem_buf, &env->segs[R_G= S].base); case IDX_SEG_REGS + 8: #ifdef TARGET_X86_64 - if (env->hflags & HF_CS64_MASK) { - env->kernelgsbase =3D ldq_p(mem_buf); - return 8; - } - env->kernelgsbase =3D ldl_p(mem_buf); + return gdb_write_reg_cs64(env->hflags, mem_buf, &env->kernelgs= base); #endif return 4; =20 @@ -382,57 +350,36 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t = *mem_buf, int n) return 4; =20 case IDX_CTL_CR0_REG: - if (env->hflags & HF_CS64_MASK) { - cpu_x86_update_cr0(env, ldq_p(mem_buf)); - return 8; - } - cpu_x86_update_cr0(env, ldl_p(mem_buf)); - return 4; + len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); + cpu_x86_update_cr0(env, tmp); + return len; =20 case IDX_CTL_CR2_REG: - if (env->hflags & HF_CS64_MASK) { - env->cr[2] =3D ldq_p(mem_buf); - return 8; - } - env->cr[2] =3D ldl_p(mem_buf); - return 4; + len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); + env->cr[2] =3D tmp; + return len; =20 case IDX_CTL_CR3_REG: - if (env->hflags & HF_CS64_MASK) { - cpu_x86_update_cr3(env, ldq_p(mem_buf)); - return 8; - } - cpu_x86_update_cr3(env, ldl_p(mem_buf)); - return 4; + len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); + cpu_x86_update_cr3(env, tmp); + return len; =20 case IDX_CTL_CR4_REG: - if (env->hflags & HF_CS64_MASK) { - cpu_x86_update_cr4(env, ldq_p(mem_buf)); - return 8; - } - cpu_x86_update_cr4(env, ldl_p(mem_buf)); - return 4; + len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); + cpu_x86_update_cr4(env, tmp); + return len; =20 case IDX_CTL_CR8_REG: - if (env->hflags & HF_CS64_MASK) { -#ifdef CONFIG_SOFTMMU - cpu_set_apic_tpr(cpu->apic_state, ldq_p(mem_buf)); + len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); +#ifndef CONFIG_USER_ONLY + cpu_set_apic_tpr(cpu->apic_state, tmp); #endif - return 8; - } -#ifdef CONFIG_SOFTMMU - cpu_set_apic_tpr(cpu->apic_state, ldl_p(mem_buf)); -#endif - return 4; + return len; =20 case IDX_CTL_EFER_REG: - if (env->hflags & HF_CS64_MASK) { - cpu_load_efer(env, ldq_p(mem_buf)); - return 8; - } - cpu_load_efer(env, ldl_p(mem_buf)); - return 4; - + len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); + cpu_load_efer(env, tmp); + return len; } } /* Unrecognised register. */ --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333577; cv=none; d=zohomail.com; s=zohoarc; b=apn/HM7KQwbQItvXVRBmK3JU3OSCdvdiBe3LG1TIeSr0uJ7R5umuviaCEiuKwq1rXiYJTSSOEutx3akjYjR7b68KRXI3gpCOReq3YihXQx5a7TwCH1T4ObCgvvhkpxKHdoHzJR6ZU0kqKamLm58AWsOAkrg5NA36E3KM2t9UZxc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333577; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=nyji0o8HxMh547pLq6nRlrCjAXfvbFNvUUBHNH0N1LA=; b=JMWz9Cibo8I6ggXk8h2BPaeNrYlfhjsHkSmTDSmsgyfMW9QFj2IRtTBu+BzTtrK0uPcvKaaAsao/xvUXkBfXOD4H8x2T/QUYO6Ls3zJRVZoCxHIf71Ajv5TrTOULoq13ffhxkVVsa1wyjmimJElea6qNMn4tpDVzXvMD6cFq/MI= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333577362879.8407824127986; Fri, 26 Feb 2021 01:59:37 -0800 (PST) Received: from localhost ([::1]:41690 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZuK-0000Dk-7P for importer@patchew.org; Fri, 26 Feb 2021 04:59:36 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36500) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl9-0005S6-6l for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:07 -0500 Received: from mx2.suse.de ([195.135.220.15]:43306) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl3-0004tO-ML for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:06 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 5D0F9AF49; Fri, 26 Feb 2021 09:49:50 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 17/18] target/i386: gdbstub: only write CR0/CR2/CR3/EFER for sysemu Date: Fri, 26 Feb 2021 10:49:38 +0100 Message-Id: <20210226094939.11087-18-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Claudio Fontana Cc: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/gdbstub.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c index 4ad1295425..098a2ad15a 100644 --- a/target/i386/gdbstub.c +++ b/target/i386/gdbstub.c @@ -351,22 +351,30 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t = *mem_buf, int n) =20 case IDX_CTL_CR0_REG: len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); +#ifndef CONFIG_USER_ONLY cpu_x86_update_cr0(env, tmp); +#endif return len; =20 case IDX_CTL_CR2_REG: len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); +#ifndef CONFIG_USER_ONLY env->cr[2] =3D tmp; +#endif return len; =20 case IDX_CTL_CR3_REG: len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); +#ifndef CONFIG_USER_ONLY cpu_x86_update_cr3(env, tmp); +#endif return len; =20 case IDX_CTL_CR4_REG: len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); +#ifndef CONFIG_USER_ONLY cpu_x86_update_cr4(env, tmp); +#endif return len; =20 case IDX_CTL_CR8_REG: @@ -378,7 +386,9 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *m= em_buf, int n) =20 case IDX_CTL_EFER_REG: len =3D gdb_write_reg_cs64(env->hflags, mem_buf, &tmp); +#ifndef CONFIG_USER_ONLY cpu_load_efer(env, tmp); +#endif return len; } } --=20 2.26.2 From nobody Thu Mar 28 16:37:04 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1614333826; cv=none; d=zohomail.com; s=zohoarc; b=Dgx8K+vZXZowb+Gvl5KpFxNx6v/VbNurlY2iFCJ8q2uHlE7wWp9MnTas0NLfpFqceconsVNzW9NHBKIr1wtQhAbeaf1m+ow5oSFFe76FysuaNKj0dE7zCDqnjuAcW9gAGuhUX4HMcBMMhZe4JDvZO8hGC18TrFFowoHtRNlMqaA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1614333826; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=MwMUfnwRr3RB9WQnv4VNX5kJYp15O3RLeFvuWU5PL1I=; b=iR/Zjc83UGOUW4DHitImmJ1vAgcV8nJSaS9ABiqFm4RvfTYMILEqbPnd8rukXuafoniEusmy7e6LlYI33LU/JHv+Qc21ePA+bQa3VZD8wyKhJrihjj67VCQHi4M4DpJu4+OUmZzN+8QrdPv9v9vIIbBd8/s5xL9UVrftTPHmArg= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1614333826269688.9161322048118; Fri, 26 Feb 2021 02:03:46 -0800 (PST) Received: from localhost ([::1]:49908 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFZyL-0003nI-5n for importer@patchew.org; Fri, 26 Feb 2021 05:03:45 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:36506) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl9-0005TA-Sj for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:07 -0500 Received: from mx2.suse.de ([195.135.220.15]:43322) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFZl4-0004uL-6F for qemu-devel@nongnu.org; Fri, 26 Feb 2021 04:50:07 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id DE0A5AF57; Fri, 26 Feb 2021 09:49:50 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Claudio Fontana To: Paolo Bonzini , Richard Henderson , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Eduardo Habkost , Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= Subject: [PATCH v24 18/18] i386: make cpu_load_efer sysemu-only Date: Fri, 26 Feb 2021 10:49:39 +0100 Message-Id: <20210226094939.11087-19-cfontana@suse.de> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210226094939.11087-1-cfontana@suse.de> References: <20210226094939.11087-1-cfontana@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=cfontana@suse.de; helo=mx2.suse.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Thomas Huth , Roman Bolshakov , Claudio Fontana , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" cpu_load_efer is now used only for sysemu code. Therefore, move this function implementation to sysemu-only section of helper.c Signed-off-by: Claudio Fontana Reviewed-by: Richard Henderson --- target/i386/cpu.h | 20 +++++--------------- target/i386/helper.c | 13 +++++++++++++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 3797789dc2..a1268abe9f 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1957,6 +1957,11 @@ static inline AddressSpace *cpu_addressspace(CPUStat= e *cs, MemTxAttrs attrs) return cpu_get_address_space(cs, cpu_asidx_from_attrs(cs, attrs)); } =20 +/* + * load efer and update the corresponding hflags. XXX: do consistency + * checks with cpuid bits? + */ +void cpu_load_efer(CPUX86State *env, uint64_t val); uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr); uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr); uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr); @@ -2053,21 +2058,6 @@ static inline uint32_t cpu_compute_eflags(CPUX86Stat= e *env) return eflags; } =20 - -/* load efer and update the corresponding hflags. XXX: do consistency - checks with cpuid bits? */ -static inline void cpu_load_efer(CPUX86State *env, uint64_t val) -{ - env->efer =3D val; - env->hflags &=3D ~(HF_LMA_MASK | HF_SVME_MASK); - if (env->efer & MSR_EFER_LMA) { - env->hflags |=3D HF_LMA_MASK; - } - if (env->efer & MSR_EFER_SVME) { - env->hflags |=3D HF_SVME_MASK; - } -} - static inline MemTxAttrs cpu_get_mem_attrs(CPUX86State *env) { return ((MemTxAttrs) { .secure =3D (env->hflags & HF_SMM_MASK) !=3D 0 = }); diff --git a/target/i386/helper.c b/target/i386/helper.c index 618ad1c409..7304721a94 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -574,6 +574,19 @@ void do_cpu_sipi(X86CPU *cpu) #endif =20 #ifndef CONFIG_USER_ONLY + +void cpu_load_efer(CPUX86State *env, uint64_t val) +{ + env->efer =3D val; + env->hflags &=3D ~(HF_LMA_MASK | HF_SVME_MASK); + if (env->efer & MSR_EFER_LMA) { + env->hflags |=3D HF_LMA_MASK; + } + if (env->efer & MSR_EFER_SVME) { + env->hflags |=3D HF_SVME_MASK; + } +} + uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr) { X86CPU *cpu =3D X86_CPU(cs); --=20 2.26.2