2020-12-12 18:55:14 +03:00
|
|
|
/*
|
|
|
|
* i386 TCG cpu class initialization
|
|
|
|
*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "qemu/osdep.h"
|
|
|
|
#include "cpu.h"
|
|
|
|
#include "helper-tcg.h"
|
2021-03-22 16:27:40 +03:00
|
|
|
#include "qemu/accel.h"
|
|
|
|
#include "hw/core/accel-cpu.h"
|
2020-12-12 18:55:14 +03:00
|
|
|
|
2021-05-06 18:20:23 +03:00
|
|
|
#include "tcg-cpu.h"
|
2020-12-12 18:55:14 +03:00
|
|
|
|
|
|
|
/* Frob eflags into and out of the CPU temporary format. */
|
|
|
|
|
|
|
|
static void x86_cpu_exec_enter(CPUState *cs)
|
|
|
|
{
|
|
|
|
X86CPU *cpu = X86_CPU(cs);
|
|
|
|
CPUX86State *env = &cpu->env;
|
|
|
|
|
|
|
|
CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
|
|
|
env->df = 1 - (2 * ((env->eflags >> 10) & 1));
|
|
|
|
CC_OP = CC_OP_EFLAGS;
|
|
|
|
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void x86_cpu_exec_exit(CPUState *cs)
|
|
|
|
{
|
|
|
|
X86CPU *cpu = X86_CPU(cs);
|
|
|
|
CPUX86State *env = &cpu->env;
|
|
|
|
|
|
|
|
env->eflags = cpu_compute_eflags(env);
|
|
|
|
}
|
|
|
|
|
2020-10-29 22:30:01 +03:00
|
|
|
static void x86_cpu_synchronize_from_tb(CPUState *cs,
|
|
|
|
const TranslationBlock *tb)
|
2020-12-12 18:55:14 +03:00
|
|
|
{
|
2023-02-27 16:51:42 +03:00
|
|
|
/* The instruction pointer is always up to date with CF_PCREL. */
|
|
|
|
if (!(tb_cflags(tb) & CF_PCREL)) {
|
2023-09-14 03:22:49 +03:00
|
|
|
CPUX86State *env = cpu_env(cs);
|
2023-12-12 20:01:38 +03:00
|
|
|
|
|
|
|
if (tb->flags & HF_CS64_MASK) {
|
|
|
|
env->eip = tb->pc;
|
|
|
|
} else {
|
|
|
|
env->eip = (uint32_t)(tb->pc - tb->cs_base);
|
|
|
|
}
|
2022-10-01 17:09:35 +03:00
|
|
|
}
|
2020-12-12 18:55:14 +03:00
|
|
|
}
|
|
|
|
|
2022-10-24 13:18:03 +03:00
|
|
|
static void x86_restore_state_to_opc(CPUState *cs,
|
|
|
|
const TranslationBlock *tb,
|
|
|
|
const uint64_t *data)
|
|
|
|
{
|
|
|
|
X86CPU *cpu = X86_CPU(cs);
|
|
|
|
CPUX86State *env = &cpu->env;
|
|
|
|
int cc_op = data[1];
|
target/i386: pcrel: store low bits of physical address in data[0]
For PC-relative translation blocks, env->eip changes during the
execution of a translation block, Therefore, QEMU must be able to
recover an instruction's PC just from the TranslationBlock struct and
the instruction data with. Because a TB will not span two pages, QEMU
stores all the low bits of EIP in the instruction data and replaces them
in x86_restore_state_to_opc. Bits 12 and higher (which may vary between
executions of a PCREL TB, since these only use the physical address in
the hash key) are kept unmodified from env->eip. The assumption is that
these bits of EIP, unlike bits 0-11, will not change as the translation
block executes.
Unfortunately, this is incorrect when the CS base is not aligned to a page.
Then the linear address of the instructions (i.e. the one with the
CS base addred) indeed will never span two pages, but bits 12+ of EIP
can actually change. For example, if CS base is 0x80262200 and EIP =
0x6FF4, the first instruction in the translation block will be at linear
address 0x802691F4. Even a very small TB will cross to EIP = 0x7xxx,
while the linear addresses will remain comfortably within a single page.
The fix is simply to use the low bits of the linear address for data[0],
since those don't change. Then x86_restore_state_to_opc uses tb->cs_base
to compute a temporary linear address (referring to some unknown
instruction in the TB, but with the correct values of bits 12 and higher);
the low bits are replaced with data[0], and EIP is obtained by subtracting
again the CS base.
Huge thanks to Mark Cave-Ayland for the image and initial debugging,
and to Gitlab user @kjliew for help with bisecting another occurrence
of (hopefully!) the same bug.
It should be relatively easy to write a testcase that performs MMIO on
an EIP with different bits 12+ than the first instruction of the translation
block; any help is welcome.
Fixes: e3a79e0e878 ("target/i386: Enable TARGET_TB_PCREL", 2022-10-11)
Cc: qemu-stable@nongnu.org
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Richard Henderson <richard.henderson@linaro.org>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1759
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1964
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2012
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-01-17 18:27:42 +03:00
|
|
|
uint64_t new_pc;
|
2022-10-24 13:18:03 +03:00
|
|
|
|
2023-02-27 16:51:42 +03:00
|
|
|
if (tb_cflags(tb) & CF_PCREL) {
|
target/i386: pcrel: store low bits of physical address in data[0]
For PC-relative translation blocks, env->eip changes during the
execution of a translation block, Therefore, QEMU must be able to
recover an instruction's PC just from the TranslationBlock struct and
the instruction data with. Because a TB will not span two pages, QEMU
stores all the low bits of EIP in the instruction data and replaces them
in x86_restore_state_to_opc. Bits 12 and higher (which may vary between
executions of a PCREL TB, since these only use the physical address in
the hash key) are kept unmodified from env->eip. The assumption is that
these bits of EIP, unlike bits 0-11, will not change as the translation
block executes.
Unfortunately, this is incorrect when the CS base is not aligned to a page.
Then the linear address of the instructions (i.e. the one with the
CS base addred) indeed will never span two pages, but bits 12+ of EIP
can actually change. For example, if CS base is 0x80262200 and EIP =
0x6FF4, the first instruction in the translation block will be at linear
address 0x802691F4. Even a very small TB will cross to EIP = 0x7xxx,
while the linear addresses will remain comfortably within a single page.
The fix is simply to use the low bits of the linear address for data[0],
since those don't change. Then x86_restore_state_to_opc uses tb->cs_base
to compute a temporary linear address (referring to some unknown
instruction in the TB, but with the correct values of bits 12 and higher);
the low bits are replaced with data[0], and EIP is obtained by subtracting
again the CS base.
Huge thanks to Mark Cave-Ayland for the image and initial debugging,
and to Gitlab user @kjliew for help with bisecting another occurrence
of (hopefully!) the same bug.
It should be relatively easy to write a testcase that performs MMIO on
an EIP with different bits 12+ than the first instruction of the translation
block; any help is welcome.
Fixes: e3a79e0e878 ("target/i386: Enable TARGET_TB_PCREL", 2022-10-11)
Cc: qemu-stable@nongnu.org
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Richard Henderson <richard.henderson@linaro.org>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1759
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1964
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2012
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-01-17 18:27:42 +03:00
|
|
|
/*
|
|
|
|
* data[0] in PC-relative TBs is also a linear address, i.e. an address with
|
|
|
|
* the CS base added, because it is not guaranteed that EIP bits 12 and higher
|
|
|
|
* stay the same across the translation block. Add the CS base back before
|
|
|
|
* replacing the low bits, and subtract it below just like for !CF_PCREL.
|
|
|
|
*/
|
|
|
|
uint64_t pc = env->eip + tb->cs_base;
|
|
|
|
new_pc = (pc & TARGET_PAGE_MASK) | data[0];
|
2022-10-24 13:18:03 +03:00
|
|
|
} else {
|
target/i386: pcrel: store low bits of physical address in data[0]
For PC-relative translation blocks, env->eip changes during the
execution of a translation block, Therefore, QEMU must be able to
recover an instruction's PC just from the TranslationBlock struct and
the instruction data with. Because a TB will not span two pages, QEMU
stores all the low bits of EIP in the instruction data and replaces them
in x86_restore_state_to_opc. Bits 12 and higher (which may vary between
executions of a PCREL TB, since these only use the physical address in
the hash key) are kept unmodified from env->eip. The assumption is that
these bits of EIP, unlike bits 0-11, will not change as the translation
block executes.
Unfortunately, this is incorrect when the CS base is not aligned to a page.
Then the linear address of the instructions (i.e. the one with the
CS base addred) indeed will never span two pages, but bits 12+ of EIP
can actually change. For example, if CS base is 0x80262200 and EIP =
0x6FF4, the first instruction in the translation block will be at linear
address 0x802691F4. Even a very small TB will cross to EIP = 0x7xxx,
while the linear addresses will remain comfortably within a single page.
The fix is simply to use the low bits of the linear address for data[0],
since those don't change. Then x86_restore_state_to_opc uses tb->cs_base
to compute a temporary linear address (referring to some unknown
instruction in the TB, but with the correct values of bits 12 and higher);
the low bits are replaced with data[0], and EIP is obtained by subtracting
again the CS base.
Huge thanks to Mark Cave-Ayland for the image and initial debugging,
and to Gitlab user @kjliew for help with bisecting another occurrence
of (hopefully!) the same bug.
It should be relatively easy to write a testcase that performs MMIO on
an EIP with different bits 12+ than the first instruction of the translation
block; any help is welcome.
Fixes: e3a79e0e878 ("target/i386: Enable TARGET_TB_PCREL", 2022-10-11)
Cc: qemu-stable@nongnu.org
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Richard Henderson <richard.henderson@linaro.org>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1759
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1964
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2012
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-01-17 18:27:42 +03:00
|
|
|
new_pc = data[0];
|
2022-10-24 13:18:03 +03:00
|
|
|
}
|
target/i386: pcrel: store low bits of physical address in data[0]
For PC-relative translation blocks, env->eip changes during the
execution of a translation block, Therefore, QEMU must be able to
recover an instruction's PC just from the TranslationBlock struct and
the instruction data with. Because a TB will not span two pages, QEMU
stores all the low bits of EIP in the instruction data and replaces them
in x86_restore_state_to_opc. Bits 12 and higher (which may vary between
executions of a PCREL TB, since these only use the physical address in
the hash key) are kept unmodified from env->eip. The assumption is that
these bits of EIP, unlike bits 0-11, will not change as the translation
block executes.
Unfortunately, this is incorrect when the CS base is not aligned to a page.
Then the linear address of the instructions (i.e. the one with the
CS base addred) indeed will never span two pages, but bits 12+ of EIP
can actually change. For example, if CS base is 0x80262200 and EIP =
0x6FF4, the first instruction in the translation block will be at linear
address 0x802691F4. Even a very small TB will cross to EIP = 0x7xxx,
while the linear addresses will remain comfortably within a single page.
The fix is simply to use the low bits of the linear address for data[0],
since those don't change. Then x86_restore_state_to_opc uses tb->cs_base
to compute a temporary linear address (referring to some unknown
instruction in the TB, but with the correct values of bits 12 and higher);
the low bits are replaced with data[0], and EIP is obtained by subtracting
again the CS base.
Huge thanks to Mark Cave-Ayland for the image and initial debugging,
and to Gitlab user @kjliew for help with bisecting another occurrence
of (hopefully!) the same bug.
It should be relatively easy to write a testcase that performs MMIO on
an EIP with different bits 12+ than the first instruction of the translation
block; any help is welcome.
Fixes: e3a79e0e878 ("target/i386: Enable TARGET_TB_PCREL", 2022-10-11)
Cc: qemu-stable@nongnu.org
Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Cc: Richard Henderson <richard.henderson@linaro.org>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1759
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1964
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2012
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-01-17 18:27:42 +03:00
|
|
|
if (tb->flags & HF_CS64_MASK) {
|
|
|
|
env->eip = new_pc;
|
|
|
|
} else {
|
|
|
|
env->eip = (uint32_t)(new_pc - tb->cs_base);
|
|
|
|
}
|
|
|
|
|
2022-10-24 13:18:03 +03:00
|
|
|
if (cc_op != CC_OP_DYNAMIC) {
|
|
|
|
env->cc_op = cc_op;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-19 21:22:47 +03:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
|
|
|
static bool x86_debug_check_breakpoint(CPUState *cs)
|
|
|
|
{
|
|
|
|
X86CPU *cpu = X86_CPU(cs);
|
|
|
|
CPUX86State *env = &cpu->env;
|
|
|
|
|
|
|
|
/* RF disables all architectural breakpoints. */
|
|
|
|
return !(env->eflags & RF_MASK);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2021-02-04 19:39:23 +03:00
|
|
|
#include "hw/core/tcg-cpu-ops.h"
|
|
|
|
|
2021-02-28 02:21:17 +03:00
|
|
|
static const struct TCGCPUOps x86_tcg_ops = {
|
2021-02-04 19:39:23 +03:00
|
|
|
.initialize = tcg_x86_init,
|
|
|
|
.synchronize_from_tb = x86_cpu_synchronize_from_tb,
|
2022-10-24 13:18:03 +03:00
|
|
|
.restore_state_to_opc = x86_restore_state_to_opc,
|
2021-02-04 19:39:23 +03:00
|
|
|
.cpu_exec_enter = x86_cpu_exec_enter,
|
|
|
|
.cpu_exec_exit = x86_cpu_exec_exit,
|
2021-09-11 19:54:15 +03:00
|
|
|
#ifdef CONFIG_USER_ONLY
|
|
|
|
.fake_user_interrupt = x86_cpu_do_interrupt,
|
2021-09-18 05:10:25 +03:00
|
|
|
.record_sigsegv = x86_cpu_record_sigsegv,
|
2022-09-18 01:27:12 +03:00
|
|
|
.record_sigbus = x86_cpu_record_sigbus,
|
2021-09-11 19:54:15 +03:00
|
|
|
#else
|
2021-09-18 05:10:25 +03:00
|
|
|
.tlb_fill = x86_cpu_tlb_fill,
|
2021-09-11 19:54:15 +03:00
|
|
|
.do_interrupt = x86_cpu_do_interrupt,
|
2021-09-11 19:54:20 +03:00
|
|
|
.cpu_exec_interrupt = x86_cpu_exec_interrupt,
|
2022-09-18 01:27:12 +03:00
|
|
|
.do_unaligned_access = x86_cpu_do_unaligned_access,
|
2021-02-04 19:39:23 +03:00
|
|
|
.debug_excp_handler = breakpoint_handler,
|
2021-07-19 21:22:47 +03:00
|
|
|
.debug_check_breakpoint = x86_debug_check_breakpoint,
|
2021-02-04 19:39:23 +03:00
|
|
|
#endif /* !CONFIG_USER_ONLY */
|
|
|
|
};
|
|
|
|
|
2024-01-10 11:30:48 +03:00
|
|
|
static void x86_tcg_cpu_init_ops(AccelCPUClass *accel_cpu, CPUClass *cc)
|
2020-12-12 18:55:14 +03:00
|
|
|
{
|
2021-03-22 16:27:59 +03:00
|
|
|
/* for x86, all cpus use the same set of operations */
|
2021-02-04 19:39:23 +03:00
|
|
|
cc->tcg_ops = &x86_tcg_ops;
|
2020-12-12 18:55:14 +03:00
|
|
|
}
|
2021-03-22 16:27:40 +03:00
|
|
|
|
2024-01-10 11:30:48 +03:00
|
|
|
static void x86_tcg_cpu_class_init(CPUClass *cc)
|
2021-03-22 16:27:59 +03:00
|
|
|
{
|
2024-01-10 11:30:48 +03:00
|
|
|
cc->init_accel_cpu = x86_tcg_cpu_init_ops;
|
2021-03-22 16:27:59 +03:00
|
|
|
}
|
|
|
|
|
2024-01-10 11:30:48 +03:00
|
|
|
static void x86_tcg_cpu_xsave_init(void)
|
2021-07-05 13:46:31 +03:00
|
|
|
{
|
|
|
|
#define XO(bit, field) \
|
|
|
|
x86_ext_save_areas[bit].offset = offsetof(X86XSaveArea, field);
|
|
|
|
|
|
|
|
XO(XSTATE_FP_BIT, legacy);
|
|
|
|
XO(XSTATE_SSE_BIT, legacy);
|
|
|
|
XO(XSTATE_YMM_BIT, avx_state);
|
|
|
|
XO(XSTATE_BNDREGS_BIT, bndreg_state);
|
|
|
|
XO(XSTATE_BNDCSR_BIT, bndcsr_state);
|
|
|
|
XO(XSTATE_OPMASK_BIT, opmask_state);
|
|
|
|
XO(XSTATE_ZMM_Hi256_BIT, zmm_hi256_state);
|
|
|
|
XO(XSTATE_Hi16_ZMM_BIT, hi16_zmm_state);
|
|
|
|
XO(XSTATE_PKRU_BIT, pkru_state);
|
|
|
|
|
|
|
|
#undef XO
|
|
|
|
}
|
|
|
|
|
2021-03-22 16:27:40 +03:00
|
|
|
/*
|
i386: do not call cpudef-only models functions for max, host, base
Some cpu properties have to be set only for cpu models in builtin_x86_defs,
registered with x86_register_cpu_model_type, and not for
cpu models "base", "max", and the subclass "host".
These properties are the ones set by function x86_cpu_apply_props,
(also including kvm_default_props, tcg_default_props),
and the "vendor" property for the KVM and HVF accelerators.
After recent refactoring of cpu, which also affected these properties,
they were instead set unconditionally for all x86 cpus.
This has been detected as a bug with Nested on AMD with cpu "host",
as svm was not turned on by default, due to the wrongful setting of
kvm_default_props via x86_cpu_apply_props, which set svm to "off".
Rectify the bug introduced in commit "i386: split cpu accelerators"
and document the functions that are builtin_x86_defs-only.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Tested-by: Alexander Bulekov <alxndr@bu.edu>
Fixes: f5cc5a5c ("i386: split cpu accelerators from cpu.c,"...)
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/477
Message-Id: <20210723112921.12637-1-cfontana@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-07-23 14:29:21 +03:00
|
|
|
* TCG-specific defaults that override cpudef models when using TCG.
|
|
|
|
* Only for builtin_x86_defs models initialized with x86_register_cpudef_types.
|
2021-03-22 16:27:40 +03:00
|
|
|
*/
|
2024-01-10 11:30:48 +03:00
|
|
|
static PropValue x86_tcg_default_props[] = {
|
2021-03-22 16:27:40 +03:00
|
|
|
{ "vme", "off" },
|
|
|
|
{ NULL, NULL },
|
|
|
|
};
|
|
|
|
|
2024-01-10 11:30:48 +03:00
|
|
|
static void x86_tcg_cpu_instance_init(CPUState *cs)
|
2021-03-22 16:27:40 +03:00
|
|
|
{
|
|
|
|
X86CPU *cpu = X86_CPU(cs);
|
i386: do not call cpudef-only models functions for max, host, base
Some cpu properties have to be set only for cpu models in builtin_x86_defs,
registered with x86_register_cpu_model_type, and not for
cpu models "base", "max", and the subclass "host".
These properties are the ones set by function x86_cpu_apply_props,
(also including kvm_default_props, tcg_default_props),
and the "vendor" property for the KVM and HVF accelerators.
After recent refactoring of cpu, which also affected these properties,
they were instead set unconditionally for all x86 cpus.
This has been detected as a bug with Nested on AMD with cpu "host",
as svm was not turned on by default, due to the wrongful setting of
kvm_default_props via x86_cpu_apply_props, which set svm to "off".
Rectify the bug introduced in commit "i386: split cpu accelerators"
and document the functions that are builtin_x86_defs-only.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Tested-by: Alexander Bulekov <alxndr@bu.edu>
Fixes: f5cc5a5c ("i386: split cpu accelerators from cpu.c,"...)
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/477
Message-Id: <20210723112921.12637-1-cfontana@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-07-23 14:29:21 +03:00
|
|
|
X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
|
|
|
|
|
|
|
|
if (xcc->model) {
|
|
|
|
/* Special cases not set in the X86CPUDefinition structs: */
|
2024-01-10 11:30:48 +03:00
|
|
|
x86_cpu_apply_props(cpu, x86_tcg_default_props);
|
i386: do not call cpudef-only models functions for max, host, base
Some cpu properties have to be set only for cpu models in builtin_x86_defs,
registered with x86_register_cpu_model_type, and not for
cpu models "base", "max", and the subclass "host".
These properties are the ones set by function x86_cpu_apply_props,
(also including kvm_default_props, tcg_default_props),
and the "vendor" property for the KVM and HVF accelerators.
After recent refactoring of cpu, which also affected these properties,
they were instead set unconditionally for all x86 cpus.
This has been detected as a bug with Nested on AMD with cpu "host",
as svm was not turned on by default, due to the wrongful setting of
kvm_default_props via x86_cpu_apply_props, which set svm to "off".
Rectify the bug introduced in commit "i386: split cpu accelerators"
and document the functions that are builtin_x86_defs-only.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Tested-by: Alexander Bulekov <alxndr@bu.edu>
Fixes: f5cc5a5c ("i386: split cpu accelerators from cpu.c,"...)
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/477
Message-Id: <20210723112921.12637-1-cfontana@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-07-23 14:29:21 +03:00
|
|
|
}
|
2021-07-05 13:46:31 +03:00
|
|
|
|
2024-01-10 11:30:48 +03:00
|
|
|
x86_tcg_cpu_xsave_init();
|
2021-03-22 16:27:40 +03:00
|
|
|
}
|
|
|
|
|
2024-01-10 11:30:48 +03:00
|
|
|
static void x86_tcg_cpu_accel_class_init(ObjectClass *oc, void *data)
|
2021-03-22 16:27:40 +03:00
|
|
|
{
|
|
|
|
AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
|
|
|
|
|
2021-05-06 18:20:23 +03:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2023-10-03 15:30:20 +03:00
|
|
|
acc->cpu_target_realize = tcg_cpu_realizefn;
|
2021-05-06 18:20:23 +03:00
|
|
|
#endif /* CONFIG_USER_ONLY */
|
|
|
|
|
2024-01-10 11:30:48 +03:00
|
|
|
acc->cpu_class_init = x86_tcg_cpu_class_init;
|
|
|
|
acc->cpu_instance_init = x86_tcg_cpu_instance_init;
|
2021-03-22 16:27:40 +03:00
|
|
|
}
|
2024-01-10 11:30:48 +03:00
|
|
|
static const TypeInfo x86_tcg_cpu_accel_type_info = {
|
2021-03-22 16:27:40 +03:00
|
|
|
.name = ACCEL_CPU_NAME("tcg"),
|
|
|
|
|
|
|
|
.parent = TYPE_ACCEL_CPU,
|
2024-01-10 11:30:48 +03:00
|
|
|
.class_init = x86_tcg_cpu_accel_class_init,
|
2021-03-22 16:27:40 +03:00
|
|
|
.abstract = true,
|
|
|
|
};
|
2024-01-10 11:30:48 +03:00
|
|
|
static void x86_tcg_cpu_accel_register_types(void)
|
2021-03-22 16:27:40 +03:00
|
|
|
{
|
2024-01-10 11:30:48 +03:00
|
|
|
type_register_static(&x86_tcg_cpu_accel_type_info);
|
2021-03-22 16:27:40 +03:00
|
|
|
}
|
2024-01-10 11:30:48 +03:00
|
|
|
type_init(x86_tcg_cpu_accel_register_types);
|