* Fixes for "-cpu max" on i386 TCG (Daniel)

* vVMLOAD/VMSAVE and vGIF implementation (Lara)
 * Reorganize i386 targets documentation in preparation for SGX (myself)
 * Meson cleanups (myself, Thomas)
 * NVMM fixes (Reinoud)
 * Suppress bogus -Wstringop-overflow (Richard)
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmE/PHEUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroNn0ggAhOApMUZR2L9p4Z56X+Nnc1835dOJ
 QlX8UmMpoRBPuIKfaJPJQWwYeRSw4Nqaik3EndXug8Mo3LJaG5AFEHTXDkZGHMgh
 tGCyeARhDnUQPfKLszT1zg0EMloX6bCLFaA9ba1JBNK8VWXE4oJJLETk3Q+pDJZt
 0ztoxaLvQ2jaMFfPKtLdyhcXjDCPeZZjaQjCFVVmWV9hj8z4np3LZLoYi8a6cRWu
 u1Rb5SrftF12tu+RWACXZFQSnxFkU+iVeoKhQB0vrh7UgV/HAAbZS8c2U46v/kM0
 H6UcuBPjrz3fF/9hHNdovb4HxyQAP2pEliBSG7tFzJ+TbnMQVcoxN5uJ2Q==
 =DBxg
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging

* Fixes for "-cpu max" on i386 TCG (Daniel)
* vVMLOAD/VMSAVE and vGIF implementation (Lara)
* Reorganize i386 targets documentation in preparation for SGX (myself)
* Meson cleanups (myself, Thomas)
* NVMM fixes (Reinoud)
* Suppress bogus -Wstringop-overflow (Richard)

# gpg: Signature made Mon 13 Sep 2021 12:56:33 BST
# gpg:                using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg:                issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg:                 aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
# Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4  E2F7 7E15 100C CD36 69B1
#      Subkey fingerprint: F133 3857 4B66 2389 866C  7682 BFFB D25F 78C7 AE83

* remotes/bonzini-gitlab/tags/for-upstream: (21 commits)
  docs: link to archived Fedora code of conduct
  Fix nvmm_ram_block_added() function arguments
  Only check CONFIG_NVMM when NEED_CPU_H is defined
  util: Suppress -Wstringop-overflow in qemu_thread_start
  fw_cfg: add etc/msr_feature_control
  meson: remove dead variable
  meson: do not use python.full_path() unnecessarily
  meson: look up cp and dtrace with find_program()
  meson.build: Do not look for VNC-related libraries if have_system is not set
  docs/system: move x86 CPU configuration to a separate document
  docs/system: standardize man page sections to --- with overline
  docs: standardize directory index to --- with overline
  docs: standardize book titles to === with overline
  target/i386: Added vVMLOAD and vVMSAVE feature
  target/i386: Added changed priority check for VIRQ
  target/i386: Added ignore TPR check in ctl_has_irq
  target/i386: Added VGIF V_IRQ masking capability
  target/i386: Moved int_ctl into CPUX86State structure
  target/i386: Added VGIF feature
  target/i386: VMRUN and VMLOAD canonicalizations
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
master
Peter Maydell 2021-09-13 13:33:21 +01:00
commit 7d79344d4f
36 changed files with 251 additions and 83 deletions

View File

@ -1,5 +1,6 @@
----------
About QEMU About QEMU
========== ----------
QEMU is a generic and open source machine emulator and virtualizer. QEMU is a generic and open source machine emulator and virtualizer.

View File

@ -55,6 +55,6 @@ Sources
------- -------
This document is based on the `Fedora Code of Conduct This document is based on the `Fedora Code of Conduct
<https://fedoraproject.org/code-of-conduct>`__ and the <http://web.archive.org/web/20210429132536/https://docs.fedoraproject.org/en-US/project/code-of-conduct/>`__
`Contributor Covenant version 1.3.0 (as of April 2021) and the `Contributor Covenant version 1.3.0
<https://www.contributor-covenant.org/version/1/3/0/code-of-conduct/>`__. <https://www.contributor-covenant.org/version/1/3/0/code-of-conduct/>`__.

View File

@ -1,5 +1,6 @@
---------------------
Developer Information Developer Information
===================== ---------------------
This section of the manual documents various parts of the internals of QEMU. This section of the manual documents various parts of the internals of QEMU.
You only need to read it if you are interested in reading or You only need to read it if you are interested in reading or

View File

@ -3,6 +3,7 @@
You can adapt this file completely to your liking, but it should at least You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive. contain the root `toctree` directive.
================================
Welcome to QEMU's documentation! Welcome to QEMU's documentation!
================================ ================================

View File

@ -1,5 +1,6 @@
------------------------------------------------
System Emulation Management and Interoperability System Emulation Management and Interoperability
================================================ ------------------------------------------------
This section of the manual contains documents and specifications that This section of the manual contains documents and specifications that
are useful for making QEMU interoperate with other software. are useful for making QEMU interoperate with other software.

View File

@ -1,5 +1,6 @@
----------------------------------------------
System Emulation Guest Hardware Specifications System Emulation Guest Hardware Specifications
============================================== ----------------------------------------------
This section of the manual contains specifications of This section of the manual contains specifications of
guest hardware that is specific to QEMU. guest hardware that is specific to QEMU.

View File

@ -1,5 +1,5 @@
Recommendations for KVM CPU model configuration on x86 hosts Recommendations for KVM CPU model configuration on x86 hosts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ============================================================
The information that follows provides recommendations for configuring The information that follows provides recommendations for configuring
CPU models on x86 hosts. The goals are to maximise performance, while CPU models on x86 hosts. The goals are to maximise performance, while
@ -368,7 +368,7 @@ featureset, which prevents guests having optimal performance.
Syntax for configuring CPU models Syntax for configuring CPU models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =================================
The examples below illustrate the approach to configuring the various The examples below illustrate the approach to configuring the various
CPU models / features in QEMU and libvirt. CPU models / features in QEMU and libvirt.

