2012-01-28 19:39:52 +04:00
|
|
|
/*
|
|
|
|
* QEMU CPU model
|
|
|
|
*
|
|
|
|
* Copyright (c) 2012 SUSE LINUX Products GmbH
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, see
|
|
|
|
* <http://www.gnu.org/licenses/gpl-2.0.html>
|
|
|
|
*/
|
|
|
|
#ifndef QEMU_CPU_H
|
|
|
|
#define QEMU_CPU_H
|
|
|
|
|
2012-12-05 20:49:13 +04:00
|
|
|
#include "hw/qdev-core.h"
|
2019-04-17 22:18:04 +03:00
|
|
|
#include "disas/dis-asm.h"
|
2013-05-27 08:49:53 +04:00
|
|
|
#include "exec/hwaddr.h"
|
2024-01-19 17:39:57 +03:00
|
|
|
#include "exec/vaddr.h"
|
2015-04-26 18:49:24 +03:00
|
|
|
#include "exec/memattrs.h"
|
2023-09-15 23:40:26 +03:00
|
|
|
#include "exec/tlb-common.h"
|
2018-02-11 12:36:01 +03:00
|
|
|
#include "qapi/qapi-types-run-state.h"
|
2016-07-11 13:53:41 +03:00
|
|
|
#include "qemu/bitmap.h"
|
2018-08-19 12:13:35 +03:00
|
|
|
#include "qemu/rcu_queue.h"
|
2013-06-25 01:50:24 +04:00
|
|
|
#include "qemu/queue.h"
|
2012-12-17 21:20:00 +04:00
|
|
|
#include "qemu/thread.h"
|
2020-09-03 23:43:22 +03:00
|
|
|
#include "qom/object.h"
|
2012-01-28 19:39:52 +04:00
|
|
|
|
2014-02-18 10:11:25 +04:00
|
|
|
typedef int (*WriteCoreDumpFunction)(const void *buf, size_t size,
|
|
|
|
void *opaque);
|
2013-04-19 18:45:06 +04:00
|
|
|
|
2012-01-28 19:39:52 +04:00
|
|
|
/**
|
|
|
|
* SECTION:cpu
|
|
|
|
* @section_id: QEMU-cpu
|
|
|
|
* @title: CPU Class
|
|
|
|
* @short_description: Base class for all CPUs
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define TYPE_CPU "cpu"
|
|
|
|
|
2014-03-28 19:25:07 +04:00
|
|
|
/* Since this macro is used a lot in hot code paths and in conjunction with
|
|
|
|
* FooCPU *foo_env_get_cpu(), we deviate from usual QOM practice by using
|
|
|
|
* an unchecked cast.
|
|
|
|
*/
|
|
|
|
#define CPU(obj) ((CPUState *)(obj))
|
|
|
|
|
2022-09-23 11:47:59 +03:00
|
|
|
/*
|
|
|
|
* The class checkers bring in CPU_GET_CLASS() which is potentially
|
|
|
|
* expensive given the eventual call to
|
|
|
|
* object_class_dynamic_cast_assert(). Because of this the CPUState
|
|
|
|
* has a cached value for the class in cs->cc which is set up in
|
|
|
|
* cpu_exec_realizefn() for use in hot code paths.
|
|
|
|
*/
|
2020-09-03 23:43:22 +03:00
|
|
|
typedef struct CPUClass CPUClass;
|
2020-09-01 00:07:33 +03:00
|
|
|
DECLARE_CLASS_CHECKERS(CPUClass, CPU,
|
|
|
|
TYPE_CPU)
|
2012-01-28 19:39:52 +04:00
|
|
|
|
2022-02-14 19:08:40 +03:00
|
|
|
/**
|
|
|
|
* OBJECT_DECLARE_CPU_TYPE:
|
|
|
|
* @CpuInstanceType: instance struct name
|
|
|
|
* @CpuClassType: class struct name
|
|
|
|
* @CPU_MODULE_OBJ_NAME: the CPU name in uppercase with underscore separators
|
|
|
|
*
|
|
|
|
* This macro is typically used in "cpu-qom.h" header file, and will:
|
|
|
|
*
|
|
|
|
* - create the typedefs for the CPU object and class structs
|
|
|
|
* - register the type for use with g_autoptr
|
|
|
|
* - provide three standard type cast functions
|
|
|
|
*
|
|
|
|
* The object struct and class struct need to be declared manually.
|
|
|
|
*/
|
|
|
|
#define OBJECT_DECLARE_CPU_TYPE(CpuInstanceType, CpuClassType, CPU_MODULE_OBJ_NAME) \
|
2022-02-14 19:15:16 +03:00
|
|
|
typedef struct ArchCPU CpuInstanceType; \
|
|
|
|
OBJECT_DECLARE_TYPE(ArchCPU, CpuClassType, CPU_MODULE_OBJ_NAME);
|
2022-02-14 19:08:40 +03:00
|
|
|
|
2016-06-14 15:26:17 +03:00
|
|
|
typedef enum MMUAccessType {
|
|
|
|
MMU_DATA_LOAD = 0,
|
|
|
|
MMU_DATA_STORE = 1,
|
|
|
|
MMU_INST_FETCH = 2
|
2023-02-23 08:17:52 +03:00
|
|
|
#define MMU_ACCESS_COUNT 3
|
2016-06-14 15:26:17 +03:00
|
|
|
} MMUAccessType;
|
|
|
|
|
2016-02-11 14:17:32 +03:00
|
|
|
typedef struct CPUWatchpoint CPUWatchpoint;
|
2012-01-28 19:39:52 +04:00
|
|
|
|
2021-02-04 19:39:26 +03:00
|
|
|
/* see accel-cpu.h */
|
|
|
|
struct AccelCPUClass;
|
|
|
|
|
2021-05-17 13:51:31 +03:00
|
|
|
/* see sysemu-cpu-ops.h */
|
|
|
|
struct SysemuCPUOps;
|
|
|
|
|
2012-01-28 19:39:52 +04:00
|
|
|
/**
|
|
|
|
* CPUClass:
|
2013-01-21 21:26:21 +04:00
|
|
|
* @class_by_name: Callback to map -cpu command line model name to an
|
2023-09-08 11:09:23 +03:00
|
|
|
* instantiatable CPU type.
|
2014-03-04 02:19:19 +04:00
|
|
|
* @parse_features: Callback to parse command line arguments.
|
2013-06-16 09:49:48 +04:00
|
|
|
* @reset_dump_flags: #CPUDumpFlags to use for reset logging.
|
2013-08-25 20:53:55 +04:00
|
|
|
* @has_work: Callback for checking if there is work to do.
|
2024-01-29 01:47:40 +03:00
|
|
|
* @mmu_index: Callback for choosing softmmu mmu index;
|
|
|
|
* may be used internally by memory_rw_debug without TCG.
|
2013-06-27 21:09:09 +04:00
|
|
|
* @memory_rw_debug: Callback for GDB memory access.
|
2013-05-27 03:33:50 +04:00
|
|
|
* @dump_state: Callback for dumping state.
|
2023-04-24 19:04:32 +03:00
|
|
|
* @query_cpu_fast:
|
|
|
|
* Fill in target specific information for the "query-cpus-fast"
|
|
|
|
* QAPI call.
|
2013-04-23 12:29:41 +04:00
|
|
|
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
|
2019-02-01 17:55:46 +03:00
|
|
|
* @set_pc: Callback for setting the Program Counter register. This
|
|
|
|
* should have the semantics used by the target architecture when
|
|
|
|
* setting the PC from a source such as an ELF file entry point;
|
|
|
|
* for example on Arm it will also set the Thumb mode bit based
|
|
|
|
* on the least significant bit of the new PC value.
|
|
|
|
* If the target behaviour here is anything other than "set
|
|
|
|
* the PC register to the value passed in" then the target must
|
|
|
|
* also implement the synchronize_from_tb hook.
|
2022-09-30 20:31:21 +03:00
|
|
|
* @get_pc: Callback for getting the Program Counter register.
|
|
|
|
* As above, with the semantics of the target architecture.
|
2013-06-29 06:18:45 +04:00
|
|
|
* @gdb_read_register: Callback for letting GDB read a register.
|
|
|
|
* @gdb_write_register: Callback for letting GDB write a register.
|
2021-07-20 18:47:23 +03:00
|
|
|
* @gdb_adjust_breakpoint: Callback for adjusting the address of a
|
|
|
|
* breakpoint. Used by AVR to handle a gdb mis-feature with
|
|
|
|
* its Harvard architecture split code and data.
|
2024-02-27 17:43:18 +03:00
|
|
|
* @gdb_num_core_regs: Number of core registers accessible to GDB or 0 to infer
|
|
|
|
* from @gdb_core_xml_file.
|
2013-07-07 17:08:22 +04:00
|
|
|
* @gdb_core_xml_file: File name for core registers GDB XML description.
|
2014-09-12 22:04:17 +04:00
|
|
|
* @gdb_stop_before_watchpoint: Indicates whether GDB expects the CPU to stop
|
|
|
|
* before the insn which triggers a watchpoint rather than after it.
|
2015-12-03 15:14:41 +03:00
|
|
|
* @gdb_arch_name: Optional callback that returns the architecture name known
|
|
|
|
* to GDB. The caller must free the returned string with g_free.
|
2015-06-24 06:57:33 +03:00
|
|
|
* @disas_set_info: Setup architecture specific components of disassembly info
|
2017-02-07 21:29:59 +03:00
|
|
|
* @adjust_watchpoint_address: Perform a target-specific adjustment to an
|
|
|
|
* address before attempting to match it against watchpoints.
|
2020-09-22 10:14:14 +03:00
|
|
|
* @deprecation_note: If this CPUClass is deprecated, this field provides
|
|
|
|
* related information.
|
2012-01-28 19:39:52 +04:00
|
|
|
*
|
|
|
|
* Represents a CPU family or model.
|
|
|
|
*/
|
2020-09-03 23:43:22 +03:00
|
|
|
struct CPUClass {
|
2012-01-28 19:39:52 +04:00
|
|
|
/*< private >*/
|
2012-12-05 20:49:13 +04:00
|
|
|
DeviceClass parent_class;
|
2012-01-28 19:39:52 +04:00
|
|
|
/*< public >*/
|
|
|
|
|
2013-01-21 21:26:21 +04:00
|
|
|
ObjectClass *(*class_by_name)(const char *cpu_model);
|
2016-06-09 20:11:01 +03:00
|
|
|
void (*parse_features)(const char *typename, char *str, Error **errp);
|
2013-01-21 21:26:21 +04:00
|
|
|
|
2013-08-25 20:53:55 +04:00
|
|
|
bool (*has_work)(CPUState *cpu);
|
2024-01-29 01:47:40 +03:00
|
|
|
int (*mmu_index)(CPUState *cpu, bool ifetch);
|
2013-06-27 21:09:09 +04:00
|
|
|
int (*memory_rw_debug)(CPUState *cpu, vaddr addr,
|
|
|
|
uint8_t *buf, int len, bool is_write);
|
2019-04-17 22:18:02 +03:00
|
|
|
void (*dump_state)(CPUState *cpu, FILE *, int flags);
|
2023-04-24 19:04:32 +03:00
|
|
|
void (*query_cpu_fast)(CPUState *cpu, CpuInfoFast *value);
|
2013-04-23 12:29:41 +04:00
|
|
|
int64_t (*get_arch_id)(CPUState *cpu);
|
2013-06-21 21:09:18 +04:00
|
|
|
void (*set_pc)(CPUState *cpu, vaddr value);
|
2022-09-30 20:31:21 +03:00
|
|
|
vaddr (*get_pc)(CPUState *cpu);
|
2020-03-16 20:21:41 +03:00
|
|
|
int (*gdb_read_register)(CPUState *cpu, GByteArray *buf, int reg);
|
2013-06-29 06:18:45 +04:00
|
|
|
int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
|
2021-07-20 18:47:23 +03:00
|
|
|
vaddr (*gdb_adjust_breakpoint)(CPUState *cpu, vaddr addr);
|
2013-01-20 23:23:22 +04:00
|
|
|
|
2013-07-07 17:08:22 +04:00
|
|
|
const char *gdb_core_xml_file;
|
2023-10-09 19:40:53 +03:00
|
|
|
const gchar * (*gdb_arch_name)(CPUState *cpu);
|
2015-06-24 06:57:33 +03:00
|
|
|
|
|
|
|
void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
|
2017-10-16 05:02:42 +03:00
|
|
|
|
2020-09-22 10:14:14 +03:00
|
|
|
const char *deprecation_note;
|
2021-02-04 19:39:26 +03:00
|
|
|
struct AccelCPUClass *accel_cpu;
|
2021-02-04 19:39:09 +03:00
|
|
|
|
2021-05-17 13:51:31 +03:00
|
|
|
/* when system emulation is not available, this pointer is NULL */
|
|
|
|
const struct SysemuCPUOps *sysemu_ops;
|
|
|
|
|
2021-02-04 19:39:23 +03:00
|
|
|
/* when TCG is not available, this pointer is NULL */
|
2024-01-28 05:46:44 +03:00
|
|
|
const TCGCPUOps *tcg_ops;
|
2021-03-22 16:27:59 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* if not NULL, this is called in order for the CPUClass to initialize
|
|
|
|
* class data that depends on the accelerator, see accel/accel-common.c.
|
|
|
|
*/
|
|
|
|
void (*init_accel_cpu)(struct AccelCPUClass *accel_cpu, CPUClass *cc);
|
2021-07-31 04:20:45 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Keep non-pointer data at the end to minimize holes.
|
|
|
|
*/
|
|
|
|
int reset_dump_flags;
|
|
|
|
int gdb_num_core_regs;
|
|
|
|
bool gdb_stop_before_watchpoint;
|
2020-09-03 23:43:22 +03:00
|
|
|
};
|
2012-01-28 19:39:52 +04:00
|
|
|
|
2023-09-15 23:40:26 +03:00
|
|
|
/*
|
|
|
|
* Fix the number of mmu modes to 16, which is also the maximum
|
|
|
|
* supported by the softmmu tlb api.
|
|
|
|
*/
|
|
|
|
#define NB_MMU_MODES 16
|
|
|
|
|
|
|
|
/* Use a fully associative victim tlb of 8 entries. */
|
|
|
|
#define CPU_VTLB_SIZE 8
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The full TLB entry, which is not accessed by generated TCG code,
|
|
|
|
* so the layout is not as critical as that of CPUTLBEntry. This is
|
|
|
|
* also why we don't want to combine the two structs.
|
|
|
|
*/
|
|
|
|
typedef struct CPUTLBEntryFull {
|
|
|
|
/*
|
|
|
|
* @xlat_section contains:
|
|
|
|
* - in the lower TARGET_PAGE_BITS, a physical section number
|
|
|
|
* - with the lower TARGET_PAGE_BITS masked off, an offset which
|
|
|
|
* must be added to the virtual address to obtain:
|
|
|
|
* + the ram_addr_t of the target RAM (if the physical section
|
|
|
|
* number is PHYS_SECTION_NOTDIRTY or PHYS_SECTION_ROM)
|
|
|
|
* + the offset within the target MemoryRegion (otherwise)
|
|
|
|
*/
|
|
|
|
hwaddr xlat_section;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @phys_addr contains the physical address in the address space
|
|
|
|
* given by cpu_asidx_from_attrs(cpu, @attrs).
|
|
|
|
*/
|
|
|
|
hwaddr phys_addr;
|
|
|
|
|
|
|
|
/* @attrs contains the memory transaction attributes for the page. */
|
|
|
|
MemTxAttrs attrs;
|
|
|
|
|
|
|
|
/* @prot contains the complete protections for the page. */
|
|
|
|
uint8_t prot;
|
|
|
|
|
|
|
|
/* @lg_page_size contains the log2 of the page size. */
|
|
|
|
uint8_t lg_page_size;
|
|
|
|
|
2024-03-01 23:41:07 +03:00
|
|
|
/* Additional tlb flags requested by tlb_fill. */
|
|
|
|
uint8_t tlb_fill_flags;
|
|
|
|
|
2023-09-15 23:40:26 +03:00
|
|
|
/*
|
|
|
|
* Additional tlb flags for use by the slow path. If non-zero,
|
|
|
|
* the corresponding CPUTLBEntry comparator must have TLB_FORCE_SLOW.
|
|
|
|
*/
|
|
|
|
uint8_t slow_flags[MMU_ACCESS_COUNT];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allow target-specific additions to this structure.
|
|
|
|
* This may be used to cache items from the guest cpu
|
|
|
|
* page tables for later use by the implementation.
|
|
|
|
*/
|
|
|
|
union {
|
|
|
|
/*
|
|
|
|
* Cache the attrs and shareability fields from the page table entry.
|
|
|
|
*
|
|
|
|
* For ARMMMUIdx_Stage2*, pte_attrs is the S2 descriptor bits [5:2].
|
|
|
|
* Otherwise, pte_attrs is the same as the MAIR_EL1 8-bit format.
|
|
|
|
* For shareability and guarded, as in the SH and GP fields respectively
|
|
|
|
* of the VMSAv8-64 PTEs.
|
|
|
|
*/
|
|
|
|
struct {
|
|
|
|
uint8_t pte_attrs;
|
|
|
|
uint8_t shareability;
|
|
|
|
bool guarded;
|
|
|
|
} arm;
|
|
|
|
} extra;
|
|
|
|
} CPUTLBEntryFull;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Data elements that are per MMU mode, minus the bits accessed by
|
|
|
|
* the TCG fast path.
|
|
|
|
*/
|
|
|
|
typedef struct CPUTLBDesc {
|
|
|
|
/*
|
|
|
|
* Describe a region covering all of the large pages allocated
|
|
|
|
* into the tlb. When any page within this region is flushed,
|
|
|
|
* we must flush the entire tlb. The region is matched if
|
|
|
|
* (addr & large_page_mask) == large_page_addr.
|
|
|
|
*/
|
|
|
|
vaddr large_page_addr;
|
|
|
|
vaddr large_page_mask;
|
|
|
|
/* host time (in ns) at the beginning of the time window */
|
|
|
|
int64_t window_begin_ns;
|
|
|
|
/* maximum number of entries observed in the window */
|
|
|
|
size_t window_max_entries;
|
|
|
|
size_t n_used_entries;
|
|
|
|
/* The next index to use in the tlb victim table. */
|
|
|
|
size_t vindex;
|
|
|
|
/* The tlb victim table, in two parts. */
|
|
|
|
CPUTLBEntry vtable[CPU_VTLB_SIZE];
|
|
|
|
CPUTLBEntryFull vfulltlb[CPU_VTLB_SIZE];
|
|
|
|
CPUTLBEntryFull *fulltlb;
|
|
|
|
} CPUTLBDesc;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Data elements that are shared between all MMU modes.
|
|
|
|
*/
|
|
|
|
typedef struct CPUTLBCommon {
|
|
|
|
/* Serialize updates to f.table and d.vtable, and others as noted. */
|
|
|
|
QemuSpin lock;
|
|
|
|
/*
|
|
|
|
* Within dirty, for each bit N, modifications have been made to
|
|
|
|
* mmu_idx N since the last time that mmu_idx was flushed.
|
|
|
|
* Protected by tlb_c.lock.
|
|
|
|
*/
|
|
|
|
uint16_t dirty;
|
|
|
|
/*
|
|
|
|
* Statistics. These are not lock protected, but are read and
|
|
|
|
* written atomically. This allows the monitor to print a snapshot
|
|
|
|
* of the stats without interfering with the cpu.
|
|
|
|
*/
|
|
|
|
size_t full_flush_count;
|
|
|
|
size_t part_flush_count;
|
|
|
|
size_t elide_flush_count;
|
|
|
|
} CPUTLBCommon;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The entire softmmu tlb, for all MMU modes.
|
|
|
|
* The meaning of each of the MMU modes is defined in the target code.
|
|
|
|
* Since this is placed within CPUNegativeOffsetState, the smallest
|
|
|
|
* negative offsets are at the end of the struct.
|
|
|
|
*/
|
|
|
|
typedef struct CPUTLB {
|
|
|
|
#ifdef CONFIG_TCG
|
|
|
|
CPUTLBCommon c;
|
|
|
|
CPUTLBDesc d[NB_MMU_MODES];
|
|
|
|
CPUTLBDescFast f[NB_MMU_MODES];
|
|
|
|
#endif
|
|
|
|
} CPUTLB;
|
|
|
|
|
2019-03-29 00:54:23 +03:00
|
|
|
/*
|
|
|
|
* Low 16 bits: number of cycles left, used only in icount mode.
|
|
|
|
* High 16 bits: Set to -1 to force TCG to stop executing linked TBs
|
|
|
|
* for this CPU and return to its top level loop (even in non-icount mode).
|
|
|
|
* This allows a single read-compare-cbranch-write sequence to test
|
|
|
|
* for both decrementer underflow and exceptions.
|
|
|
|
*/
|
|
|
|
typedef union IcountDecr {
|
|
|
|
uint32_t u32;
|
|
|
|
struct {
|
2022-03-23 18:57:17 +03:00
|
|
|
#if HOST_BIG_ENDIAN
|
2019-03-29 00:54:23 +03:00
|
|
|
uint16_t high;
|
|
|
|
uint16_t low;
|
2013-08-26 07:51:49 +04:00
|
|
|
#else
|
2019-03-29 00:54:23 +03:00
|
|
|
uint16_t low;
|
|
|
|
uint16_t high;
|
2013-08-26 07:51:49 +04:00
|
|
|
#endif
|
2019-03-29 00:54:23 +03:00
|
|
|
} u16;
|
|
|
|
} IcountDecr;
|
2013-08-26 07:51:49 +04:00
|
|
|
|
2023-09-15 23:40:26 +03:00
|
|
|
/*
|
2023-09-13 03:47:56 +03:00
|
|
|
* Elements of CPUState most efficiently accessed from CPUArchState,
|
|
|
|
* via small negative offsets.
|
2023-09-15 23:40:26 +03:00
|
|
|
*/
|
|
|
|
typedef struct CPUNegativeOffsetState {
|
|
|
|
CPUTLB tlb;
|
|
|
|
IcountDecr icount_decr;
|
2023-09-16 01:41:39 +03:00
|
|
|
bool can_do_io;
|
2023-09-15 23:40:26 +03:00
|
|
|
} CPUNegativeOffsetState;
|
|
|
|
|
2013-08-26 23:22:53 +04:00
|
|
|
typedef struct CPUBreakpoint {
|
|
|
|
vaddr pc;
|
|
|
|
int flags; /* BP_* */
|
|
|
|
QTAILQ_ENTRY(CPUBreakpoint) entry;
|
|
|
|
} CPUBreakpoint;
|
|
|
|
|
2016-02-11 14:17:32 +03:00
|
|
|
struct CPUWatchpoint {
|
2013-08-26 20:23:18 +04:00
|
|
|
vaddr vaddr;
|
2014-09-12 17:06:48 +04:00
|
|
|
vaddr len;
|
2014-09-12 17:06:48 +04:00
|
|
|
vaddr hitaddr;
|
2015-04-26 18:49:24 +03:00
|
|
|
MemTxAttrs hitattrs;
|
2013-08-26 20:23:18 +04:00
|
|
|
int flags; /* BP_* */
|
|
|
|
QTAILQ_ENTRY(CPUWatchpoint) entry;
|
2016-02-11 14:17:32 +03:00
|
|
|
};
|
2013-08-26 20:23:18 +04:00
|
|
|
|
2012-12-01 08:35:08 +04:00
|
|
|
struct KVMState;
|
2012-12-01 09:18:14 +04:00
|
|
|
struct kvm_run;
|
2012-12-01 08:35:08 +04:00
|
|
|
|
2016-03-15 18:47:38 +03:00
|
|
|
/* work queue */
|
2016-10-31 12:36:08 +03:00
|
|
|
|
|
|
|
/* The union type allows passing of 64 bit target pointers on 32 bit
|
|
|
|
* hosts in a single parameter
|
|
|
|
*/
|
|
|
|
typedef union {
|
|
|
|
int host_int;
|
|
|
|
unsigned long host_ulong;
|
|
|
|
void *host_ptr;
|
|
|
|
vaddr target_ptr;
|
|
|
|
} run_on_cpu_data;
|
|
|
|
|
|
|
|
#define RUN_ON_CPU_HOST_PTR(p) ((run_on_cpu_data){.host_ptr = (p)})
|
|
|
|
#define RUN_ON_CPU_HOST_INT(i) ((run_on_cpu_data){.host_int = (i)})
|
|
|
|
#define RUN_ON_CPU_HOST_ULONG(ul) ((run_on_cpu_data){.host_ulong = (ul)})
|
|
|
|
#define RUN_ON_CPU_TARGET_PTR(v) ((run_on_cpu_data){.target_ptr = (v)})
|
|
|
|
#define RUN_ON_CPU_NULL RUN_ON_CPU_HOST_PTR(NULL)
|
|
|
|
|
|
|
|
typedef void (*run_on_cpu_func)(CPUState *cpu, run_on_cpu_data data);
|
|
|
|
|
2016-08-29 10:51:00 +03:00
|
|
|
struct qemu_work_item;
|
2016-03-15 18:47:38 +03:00
|
|
|
|
2017-05-10 14:29:46 +03:00
|
|
|
#define CPU_UNSET_NUMA_NODE_ID -1
|
|
|
|
|
2012-01-28 19:39:52 +04:00
|
|
|
/**
|
|
|
|
* CPUState:
|
2012-12-17 09:18:02 +04:00
|
|
|
* @cpu_index: CPU index (informative).
|
2019-01-29 14:46:05 +03:00
|
|
|
* @cluster_index: Identifies which cluster this CPU is in.
|
|
|
|
* For boards which don't define clusters or for "loose" CPUs not assigned
|
|
|
|
* to a cluster this will be UNASSIGNED_CLUSTER_INDEX; otherwise it will
|
|
|
|
* be the same as the cluster-id property of the CPU object's TYPE_CPU_CLUSTER
|
|
|
|
* QOM parent.
|
2023-02-16 12:09:48 +03:00
|
|
|
* Under TCG this value is propagated to @tcg_cflags.
|
|
|
|
* See TranslationBlock::TCG CF_CLUSTER_MASK.
|
2021-03-02 06:21:08 +03:00
|
|
|
* @tcg_cflags: Pre-computed cflags for this cpu.
|
2012-12-17 06:27:07 +04:00
|
|
|
* @nr_cores: Number of cores within this CPU package.
|
2023-10-24 12:03:07 +03:00
|
|
|
* @nr_threads: Number of threads within this CPU core.
|
2016-08-31 22:33:58 +03:00
|
|
|
* @running: #true if CPU is currently running (lockless).
|
|
|
|
* @has_waiter: #true if a CPU is currently waiting for the cpu_exec_end;
|
2016-08-31 17:56:04 +03:00
|
|
|
* valid under cpu_list_lock.
|
2012-05-03 00:49:36 +04:00
|
|
|
* @created: Indicates whether the CPU thread has been successfully created.
|
2013-01-17 21:51:17 +04:00
|
|
|
* @interrupt_request: Indicates a pending interrupt request.
|
|
|
|
* @halted: Nonzero if the CPU is in suspended state.
|
2012-05-03 01:10:09 +04:00
|
|
|
* @stop: Indicates a pending stop request.
|
2012-05-03 01:26:21 +04:00
|
|
|
* @stopped: Indicates the CPU has been artificially stopped.
|
2016-05-12 06:48:13 +03:00
|
|
|
* @unplug: Indicates a pending CPU unplug request.
|
2015-07-03 15:01:44 +03:00
|
|
|
* @crash_occurred: Indicates the OS reported a crash (panic) for this CPU
|
2013-06-21 22:20:45 +04:00
|
|
|
* @singlestep_enabled: Flags for single-stepping.
|
2013-08-26 07:39:29 +04:00
|
|
|
* @icount_extra: Instructions until next timer event.
|
2023-09-16 01:41:39 +03:00
|
|
|
* @neg.can_do_io: True if memory-mapped IO is allowed.
|
2015-10-01 17:29:50 +03:00
|
|
|
* @cpu_ases: Pointer to array of CPUAddressSpaces (which define the
|
|
|
|
* AddressSpaces this CPU has)
|
2016-01-21 17:15:04 +03:00
|
|
|
* @num_ases: number of CPUAddressSpaces in @cpu_ases
|
2015-10-01 17:29:50 +03:00
|
|
|
* @as: Pointer to the first AddressSpace, for the convenience of targets which
|
|
|
|
* only have a single AddressSpace
|
2013-06-28 23:11:37 +04:00
|
|
|
* @gdb_regs: Additional GDB registers.
|
2013-06-29 01:18:47 +04:00
|
|
|
* @gdb_num_regs: Number of total registers accessible to GDB.
|
2013-08-12 20:09:47 +04:00
|
|
|
* @gdb_num_g_regs: Number of registers in GDB 'g' packets.
|
2023-11-29 21:31:16 +03:00
|
|
|
* @node: QTAILQ of CPUs sharing TB cache.
|
2013-08-26 20:14:44 +04:00
|
|
|
* @opaque: User data.
|
2013-08-26 05:41:01 +04:00
|
|
|
* @mem_io_pc: Host Program Counter at which the memory was accessed.
|
2023-03-29 20:01:49 +03:00
|
|
|
* @accel: Pointer to accelerator specific state.
|
2012-10-31 08:29:00 +04:00
|
|
|
* @kvm_fd: vCPU file descriptor for KVM.
|
2020-06-12 22:02:24 +03:00
|
|
|
* @work_mutex: Lock to prevent multiple access to @work_list.
|
|
|
|
* @work_list: List of pending asynchronous work.
|
2024-02-27 17:43:28 +03:00
|
|
|
* @plugin_mem_cbs: active plugin memory callbacks
|
|
|
|
* @plugin_state: per-CPU plugin state
|
2017-09-07 15:54:54 +03:00
|
|
|
* @ignore_memory_transaction_failures: Cached copy of the MachineState
|
|
|
|
* flag of the same name: allows the board to suppress calling of the
|
|
|
|
* CPU do_transaction_failed hook function.
|
2021-05-17 11:23:50 +03:00
|
|
|
* @kvm_dirty_gfns: Points to the KVM dirty ring for this CPU when KVM dirty
|
|
|
|
* ring is enabled.
|
|
|
|
* @kvm_fetch_index: Keeps the index that we last fetched from the per-vCPU
|
|
|
|
* dirty ring structure.
|
2012-01-28 19:39:52 +04:00
|
|
|
*
|
|
|
|
* State of one CPU core or thread.
|
2023-09-13 03:47:56 +03:00
|
|
|
*
|
|
|
|
* Align, in order to match possible alignment required by CPUArchState,
|
|
|
|
* and eliminate a hole between CPUState and CPUArchState within ArchCPU.
|
2012-01-28 19:39:52 +04:00
|
|
|
*/
|
|
|
|
struct CPUState {
|
|
|
|
/*< private >*/
|
2012-12-05 20:49:13 +04:00
|
|
|
DeviceState parent_obj;
|
2022-09-23 11:47:59 +03:00
|
|
|
/* cache to avoid expensive CPU_GET_CLASS */
|
|
|
|
CPUClass *cc;
|
2012-01-28 19:39:52 +04:00
|
|
|
/*< public >*/
|
|
|
|
|
2012-12-17 06:27:07 +04:00
|
|
|
int nr_cores;
|
|
|
|
int nr_threads;
|
|
|
|
|
2012-05-02 19:00:37 +04:00
|
|
|
struct QemuThread *thread;
|
2012-05-02 17:24:40 +04:00
|
|
|
#ifdef _WIN32
|
2022-10-28 07:57:26 +03:00
|
|
|
QemuSemaphore sem;
|
2012-05-02 17:24:40 +04:00
|
|
|
#endif
|
2012-05-03 08:59:07 +04:00
|
|
|
int thread_id;
|
2016-08-31 22:33:58 +03:00
|
|
|
bool running, has_waiter;
|
2012-05-03 03:22:49 +04:00
|
|
|
struct QemuCond *halt_cond;
|
2012-05-02 19:49:49 +04:00
|
|
|
bool thread_kicked;
|
2012-05-03 00:49:36 +04:00
|
|
|
bool created;
|
2012-05-03 01:10:09 +04:00
|
|
|
bool stop;
|
2012-05-03 01:26:21 +04:00
|
|
|
bool stopped;
|
2020-08-26 08:55:28 +03:00
|
|
|
|
|
|
|
/* Should CPU start in powered-off state? */
|
|
|
|
bool start_powered_off;
|
|
|
|
|
2016-05-12 06:48:13 +03:00
|
|
|
bool unplug;
|
2015-07-03 15:01:44 +03:00
|
|
|
bool crash_occurred;
|
2015-08-26 01:19:19 +03:00
|
|
|
bool exit_request;
|
2023-02-14 17:08:27 +03:00
|
|
|
int exclusive_context_count;
|
2017-10-13 20:50:02 +03:00
|
|
|
uint32_t cflags_next_tb;
|
tcg: drop global lock during TCG code execution
This finally allows TCG to benefit from the iothread introduction: Drop
the global mutex while running pure TCG CPU code. Reacquire the lock
when entering MMIO or PIO emulation, or when leaving the TCG loop.
We have to revert a few optimization for the current TCG threading
model, namely kicking the TCG thread in qemu_mutex_lock_iothread and not
kicking it in qemu_cpu_kick. We also need to disable RAM block
reordering until we have a more efficient locking mechanism at hand.
Still, a Linux x86 UP guest and my Musicpal ARM model boot fine here.
These numbers demonstrate where we gain something:
20338 jan 20 0 331m 75m 6904 R 99 0.9 0:50.95 qemu-system-arm
20337 jan 20 0 331m 75m 6904 S 20 0.9 0:26.50 qemu-system-arm
The guest CPU was fully loaded, but the iothread could still run mostly
independent on a second core. Without the patch we don't get beyond
32206 jan 20 0 330m 73m 7036 R 82 0.9 1:06.00 qemu-system-arm
32204 jan 20 0 330m 73m 7036 S 21 0.9 0:17.03 qemu-system-arm
We don't benefit significantly, though, when the guest is not fully
loading a host CPU.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Message-Id: <1439220437-23957-10-git-send-email-fred.konrad@greensocs.com>
[FK: Rebase, fix qemu_devices_reset deadlock, rm address_space_* mutex]
Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
[EGC: fixed iothread lock for cpu-exec IRQ handling]
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: -smp single-threaded fix, clean commit msg, BQL fixes]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Pranith Kumar <bobby.prani@gmail.com>
[PM: target-arm changes]
Acked-by: Peter Maydell <peter.maydell@linaro.org>
2017-02-23 21:29:11 +03:00
|
|
|
/* updates protected by BQL */
|
2013-01-17 21:51:17 +04:00
|
|
|
uint32_t interrupt_request;
|
2013-06-21 22:20:45 +04:00
|
|
|
int singlestep_enabled;
|
2017-03-31 18:09:42 +03:00
|
|
|
int64_t icount_budget;
|
2013-08-26 07:39:29 +04:00
|
|
|
int64_t icount_extra;
|
2019-03-14 23:06:29 +03:00
|
|
|
uint64_t random_seed;
|
2013-08-26 08:22:03 +04:00
|
|
|
sigjmp_buf jmp_env;
|
2012-05-02 17:24:40 +04:00
|
|
|
|
2015-07-10 13:32:32 +03:00
|
|
|
QemuMutex work_mutex;
|
2020-06-12 22:02:24 +03:00
|
|
|
QSIMPLEQ_HEAD(, qemu_work_item) work_list;
|
2015-07-10 13:32:32 +03:00
|
|
|
|
2015-10-01 17:29:50 +03:00
|
|
|
CPUAddressSpace *cpu_ases;
|
2016-01-21 17:15:04 +03:00
|
|
|
int num_ases;
|
2013-12-17 07:06:51 +04:00
|
|
|
AddressSpace *as;
|
2016-01-21 17:15:06 +03:00
|
|
|
MemoryRegion *memory;
|
2013-12-17 07:06:51 +04:00
|
|
|
|
2022-08-15 23:13:05 +03:00
|
|
|
CPUJumpCache *tb_jmp_cache;
|
2016-10-27 18:10:03 +03:00
|
|
|
|
2023-10-09 19:40:58 +03:00
|
|
|
GArray *gdb_regs;
|
2013-06-29 01:18:47 +04:00
|
|
|
int gdb_num_regs;
|
2013-08-12 20:09:47 +04:00
|
|
|
int gdb_num_g_regs;
|
2013-06-25 01:50:24 +04:00
|
|
|
QTAILQ_ENTRY(CPUState) node;
|
2013-01-16 22:29:31 +04:00
|
|
|
|
2013-08-26 23:22:53 +04:00
|
|
|
/* ice debug support */
|
2018-12-06 13:58:10 +03:00
|
|
|
QTAILQ_HEAD(, CPUBreakpoint) breakpoints;
|
2013-08-26 23:22:53 +04:00
|
|
|
|
2018-12-06 13:58:10 +03:00
|
|
|
QTAILQ_HEAD(, CPUWatchpoint) watchpoints;
|
2013-08-26 20:23:18 +04:00
|
|
|
CPUWatchpoint *watchpoint_hit;
|
|
|
|
|
2013-08-26 20:14:44 +04:00
|
|
|
void *opaque;
|
|
|
|
|
2013-08-26 05:41:01 +04:00
|
|
|
/* In order to avoid passing too many arguments to the MMIO helpers,
|
|
|
|
* we store some rarely used information in the CPU context.
|
|
|
|
*/
|
|
|
|
uintptr_t mem_io_pc;
|
|
|
|
|
2021-05-17 11:23:50 +03:00
|
|
|
/* Only used in KVM */
|
2012-10-31 08:29:00 +04:00
|
|
|
int kvm_fd;
|
2012-12-01 08:35:08 +04:00
|
|
|
struct KVMState *kvm_state;
|
2012-12-01 09:18:14 +04:00
|
|
|
struct kvm_run *kvm_run;
|
2021-05-17 11:23:50 +03:00
|
|
|
struct kvm_dirty_gfn *kvm_dirty_gfns;
|
|
|
|
uint32_t kvm_fetch_index;
|
2021-06-29 19:01:18 +03:00
|
|
|
uint64_t dirty_pages;
|
2023-06-19 00:24:40 +03:00
|
|
|
int kvm_vcpu_stats_fd;
|
2012-10-31 08:29:00 +04:00
|
|
|
|
2022-11-11 18:47:56 +03:00
|
|
|
/* Use by accel-block: CPU is executing an ioctl() */
|
|
|
|
QemuLockCnt in_ioctl_lock;
|
|
|
|
|
2020-07-13 23:04:10 +03:00
|
|
|
#ifdef CONFIG_PLUGIN
|
2024-02-27 17:43:28 +03:00
|
|
|
/*
|
|
|
|
* The callback pointer stays in the main CPUState as it is
|
|
|
|
* accessed via TCG (see gen_empty_mem_helper).
|
|
|
|
*/
|
2017-08-31 01:39:53 +03:00
|
|
|
GArray *plugin_mem_cbs;
|
2024-02-27 17:43:28 +03:00
|
|
|
CPUPluginState *plugin_state;
|
2023-06-20 20:57:12 +03:00
|
|
|
#endif
|
2017-08-31 01:39:53 +03:00
|
|
|
|
2012-05-03 00:28:58 +04:00
|
|
|
/* TODO Move common fields from CPUArchState here. */
|
2017-09-13 16:23:57 +03:00
|
|
|
int cpu_index;
|
2019-01-29 14:46:05 +03:00
|
|
|
int cluster_index;
|
2021-03-02 06:21:08 +03:00
|
|
|
uint32_t tcg_cflags;
|
2017-09-13 16:23:57 +03:00
|
|
|
uint32_t halted;
|
|
|
|
int32_t exception_index;
|
2014-03-15 02:30:10 +04:00
|
|
|
|
2023-03-29 20:01:49 +03:00
|
|
|
AccelCPUState *accel;
|
2023-06-24 01:52:29 +03:00
|
|
|
/* shared by kvm and hvf */
|
2017-06-18 22:11:01 +03:00
|
|
|
bool vcpu_dirty;
|
|
|
|
|
2015-09-08 20:12:33 +03:00
|
|
|
/* Used to keep track of an outstanding cpu throttle thread for migration
|
|
|
|
* autoconverge
|
|
|
|
*/
|
|
|
|
bool throttle_thread_scheduled;
|
|
|
|
|
2022-06-25 20:38:35 +03:00
|
|
|
/*
|
|
|
|
* Sleep throttle_us_per_full microseconds once dirty ring is full
|
|
|
|
* if dirty page rate limit is enabled.
|
|
|
|
*/
|
|
|
|
int64_t throttle_us_per_full;
|
|
|
|
|
2017-09-07 15:54:54 +03:00
|
|
|
bool ignore_memory_transaction_failures;
|
|
|
|
|
2021-12-27 18:01:24 +03:00
|
|
|
/* Used for user-only emulation of prctl(PR_SET_UNALIGN). */
|
|
|
|
bool prctl_unalign_sigbus;
|
|
|
|
|
2018-06-15 16:57:16 +03:00
|
|
|
/* track IOMMUs whose translations we've cached in the TCG TLB */
|
|
|
|
GArray *iommu_notifiers;
|
2023-09-13 03:47:56 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* MUST BE LAST in order to minimize the displacement to CPUArchState.
|
|
|
|
*/
|
|
|
|
char neg_align[-sizeof(CPUNegativeOffsetState) % 16] QEMU_ALIGNED(16);
|
|
|
|
CPUNegativeOffsetState neg;
|
2012-01-28 19:39:52 +04:00
|
|
|
};
|
|
|
|
|
2023-09-13 03:47:56 +03:00
|
|
|
/* Validate placement of CPUNegativeOffsetState. */
|
|
|
|
QEMU_BUILD_BUG_ON(offsetof(CPUState, neg) !=
|
|
|
|
sizeof(CPUState) - sizeof(CPUNegativeOffsetState));
|
|
|
|
|
2023-09-14 03:22:49 +03:00
|
|
|
static inline CPUArchState *cpu_env(CPUState *cpu)
|
|
|
|
{
|
|
|
|
/* We validate that CPUArchState follows CPUState in cpu-all.h. */
|
|
|
|
return (CPUArchState *)(cpu + 1);
|
|
|
|
}
|
|
|
|
|
2018-12-06 13:56:15 +03:00
|
|
|
typedef QTAILQ_HEAD(CPUTailQ, CPUState) CPUTailQ;
|
2023-10-09 10:02:04 +03:00
|
|
|
extern CPUTailQ cpus_queue;
|
2018-12-06 13:56:15 +03:00
|
|
|
|
2023-10-09 10:02:04 +03:00
|
|
|
#define first_cpu QTAILQ_FIRST_RCU(&cpus_queue)
|
2018-08-19 12:13:35 +03:00
|
|
|
#define CPU_NEXT(cpu) QTAILQ_NEXT_RCU(cpu, node)
|
2023-10-09 10:02:04 +03:00
|
|
|
#define CPU_FOREACH(cpu) QTAILQ_FOREACH_RCU(cpu, &cpus_queue, node)
|
2013-06-25 01:50:24 +04:00
|
|
|
#define CPU_FOREACH_SAFE(cpu, next_cpu) \
|
2023-10-09 10:02:04 +03:00
|
|
|
QTAILQ_FOREACH_SAFE_RCU(cpu, &cpus_queue, node, next_cpu)
|
2013-05-30 00:29:20 +04:00
|
|
|
|
2015-08-26 01:17:58 +03:00
|
|
|
extern __thread CPUState *current_cpu;
|
2013-05-27 07:17:50 +04:00
|
|
|
|
2017-02-23 21:29:08 +03:00
|
|
|
/**
|
|
|
|
* qemu_tcg_mttcg_enabled:
|
|
|
|
* Check whether we are running MultiThread TCG or not.
|
|
|
|
*
|
|
|
|
* Returns: %true if we are in MTTCG mode %false otherwise.
|
|
|
|
*/
|
|
|
|
extern bool mttcg_enabled;
|
|
|
|
#define qemu_tcg_mttcg_enabled() (mttcg_enabled)
|
|
|
|
|
2013-05-28 15:28:38 +04:00
|
|
|
/**
|
|
|
|
* cpu_paging_enabled:
|
|
|
|
* @cpu: The CPU whose state is to be inspected.
|
|
|
|
*
|
|
|
|
* Returns: %true if paging is enabled, %false otherwise.
|
|
|
|
*/
|
|
|
|
bool cpu_paging_enabled(const CPUState *cpu);
|
|
|
|
|
2013-05-28 15:52:01 +04:00
|
|
|
/**
|
|
|
|
* cpu_get_memory_mapping:
|
|
|
|
* @cpu: The CPU whose memory mappings are to be obtained.
|
|
|
|
* @list: Where to write the memory mappings to.
|
|
|
|
* @errp: Pointer for reporting an #Error.
|
2023-10-09 10:53:10 +03:00
|
|
|
*
|
|
|
|
* Returns: %true on success, %false otherwise.
|
2013-05-28 15:52:01 +04:00
|
|
|
*/
|
2023-10-09 10:53:10 +03:00
|
|
|
bool cpu_get_memory_mapping(CPUState *cpu, MemoryMappingList *list,
|
2013-05-28 15:52:01 +04:00
|
|
|
Error **errp);
|
|
|
|
|
2020-05-22 20:25:09 +03:00
|
|
|
#if !defined(CONFIG_USER_ONLY)
|
|
|
|
|
2013-04-19 18:45:06 +04:00
|
|
|
/**
|
|
|
|
* cpu_write_elf64_note:
|
|
|
|
* @f: pointer to a function that writes memory to a file
|
|
|
|
* @cpu: The CPU whose memory is to be dumped
|
|
|
|
* @cpuid: ID number of the CPU
|
|
|
|
* @opaque: pointer to the CPUState struct
|
|
|
|
*/
|
|
|
|
int cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
|
|
|
|
int cpuid, void *opaque);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cpu_write_elf64_qemunote:
|
|
|
|
* @f: pointer to a function that writes memory to a file
|
|
|
|
* @cpu: The CPU whose memory is to be dumped
|
|
|
|
* @cpuid: ID number of the CPU
|
|
|
|
* @opaque: pointer to the CPUState struct
|
|
|
|
*/
|
|
|
|
int cpu_write_elf64_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
|
|
|
|
void *opaque);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cpu_write_elf32_note:
|
|
|
|
* @f: pointer to a function that writes memory to a file
|
|
|
|
* @cpu: The CPU whose memory is to be dumped
|
|
|
|
* @cpuid: ID number of the CPU
|
|
|
|
* @opaque: pointer to the CPUState struct
|
|
|
|
*/
|
|
|
|
int cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cpu,
|
|
|
|
int cpuid, void *opaque);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cpu_write_elf32_qemunote:
|
|
|
|
* @f: pointer to a function that writes memory to a file
|
|
|
|
* @cpu: The CPU whose memory is to be dumped
|
|
|
|
* @cpuid: ID number of the CPU
|
|
|
|
* @opaque: pointer to the CPUState struct
|
|
|
|
*/
|
|
|
|
int cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cpu,
|
|
|
|
void *opaque);
|
2012-01-28 19:39:52 +04:00
|
|
|
|
2017-02-14 09:25:23 +03:00
|
|
|
/**
|
|
|
|
* cpu_get_crash_info:
|
|
|
|
* @cpu: The CPU to get crash information for
|
|
|
|
*
|
|
|
|
* Gets the previously saved crash information.
|
|
|
|
* Caller is responsible for freeing the data.
|
|
|
|
*/
|
|
|
|
GuestPanicInformation *cpu_get_crash_info(CPUState *cpu);
|
|
|
|
|
2020-05-22 20:25:09 +03:00
|
|
|
#endif /* !CONFIG_USER_ONLY */
|
|
|
|
|
2013-05-27 03:33:50 +04:00
|
|
|
/**
|
|
|
|
* CPUDumpFlags:
|
|
|
|
* @CPU_DUMP_CODE:
|
|
|
|
* @CPU_DUMP_FPU: dump FPU register state, not just integer
|
|
|
|
* @CPU_DUMP_CCOP: dump info about TCG QEMU's condition code optimization state
|
2023-04-10 15:44:50 +03:00
|
|
|
* @CPU_DUMP_VPU: dump VPU registers
|
2013-05-27 03:33:50 +04:00
|
|
|
*/
|
|
|
|
enum CPUDumpFlags {
|
|
|
|
CPU_DUMP_CODE = 0x00010000,
|
|
|
|
CPU_DUMP_FPU = 0x00020000,
|
|
|
|
CPU_DUMP_CCOP = 0x00040000,
|
2023-04-10 15:44:50 +03:00
|
|
|
CPU_DUMP_VPU = 0x00080000,
|
2013-05-27 03:33:50 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cpu_dump_state:
|
|
|
|
* @cpu: The CPU whose state is to be dumped.
|
2019-04-17 22:18:02 +03:00
|
|
|
* @f: If non-null, dump to this stream, else to current print sink.
|
2013-05-27 03:33:50 +04:00
|
|
|
*
|
|
|
|
* Dumps CPU state.
|
|
|
|
*/
|
2019-04-17 22:18:02 +03:00
|
|
|
void cpu_dump_state(CPUState *cpu, FILE *f, int flags);
|
2013-05-27 03:33:50 +04:00
|
|
|
|
2013-06-29 20:55:54 +04:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2016-01-21 17:15:05 +03:00
|
|
|
/**
|
|
|
|
* cpu_get_phys_page_attrs_debug:
|
|
|
|
* @cpu: The CPU to obtain the physical page address for.
|
|
|
|
* @addr: The virtual address.
|
|
|
|
* @attrs: Updated on return with the memory transaction attributes to use
|
|
|
|
* for this access.
|
|
|
|
*
|
|
|
|
* Obtains the physical page corresponding to a virtual one, together
|
|
|
|
* with the corresponding memory transaction attributes to use for the access.
|
|
|
|
* Use it only for debugging because no protection checks are done.
|
|
|
|
*
|
|
|
|
* Returns: Corresponding physical page address or -1 if no page found.
|
|
|
|
*/
|
2021-05-17 13:51:23 +03:00
|
|
|
hwaddr cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
|
|
|
|
MemTxAttrs *attrs);
|
2016-01-21 17:15:05 +03:00
|
|
|
|
2013-06-29 20:55:54 +04:00
|
|
|
/**
|
|
|
|
* cpu_get_phys_page_debug:
|
|
|
|
* @cpu: The CPU to obtain the physical page address for.
|
|
|
|
* @addr: The virtual address.
|
|
|
|
*
|
|
|
|
* Obtains the physical page corresponding to a virtual one.
|
|
|
|
* Use it only for debugging because no protection checks are done.
|
|
|
|
*
|
|
|
|
* Returns: Corresponding physical page address or -1 if no page found.
|
|
|
|
*/
|
2021-05-17 13:51:23 +03:00
|
|
|
hwaddr cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
|
2016-01-21 17:15:05 +03:00
|
|
|
|
|
|
|
/** cpu_asidx_from_attrs:
|
|
|
|
* @cpu: CPU
|
|
|
|
* @attrs: memory transaction attributes
|
|
|
|
*
|
|
|
|
* Returns the address space index specifying the CPU AddressSpace
|
|
|
|
* to use for a memory access with the given transaction attributes.
|
|
|
|
*/
|
2021-05-17 13:51:23 +03:00
|
|
|
int cpu_asidx_from_attrs(CPUState *cpu, MemTxAttrs attrs);
|
2016-01-21 17:15:05 +03:00
|
|
|
|
2021-05-17 13:51:24 +03:00
|
|
|
/**
|
|
|
|
* cpu_virtio_is_big_endian:
|
|
|
|
* @cpu: CPU
|
|
|
|
|
|
|
|
* Returns %true if a CPU which supports runtime configurable endianness
|
|
|
|
* is currently big-endian.
|
|
|
|
*/
|
|
|
|
bool cpu_virtio_is_big_endian(CPUState *cpu);
|
2020-05-22 20:25:09 +03:00
|
|
|
|
|
|
|
#endif /* CONFIG_USER_ONLY */
|
2013-06-29 20:55:54 +04:00
|
|
|
|
2016-08-28 04:45:14 +03:00
|
|
|
/**
|
|
|
|
* cpu_list_add:
|
|
|
|
* @cpu: The CPU to be added to the list of CPUs.
|
|
|
|
*/
|
|
|
|
void cpu_list_add(CPUState *cpu);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cpu_list_remove:
|
|
|
|
* @cpu: The CPU to be removed from the list of CPUs.
|
|
|
|
*/
|
|
|
|
void cpu_list_remove(CPUState *cpu);
|
|
|
|
|
2012-01-28 19:39:52 +04:00
|
|
|
/**
|
|
|
|
* cpu_reset:
|
|
|
|
* @cpu: The CPU whose state is to be reset.
|
|
|
|
*/
|
|
|
|
void cpu_reset(CPUState *cpu);
|
|
|
|
|
2013-01-21 21:26:21 +04:00
|
|
|
/**
|
|
|
|
* cpu_class_by_name:
|
|
|
|
* @typename: The CPU base type.
|
|
|
|
* @cpu_model: The model string without any parameters.
|
|
|
|
*
|
2023-09-08 11:09:23 +03:00
|
|
|
* Looks up a concrete CPU #ObjectClass matching name @cpu_model.
|
2013-01-21 21:26:21 +04:00
|
|
|
*
|
2023-09-08 11:09:23 +03:00
|
|
|
* Returns: A concrete #CPUClass or %NULL if no matching class is found
|
|
|
|
* or if the matching class is abstract.
|
2013-01-21 21:26:21 +04:00
|
|
|
*/
|
|
|
|
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model);
|
|
|
|
|
2023-11-15 02:56:02 +03:00
|
|
|
/**
|
|
|
|
* cpu_model_from_type:
|
|
|
|
* @typename: The CPU type name
|
|
|
|
*
|
|
|
|
* Extract the CPU model name from the CPU type name. The
|
|
|
|
* CPU type name is either the combination of the CPU model
|
|
|
|
* name and suffix, or same to the CPU model name.
|
|
|
|
*
|
|
|
|
* Returns: CPU model name or NULL if the CPU class doesn't exist
|
|
|
|
* The user should g_free() the string once no longer needed.
|
|
|
|
*/
|
|
|
|
char *cpu_model_from_type(const char *typename);
|
|
|
|
|
2017-09-13 19:04:53 +03:00
|
|
|
/**
|
|
|
|
* cpu_create:
|
|
|
|
* @typename: The CPU type.
|
|
|
|
*
|
|
|
|
* Instantiates a CPU and realizes the CPU.
|
|
|
|
*
|
|
|
|
* Returns: A #CPUState or %NULL if an error occurred.
|
|
|
|
*/
|
|
|
|
CPUState *cpu_create(const char *typename);
|
|
|
|
|
|
|
|
/**
|
2019-04-17 05:59:40 +03:00
|
|
|
* parse_cpu_option:
|
|
|
|
* @cpu_option: The -cpu option including optional parameters.
|
2017-09-13 19:04:53 +03:00
|
|
|
*
|
|
|
|
* processes optional parameters and registers them as global properties
|
|
|
|
*
|
2017-09-13 19:04:54 +03:00
|
|
|
* Returns: type of CPU to create or prints error and terminates process
|
|
|
|
* if an error occurred.
|
2017-09-13 19:04:53 +03:00
|
|
|
*/
|
2019-04-17 05:59:40 +03:00
|
|
|
const char *parse_cpu_option(const char *cpu_option);
|
2014-03-04 06:17:10 +04:00
|
|
|
|
2012-05-03 08:43:49 +04:00
|
|
|
/**
|
2013-08-25 20:53:55 +04:00
|
|
|
* cpu_has_work:
|
2012-05-03 08:43:49 +04:00
|
|
|
* @cpu: The vCPU to check.
|
|
|
|
*
|
|
|
|
* Checks whether the CPU has work to do.
|
|
|
|
*
|
|
|
|
* Returns: %true if the CPU has work, %false otherwise.
|
|
|
|
*/
|
2013-08-25 20:53:55 +04:00
|
|
|
static inline bool cpu_has_work(CPUState *cpu)
|
|
|
|
{
|
|
|
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
|
|
|
|
|
|
|
g_assert(cc->has_work);
|
|
|
|
return cc->has_work(cpu);
|
|
|
|
}
|
2012-05-03 08:43:49 +04:00
|
|
|
|
2012-05-03 00:23:49 +04:00
|
|
|
/**
|
|
|
|
* qemu_cpu_is_self:
|
|
|
|
* @cpu: The vCPU to check against.
|
|
|
|
*
|
|
|
|
* Checks whether the caller is executing on the vCPU thread.
|
|
|
|
*
|
|
|
|
* Returns: %true if called from @cpu's thread, %false otherwise.
|
|
|
|
*/
|
|
|
|
bool qemu_cpu_is_self(CPUState *cpu);
|
|
|
|
|
2012-05-03 06:34:15 +04:00
|
|
|
/**
|
|
|
|
* qemu_cpu_kick:
|
|
|
|
* @cpu: The vCPU to kick.
|
|
|
|
*
|
|
|
|
* Kicks @cpu's thread.
|
|
|
|
*/
|
|
|
|
void qemu_cpu_kick(CPUState *cpu);
|
|
|
|
|
2012-05-03 01:38:39 +04:00
|
|
|
/**
|
|
|
|
* cpu_is_stopped:
|
|
|
|
* @cpu: The CPU to check.
|
|
|
|
*
|
|
|
|
* Checks whether the CPU is stopped.
|
|
|
|
*
|
|
|
|
* Returns: %true if run state is not running or if artificially stopped;
|
|
|
|
* %false otherwise.
|
|
|
|
*/
|
|
|
|
bool cpu_is_stopped(CPUState *cpu);
|
|
|
|
|
2016-08-29 10:51:00 +03:00
|
|
|
/**
|
|
|
|
* do_run_on_cpu:
|
|
|
|
* @cpu: The vCPU to run on.
|
|
|
|
* @func: The function to be executed.
|
|
|
|
* @data: Data to pass to the function.
|
|
|
|
* @mutex: Mutex to release while waiting for @func to run.
|
|
|
|
*
|
|
|
|
* Used internally in the implementation of run_on_cpu.
|
|
|
|
*/
|
2016-10-31 12:36:08 +03:00
|
|
|
void do_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data,
|
2016-08-29 10:51:00 +03:00
|
|
|
QemuMutex *mutex);
|
|
|
|
|
2012-05-03 16:58:47 +04:00
|
|
|
/**
|
|
|
|
* run_on_cpu:
|
|
|
|
* @cpu: The vCPU to run on.
|
|
|
|
* @func: The function to be executed.
|
|
|
|
* @data: Data to pass to the function.
|
|
|
|
*
|
|
|
|
* Schedules the function @func for execution on the vCPU @cpu.
|
|
|
|
*/
|
2016-10-31 12:36:08 +03:00
|
|
|
void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data);
|
2012-05-03 16:58:47 +04:00
|
|
|
|
2013-06-24 13:49:41 +04:00
|
|
|
/**
|
|
|
|
* async_run_on_cpu:
|
|
|
|
* @cpu: The vCPU to run on.
|
|
|
|
* @func: The function to be executed.
|
|
|
|
* @data: Data to pass to the function.
|
|
|
|
*
|
|
|
|
* Schedules the function @func for execution on the vCPU @cpu asynchronously.
|
|
|
|
*/
|
2016-10-31 12:36:08 +03:00
|
|
|
void async_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data);
|
2013-06-24 13:49:41 +04:00
|
|
|
|
2016-08-28 06:38:24 +03:00
|
|
|
/**
|
|
|
|
* async_safe_run_on_cpu:
|
|
|
|
* @cpu: The vCPU to run on.
|
|
|
|
* @func: The function to be executed.
|
|
|
|
* @data: Data to pass to the function.
|
|
|
|
*
|
|
|
|
* Schedules the function @func for execution on the vCPU @cpu asynchronously,
|
|
|
|
* while all other vCPUs are sleeping.
|
|
|
|
*
|
|
|
|
* Unlike run_on_cpu and async_run_on_cpu, the function is run outside the
|
|
|
|
* BQL.
|
|
|
|
*/
|
2016-10-31 12:36:08 +03:00
|
|
|
void async_safe_run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data);
|
2016-08-28 06:38:24 +03:00
|
|
|
|
2018-11-27 01:14:43 +03:00
|
|
|
/**
|
|
|
|
* cpu_in_exclusive_context()
|
|
|
|
* @cpu: The vCPU to check
|
|
|
|
*
|
|
|
|
* Returns true if @cpu is an exclusive context, for example running
|
|
|
|
* something which has previously been queued via async_safe_run_on_cpu().
|
|
|
|
*/
|
|
|
|
static inline bool cpu_in_exclusive_context(const CPUState *cpu)
|
|
|
|
{
|
2023-02-14 17:08:27 +03:00
|
|
|
return cpu->exclusive_context_count;
|
2018-11-27 01:14:43 +03:00
|
|
|
}
|
|
|
|
|
2012-12-17 22:47:15 +04:00
|
|
|
/**
|
|
|
|
* qemu_get_cpu:
|
|
|
|
* @index: The CPUState@cpu_index value of the CPU to obtain.
|
|
|
|
*
|
|
|
|
* Gets a CPU matching @index.
|
|
|
|
*
|
|
|
|
* Returns: The CPU or %NULL if there is no matching CPU.
|
|
|
|
*/
|
|
|
|
CPUState *qemu_get_cpu(int index);
|
|
|
|
|
2013-04-25 18:05:24 +04:00
|
|
|
/**
|
|
|
|
* cpu_exists:
|
|
|
|
* @id: Guest-exposed CPU ID to lookup.
|
|
|
|
*
|
|
|
|
* Search for CPU with specified ID.
|
|
|
|
*
|
|
|
|
* Returns: %true - CPU is found, %false - CPU isn't found.
|
|
|
|
*/
|
|
|
|
bool cpu_exists(int64_t id);
|
|
|
|
|
2017-07-26 21:44:35 +03:00
|
|
|
/**
|
|
|
|
* cpu_by_arch_id:
|
|
|
|
* @id: Guest-exposed CPU ID of the CPU to obtain.
|
|
|
|
*
|
|
|
|
* Get a CPU with matching @id.
|
|
|
|
*
|
|
|
|
* Returns: The CPU or %NULL if there is no matching CPU.
|
|
|
|
*/
|
|
|
|
CPUState *cpu_by_arch_id(int64_t id);
|
|
|
|
|
2013-01-18 18:03:43 +04:00
|
|
|
/**
|
|
|
|
* cpu_interrupt:
|
|
|
|
* @cpu: The CPU to set an interrupt on.
|
2018-09-05 15:29:08 +03:00
|
|
|
* @mask: The interrupts to set.
|
2013-01-18 18:03:43 +04:00
|
|
|
*
|
|
|
|
* Invokes the interrupt handler.
|
|
|
|
*/
|
|
|
|
|
|
|
|
void cpu_interrupt(CPUState *cpu, int mask);
|
|
|
|
|
2015-06-24 06:19:20 +03:00
|
|
|
/**
|
|
|
|
* cpu_set_pc:
|
|
|
|
* @cpu: The CPU to set the program counter for.
|
|
|
|
* @addr: Program counter value.
|
|
|
|
*
|
|
|
|
* Sets the program counter for a CPU.
|
|
|
|
*/
|
|
|
|
static inline void cpu_set_pc(CPUState *cpu, vaddr addr)
|
|
|
|
{
|
|
|
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
|
|
|
|
|
|
|
cc->set_pc(cpu, addr);
|
|
|
|
}
|
|
|
|
|
2013-01-18 01:30:20 +04:00
|
|
|
/**
|
|
|
|
* cpu_reset_interrupt:
|
|
|
|
* @cpu: The CPU to clear the interrupt on.
|
|
|
|
* @mask: The interrupt mask to clear.
|
|
|
|
*
|
|
|
|
* Resets interrupts on the vCPU @cpu.
|
|
|
|
*/
|
|
|
|
void cpu_reset_interrupt(CPUState *cpu, int mask);
|
|
|
|
|
2013-05-17 20:26:54 +04:00
|
|
|
/**
|
|
|
|
* cpu_exit:
|
|
|
|
* @cpu: The CPU to exit.
|
|
|
|
*
|
|
|
|
* Requests the CPU @cpu to exit execution.
|
|
|
|
*/
|
|
|
|
void cpu_exit(CPUState *cpu);
|
|
|
|
|
2013-04-23 12:29:37 +04:00
|
|
|
/**
|
|
|
|
* cpu_resume:
|
|
|
|
* @cpu: The CPU to resume.
|
|
|
|
*
|
|
|
|
* Resumes CPU, i.e. puts CPU into runnable state.
|
|
|
|
*/
|
|
|
|
void cpu_resume(CPUState *cpu);
|
2012-01-28 19:39:52 +04:00
|
|
|
|
2016-05-12 06:48:13 +03:00
|
|
|
/**
|
2016-05-12 06:48:14 +03:00
|
|
|
* cpu_remove_sync:
|
|
|
|
* @cpu: The CPU to remove.
|
|
|
|
*
|
|
|
|
* Requests the CPU to be removed and waits till it is removed.
|
|
|
|
*/
|
|
|
|
void cpu_remove_sync(CPUState *cpu);
|
|
|
|
|
2016-08-29 10:51:00 +03:00
|
|
|
/**
|
|
|
|
* process_queued_cpu_work() - process all items on CPU work queue
|
|
|
|
* @cpu: The CPU which work queue to process.
|
|
|
|
*/
|
|
|
|
void process_queued_cpu_work(CPUState *cpu);
|
|
|
|
|
2016-08-31 17:56:04 +03:00
|
|
|
/**
|
|
|
|
* cpu_exec_start:
|
|
|
|
* @cpu: The CPU for the current thread.
|
|
|
|
*
|
|
|
|
* Record that a CPU has started execution and can be interrupted with
|
|
|
|
* cpu_exit.
|
|
|
|
*/
|
|
|
|
void cpu_exec_start(CPUState *cpu);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cpu_exec_end:
|
|
|
|
* @cpu: The CPU for the current thread.
|
|
|
|
*
|
|
|
|
* Record that a CPU has stopped execution and exclusive sections
|
|
|
|
* can be executed without interrupting it.
|
|
|
|
*/
|
|
|
|
void cpu_exec_end(CPUState *cpu);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start_exclusive:
|
|
|
|
*
|
|
|
|
* Wait for a concurrent exclusive section to end, and then start
|
|
|
|
* a section of work that is run while other CPUs are not running
|
|
|
|
* between cpu_exec_start and cpu_exec_end. CPUs that are running
|
|
|
|
* cpu_exec are exited immediately. CPUs that call cpu_exec_start
|
|
|
|
* during the exclusive section go to sleep until this CPU calls
|
|
|
|
* end_exclusive.
|
|
|
|
*/
|
|
|
|
void start_exclusive(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* end_exclusive:
|
|
|
|
*
|
|
|
|
* Concludes an exclusive execution section started by start_exclusive.
|
|
|
|
*/
|
|
|
|
void end_exclusive(void);
|
|
|
|
|
2013-05-27 05:23:24 +04:00
|
|
|
/**
|
|
|
|
* qemu_init_vcpu:
|
|
|
|
* @cpu: The vCPU to initialize.
|
|
|
|
*
|
|
|
|
* Initializes a vCPU.
|
|
|
|
*/
|
|
|
|
void qemu_init_vcpu(CPUState *cpu);
|
|
|
|
|
2013-06-24 20:41:06 +04:00
|
|
|
#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
|
|
|
|
#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
|
|
|
|
#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cpu_single_step:
|
|
|
|
* @cpu: CPU to the flags for.
|
|
|
|
* @enabled: Flags to enable.
|
|
|
|
*
|
|
|
|
* Enables or disables single-stepping for @cpu.
|
|
|
|
*/
|
|
|
|
void cpu_single_step(CPUState *cpu, int enabled);
|
|
|
|
|
2013-09-02 19:26:20 +04:00
|
|
|
/* Breakpoint/watchpoint flags */
|
|
|
|
#define BP_MEM_READ 0x01
|
|
|
|
#define BP_MEM_WRITE 0x02
|
|
|
|
#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
|
|
|
|
#define BP_STOP_BEFORE_ACCESS 0x04
|
2014-09-12 17:06:48 +04:00
|
|
|
/* 0x08 currently unused */
|
2013-09-02 19:26:20 +04:00
|
|
|
#define BP_GDB 0x10
|
|
|
|
#define BP_CPU 0x20
|
2015-09-18 01:58:10 +03:00
|
|
|
#define BP_ANY (BP_GDB | BP_CPU)
|
2023-02-23 11:16:51 +03:00
|
|
|
#define BP_HIT_SHIFT 6
|
|
|
|
#define BP_WATCHPOINT_HIT_READ (BP_MEM_READ << BP_HIT_SHIFT)
|
|
|
|
#define BP_WATCHPOINT_HIT_WRITE (BP_MEM_WRITE << BP_HIT_SHIFT)
|
|
|
|
#define BP_WATCHPOINT_HIT (BP_MEM_ACCESS << BP_HIT_SHIFT)
|
2013-09-02 19:26:20 +04:00
|
|
|
|
|
|
|
int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
|
|
|
|
CPUBreakpoint **breakpoint);
|
|
|
|
int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags);
|
|
|
|
void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint);
|
|
|
|
void cpu_breakpoint_remove_all(CPUState *cpu, int mask);
|
|
|
|
|
2015-09-18 01:58:10 +03:00
|
|
|
/* Return true if PC matches an installed breakpoint. */
|
|
|
|
static inline bool cpu_breakpoint_test(CPUState *cpu, vaddr pc, int mask)
|
|
|
|
{
|
|
|
|
CPUBreakpoint *bp;
|
|
|
|
|
|
|
|
if (unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
|
|
|
|
QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
|
|
|
|
if (bp->pc == pc && (bp->flags & mask)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-03-28 20:31:17 +03:00
|
|
|
#if defined(CONFIG_USER_ONLY)
|
2019-08-24 23:31:58 +03:00
|
|
|
static inline int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
|
|
|
|
int flags, CPUWatchpoint **watchpoint)
|
|
|
|
{
|
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int cpu_watchpoint_remove(CPUState *cpu, vaddr addr,
|
|
|
|
vaddr len, int flags)
|
|
|
|
{
|
|
|
|
return -ENOSYS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void cpu_watchpoint_remove_by_ref(CPUState *cpu,
|
|
|
|
CPUWatchpoint *wp)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#else
|
2013-09-02 18:57:02 +04:00
|
|
|
int cpu_watchpoint_insert(CPUState *cpu, vaddr addr, vaddr len,
|
|
|
|
int flags, CPUWatchpoint **watchpoint);
|
|
|
|
int cpu_watchpoint_remove(CPUState *cpu, vaddr addr,
|
|
|
|
vaddr len, int flags);
|
|
|
|
void cpu_watchpoint_remove_by_ref(CPUState *cpu, CPUWatchpoint *watchpoint);
|
|
|
|
void cpu_watchpoint_remove_all(CPUState *cpu, int mask);
|
2019-08-24 23:31:58 +03:00
|
|
|
#endif
|
2013-09-02 18:57:02 +04:00
|
|
|
|
plugins: force slow path when plugins instrument memory ops
The lack of SVE memory instrumentation has been an omission in plugin
handling since it was introduced. Fortunately we can utilise the
probe_* functions to force all all memory access to follow the slow
path. We do this by checking the access type and presence of plugin
memory callbacks and if set return the TLB_MMIO flag.
We have to jump through a few hoops in user mode to re-use the flag
but it was the desired effect:
./qemu-system-aarch64 -display none -serial mon:stdio \
-M virt -cpu max -semihosting-config enable=on \
-kernel ./tests/tcg/aarch64-softmmu/memory-sve \
-plugin ./contrib/plugins/libexeclog.so,ifilter=st1w,afilter=0x40001808 -d plugin
gives (disas doesn't currently understand st1w):
0, 0x40001808, 0xe54342a0, ".byte 0xa0, 0x42, 0x43, 0xe5", store, 0x40213010, RAM, store, 0x40213014, RAM, store, 0x40213018, RAM
And for user-mode:
./qemu-aarch64 \
-plugin contrib/plugins/libexeclog.so,afilter=0x4007c0 \
-d plugin \
./tests/tcg/aarch64-linux-user/sha512-sve
gives:
1..10
ok 1 - do_test(&tests[i])
0, 0x4007c0, 0xa4004b80, ".byte 0x80, 0x4b, 0x00, 0xa4", load, 0x5500800370, load, 0x5500800371, load, 0x5500800372, load, 0x5500800373, load, 0x5500800374, load, 0x5500800375, load, 0x5500800376, load, 0x5500800377, load, 0x5500800378, load, 0x5500800379, load, 0x550080037a, load, 0x550080037b, load, 0x550080037c, load, 0x550080037d, load, 0x550080037e, load, 0x550080037f, load, 0x5500800380, load, 0x5500800381, load, 0x5500800382, load, 0x5500800383, load, 0x5500800384, load, 0x5500800385, load, 0x5500800386, lo
ad, 0x5500800387, load, 0x5500800388, load, 0x5500800389, load, 0x550080038a, load, 0x550080038b, load, 0x550080038c, load, 0x550080038d, load, 0x550080038e, load, 0x550080038f, load, 0x5500800390, load, 0x5500800391, load, 0x5500800392, load, 0x5500800393, load, 0x5500800394, load, 0x5500800395, load, 0x5500800396, load, 0x5500800397, load, 0x5500800398, load, 0x5500800399, load, 0x550080039a, load, 0x550080039b, load, 0x550080039c, load, 0x550080039d, load, 0x550080039e, load, 0x550080039f, load, 0x55008003a0, load, 0x55008003a1, load, 0x55008003a2, load, 0x55008003a3, load, 0x55008003a4, load, 0x55008003a5, load, 0x55008003a6, load, 0x55008003a7, load, 0x55008003a8, load, 0x55008003a9, load, 0x55008003aa, load, 0x55008003ab, load, 0x55008003ac, load, 0x55008003ad, load, 0x55008003ae, load, 0x55008003af
(4007c0 is the ld1b in the sha512-sve)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Cc: Robert Henry <robhenry@microsoft.com>
Cc: Aaron Lindsay <aaron@os.amperecomputing.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20230630180423.558337-20-alex.bennee@linaro.org>
2023-06-30 21:04:04 +03:00
|
|
|
/**
|
|
|
|
* cpu_plugin_mem_cbs_enabled() - are plugin memory callbacks enabled?
|
|
|
|
* @cs: CPUState pointer
|
|
|
|
*
|
|
|
|
* The memory callbacks are installed if a plugin has instrumented an
|
|
|
|
* instruction for memory. This can be useful to know if you want to
|
|
|
|
* force a slow path for a series of memory accesses.
|
|
|
|
*/
|
|
|
|
static inline bool cpu_plugin_mem_cbs_enabled(const CPUState *cpu)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_PLUGIN
|
|
|
|
return !!cpu->plugin_mem_cbs;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-03-15 15:18:37 +03:00
|
|
|
/**
|
|
|
|
* cpu_get_address_space:
|
|
|
|
* @cpu: CPU to get address space from
|
|
|
|
* @asidx: index identifying which address space to get
|
|
|
|
*
|
|
|
|
* Return the requested address space of this CPU. @asidx
|
|
|
|
* specifies which address space to read.
|
|
|
|
*/
|
|
|
|
AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx);
|
|
|
|
|
2022-04-20 16:26:02 +03:00
|
|
|
G_NORETURN void cpu_abort(CPUState *cpu, const char *fmt, ...)
|
2022-02-20 19:39:25 +03:00
|
|
|
G_GNUC_PRINTF(2, 3);
|
2021-02-04 19:39:11 +03:00
|
|
|
|
|
|
|
/* $(top_srcdir)/cpu.c */
|
2021-08-22 10:25:28 +03:00
|
|
|
void cpu_class_init_props(DeviceClass *dc);
|
2016-10-20 14:26:02 +03:00
|
|
|
void cpu_exec_initfn(CPUState *cpu);
|
2023-09-15 17:26:52 +03:00
|
|
|
bool cpu_exec_realizefn(CPUState *cpu, Error **errp);
|
2016-10-20 14:26:04 +03:00
|
|
|
void cpu_exec_unrealizefn(CPUState *cpu);
|
2023-09-15 23:55:33 +03:00
|
|
|
void cpu_exec_reset_hold(CPUState *cpu);
|
2013-09-03 19:38:47 +04:00
|
|
|
|
2018-10-05 15:46:02 +03:00
|
|
|
/**
|
|
|
|
* target_words_bigendian:
|
|
|
|
* Returns true if the (default) endianness of the target is big endian,
|
|
|
|
* false otherwise. Note that in target-specific code, you can use
|
2022-03-23 18:57:18 +03:00
|
|
|
* TARGET_BIG_ENDIAN directly instead. On the other hand, common
|
2018-10-05 15:46:02 +03:00
|
|
|
* code should normally never need to know about the endianness of the
|
|
|
|
* target, so please do *not* use this function unless you know very well
|
|
|
|
* what you are doing!
|
|
|
|
*/
|
|
|
|
bool target_words_bigendian(void);
|
|
|
|
|
2023-04-24 19:04:33 +03:00
|
|
|
const char *target_name(void);
|
|
|
|
|
2017-06-26 08:22:56 +03:00
|
|
|
#ifdef NEED_CPU_H
|
|
|
|
|
2023-06-13 16:33:43 +03:00
|
|
|
#ifndef CONFIG_USER_ONLY
|
2021-05-17 13:51:32 +03:00
|
|
|
|
2019-08-12 08:23:44 +03:00
|
|
|
extern const VMStateDescription vmstate_cpu_common;
|
2013-06-17 06:09:11 +04:00
|
|
|
|
|
|
|
#define VMSTATE_CPU() { \
|
|
|
|
.name = "parent_obj", \
|
|
|
|
.size = sizeof(CPUState), \
|
|
|
|
.vmsd = &vmstate_cpu_common, \
|
|
|
|
.flags = VMS_STRUCT, \
|
|
|
|
.offset = 0, \
|
|
|
|
}
|
2023-06-13 16:33:43 +03:00
|
|
|
#endif /* !CONFIG_USER_ONLY */
|
2013-06-17 06:09:11 +04:00
|
|
|
|
2017-06-26 08:22:56 +03:00
|
|
|
#endif /* NEED_CPU_H */
|
|
|
|
|
2016-07-25 12:59:21 +03:00
|
|
|
#define UNASSIGNED_CPU_INDEX -1
|
2019-01-29 14:46:05 +03:00
|
|
|
#define UNASSIGNED_CLUSTER_INDEX -1
|
2016-07-25 12:59:21 +03:00
|
|
|
|
2012-01-28 19:39:52 +04:00
|
|
|
#endif
|