1
docs/system/i386/cpu.rst Normal file
View File

@ -0,0 +1 @@
.. include:: ../cpu-models-x86.rst.inc

View File

@ -1,5 +1,6 @@
----------------
System Emulation System Emulation
================ ----------------
This section of the manual is the overall guide for users using QEMU This section of the manual is the overall guide for users using QEMU
for full system emulation (as opposed to user-mode emulation). for full system emulation (as opposed to user-mode emulation).

View File

@ -1,18 +1,22 @@
:orphan: :orphan:
============================
QEMU block drivers reference QEMU block drivers reference
============================ ============================
--------
Synopsis Synopsis
-------- --------
QEMU block driver reference manual QEMU block driver reference manual
-----------
Description Description
----------- -----------
.. include:: qemu-block-drivers.rst.inc .. include:: qemu-block-drivers.rst.inc
--------
See also See also
-------- --------

View File

@ -1,20 +1,24 @@
:orphan: :orphan:
==================================
QEMU / KVM CPU model configuration QEMU / KVM CPU model configuration
================================== ==================================
--------
Synopsis Synopsis
'''''''' --------
QEMU CPU Modelling Infrastructure manual QEMU CPU Modelling Infrastructure manual
-----------
Description Description
''''''''''' -----------
.. include:: cpu-models-x86.rst.inc .. include:: cpu-models-x86.rst.inc
.. include:: cpu-models-mips.rst.inc .. include:: cpu-models-mips.rst.inc
--------
See also See also
'''''''' --------
The HTML documentation of QEMU for more precise information and Linux user mode emulator invocation. The HTML documentation of QEMU for more precise information and Linux user mode emulator invocation.

View File

@ -6,9 +6,11 @@
parts of the documentation that go in the manpage as well as the parts of the documentation that go in the manpage as well as the
HTML manual. HTML manual.
Title =======================
===== QEMU User Documentation
=======================
--------
Synopsis Synopsis
-------- --------
@ -16,11 +18,13 @@ Synopsis
|qemu_system| [options] [disk_image] |qemu_system| [options] [disk_image]
-----------
Description Description
----------- -----------
.. include:: target-i386-desc.rst.inc .. include:: target-i386-desc.rst.inc
-------
Options Options
------- -------
@ -33,11 +37,13 @@ not need a disk image.
.. include:: mux-chardev.rst.inc .. include:: mux-chardev.rst.inc
-----
Notes Notes
----- -----
.. include:: device-url-syntax.rst.inc .. include:: device-url-syntax.rst.inc
--------
See also See also
-------- --------

View File

@ -19,7 +19,13 @@ Board-specific documentation
i386/microvm i386/microvm
i386/pc i386/pc
.. include:: cpu-models-x86.rst.inc Architectural features
~~~~~~~~~~~~~~~~~~~~~~
.. toctree::
:maxdepth: 1
i386/cpu
.. _pcsys_005freq: .. _pcsys_005freq:

View File

@ -1,5 +1,6 @@
-----
Tools Tools
===== -----
This section of the manual documents QEMU's "tools": its This section of the manual documents QEMU's "tools": its
command line utilities and other standalone programs. command line utilities and other standalone programs.

View File

@ -1,3 +1,4 @@
=======================
QEMU disk image utility QEMU disk image utility
======================= =======================

View File

@ -1,3 +1,4 @@
=====================================
QEMU Disk Network Block Device Server QEMU Disk Network Block Device Server
===================================== =====================================

View File

@ -1,3 +1,4 @@
==================================
QEMU persistent reservation helper QEMU persistent reservation helper
================================== ==================================

View File

@ -1,3 +1,4 @@
===================
QEMU Storage Daemon QEMU Storage Daemon
=================== ===================

View File

@ -1,3 +1,4 @@
=========================
QEMU SystemTap trace tool QEMU SystemTap trace tool
========================= =========================

View File

@ -1,5 +1,6 @@
-------------------
User Mode Emulation User Mode Emulation
=================== -------------------
This section of the manual is the overall guide for users using QEMU This section of the manual is the overall guide for users using QEMU
for user-mode emulation. In this mode, QEMU can launch for user-mode emulation. In this mode, QEMU can launch

View File

@ -878,6 +878,7 @@ static struct {
{ "etc/tpm/log", 150 }, { "etc/tpm/log", 150 },
{ "etc/acpi/rsdp", 160 }, { "etc/acpi/rsdp", 160 },
{ "bootorder", 170 }, { "bootorder", 170 },
{ "etc/msr_feature_control", 180 },
#define FW_CFG_ORDER_OVERRIDE_LAST 200 #define FW_CFG_ORDER_OVERRIDE_LAST 200
}; };

View File

@ -10,8 +10,7 @@
#ifndef QEMU_NVMM_H #ifndef QEMU_NVMM_H
#define QEMU_NVMM_H #define QEMU_NVMM_H
#include "config-host.h" #ifdef NEED_CPU_H
#include "qemu-common.h"
#ifdef CONFIG_NVMM #ifdef CONFIG_NVMM
@ -23,4 +22,6 @@ int nvmm_enabled(void);
#endif /* CONFIG_NVMM */ #endif /* CONFIG_NVMM */
#endif /* CONFIG_NVMM */ #endif /* NEED_CPU_H */
#endif /* QEMU_NVMM_H */

View File

@ -931,7 +931,7 @@ vnc = not_found
png = not_found png = not_found
jpeg = not_found jpeg = not_found
sasl = not_found sasl = not_found
if not get_option('vnc').disabled() if have_system and not get_option('vnc').disabled()
vnc = declare_dependency() # dummy dependency vnc = declare_dependency() # dummy dependency
png = dependency('libpng', required: get_option('vnc_png'), png = dependency('libpng', required: get_option('vnc_png'),
method: 'pkg-config', kwargs: static_kwargs) method: 'pkg-config', kwargs: static_kwargs)

View File

@ -38,6 +38,7 @@ if meson.is_cross_build() or 'CONFIG_XKBCOMMON' not in config_host
else else
native_qemu_keymap = qemu_keymap native_qemu_keymap = qemu_keymap
endif endif
cp = find_program('cp')
t = [] t = []
foreach km, args: keymaps foreach km, args: keymaps
@ -55,7 +56,7 @@ foreach km, args: keymaps
build_by_default: true, build_by_default: true,
input: km, input: km,
output: km, output: km,
command: ['cp', '@INPUT@', '@OUTPUT@'], command: [cp, '@INPUT@', '@OUTPUT@'],
install: true, install: true,
install_dir: qemu_datadir / 'keymaps') install_dir: qemu_datadir / 'keymaps')
endif endif

View File

@ -631,7 +631,8 @@ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \ #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A) CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
#define TCG_EXT4_FEATURES 0 #define TCG_EXT4_FEATURES 0
#define TCG_SVM_FEATURES CPUID_SVM_NPT #define TCG_SVM_FEATURES (CPUID_SVM_NPT | CPUID_SVM_VGIF | \
CPUID_SVM_SVME_ADDR_CHK)
#define TCG_KVM_FEATURES 0 #define TCG_KVM_FEATURES 0
#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \ #define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP | \
CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \ CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX | \
@ -5115,6 +5116,15 @@ static void x86_register_cpudef_types(const X86CPUDefinition *def)
} }
uint32_t cpu_x86_virtual_addr_width(CPUX86State *env)
{
if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57) {
return 57; /* 57 bits virtual */
} else {
return 48; /* 48 bits virtual */
}
}
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx, uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx) uint32_t *ecx, uint32_t *edx)
@ -5517,16 +5527,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
break; break;
case 0x80000008: case 0x80000008:
/* virtual & phys address size in low 2 bytes. */ /* virtual & phys address size in low 2 bytes. */
*eax = cpu->phys_bits;
if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) { if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
/* 64 bit processor */ /* 64 bit processor */
*eax = cpu->phys_bits; /* configurable physical bits */ *eax |= (cpu_x86_virtual_addr_width(env) << 8);
if (env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_LA57) {
*eax |= 0x00003900; /* 57 bits virtual */
} else {
*eax |= 0x00003000; /* 48 bits virtual */
}
} else {
*eax = cpu->phys_bits;
} }
*ebx = env->features[FEAT_8000_0008_EBX]; *ebx = env->features[FEAT_8000_0008_EBX];
if (cs->nr_cores * cs->nr_threads > 1) { if (cs->nr_cores * cs->nr_threads > 1) {
@ -5651,8 +5655,9 @@ static void x86_cpu_reset(DeviceState *dev)
env->old_exception = -1; env->old_exception = -1;
/* init to reset state */ /* init to reset state */
env->int_ctl = 0;
env->hflags2 |= HF2_GIF_MASK; env->hflags2 |= HF2_GIF_MASK;
env->hflags2 |= HF2_VGIF_MASK;
env->hflags &= ~HF_GUEST_MASK; env->hflags &= ~HF_GUEST_MASK;
cpu_x86_update_cr0(env, 0x60000010); cpu_x86_update_cr0(env, 0x60000010);
@ -6536,10 +6541,12 @@ int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request)
!(env->hflags & HF_INHIBIT_IRQ_MASK))))) { !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
return CPU_INTERRUPT_HARD; return CPU_INTERRUPT_HARD;
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
} else if ((interrupt_request & CPU_INTERRUPT_VIRQ) && } else if (env->hflags2 & HF2_VGIF_MASK) {
if((interrupt_request & CPU_INTERRUPT_VIRQ) &&
(env->eflags & IF_MASK) && (env->eflags & IF_MASK) &&
!(env->hflags & HF_INHIBIT_IRQ_MASK)) { !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
return CPU_INTERRUPT_VIRQ; return CPU_INTERRUPT_VIRQ;
}
#endif #endif
} }
} }

View File

@ -203,6 +203,7 @@ typedef enum X86Seg {
#define HF2_MPX_PR_SHIFT 5 /* BNDCFGx.BNDPRESERVE */ #define HF2_MPX_PR_SHIFT 5 /* BNDCFGx.BNDPRESERVE */
#define HF2_NPT_SHIFT 6 /* Nested Paging enabled */ #define HF2_NPT_SHIFT 6 /* Nested Paging enabled */
#define HF2_IGNNE_SHIFT 7 /* Ignore CR0.NE=0 */ #define HF2_IGNNE_SHIFT 7 /* Ignore CR0.NE=0 */
#define HF2_VGIF_SHIFT 8 /* Can take VIRQ*/
#define HF2_GIF_MASK (1 << HF2_GIF_SHIFT) #define HF2_GIF_MASK (1 << HF2_GIF_SHIFT)
#define HF2_HIF_MASK (1 << HF2_HIF_SHIFT) #define HF2_HIF_MASK (1 << HF2_HIF_SHIFT)
@ -212,6 +213,7 @@ typedef enum X86Seg {
#define HF2_MPX_PR_MASK (1 << HF2_MPX_PR_SHIFT) #define HF2_MPX_PR_MASK (1 << HF2_MPX_PR_SHIFT)
#define HF2_NPT_MASK (1 << HF2_NPT_SHIFT) #define HF2_NPT_MASK (1 << HF2_NPT_SHIFT)
#define HF2_IGNNE_MASK (1 << HF2_IGNNE_SHIFT) #define HF2_IGNNE_MASK (1 << HF2_IGNNE_SHIFT)
#define HF2_VGIF_MASK (1 << HF2_VGIF_SHIFT)
#define CR0_PE_SHIFT 0 #define CR0_PE_SHIFT 0
#define CR0_MP_SHIFT 1 #define CR0_MP_SHIFT 1
@ -257,6 +259,7 @@ typedef enum X86Seg {
| CR4_DE_MASK | CR4_PSE_MASK | CR4_PAE_MASK \ | CR4_DE_MASK | CR4_PSE_MASK | CR4_PAE_MASK \
| CR4_MCE_MASK | CR4_PGE_MASK | CR4_PCE_MASK \ | CR4_MCE_MASK | CR4_PGE_MASK | CR4_PCE_MASK \
| CR4_OSFXSR_MASK | CR4_OSXMMEXCPT_MASK |CR4_UMIP_MASK \ | CR4_OSFXSR_MASK | CR4_OSXMMEXCPT_MASK |CR4_UMIP_MASK \
| CR4_LA57_MASK \
| CR4_FSGSBASE_MASK | CR4_PCIDE_MASK | CR4_OSXSAVE_MASK \ | CR4_FSGSBASE_MASK | CR4_PCIDE_MASK | CR4_OSXSAVE_MASK \
| CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK)) | CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_PKE_MASK | CR4_PKS_MASK))
@ -1577,6 +1580,7 @@ typedef struct CPUX86State {
uint64_t nested_cr3; uint64_t nested_cr3;
uint32_t nested_pg_mode; uint32_t nested_pg_mode;
uint8_t v_tpr; uint8_t v_tpr;
uint32_t int_ctl;
/* KVM states, automatically cleared on reset */ /* KVM states, automatically cleared on reset */
uint8_t nmi_injected; uint8_t nmi_injected;
@ -1954,6 +1958,8 @@ typedef struct PropValue {
} PropValue; } PropValue;
void x86_cpu_apply_props(X86CPU *cpu, PropValue *props); void x86_cpu_apply_props(X86CPU *cpu, PropValue *props);
uint32_t cpu_x86_virtual_addr_width(CPUX86State *env);
/* cpu.c other functions (cpuid) */ /* cpu.c other functions (cpuid) */
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx, uint32_t *eax, uint32_t *ebx,
@ -2240,6 +2246,23 @@ static inline uint64_t cr4_reserved_bits(CPUX86State *env)
return reserved_bits; return reserved_bits;
} }
static inline bool ctl_has_irq(CPUX86State *env)
{
uint32_t int_prio;
uint32_t tpr;
int_prio = (env->int_ctl & V_INTR_PRIO_MASK) >> V_INTR_PRIO_SHIFT;
tpr = env->int_ctl & V_TPR_MASK;
if (env->int_ctl & V_IGN_TPR_MASK) {
return (env->int_ctl & V_IRQ_MASK);
}
return (env->int_ctl & V_IRQ_MASK) && (int_prio >= tpr);
}
hwaddr get_hphys(CPUState *cs, hwaddr gphys, MMUAccessType access_type,
int *prot);
#if defined(TARGET_X86_64) && \ #if defined(TARGET_X86_64) && \
defined(CONFIG_USER_ONLY) && \ defined(CONFIG_USER_ONLY) && \
defined(CONFIG_LINUX) defined(CONFIG_LINUX)

View File

@ -203,7 +203,7 @@ static int cpu_pre_save(void *opaque)
X86CPU *cpu = opaque; X86CPU *cpu = opaque;
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
int i; int i;
env->v_tpr = env->int_ctl & V_TPR_MASK;
/* FPU */ /* FPU */
env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
env->fptag_vmstate = 0; env->fptag_vmstate = 0;
@ -1356,6 +1356,25 @@ static const VMStateDescription vmstate_svm_npt = {
} }
}; };
static bool svm_guest_needed(void *opaque)
{
X86CPU *cpu = opaque;
CPUX86State *env = &cpu->env;
return tcg_enabled() && env->int_ctl;
}
static const VMStateDescription vmstate_svm_guest = {
.name = "cpu/svm_guest",
.version_id = 1,
.minimum_version_id = 1,
.needed = svm_guest_needed,
.fields = (VMStateField[]){
VMSTATE_UINT32(env.int_ctl, X86CPU),
VMSTATE_END_OF_LIST()
}
};
#ifndef TARGET_X86_64 #ifndef TARGET_X86_64
static bool intel_efer32_needed(void *opaque) static bool intel_efer32_needed(void *opaque)
{ {
@ -1524,6 +1543,7 @@ const VMStateDescription vmstate_x86_cpu = {
&vmstate_msr_intel_pt, &vmstate_msr_intel_pt,
&vmstate_msr_virt_ssbd, &vmstate_msr_virt_ssbd,
&vmstate_svm_npt, &vmstate_svm_npt,
&vmstate_svm_guest,
#ifndef TARGET_X86_64 #ifndef TARGET_X86_64
&vmstate_efer32, &vmstate_efer32,
#endif #endif

View File

@ -1132,13 +1132,14 @@ static MemoryListener nvmm_memory_listener = {
}; };
static void static void
nvmm_ram_block_added(RAMBlockNotifier *n, void *host, size_t size) nvmm_ram_block_added(RAMBlockNotifier *n, void *host, size_t size,
size_t max_size)
{ {
struct nvmm_machine *mach = get_nvmm_mach(); struct nvmm_machine *mach = get_nvmm_mach();
uintptr_t hva = (uintptr_t)host; uintptr_t hva = (uintptr_t)host;
int ret; int ret;
ret = nvmm_hva_map(mach, hva, size); ret = nvmm_hva_map(mach, hva, max_size);
if (ret == -1) { if (ret == -1) {
error_report("NVMM: Failed to map HVA, HostVA:%p " error_report("NVMM: Failed to map HVA, HostVA:%p "

View File

@ -9,6 +9,12 @@
#define V_IRQ_SHIFT 8 #define V_IRQ_SHIFT 8
#define V_IRQ_MASK (1 << V_IRQ_SHIFT) #define V_IRQ_MASK (1 << V_IRQ_SHIFT)
#define V_GIF_ENABLED_SHIFT 25
#define V_GIF_ENABLED_MASK (1 << V_GIF_ENABLED_SHIFT)
#define V_GIF_SHIFT 9
#define V_GIF_MASK (1 << V_GIF_SHIFT)
#define V_INTR_PRIO_SHIFT 16 #define V_INTR_PRIO_SHIFT 16
#define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT)
@ -18,6 +24,8 @@
#define V_INTR_MASKING_SHIFT 24 #define V_INTR_MASKING_SHIFT 24
#define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT)
#define V_VMLOAD_VMSAVE_ENABLED_MASK (1 << 1)
#define SVM_INTERRUPT_SHADOW_MASK 1 #define SVM_INTERRUPT_SHADOW_MASK 1
#define SVM_IOIO_STR_SHIFT 2 #define SVM_IOIO_STR_SHIFT 2

View File

@ -1166,7 +1166,6 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
break; break;
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
case CPU_INTERRUPT_VIRQ: case CPU_INTERRUPT_VIRQ:
/* FIXME: this should respect TPR */
cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0); cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0);
intno = x86_ldl_phys(cs, env->vm_vmcb intno = x86_ldl_phys(cs, env->vm_vmcb
+ offsetof(struct vmcb, control.int_vector)); + offsetof(struct vmcb, control.int_vector));
@ -1174,6 +1173,7 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
"Servicing virtual hardware INT=0x%02x\n", intno); "Servicing virtual hardware INT=0x%02x\n", intno);
do_interrupt_x86_hardirq(env, intno, 1); do_interrupt_x86_hardirq(env, intno, 1);
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ; cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
env->int_ctl &= ~V_IRQ_MASK;
break; break;
#endif #endif
} }

View File

@ -358,7 +358,7 @@ do_check_protect_pse36:
return error_code; return error_code;
} }
static hwaddr get_hphys(CPUState *cs, hwaddr gphys, MMUAccessType access_type, hwaddr get_hphys(CPUState *cs, hwaddr gphys, MMUAccessType access_type,
int *prot) int *prot)
{ {
CPUX86State *env = &X86_CPU(cs)->env; CPUX86State *env = &X86_CPU(cs)->env;

View File

@ -73,7 +73,7 @@ target_ulong helper_read_crN(CPUX86State *env, int reg)
if (!(env->hflags2 & HF2_VINTR_MASK)) { if (!(env->hflags2 & HF2_VINTR_MASK)) {
val = cpu_get_apic_tpr(env_archcpu(env)->apic_state); val = cpu_get_apic_tpr(env_archcpu(env)->apic_state);
} else { } else {
val = env->v_tpr; val = env->int_ctl & V_TPR_MASK;
} }
break; break;
} }
@ -121,7 +121,14 @@ void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0); cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0);
qemu_mutex_unlock_iothread(); qemu_mutex_unlock_iothread();
} }
env->v_tpr = t0 & 0x0f; env->int_ctl = (env->int_ctl & ~V_TPR_MASK) | (t0 & V_TPR_MASK);
CPUState *cs = env_cpu(env);
if (ctl_has_irq(env)) {
cpu_interrupt(cs, CPU_INTERRUPT_VIRQ);
} else {
cpu_reset_interrupt(cs, CPU_INTERRUPT_VIRQ);
}
break; break;
default: default:
env->cr[reg] = t0; env->cr[reg] = t0;

View File

@ -41,6 +41,16 @@ static inline void svm_save_seg(CPUX86State *env, hwaddr addr,
((sc->flags >> 8) & 0xff) | ((sc->flags >> 12) & 0x0f00)); ((sc->flags >> 8) & 0xff) | ((sc->flags >> 12) & 0x0f00));
} }
/*
* VMRUN and VMLOAD canonicalizes (i.e., sign-extend to bit 63) all base
* addresses in the segment registers that have been loaded.
*/
static inline void svm_canonicalization(CPUX86State *env, target_ulong *seg_base)
{
uint16_t shift_amt = 64 - cpu_x86_virtual_addr_width(env);
*seg_base = ((((long) *seg_base) << shift_amt) >> shift_amt);
}
static inline void svm_load_seg(CPUX86State *env, hwaddr addr, static inline void svm_load_seg(CPUX86State *env, hwaddr addr,
SegmentCache *sc) SegmentCache *sc)
{ {
@ -53,6 +63,7 @@ static inline void svm_load_seg(CPUX86State *env, hwaddr addr,
sc->limit = x86_ldl_phys(cs, addr + offsetof(struct vmcb_seg, limit)); sc->limit = x86_ldl_phys(cs, addr + offsetof(struct vmcb_seg, limit));
flags = x86_lduw_phys(cs, addr + offsetof(struct vmcb_seg, attrib)); flags = x86_lduw_phys(cs, addr + offsetof(struct vmcb_seg, attrib));
sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12); sc->flags = ((flags & 0xff) << 8) | ((flags & 0x0f00) << 12);
svm_canonicalization(env, &sc->base);
} }
static inline void svm_load_seg_cache(CPUX86State *env, hwaddr addr, static inline void svm_load_seg_cache(CPUX86State *env, hwaddr addr,
@ -65,16 +76,6 @@ static inline void svm_load_seg_cache(CPUX86State *env, hwaddr addr,
sc->base, sc->limit, sc->flags); sc->base, sc->limit, sc->flags);
} }
static inline bool ctl_has_irq(uint32_t int_ctl)
{
uint32_t int_prio;
uint32_t tpr;
int_prio = (int_ctl & V_INTR_PRIO_MASK) >> V_INTR_PRIO_SHIFT;
tpr = int_ctl & V_TPR_MASK;
return (int_ctl & V_IRQ_MASK) && (int_prio >= tpr);
}
static inline bool is_efer_invalid_state (CPUX86State *env) static inline bool is_efer_invalid_state (CPUX86State *env)
{ {
if (!(env->efer & MSR_EFER_SVME)) { if (!(env->efer & MSR_EFER_SVME)) {
@ -110,6 +111,39 @@ static inline bool is_efer_invalid_state (CPUX86State *env)
return false; return false;
} }
static inline bool virtual_gif_enabled(CPUX86State *env)
{
if (likely(env->hflags & HF_GUEST_MASK)) {
return (env->features[FEAT_SVM] & CPUID_SVM_VGIF)
&& (env->int_ctl & V_GIF_ENABLED_MASK);
}
return false;
}
static inline bool virtual_vm_load_save_enabled(CPUX86State *env, uint32_t exit_code, uintptr_t retaddr)
{
uint64_t lbr_ctl;
if (likely(env->hflags & HF_GUEST_MASK)) {
if (likely(!(env->hflags2 & HF2_NPT_MASK)) || !(env->efer & MSR_EFER_LMA)) {
cpu_vmexit(env, exit_code, 0, retaddr);
}
lbr_ctl = x86_ldl_phys(env_cpu(env), env->vm_vmcb + offsetof(struct vmcb,
control.lbr_ctl));
return (env->features[FEAT_SVM] & CPUID_SVM_V_VMSAVE_VMLOAD)
&& (lbr_ctl & V_VMLOAD_VMSAVE_ENABLED_MASK);
}
return false;
}
static inline bool virtual_gif_set(CPUX86State *env)
{
return !virtual_gif_enabled(env) || (env->int_ctl & V_GIF_MASK);
}
void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend) void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
{ {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
@ -117,7 +151,6 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
target_ulong addr; target_ulong addr;
uint64_t nested_ctl; uint64_t nested_ctl;
uint32_t event_inj; uint32_t event_inj;
uint32_t int_ctl;
uint32_t asid; uint32_t asid;
uint64_t new_cr0; uint64_t new_cr0;
uint64_t new_cr3; uint64_t new_cr3;
@ -245,16 +278,6 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
env->tsc_offset = x86_ldq_phys(cs, env->vm_vmcb + env->tsc_offset = x86_ldq_phys(cs, env->vm_vmcb +
offsetof(struct vmcb, control.tsc_offset)); offsetof(struct vmcb, control.tsc_offset));
env->gdt.base = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
save.gdtr.base));
env->gdt.limit = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
save.gdtr.limit));
env->idt.base = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
save.idtr.base));
env->idt.limit = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
save.idtr.limit));
new_cr0 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr0)); new_cr0 = x86_ldq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.cr0));
if (new_cr0 & SVM_CR0_RESERVED_MASK) { if (new_cr0 & SVM_CR0_RESERVED_MASK) {
cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC()); cpu_vmexit(env, SVM_EXIT_ERR, 0, GETPC());
@ -280,11 +303,10 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
cpu_x86_update_cr3(env, new_cr3); cpu_x86_update_cr3(env, new_cr3);
env->cr[2] = x86_ldq_phys(cs, env->cr[2] = x86_ldq_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, save.cr2)); env->vm_vmcb + offsetof(struct vmcb, save.cr2));
int_ctl = x86_ldl_phys(cs, env->int_ctl = x86_ldl_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)); env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK); env->hflags2 &= ~(HF2_HIF_MASK | HF2_VINTR_MASK);
if (int_ctl & V_INTR_MASKING_MASK) { if (env->int_ctl & V_INTR_MASKING_MASK) {
env->v_tpr = int_ctl & V_TPR_MASK;
env->hflags2 |= HF2_VINTR_MASK; env->hflags2 |= HF2_VINTR_MASK;
if (env->eflags & IF_MASK) { if (env->eflags & IF_MASK) {
env->hflags2 |= HF2_HIF_MASK; env->hflags2 |= HF2_HIF_MASK;
@ -308,6 +330,10 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
R_SS); R_SS);
svm_load_seg_cache(env, env->vm_vmcb + offsetof(struct vmcb, save.ds), svm_load_seg_cache(env, env->vm_vmcb + offsetof(struct vmcb, save.ds),
R_DS); R_DS);
svm_load_seg(env, env->vm_vmcb + offsetof(struct vmcb, save.idtr),
&env->idt);
svm_load_seg(env, env->vm_vmcb + offsetof(struct vmcb, save.gdtr),
&env->gdt);
env->eip = x86_ldq_phys(cs, env->eip = x86_ldq_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, save.rip)); env->vm_vmcb + offsetof(struct vmcb, save.rip));
@ -346,12 +372,16 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
env->hflags2 |= HF2_GIF_MASK; env->hflags2 |= HF2_GIF_MASK;
if (ctl_has_irq(int_ctl)) { if (ctl_has_irq(env)) {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
cs->interrupt_request |= CPU_INTERRUPT_VIRQ; cs->interrupt_request |= CPU_INTERRUPT_VIRQ;
} }
if (virtual_gif_set(env)) {
env->hflags2 |= HF2_VGIF_MASK;
}
/* maybe we need to inject an event */ /* maybe we need to inject an event */
event_inj = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb, event_inj = x86_ldl_phys(cs, env->vm_vmcb + offsetof(struct vmcb,
control.event_inj)); control.event_inj));
@ -420,6 +450,7 @@ void helper_vmload(CPUX86State *env, int aflag)
{ {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
target_ulong addr; target_ulong addr;
int prot;
cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0, GETPC()); cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0, GETPC());
@ -429,6 +460,10 @@ void helper_vmload(CPUX86State *env, int aflag)
addr = (uint32_t)env->regs[R_EAX]; addr = (uint32_t)env->regs[R_EAX];
} }
if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMLOAD, GETPC())) {
addr = get_hphys(cs, addr, MMU_DATA_LOAD, &prot);
}
qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmload! " TARGET_FMT_lx
"\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
addr, x86_ldq_phys(cs, addr + offsetof(struct vmcb, addr, x86_ldq_phys(cs, addr + offsetof(struct vmcb,
@ -446,6 +481,7 @@ void helper_vmload(CPUX86State *env, int aflag)
env->lstar = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.lstar)); env->lstar = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.lstar));
env->cstar = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.cstar)); env->cstar = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.cstar));
env->fmask = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.sfmask)); env->fmask = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.sfmask));
svm_canonicalization(env, &env->kernelgsbase);
#endif #endif
env->star = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.star)); env->star = x86_ldq_phys(cs, addr + offsetof(struct vmcb, save.star));
env->sysenter_cs = x86_ldq_phys(cs, env->sysenter_cs = x86_ldq_phys(cs,
@ -454,12 +490,14 @@ void helper_vmload(CPUX86State *env, int aflag)
save.sysenter_esp)); save.sysenter_esp));
env->sysenter_eip = x86_ldq_phys(cs, addr + offsetof(struct vmcb, env->sysenter_eip = x86_ldq_phys(cs, addr + offsetof(struct vmcb,
save.sysenter_eip)); save.sysenter_eip));
} }
void helper_vmsave(CPUX86State *env, int aflag) void helper_vmsave(CPUX86State *env, int aflag)
{ {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
target_ulong addr; target_ulong addr;
int prot;
cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0, GETPC()); cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0, GETPC());
@ -469,6 +507,10 @@ void helper_vmsave(CPUX86State *env, int aflag)
addr = (uint32_t)env->regs[R_EAX]; addr = (uint32_t)env->regs[R_EAX];
} }
if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMSAVE, GETPC())) {
addr = get_hphys(cs, addr, MMU_DATA_STORE, &prot);
}
qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmsave! " TARGET_FMT_lx qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmsave! " TARGET_FMT_lx
"\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n",
addr, x86_ldq_phys(cs, addr, x86_ldq_phys(cs,
@ -503,13 +545,25 @@ void helper_vmsave(CPUX86State *env, int aflag)
void helper_stgi(CPUX86State *env) void helper_stgi(CPUX86State *env)
{ {
cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0, GETPC()); cpu_svm_check_intercept_param(env, SVM_EXIT_STGI, 0, GETPC());
env->hflags2 |= HF2_GIF_MASK;
if (virtual_gif_enabled(env)) {
env->int_ctl |= V_GIF_MASK;
env->hflags2 |= HF2_VGIF_MASK;
} else {
env->hflags2 |= HF2_GIF_MASK;
}
} }
void helper_clgi(CPUX86State *env) void helper_clgi(CPUX86State *env)
{ {
cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0, GETPC()); cpu_svm_check_intercept_param(env, SVM_EXIT_CLGI, 0, GETPC());
env->hflags2 &= ~HF2_GIF_MASK;
if (virtual_gif_enabled(env)) {
env->int_ctl &= ~V_GIF_MASK;
env->hflags2 &= ~HF2_VGIF_MASK;
} else {
env->hflags2 &= ~HF2_GIF_MASK;
}
} }
bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type) bool cpu_svm_has_intercept(CPUX86State *env, uint32_t type)
@ -654,7 +708,6 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
void do_vmexit(CPUX86State *env) void do_vmexit(CPUX86State *env)
{ {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
uint32_t int_ctl;
if (env->hflags & HF_INHIBIT_IRQ_MASK) { if (env->hflags & HF_INHIBIT_IRQ_MASK) {
x86_stl_phys(cs, x86_stl_phys(cs,
@ -697,16 +750,8 @@ void do_vmexit(CPUX86State *env)
env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]); env->vm_vmcb + offsetof(struct vmcb, save.cr3), env->cr[3]);
x86_stq_phys(cs, x86_stq_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]); env->vm_vmcb + offsetof(struct vmcb, save.cr4), env->cr[4]);
int_ctl = x86_ldl_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));
int_ctl &= ~(V_TPR_MASK | V_IRQ_MASK);
int_ctl |= env->v_tpr & V_TPR_MASK;
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
int_ctl |= V_IRQ_MASK;
}
x86_stl_phys(cs, x86_stl_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), int_ctl); env->vm_vmcb + offsetof(struct vmcb, control.int_ctl), env->int_ctl);
x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rflags), x86_stq_phys(cs, env->vm_vmcb + offsetof(struct vmcb, save.rflags),
cpu_compute_eflags(env)); cpu_compute_eflags(env));
@ -729,6 +774,7 @@ void do_vmexit(CPUX86State *env)
env->intercept = 0; env->intercept = 0;
env->intercept_exceptions = 0; env->intercept_exceptions = 0;
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ; cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
env->int_ctl = 0;
env->tsc_offset = 0; env->tsc_offset = 0;
env->gdt.base = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb, env->gdt.base = x86_ldq_phys(cs, env->vm_hsave + offsetof(struct vmcb,
@ -796,6 +842,7 @@ void do_vmexit(CPUX86State *env)
env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 0); env->vm_vmcb + offsetof(struct vmcb, control.event_inj), 0);
env->hflags2 &= ~HF2_GIF_MASK; env->hflags2 &= ~HF2_GIF_MASK;
env->hflags2 &= ~HF2_VGIF_MASK;
/* FIXME: Resets the current ASID register to zero (host ASID). */ /* FIXME: Resets the current ASID register to zero (host ASID). */
/* Clears the V_IRQ and V_INTR_MASKING bits inside the processor. */ /* Clears the V_IRQ and V_INTR_MASKING bits inside the processor. */

View File

@ -2,6 +2,7 @@
specific_ss.add(files('control-target.c')) specific_ss.add(files('control-target.c'))
trace_events_files = [] trace_events_files = []
dtrace = find_program('dtrace', required: 'CONFIG_TRACE_DTRACE' in config_host)
foreach dir : [ '.' ] + trace_events_subdirs foreach dir : [ '.' ] + trace_events_subdirs
trace_events_file = meson.source_root() / dir / 'trace-events' trace_events_file = meson.source_root() / dir / 'trace-events'
trace_events_files += [ trace_events_file ] trace_events_files += [ trace_events_file ]
@ -39,13 +40,13 @@ foreach dir : [ '.' ] + trace_events_subdirs
trace_dtrace_h = custom_target(fmt.format('trace-dtrace', 'h'), trace_dtrace_h = custom_target(fmt.format('trace-dtrace', 'h'),
output: fmt.format('trace-dtrace', 'h'), output: fmt.format('trace-dtrace', 'h'),
input: trace_dtrace, input: trace_dtrace,
command: [ 'dtrace', '-DSTAP_SDT_V2', '-o', '@OUTPUT@', '-h', '-s', '@INPUT@' ]) command: [ dtrace, '-DSTAP_SDT_V2', '-o', '@OUTPUT@', '-h', '-s', '@INPUT@' ])
trace_ss.add(trace_dtrace_h) trace_ss.add(trace_dtrace_h)
if host_machine.system() != 'darwin' if host_machine.system() != 'darwin'
trace_dtrace_o = custom_target(fmt.format('trace-dtrace', 'o'), trace_dtrace_o = custom_target(fmt.format('trace-dtrace', 'o'),
output: fmt.format('trace-dtrace', 'o'), output: fmt.format('trace-dtrace', 'o'),
input: trace_dtrace, input: trace_dtrace,
command: [ 'dtrace', '-DSTAP_SDT_V2', '-o', '@OUTPUT@', '-G', '-s', '@INPUT@' ]) command: [ dtrace, '-DSTAP_SDT_V2', '-o', '@OUTPUT@', '-G', '-s', '@INPUT@' ])
trace_ss.add(trace_dtrace_o) trace_ss.add(trace_dtrace_o)
endif endif

View File

@ -105,8 +105,6 @@ if config_host.has_key('CONFIG_SPICE') and config_host.has_key('CONFIG_GIO')
ui_modules += {'spice-app': spice_ss} ui_modules += {'spice-app': spice_ss}
endif endif
keymap_gen = find_program('keycodemapdb/tools/keymap-gen')
keymaps = [ keymaps = [
['atset1', 'qcode'], ['atset1', 'qcode'],
['linux', 'qcode'], ['linux', 'qcode'],
@ -134,7 +132,7 @@ if have_system or xkbcommon.found()
output: output, output: output,
capture: true, capture: true,
input: files('keycodemapdb/data/keymaps.csv'), input: files('keycodemapdb/data/keymaps.csv'),
command: [python.full_path(), files('keycodemapdb/tools/keymap-gen'), command: [python, files('keycodemapdb/tools/keymap-gen'),
'code-map', 'code-map',
'--lang', 'glib2', '--lang', 'glib2',
'--varname', 'qemu_input_map_@0@_to_@1@'.format(e[0], e[1]), '--varname', 'qemu_input_map_@0@_to_@1@'.format(e[0], e[1]),

View File

@ -537,9 +537,28 @@ static void *qemu_thread_start(void *args)
QEMU_TSAN_ANNOTATE_THREAD_NAME(qemu_thread_args->name); QEMU_TSAN_ANNOTATE_THREAD_NAME(qemu_thread_args->name);
g_free(qemu_thread_args->name); g_free(qemu_thread_args->name);
g_free(qemu_thread_args); g_free(qemu_thread_args);
/*
* GCC 11 with glibc 2.17 on PowerPC reports
*
* qemu-thread-posix.c:540:5: error: __sigsetjmp accessing 656 bytes
* in a region of size 528 [-Werror=stringop-overflow=]
* 540 | pthread_cleanup_push(qemu_thread_atexit_notify, NULL);
* | ^~~~~~~~~~~~~~~~~~~~
*
* which is clearly nonsense.
*/
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
pthread_cleanup_push(qemu_thread_atexit_notify, NULL); pthread_cleanup_push(qemu_thread_atexit_notify, NULL);
r = start_routine(arg); r = start_routine(arg);
pthread_cleanup_pop(1); pthread_cleanup_pop(1);
#pragma GCC diagnostic pop
return r; return r;
} }