Compare commits

...
106 Commits
Author SHA1 Message Date
Michael Tokarev ccaea6b265 Update version for 10.1.2 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-20 12:41:23 +03:00
Philippe Mathieu-Daudé acef0da910 linux-user/microblaze: Fix little-endianness binary
MicroBlaze CPU model has a "little-endian" property, pointing to
the @endi internal field. Commit c36ec3a965 ("hw/microblaze:
Explicit CPU endianness") took care of having all MicroBlaze
boards with an explicit default endianness, so later commit
415aae543e ("target/microblaze: Consider endianness while
translating code") could infer the endianness at runtime from
the @endi field, and not a compile time via the TARGET_BIG_ENDIAN
definition. Doing so, we forgot to make the endianness explicit
on user emulation, so there all CPUs are started with the default
"little-endian=off" value, leading to breaking support for little
endian binaries:

  $ readelf -h ./hello-world-mbel
  ELF Header:
    Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
    Class:                             ELF32
    Data:                              2's complement, little endian

  $ qemu-microblazeel ./hello-world-mbel
  qemu: uncaught target signal 11 (Segmentation fault) - core dumped
  Segmentation fault (core dumped)

Fix by restoring the previous behavior of starting with the
builtin endianness of the binary:

  $ qemu-microblazeel ./hello-world-mbel
  Hello World

Cc: qemu-stable@nongnu.org
Fixes: 415aae543e ("target/microblaze: Consider endianness while translating code")
Reported-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
Message-Id: <20251006173350.17455-1-philmd@linaro.org>
(cherry picked from commit 91fc6d8101)
(Mjt: adapt for missing v10.1.0-38-gaf880af8d4
 "linux-user: Move get_elf_cpu_model to target/elfload.c")
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-17 09:02:53 +03:00
Gabriel Brookman e80709183c target/hppa: correct size bit parity for fmpyadd
For the fmpyadd instruction on the hppa architecture, there is a bit
used to specify whether the instruction is operating on a 32 bit or
64 bit floating point register. For most instructions, such a bit is 0
when operating on the smaller register and 1 when operating on the
larger register. However, according to page 6-57 of the PA-RISC 1.1
Architecture and Instruction Set Reference Manual, this convention is
reversed for the fmpyadd instruction specifically, meaning the bit is
1 for operations on 32 bit registers and 0 for 64 bit registers. See
also page 6-18 (fig. 6-8) and 6-19 (table 6-16), where the f field
for FMPYADD and FMPYSUB is documented. Previously, QEMU decoded this
operation as operating on the other size of register, leading to bugs
when translating the fmpyadd instruction. This patch fixes that issue.

Reported-by: Andreas Hüttel <andreas.huettel@ur.de>
Signed-off-by: Gabriel Brookman <brookmangabriel@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3096
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Acked-by: Helge Deller <deller@gmx.de>
Message-ID: <20251009-hppa-correct-fmpyadd-size-bit-decoding-v1-1-f63bb6c3290c@gmail.com>
[PMD: Add documentation refs mentioned by Andreas K. Huettel]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit cea82f8cdd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-17 08:53:55 +03:00
Richard Henderson e14614fe78 accel/tcg: Hoist first page lookup above pointer_wrap
For strict alignment targets we registered cpu_pointer_wrap_notreached,
but generic code used it before recognizing the alignment exception.
Hoist the first page lookup, so that the alignment exception happens first.

Cc: qemu-stable@nongnu.org
Buglink: https://bugs.debian.org/1112285
Fixes: a4027ed7d4 ("target: Use cpu_pointer_wrap_notreached for strict align targets")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit ec03dd9723)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-15 07:42:34 +03:00
Paolo Bonzini 95c1555cd8 target/i386: user: do not set up a valid LDT on reset
In user-mode emulation, QEMU uses the default setting of the LDT base
and limit, which places it at the bottom 64K of virtual address space.
However, by default there is no LDT at all in Linux processes, and
therefore the limit should be 0.

This is visible as a NULL pointer dereference in LSL and LAR instructions
when they try to read the LDT at an unmapped address.

Resolves: #1376
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 58aa1d08bb)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-15 07:36:30 +03:00
Paolo Bonzini 4e58c5bf0c async: access bottom half flags with qatomic_read
Running test-aio-multithread under TSAN reveals data races on bh->flags.
Because bottom halves may be scheduled or canceled asynchronously,
without taking a lock, adjust aio_compute_bh_timeout() and aio_ctx_check()
to use a relaxed read to access the flags.

Use an acquire load to ensure that anything that was written prior to
qemu_bh_schedule() is visible.

Closes: https://gitlab.com/qemu-project/qemu/-/issues/2749
Closes: https://gitlab.com/qemu-project/qemu/-/issues/851
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5142397c79)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-15 07:35:35 +03:00
Paolo Bonzini f316e90a82 target/i386: fix access to the T bit of the TSS
The T bit is bit 0 of the 16-bit word at offset 100 of the TSS.  However,
accessing it with a 32-bit word is not really correct, because bytes
102-103 contain the I/O map base address (relative to the base of the
TSS) and bits 1-15 are reserved.  In particular, any task switch to a TSS that
has a nonzero I/O map base address is broken.

This fixes the eventinj and taskswitch tests in kvm-unit-tests.

Cc: qemu-stable@nongnu.org
Fixes: ad441b8b79 ("target/i386: implement TSS trap bit", 2025-05-12)
Reported-by: Thomas Huth <thuth@redhat.com>
Closes: https://gitlab.com/qemu-project/qemu/-/issues/3101
Tested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 0d22b621b7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-15 07:34:45 +03:00
Thomas Ogrisegg b70ff85fef target/i386: fix x86_64 pushw op
For x86_64 a 16 bit push op (pushw) of a memory address would generate
a 64 bit store on the stack instead of a 16 bit store.

For example:
        pushw (%rax)

behaves like
        pushq (%rax)

which is incorrect.

This patch fixes that.

Signed-off-by: Thomas Ogrisegg <tom-bugs-qemu@fnord.at>
Link: https://lore.kernel.org/r/20250715210307.GA1115@x1.fnord.at
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 5a2faa0a0a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-15 07:33:12 +03:00
YiFei Zhu 68630e6701 i386/tcg/smm_helper: Properly apply DR values on SMM entry / exit
do_smm_enter and helper_rsm sets the env->dr, but does not sync the
values with cpu_x86_update_dr7. A malicious kernel may control the
instruction pointer in SMM by setting a breakpoint on the SMI
entry point, and after do_smm_enter cpu->breakpoints contains the
stale breakpoint; and because IDT is not reloaded upon SMI entry,
the debug exception handler controlled by the malicious kernel
is invoked.

Fixes: 01df040b52 ("x86: Debug register emulation (Jan Kiszka)")
Reported-by: unvariant.winter@gmail.com
Signed-off-by: YiFei Zhu <zhuyifei@google.com>
Link: https://lore.kernel.org/r/2bacb9b24e9d337dbe48791aa25d349eb9c52c3a.1758794468.git.zhuyifei@google.com
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit cdba90ac1b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-15 07:32:24 +03:00
Paolo Bonzini cf8dff8d9f i386/cpu: Prevent delivering SIPI during SMM in TCG mode
[commit message by YiFei Zhu]

A malicious kernel may control the instruction pointer in SMM in a
multi-processor VM by sending a sequence of IPIs via APIC:

CPU0			CPU1
IPI(CPU1, MODE_INIT)
			x86_cpu_exec_reset()
			apic_init_reset()
			s->wait_for_sipi = true
IPI(CPU1, MODE_SMI)
			do_smm_enter()
			env->hflags |= HF_SMM_MASK;
IPI(CPU1, MODE_STARTUP, vector)
			do_cpu_sipi()
			apic_sipi()
			/* s->wait_for_sipi check passes */
			cpu_x86_load_seg_cache_sipi(vector)

A different sequence, SMI INIT SIPI, is also buggy in TCG because
INIT is not blocked or latched during SMM. However, it is not
vulnerable to an instruction pointer control in the same way because
x86_cpu_exec_reset clears env->hflags, exiting SMM.

Fixes: a9bad65d2c ("target-i386: wake up processors that receive an SMI")
Analyzed-by: YiFei Zhu <zhuyifei@google.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit df32e5c568)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-15 07:31:18 +03:00
Jon Kohler 9ca80ff527 i386/kvm: Expose ARCH_CAP_FB_CLEAR when invulnerable to MDS
Newer Intel hardware (Sapphire Rapids and higher) sets multiple MDS
immunity bits in MSR_IA32_ARCH_CAPABILITIES but lacks the hardware-level
MSR_ARCH_CAP_FB_CLEAR (bit 17):
    ARCH_CAP_MDS_NO
    ARCH_CAP_TAA_NO
    ARCH_CAP_PSDP_NO
    ARCH_CAP_FBSDP_NO
    ARCH_CAP_SBDR_SSDP_NO

This prevents VMs with fb-clear=on from migrating from older hardware
(Cascade Lake, Ice Lake) to newer hardware, limiting live migration
capabilities. Note fb-clear was first introduced in v8.1.0 [1].

Expose MSR_ARCH_CAP_FB_CLEAR for MDS-invulnerable systems to enable
seamless migration between hardware generations.

Note: There is no impact when a guest migrates to newer hardware as
the existing bit combinations already mark the host as MMIO-immune and
disable FB_CLEAR operations in the kernel (see Linux's
arch_cap_mmio_immune() and vmx_update_fb_clear_dis()). See kernel side
discussion for [2] for additional context.

[1] 22e1094ca8 ("target/i386: add support for FB_CLEAR feature")
[2] https://patchwork.kernel.org/project/kvm/patch/20250401044931.793203-1-jon@nutanix.com/

Cc: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Jon Kohler <jon@nutanix.com>
Link: https://lore.kernel.org/r/20251008202557.4141285-1-jon@nutanix.com
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 00001a22d1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-15 07:30:47 +03:00
Mathias Krause 19ab9f3102 target/i386: Fix CR2 handling for non-canonical addresses
Commit 3563362ddf ("target/i386: Introduce structures for mmu_translate")
accidentally modified CR2 for non-canonical address exceptions while these
should lead to a #GP / #SS instead -- without changing CR2.

Fix that.

A KUT test for this was submitted as [1].

[1] https://lore.kernel.org/kvm/20250612141637.131314-1-minipli@grsecurity.net/

Fixes: 3563362ddf ("target/i386: Introduce structures for mmu_translate")
Signed-off-by: Mathias Krause <minipli@grsecurity.net>
Link: https://lore.kernel.org/r/20250612142155.132175-1-minipli@grsecurity.net
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit df9a3372dd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-15 07:29:25 +03:00
Richard W.M. Jones f0839fec94 block/curl.c: Use explicit long constants in curl_easy_setopt calls
curl_easy_setopt takes a variable argument that depends on what
CURLOPT you are setting.  Some require a long constant.  Passing a
plain int constant is potentially wrong on some platforms.

With warnings enabled, multiple warnings like this were printed:

../block/curl.c: In function ‘curl_init_state’:
../block/curl.c:474:13: warning: call to ‘_curl_easy_setopt_err_long’ declared with attribute warning: curl_easy_setopt expects a long argument [-Wattribute-warning]
  474 |             curl_easy_setopt(state->curl, CURLOPT_AUTOREFERER, 1) ||
      |             ^

Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Chenxi Mao <maochenxi@bosc.ac.cn>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20251009141026.4042021-2-rjones@redhat.com>
(cherry picked from commit ed26056d90)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-14 17:57:39 +03:00
Hector Cao 400eeeefee target/i386: add compatibility property for pdcm feature
The pdcm feature is supposed to be disabled when PMU is not
available. Up until v10.1, pdcm feature is enabled even when PMU
is off. This behavior has been fixed but this change breaks the
migration of VMs that are run with QEMU < 10.0 and expect the pdcm
feature to be enabled on the destination host.

This commit restores the legacy behavior for machines with version
prior to 10.1 to allow the migration from older QEMU to QEMU 10.1.

Signed-off-by: Hector Cao <hector.cao@canonical.com>
Link: https://lore.kernel.org/r/20250910115733.21149-3-hector.cao@canonical.com
Fixes: e68ec29809 ("i386/cpu: Move adjustment of CPUID_EXT_PDCM before feature_dependencies[] check", 2025-06-20)
[Move property from migration object to CPU. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 6529f31e0d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-14 17:33:16 +03:00
Paolo Bonzini 608a19009a target/i386: add compatibility property for arch_capabilities
Prior to v10.1, if requested by user, arch-capabilities is always on
despite the fact that CPUID advertises it to be off/unvailable.
This causes a migration issue for VMs that are run on a machine
without arch-capabilities and expect this feature to be present
on the destination host with QEMU 10.1.

Add a compatibility property to restore the legacy behavior for all
machines with version prior to 10.1.

To preserve the functionality (added by 10.1) of turning off
ARCH_CAPABILITIES where Windows does not like it, use directly
the guest CPU vendor: x86_cpu_get_supported_feature_word is not
KVM-specific and therefore should not necessarily use the host
CPUID.

Co-authored-by: Hector Cao <hector.cao@canonical.com>
Signed-off-by: Hector Cao <hector.cao@canonical.com>
Fixes: d3a24134e3 ("target/i386: do not expose ARCH_CAPABILITIES on AMD CPU", 2025-07-17)
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit e9efa4a771)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-14 17:33:12 +03:00
Max Chou be9075c7c9 target/riscv: rvv: Fix vslide1[up|down].vx unexpected result when XLEN=32 and SEW=64
When XLEN is 32 and SEW is 64, the original implementation of
vslide1up.vx and vslide1down.vx helper functions fills the 32-bit value
of rs1 into the first element of the destination vector register (rd),
which is a 64-bit element.

This commit attempted to resolve the issue by extending the rs1 value
to 64 bits during the TCG translation phase to ensure that the helper
functions won't lost the higer 32 bits.

Signed-off-by: Max Chou <max.chou@sifive.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250124073325.2467664-1-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 81d1885dcc)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-09 08:06:07 +03:00
Jim Shu 3a184ef664 target/riscv: Fix ssamoswap error handling
Follow the RISC-V CFI v1.0 spec [1] to fix the exception type
when ssamoswap is disabled by xSSE.

[1] RISC-V CFI spec v1.0, ch2.7 Atomic Swap from a Shadow Stack Location

Signed-off-by: Jim Shu <jim.shu@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250924074818.230010-4-jim.shu@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 0b16c7b6a8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-09 08:05:12 +03:00
Jim Shu 45a31df407 target/riscv: Fix SSP CSR error handling in VU/VS mode
In VU/VS mode, accessing $ssp CSR will trigger the virtual instruction
exception instead of illegal instruction exception if SSE is disabled
via xenvcfg CSRs.

This is from RISC-V CFI v1.0 spec ch2.2.4. Shadow Stack Pointer

Signed-off-by: Jim Shu <jim.shu@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250924074818.230010-3-jim.shu@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 84c1605b76)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-09 08:05:12 +03:00
Jim Shu 1cea32f332 target/riscv: Fix the mepc when sspopchk triggers the exception
When sspopchk is in the middle of TB and triggers the SW check
exception, it should update PC from gen_update_pc(). If not, RISC-V mepc
CSR will get wrong PC address which is still at the start of TB.

Signed-off-by: Jim Shu <jim.shu@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250924074818.230010-2-jim.shu@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit c851052a77)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-09 08:05:12 +03:00
Peter Maydell 19a3344754 target/arm: Don't set HCR.RW for AArch32 only CPUs
In commit 39ec3fc030 we fixed a bug where we were not implementing
HCR_EL2.RW as RAO/WI for CPUs where EL1 doesn't support AArch32.
However, we got the condition wrong, so we now set this bit even on
CPUs which have no AArch64 support at all.  This is wrong because the
AArch32 HCR register defines this bit as RES0.

Correct the condition we use for forcing HCR_RW to be set.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3128
Fixes: 39ec3fc030 ("target/arm: HCR_EL2.RW should be RAO/WI if EL1 doesn't support AArch32")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250925115723.1293233-1-peter.maydell@linaro.org
(cherry picked from commit a23e719ca8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-08 18:44:30 +03:00
Stefan Hajnoczi 3a27ff6cb9 pcie_sriov: make pcie_sriov_pf_exit() safe on non-SR-IOV devices
Commit 3f9cfaa92c ("virtio-pci: Implement SR-IOV PF") added an
unconditional call from virtio_pci_exit() to pcie_sriov_pf_exit().

pcie_sriov_pf_exit() reads from the SR-IOV Capability in Configuration
Space:

  uint8_t *cfg = dev->config + dev->exp.sriov_cap;
  ...
  unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This results in undefined behavior when dev->exp.sriov_cap is 0 because
this is not an SR-IOV device. For example, unparent_vfs() segfaults when
total_vfs happens to be non-zero.

Fix this by returning early from pcie_sriov_pf_exit() when
dev->exp.sriov_cap is 0 because this is not an SR-IOV device.

Cc: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Cc: Michael S. Tsirkin <mst@redhat.com>
Reported-by: Qing Wang <qinwang@redhat.com>
Buglink: https://issues.redhat.com/browse/RHEL-116443
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Fixes: cab1398a60 ("pcie_sriov: Reuse SR-IOV VF device instances")
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20250924155153.579495-1-stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit bab681f752)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-08 17:52:33 +03:00
nanliu 30ff0b5651 docs/devel: Correct uefi-vars-x64 device name
The documentation for UEFI variable storage in uefi-vars.rst
incorrectly listed the device name as `uefi-vars-x86`.

The correct device name as implemented in the source code is
`uefi-vars-x64`.

This commit updates the documentation to use the correct name,
aligning it with the implementation.

Signed-off-by: Nana Liu <nanliu@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit f65918497c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-08 17:25:51 +03:00
ShengYi Hung 3870276618 hid: fix incorrect return value for hid
The return value of hid_keyboard_write is used to set the packet's actual_length
and pass to xhci directly to allow guest know how many byte actually processed.
Therefore, return 1 to indicate a successful transfer or it will be
considered as a wrong xfer.

Signed-off-by: ShengYi Hung <aokblast@FreeBSD.org>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 1c0f5142d9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-08 17:24:44 +03:00
Damien Bergamini c3ae83117d pcie_sriov: Fix broken MMIO accesses from SR-IOV VFs
Starting with commit cab1398a60, SR-IOV VFs are realized as soon as
pcie_sriov_pf_init() is called.  Because pcie_sriov_pf_init() must be
called before pcie_sriov_pf_init_vf_bar(), the VF BARs types won't be
known when the VF realize function calls pcie_sriov_vf_register_bar().

This breaks the memory regions of the VFs (for instance with igbvf):

$ lspci
...
    Region 0: Memory at 281a00000 (64-bit, prefetchable) [virtual] [size=16K]
    Region 3: Memory at 281a20000 (64-bit, prefetchable) [virtual] [size=16K]

$ info mtree
...
address-space: pci_bridge_pci_mem
  0000000000000000-ffffffffffffffff (prio 0, i/o): pci_bridge_pci
    0000000081a00000-0000000081a03fff (prio 1, i/o): igbvf-mmio
    0000000081a20000-0000000081a23fff (prio 1, i/o): igbvf-msix

and causes MMIO accesses to fail:

    Invalid write at addr 0x281A01520, size 4, region '(null)', reason: rejected
    Invalid read at addr 0x281A00C40, size 4, region '(null)', reason: rejected

To fix this, VF BARs are now registered with pci_register_bar() which
has a type parameter and pcie_sriov_vf_register_bar() is removed.

Fixes: cab1398a60 ("pcie_sriov: Reuse SR-IOV VF device instances")
Signed-off-by: Damien Bergamini <damien.bergamini@eviden.com>
Signed-off-by: Clement Mathieu--Drif <clement.mathieu--drif@eviden.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20250901151314.1038020-1-clement.mathieu--drif@eviden.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 2e54e5fda7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-08 13:43:17 +03:00
Michael Tokarev 339768517a Update version for 10.1.1 release
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-08 10:54:47 +03:00
Thomas Huth 677d73bde7 tests/functional/aarch64: Fix assets of test_hotplug_pci
The old bookworm URLs don't work anymore, resulting in a 404 error
now. Let's update the test to Debian Trixie to get it going again.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 769acb2a1e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-05 19:10:50 +03:00
Peter Maydell 7bd98c65e0 physmem: Destroy all CPU AddressSpaces on unrealize
When we unrealize a CPU object (which happens on vCPU hot-unplug), we
should destroy all the AddressSpace objects we created via calls to
cpu_address_space_init() when the CPU was realized.

Commit 24bec42f3d added a function to do this for a specific
AddressSpace, but did not add any places where the function was
called.

Since we always want to destroy all the AddressSpaces on unrealize,
regardless of the target architecture, we don't need to try to keep
track of how many are still undestroyed, or make the target
architecture code manually call a destroy function for each AS it
created.  Instead we can adjust the function to always completely
destroy the whole cpu->ases array, and arrange for it to be called
during CPU unrealize as part of the common code.

Without this fix, AddressSanitizer will report a leak like this
from a run where we hot-plugged and then hot-unplugged an x86 KVM
vCPU:

Direct leak of 416 byte(s) in 1 object(s) allocated from:
    #0 0x5b638565053d in calloc (/data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/qemu-system-x86_64+0x1ee153d) (BuildId: c1cd6022b195142106e1bffeca23498c2b752bca)
    #1 0x7c28083f77b1 in g_malloc0 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x637b1) (BuildId: 1eb6131419edb83b2178b682829a6913cf682d75)
    #2 0x5b6386999c7c in cpu_address_space_init /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../system/physmem.c:797:25
    #3 0x5b638727f049 in kvm_cpu_realizefn /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../target/i386/kvm/kvm-cpu.c:102:5
    #4 0x5b6385745f40 in accel_cpu_common_realize /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../accel/accel-common.c:101:13
    #5 0x5b638568fe3c in cpu_exec_realizefn /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../hw/core/cpu-common.c:232:10
    #6 0x5b63874a2cd5 in x86_cpu_realizefn /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../target/i386/cpu.c:9321:5
    #7 0x5b6387a0469a in device_set_realized /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../hw/core/qdev.c:494:13
    #8 0x5b6387a27d9e in property_set_bool /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../qom/object.c:2375:5
    #9 0x5b6387a2090b in object_property_set /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../qom/object.c:1450:5
    #10 0x5b6387a35b05 in object_property_set_qobject /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../qom/qom-qobject.c:28:10
    #11 0x5b6387a21739 in object_property_set_bool /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../qom/object.c:1520:15
    #12 0x5b63879fe510 in qdev_realize /data_nvme1n1/linaro/qemu-from-laptop/qemu/build/x86-tgts-asan/../../hw/core/qdev.c:276:12

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2517
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Link: https://lore.kernel.org/r/20250929144228.1994037-4-peter.maydell@linaro.org
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 300a87c502)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-05 09:40:28 +03:00
Peter Xu ded5c62454 memory: New AS helper to serialize destroy+free
If an AddressSpace has been created in its own allocated
memory, cleaning it up requires first destroying the AS
and then freeing the memory. Doing this doesn't work:

    address_space_destroy(as);
    g_free_rcu(as, rcu);

because both address_space_destroy() and g_free_rcu()
try to use the same 'rcu' node in the AddressSpace struct
and the address_space_destroy hook gets overwritten.

Provide a new address_space_destroy_free() function which
will destroy the AS and then free the memory it uses, all
in one RCU callback.

(CC to stable because the next commit needs this function.)

Cc: qemu-stable@nongnu.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Link: https://lore.kernel.org/r/20250929144228.1994037-3-peter.maydell@linaro.org
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 041600e23f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-05 09:40:28 +03:00
Peter Maydell 977ffc7abc include/system/memory.h: Clarify address_space_destroy() behaviour
address_space_destroy() doesn't actually immediately destroy the AS;
it queues it to be destroyed via RCU. This means you can't g_free()
the memory the AS struct is in until that has happened.

Clarify this in the documentation.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Link: https://lore.kernel.org/r/20250929144228.1994037-2-peter.maydell@linaro.org
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 9e7bfda490)
(Mjt: this is just a comment fix, but it makes subsequent changes to apply c
leanly)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-05 09:40:23 +03:00
Juraj Marcin 109f336448 migration: Fix state transition in postcopy_start() error handling
Commit 4881411136 ("migration: Always set DEVICE state") introduced
DEVICE state to postcopy, which moved the actual state transition that
leads to POSTCOPY_ACTIVE.

However, the error handling part of the postcopy_start() function still
expects the state POSTCOPY_ACTIVE, but depending on where an error
happens, now the state can be either ACTIVE, DEVICE or CANCELLING, but
never POSTCOPY_ACTIVE, as this transition now happens just before a
successful return from the function.

Instead, accept any state except CANCELLING when transitioning to FAILED
state.

Cc: qemu-stable@nongnu.org
Fixes: 4881411136 ("migration: Always set DEVICE state")
Signed-off-by: Juraj Marcin <jmarcin@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Link: https://lore.kernel.org/r/20250826115145.871272-1-jmarcin@redhat.com
Signed-off-by: Peter Xu <peterx@redhat.com>
(cherry picked from commit 725a9e5f78)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-05 09:35:18 +03:00
Max Chou d7f661905b target/riscv: rvv: Modify minimum VLEN according to enabled vector extensions
According to the RISC-V unprivileged specification, the VLEN should be greater
or equal to the ELEN. This commit modifies the minimum VLEN based on the vector
extensions and introduces a check rule for VLEN and ELEN.

  Extension     Minimum VLEN
* V                      128
* Zve64[d|f|x]            64
* Zve32[f|x]              32

Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250923090729.1887406-3-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit be50ff3a73)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-04 10:43:20 +03:00
Max Chou 8650b5597a target/riscv: rvv: Replace checking V by checking Zve32x
The Zve32x extension will be applied by the V and Zve* extensions.
Therefore we can replace the original V checking with Zve32x checking for both
the V and Zve* extensions.

Signed-off-by: Max Chou <max.chou@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250923090729.1887406-2-max.chou@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit ae4a37f578)
(Mjt: drop the MonitorDef change due to missing v10.1.0-850-ge06d209aa6 "target/riscv: implement MonitorDef HMP API")
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-04 10:41:27 +03:00
vhaudiquet e3641f4ecf target/riscv: Fix endianness swap on compressed instructions
Three instructions were not using the endianness swap flag, which resulted in a bug on big-endian architectures.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3131
Buglink: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/2123828

Fixes: e0a3054f18 ("target/riscv: add support for Zcb extension")
Signed-off-by: Valentin Haudiquet <valentin.haudiquet@canonical.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Anton Johansson <anjo@rev.ng>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250929115543.1648157-1-valentin.haudiquet@canonical.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit b25133d38f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-04 10:34:22 +03:00
Guo Ren (Alibaba DAMO Academy) b01f2eccf2 hw/riscv/riscv-iommu: Fixup PDT Nested Walk
Current implementation is wrong when iohgatp != bare. The RISC-V
IOMMU specification has defined that the PDT is based on GPA, not
SPA. So this patch fixes the problem, making PDT walk correctly
when the G-stage table walk is enabled.

Fixes: 0c54acb824 ("hw/riscv: add RISC-V IOMMU base emulation")
Cc: qemu-stable@nongnu.org
Cc: Sebastien Boeuf <seb@rivosinc.com>
Cc: Tomasz Jeznach <tjeznach@rivosinc.com>
Reviewed-by: Weiwei Li <liwei1518@gmail.com>
Reviewed-by: Nutty Liu <liujingqi@lanxincomputing.com>
Signed-off-by: Guo Ren (Alibaba DAMO Academy) <guoren@kernel.org>
Tested-by: Chen Pei <cp0613@linux.alibaba.com>
Tested-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Message-ID: <20250913041233.972870-1-guoren@kernel.org>
[ Changes by AF:
 - Add braces to if statements
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 15abfced80)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-04 10:33:44 +03:00
Vladimir Isaev c65d1a6b13 target/riscv: do not use translator_ldl in opcode_at
opcode_at is used only in semihosting checks to match opcodes with expected
pattern.

This is not a translator and if we got following assert if page is not in TLB:
qemu-system-riscv64: ../accel/tcg/translator.c:363: record_save: Assertion
`offset == db->record_start + db->record_len' failed.

Fixes: 1f9c446233 ("target/riscv: Use translator_ld* for everything")
Signed-off-by: Vladimir Isaev <vladimir.isaev@syntacore.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250815140633.86920-1-vladimir.isaev@syntacore.com>
[ Changes by AF:
 - Fixup header includes after rebase
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit a86d3352ab)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-04 10:29:29 +03:00
stove 7c7694d73c target/riscv: use riscv_csrr in riscv_csr_read
Commit 38c83e8d3a ("target/riscv: raise an exception when CSRRS/CSRRC
writes a read-only CSR") changed the behavior of riscv_csrrw, which
would formerly be treated as read-only if the write mask were set to 0.

Fixes an exception being raised when accessing read-only vector CSRs
like vtype.

Fixes: 38c83e8d3a ("target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR")

Signed-off-by: stove <stove@rivosinc.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20250827203617.79947-1-stove@rivosinc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit cebaf7434b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-04 10:20:28 +03:00
Frank Chang 0be25ffa79 hw/char: sifive_uart: Raise IRQ according to the Tx/Rx watermark thresholds
Currently, the SiFive UART raises an IRQ whenever:

  1. ie.txwm is enabled.
  2. ie.rxwm is enabled and the Rx FIFO is not empty.

It does not check the watermark thresholds set by software. However,
since commit [1] changed the SiFive UART character printing from
synchronous to asynchronous, Tx overflows may occur, causing characters
to be dropped when running Linux because:

  1. The Linux SiFive UART driver sets the transmit watermark level to 1
     [2], meaning a transmit watermark interrupt is raised whenever a
     character is enqueued into the Tx FIFO.
  2. Upon receiving a transmit watermark interrupt, the Linux driver
     transfers up to a full Tx FIFO's worth of characters from the Linux
     serial transmit buffer [3], without checking the txdata.full flag
     before transferring multiple characters [4].

To fix this issue, we must honor the Tx/Rx watermark thresholds and
raise interrupts only when the Tx threshold is exceeded or the Rx
threshold is undercut.

[1] 53c1557b23
[2] https://github.com/torvalds/linux/blob/master/drivers/tty/serial/sifive.c#L1039
[3] https://github.com/torvalds/linux/blob/master/drivers/tty/serial/sifive.c#L538
[4] https://github.com/torvalds/linux/blob/master/drivers/tty/serial/sifive.c#L291

Signed-off-by: Frank Chang <frank.chang@sifive.com>
Signed-off-by: Emmanuel Blot <emmanuel.blot@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250911160647.5710-2-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 191df34617)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-04 10:11:09 +03:00
Andrea Bolognani c25be2649c docs/interop/firmware: Add riscv64 to FirmwareArchitecture
Descriptors using this value have been shipped for years
by distros, so we just need to update the spec to match
reality.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Kashyap Chamarthy <kchamart@redhat.com>
Message-ID: <20250910121501.676219-1-abologna@redhat.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit da14767b35)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-04 09:57:06 +03:00
Andrew Jones e93d2c5fdd hw/riscv/riscv-iommu: Fix MSI table size limit
The MSI table is not limited to 4k. The only constraint the table has
is that its base address must be aligned to its size, ensuring no
offsets of the table size will overrun when added to the base address
(see "8.5. MSI page tables" of the AIA spec).

Fixes: 0c54acb824 ("hw/riscv: add RISC-V IOMMU base emulation")
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20250904132723.614507-2-ajones@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 4f7528295b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-04 09:56:19 +03:00
Thomas Huth f3b84ec247 ui/icons/qemu.svg: Add metadata information (author, license) to the logo
We've got two versions of the QEMU logo in the repository, one with
the whole word "QEMU" (pc-bios/qemu_logo.svg) and one that only contains
the letter "Q" (ui/icons/qemu.svg). While qemu_logo.svg contains the
proper metadata with license and author information, this is missing
from the ui/icons/qemu.svg file. Copy the meta data there so that
people have a chance to know the license of the file if they only
look at the qemu.svg file.

Closes: https://gitlab.com/qemu-project/qemu/-/issues/3139
Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20250930071419.117592-1-thuth@redhat.com>
(cherry picked from commit 9163424c50)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-01 22:10:08 +03:00
Marc-André Lureau ecc1aef81e ui/spice: fix crash when disabling GL scanout on
When spice_qxl_gl_scanout2() isn't available, the fallback code
incorrectly handles NULL arguments to disable the scanout, leading to:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  spice_server_gl_scanout (qxl=0x55a25ce57ae8, fd=0x0, width=0, height=0, offset=0x0, stride=0x0, num_planes=0, format=0, modifier=72057594037927935, y_0_top=0)
    at ../ui/spice-display.c:983
983         if (num_planes <= 1) {

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2391334
Fixes: 98a050ca93 ("ui/spice: support multi plane dmabuf scanout")
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
Message-Id: <20250903193818.2460914-1-marcandre.lureau@redhat.com>
(cherry picked from commit 62fd247a24)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-01 22:09:15 +03:00
Mohamed Akram daa07cbe01 ui/spice: Fix abort on macOS
The check is faulty because the thread variable was assigned in the main
thread while the main loop runs in a different thread on macOS.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3070
Signed-off-by: Mohamed Akram <mohd.akram@outlook.com>
Acked-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <C87205B9-DD8F-4E53-AB5B-C8BF82EF1D16@outlook.com>
(cherry picked from commit e7ecb533ee)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-10-01 22:08:30 +03:00
Harsh Prateek Bora e60467febb ppc/spapr: init lrdr-capapcity phys with ram size if maxmem not provided
lrdr-capacity contains phys field which communicates the maximum address
in bytes and therefore, the most memory that can be allocated to this
partition. This is usually populated when maxmem is provided alongwith
memory size on qemu command line. However since maxmem is an optional
param, this leads to bits being set to 0 in absence of maxmem param.
Fix this by initializing the respective bits as per total mem size in
such case.

Reported-by: Gaurav Batra <gbatra@us.ibm.com>
Tested-by: David Christensen <drc@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Reviewed-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://lore.kernel.org/r/20250506042903.76250-1-harshpb@linux.ibm.com
Message-ID: <20250506042903.76250-1-harshpb@linux.ibm.com>
(cherry picked from commit 6285eebd3a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-29 22:34:45 +03:00
Fabian Vogt f906aa2e33 hw/intc/xics: Add missing call to register vmstate_icp_server
An obsolete wrapper function with a workaround was removed entirely,
without restoring the call it wrapped.

Without this, the guest is stuck after savevm/loadvm.

Fixes: 24ee9229fe ("ppc/spapr: remove deprecated machine pseries-2.9")
Signed-off-by: Fabian Vogt <fvogt@suse.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/qemu-devel/6187781.lOV4Wx5bFT@fvogt-thinkpad
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250819223905.2247-2-farosas@suse.de
Message-ID: <20250819223905.2247-2-farosas@suse.de>
(cherry picked from commit f5738aedc2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-29 22:23:16 +03:00
Laurent Vivier 2d1b1bad05 net/passt: Fix build failure due to missing GIO dependency
The passt networking backend uses functions from the GIO library,
such as g_subprocess_launcher_new(), to manage its daemon process.
So, building with passt enabled requires GIO to be available.

If we enable passt and disable gio the build fails during linkage with
undefined reference errors:

  /usr/bin/ld: libsystem.a.p/net_passt.c.o: in function `net_passt_start_daemon':
  net/passt.c:250: undefined reference to `g_subprocess_launcher_new'
  /usr/bin/ld: net/passt.c:251: undefined reference to `g_subprocess_launcher_take_fd'
  /usr/bin/ld: net/passt.c:253: undefined reference to `g_subprocess_launcher_spawnv'
  /usr/bin/ld: net/passt.c:256: undefined reference to `g_object_unref'
  /usr/bin/ld: net/passt.c:263: undefined reference to `g_subprocess_wait'
  /usr/bin/ld: net/passt.c:268: undefined reference to `g_subprocess_get_if_exited'
  /usr/bin/ld: libsystem.a.p/net_passt.c.o: in function `glib_autoptr_clear_GSubprocess':
  /usr/include/glib-2.0/gio/gio-autocleanups.h:132: undefined reference to `g_object_unref'
  /usr/bin/ld: libsystem.a.p/net_passt.c.o: in function `net_passt_start_daemon':
  net/passt.c:269: undefined reference to `g_subprocess_get_exit_status'

Fix this by adding an explicit weson dependency on GIO for the passt
option.
The existing dependency on linux is kept because passt is only available
on this OS.

Cc: qemu-stable@nongnu.org
Fixes: 854ee02b22 ("net: Add passt network backend")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3121
Reported-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 4ccca2cc05)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-27 18:43:12 +03:00
Peter Maydell dfae27159d hw/usb/hcd-uhci: don't assert for SETUP to non-0 endpoint
If the guest feeds invalid data to the UHCI controller, we
can assert:
qemu-system-x86_64: ../../hw/usb/core.c:744: usb_ep_get: Assertion `pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT' failed.

(see issue 2548 for the repro case).  This happens because the guest
attempts USB_TOKEN_SETUP to an endpoint other than 0, which is not
valid.  The controller code doesn't catch this guest error, so
instead we hit the assertion in the USB core code.

Catch the case of SETUP to non-zero endpoint, and treat it as a fatal
error in the TD, in the same way we do for an invalid PID value in
the TD.

This is the UHCI equivalent of the same bug in OHCI that we fixed in
commit 3c3c233677 ("hw/usb/hcd-ohci: Fix #1510, #303: pid not IN or
OUT").

This bug has been tracked as CVE-2024-8354.

Cc: qemu-stable@nongnu.org
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2548
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit d0af3cd027)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-27 18:42:16 +03:00
Richard Henderson 562020faa2 tests/tcg/multiarch: Add tb-link test
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit e13e1195db)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Richard Henderson daf8f84e74 accel/tcg: Properly unlink a TB linked to itself
When we remove dest from orig's links, we lose the link
that we rely on later to reset links.  This can lead to
failure to release from spinlock with self-modifying code.

Cc: qemu-stable@nongnu.org
Reported-by: 李威威 <liweiwei@kubuds.cn>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Anton Johansson <anjo@rev.ng>
Tested-by: Anton Johansson <anjo@rev.ng>
(cherry picked from commit 03fe665980)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Thomas Huth ed37926cfb tests: Fix "make check-functional" for targets without thorough tests
If QEMU gets configured for a single target that does not have
any thorough functional tests, "make check-functional" currently
fails with the error message "No rule to make target 'check-func'".
This happens because "check-func" only gets defined for thorough
tests (quick ones get added to "check-func-quick" instead).
The same problem can happen with the quick tests for targets that
do not have any functional test at all. To fix it, simply make sure
that the targets are always available in the Makefile.

Reported-by: Peter Maydell <peter.maydell@linaro.org>
Closes: https://gitlab.com/qemu-project/qemu/-/issues/3119
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20250918125154.126072-1-thuth@redhat.com>
(cherry picked from commit 4f1ebc7712)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Peter Maydell f4eeb2f48d .gitlab-ci.d/buildtest.yml: Unset CI_COMMIT_DESCRIPTION for htags
In commit 52a21689cd we added a workaround for a bug in older
versions of htags where they fail with a weird error message if the
environment is too large.  However, we missed one variable which
gitlab CI can set to the body of the commit message:
CI_COMMIT_DESCRIPTION.

Add this to the variables we unset when running htags, so that
the 'pages' job doesn't fail if the most recent commit happens
to have a very large commit message.

Cc: qemu-stable@nongnu.org
Fixes: 52a21689cd (".gitlab-ci.d/buildtest.yml: Work around htags bug when environment is large")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20250916163030.1467893-1-peter.maydell@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit fd34f56fe8)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
WANG Rui 903045d724 tcg/optimize: Fix folding of vector bitsel
It looks like a typo. When the false value (C) is the constant -1, the
correct fold should be: R = B | ~A

Reproducer (LoongArch64 assembly):

     .text
     .globl  _start
 _start:
     vldi    $vr1, 3073
     vldi    $vr2, 1023
     vbitsel.v       $vr0, $vr2, $vr1, $vr2
     vpickve2gr.d    $a1, $vr0, 1
     xori    $a0, $a1, 1
     li.w    $a7, 93
     syscall 0

Fixes: e58b977238 ("tcg/optimize: Optimize bitsel_vec")
Link: https://github.com/llvm/llvm-project/issues/159610
Signed-off-by: WANG Rui <wangrui@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250919124901.2756538-1-wangrui@loongson.cn>
(cherry picked from commit a50347a414)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Peter Maydell bbb31acea9 hw/pci-host/astro: Don't call pci_regsiter_root_bus() in init
In the astro PCI host bridge device, we call pci_register_root_bus()
in the device's instance_init. This is a problem for two reasons
 * the PCI bridge is then available to the rest of the simulation
   (e.g. via pci_qdev_find_device()), even though it hasn't
   yet been realized
 * we do not attempt to unregister in an instance_deinit,
   which means that if you go through an instance_init -> deinit
   lifecycle the freed memory for the host-bridge device is
   left on the pci_host_bridges list

ASAN reports the resulting use-after-free:

==1776584==ERROR: AddressSanitizer: heap-use-after-free on address 0x51f00000cb00 at pc 0x5b2d460a89b5 bp 0x7ffef7617f50 sp 0x7ffef7617f48
WRITE of size 8 at 0x51f00000cb00 thread T0
    #0 0x5b2d460a89b4 in pci_host_bus_register /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci/pci.c:608:5
    #1 0x5b2d46093566 in pci_root_bus_internal_init /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci/pci.c:677:5
    #2 0x5b2d460935e0 in pci_root_bus_new /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci/pci.c:706:5
    #3 0x5b2d46093fe5 in pci_register_root_bus /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci/pci.c:751:11
    #4 0x5b2d46fe2335 in elroy_pcihost_init /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci-host/astro.c:455:16

0x51f00000cb00 is located 1664 bytes inside of 3456-byte region [0x51f00000c480,0x51f00000d200)
freed by thread T0 here:
    #0 0x5b2d4582385a in free (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/qemu-system-hppa+0x17ad85a) (BuildId: 692b49eedc6fb0ef618bbb6784a09311b3b7f1e8)
    #1 0x5b2d47160723 in object_finalize /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/object.c:734:9
    #2 0x5b2d471589db in object_unref /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/object.c:1232:9
    #3 0x5b2d477d373c in qmp_device_list_properties /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/qom-qmp-cmds.c:237:5

previously allocated by thread T0 here:
    #0 0x5b2d45823af3 in malloc (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/qemu-system-hppa+0x17adaf3) (BuildId: 692b49eedc6fb0ef618bbb6784a09311b3b7f1e8)
    #1 0x79728fa08b09 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62b09) (BuildId: 1eb6131419edb83b2178b682829a6913cf682d75)
    #2 0x5b2d471595fc in object_new_with_type /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/object.c:767:15
    #3 0x5b2d47159409 in object_new_with_class /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/object.c:782:12
    #4 0x5b2d477d29a5 in qmp_device_list_properties /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/qom-qmp-cmds.c:206:11

Cc: qemu-stable@nongnu.org
Fixes: e029bb00a7 ("hw/pci-host: Add Astro system bus adapter found on PA-RISC machines")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3118
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250918114259.1802337-3-peter.maydell@linaro.org>
(cherry picked from commit 76d2b8d42a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Peter Maydell 975d8f329e hw/pci-host/dino: Don't call pci_register_root_bus() in init
In the dino PCI host bridge device, we call pci_register_root_bus()
in the device's instance_init. This is a problem for two reasons
 * the PCI bridge is then available to the rest of the simulation
   (e.g. via pci_qdev_find_device()), even though it hasn't
   yet been realized
 * we do not attempt to unregister in an instance_deinit,
   which means that if you go through an instance_init -> deinit
   lifecycle the freed memory for the host-bridge device is
   left on the pci_host_bridges list

ASAN reports the resulting use-after-free:

==1771223==ERROR: AddressSanitizer: heap-use-after-free on address 0x527000018f80 at pc 0x5b4b9d3369b5 bp 0x7ffd01929980 sp 0x7ffd01929978
WRITE of size 8 at 0x527000018f80 thread T0
    #0 0x5b4b9d3369b4 in pci_host_bus_register /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci/pci.c:608:5
    #1 0x5b4b9d321566 in pci_root_bus_internal_init /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci/pci.c:677:5
    #2 0x5b4b9d3215e0 in pci_root_bus_new /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci/pci.c:706:5
    #3 0x5b4b9d321fe5 in pci_register_root_bus /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci/pci.c:751:11
    #4 0x5b4b9d390521 in dino_pcihost_init /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../hw/pci-host/dino.c:473:16

0x527000018f80 is located 1664 bytes inside of 12384-byte region [0x527000018900,0x52700001b960)
freed by thread T0 here:
    #0 0x5b4b9cab185a in free (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/qemu-system-hppa+0x17ad85a) (BuildId: ca496bb2e4fc750ebd289b448bad8d99c0ecd140)
    #1 0x5b4b9e3ee723 in object_finalize /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/object.c:734:9
    #2 0x5b4b9e3e69db in object_unref /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/object.c:1232:9
    #3 0x5b4b9ea6173c in qmp_device_list_properties /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/qom-qmp-cmds.c:237:5
    #4 0x5b4b9ec4e0f3 in qmp_marshal_device_list_properties /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/qapi/qapi-commands-qdev.c:65:14

previously allocated by thread T0 here:
    #0 0x5b4b9cab1af3 in malloc (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/qemu-system-hppa+0x17adaf3) (BuildId: ca496bb2e4fc750ebd289b448bad8d99c0ecd140)
    #1 0x799d8270eb09 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62b09) (BuildId: 1eb6131419edb83b2178b682829a6913cf682d75)
    #2 0x5b4b9e3e75fc in object_new_with_type /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/object.c:767:15
    #3 0x5b4b9e3e7409 in object_new_with_class /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/object.c:782:12
    #4 0x5b4b9ea609a5 in qmp_device_list_properties /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/hppa-asan/../../qom/qom-qmp-cmds.c:206:11

where we allocated one instance of the dino device, put it on the
list, freed it, and then trying to allocate a second instance touches
the freed memory on the pci_host_bridges list.

Fix this by deferring all the setup of memory regions and registering
the PCI bridge to the device's realize method.  This brings it into
line with almost all other PCI host bridges, which call
pci_register_root_bus() in realize.

Cc: qemu-stable@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3118
Fixes: 63901b6cc4 ("dino: move PCI bus initialisation to dino_pcihost_init()")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250918114259.1802337-2-peter.maydell@linaro.org>
(cherry picked from commit e4a1b308b2)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Richard Henderson 431d064c8e target/sparc: Relax decode of rs2_or_imm for v7
For v7, bits [12:5] are ignored for !imm.
For v8, those same bits are reserved, but are not trapped.

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit df663ac0a4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Richard Henderson 5f51aa7f60 target/sparc: Loosen decode of RDTBR for v7
For v7, bits [18:0] are ignored.
For v8, bits [18:14] are reserved and bits [13:0] are ignored.

Fixes: e8325dc02d ("target/sparc: Move RDTBR, FLUSHW to decodetree")
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit 6ff52f9dee)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Richard Henderson e574af4a5a target/sparc: Loosen decode of RDWIM for v7
For v7, bits [18:0] are ignored.
For v8, bits [18:14] are reserved and bits [13:0] are ignored.

Fixes: 5d617bfba0 ("target/sparc: Move RDWIM, RDPR to decodetree")
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit dc9678cc97)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Richard Henderson ba5f5ae5b2 target/sparc: Loosen decode of RDPSR for v7
For v7, bits [18:0] are ignored.
For v8, bits [18:14] are reserved and bits [13:0] are ignored.

Fixes: 668bb9b755 ("target/sparc: Move RDPSR, RDHPR to decodetree")
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit a0345f6283)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Richard Henderson 7c48b47055 target/sparc: Loosen decode of RDY for v7
Bits [18:0] are not decoded with v7, and for v8 unused values
of rs1 simply produce undefined results.

Fixes: af25071c1d ("target/sparc: Move RDASR, STBAR, MEMBAR to decodetree")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
(cherry picked from commit 49d669ccf3)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Richard Henderson dd93f80d02 target/sparc: Loosen decode of STBAR for v8
Solaris 8 appears to have a bug whereby it executes v9 MEMBAR
instructions when booting a freshly installed image. According
to the SPARC v8 architecture manual, whilst bits 13 and bits 12-0
of the "Read State Register Instructions" are notionally zero,
they are marked as unused (i.e. ignored).

Fixes: af25071c1d ("target/sparc: Move RDASR, STBAR, MEMBAR to decodetree")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3097
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
(cherry picked from commit b6cdd6c605)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:36 +03:00
Richard Henderson 307f5bb43f target/sparc: Allow TRANS macro with no extra arguments
Use ## to drop the preceding comma if __VA_ARGS__ is empty.

Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit b7cd0a1821)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-26 09:58:24 +03:00
Paolo Bonzini 4e95da0305 linux-user: avoid -Werror=int-in-bool-context
linux-user is failing to compile on Fedora 43:

../linux-user/strace.c:57:66: error: enum constant in boolean context [-Werror=int-in-bool-context]
   57 | #define FLAG_BASIC(V, M, N)      { V, M | QEMU_BUILD_BUG_ON_ZERO(!(M)), N }

The warning does not seem to be too useful and we could even disable it,
but the workaround is simple in this case.

Cc: qemu-stable@nongnu.org
Cc: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit db05b0d21e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-25 10:06:33 +03:00
Xiaoyao Li e460ac0c14 multiboot: Fix the split lock
While running the kvm-unit-tests on Intel platforms with "split lock
disable" feature, every test triggers a kernel warning of

  x86/split lock detection: #AC: qemu-system-x86_64/373232 took a split_lock trap at address: 0x1e3

Hack KVM by exiting to QEMU on split lock #AC, we get

KVM: exception 17 exit (error code 0x0)
EAX=00000001 EBX=00000000 ECX=00000014 EDX=0001fb80
ESI=00000000 EDI=000000a8 EBP=00000000 ESP=00006f10
EIP=000001e3 EFL=00010002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0900 00009000 0000ffff 00009300 DPL=0 DS16 [-WA]
CS =c000 000c0000 0000ffff 00009b00 DPL=0 CS16 [-RA]
SS =0000 00000000 0000ffff 00009300 DPL=0 DS16 [-WA]
DS =c000 000c0000 0000ffff 00009300 DPL=0 DS16 [-WA]
FS =0950 00009500 0000ffff 00009300 DPL=0 DS16 [-WA]
GS =06f2 00006f20 0000ffff 00009300 DPL=0 DS16 [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT=     000c02b4 00000027
IDT=     00000000 000003ff
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
EFER=0000000000000000
Code=89 16 08 00 65 66 0f 01 16 06 00 66 b8 01 00 00 00 0f 22 c0 <65> 66 ff 2e 00 00 b8 10 00 00 00 8e d0 8e d8 8e c0 8e e0 8e e8 66 b8 08 00 66 ba 10 05 66

And it matches with what disassembled from multiboo_dma.bin:

 #objdump -b binary -m i386 -D pc-bios/multiboot_dma.bin

  1d1:   08 00                   or     %al,(%eax)
  1d3:   65 66 0f 01 16          lgdtw  %gs:(%esi)
  1d8:   06                      push   %es
  1d9:   00 66 b8                add    %ah,-0x48(%esi)
  1dc:   01 00                   add    %eax,(%eax)
  1de:   00 00                   add    %al,(%eax)
  1e0:   0f 22 c0                mov    %eax,%cr0
> 1e3:   65 66 ff 2e             ljmpw  *%gs:(%esi)
  1e7:   00 00                   add    %al,(%eax)
  1e9:   b8 10 00 00 00          mov    $0x10,%eax
  1ee:   8e d0                   mov    %eax,%ss
  1f0:   8e d8                   mov    %eax,%ds
  1f2:   8e c0                   mov    %eax,%es
  1f4:   8e e0                   mov    %eax,%fs
  1f6:   8e e8                   mov    %eax,%gs
  1f8:   66 b8 08 00             mov    $0x8,%ax
  1fc:   66 ba 10 05             mov    $0x510,%dx

We can see that the instruction at 0x1e3 is a far jmp through the GDT.
However, the GDT is not 8 byte aligned, the base is 0xc02b4.

Intel processors follow the LOCK semantics to set the accessed flag of the
segment descriptor when loading a segment descriptor. If the the segment
descriptor crosses two cache line, it causes split lock.

Fix it by aligning the GDT on 8 bytes, so that segment descriptor cannot
span two cache lines.

Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/r/20250808035027.2194673-1-xiaoyao.li@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 4c8f69b948)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-18 20:24:19 +03:00
Xiaoyao Li 46cda5823b target/i386: Define enum X86ASIdx for x86's address spaces
Define X86ASIdx as enum, like ARM's ARMASIdx, so that it's clear index 0
is for memory and index 1 is for SMM.

Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Tested-By: Kirill Martynov <stdcalllevi@yandex-team.ru>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Link: https://lore.kernel.org/r/20250730095253.1833411-3-xiaoyao.li@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 591f817d81)
(Mjt: pick this change for completness with the previous one)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-18 20:23:49 +03:00
Xiaoyao Li 6130ab24d0 i386/cpu: Enable SMM cpu address space under KVM
Kirill Martynov reported assertation in cpu_asidx_from_attrs() being hit
when x86_cpu_dump_state() is called to dump the CPU state[*]. It happens
when the CPU is in SMM and KVM emulation failure due to misbehaving
guest.

The root cause is that QEMU i386 never enables the SMM address space for
cpu since KVM SMM support has been added.

Enable the SMM cpu address space under KVM when the SMM is enabled for
the x86machine.

[*] https://lore.kernel.org/qemu-devel/20250523154431.506993-1-stdcalllevi@yandex-team.ru/

Reported-by: Kirill Martynov <stdcalllevi@yandex-team.ru>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Tested-by: Kirill Martynov <stdcalllevi@yandex-team.ru>
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Link: https://lore.kernel.org/r/20250730095253.1833411-2-xiaoyao.li@intel.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 0516f4b702)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-18 19:24:59 +03:00
Stéphane Graber 88006572b4 hw/usb/network: Remove hardcoded 0x40 prefix in STRING_ETHADDR response
USB NICs have a "40:" prefix hardcoded for all MAC addresses when we
return the guest the MAC address if it queries the STRING_ETHADDR USB
string property.  This doesn't match what we use for the
OID_802_3_PERMANENT_ADDRESS or OID_802_3_CURRENT_ADDRESS OIDs for
NDIS, or the MAC address we actually use in the QEMU networking code
to send/receive packets for this device, or the NIC info string we
print for users.  In all those other places we directly use
s->conf.macaddr.a, which is the full thing the user asks for.

This overrides user-provided configuration and leads to an inconsistent
experience.

I couldn't find any documented reason (comment or git commits) for
this behavior.  It seems like everyone is just expecting the MAC
address to be fully passed through to the guest, but it isn't.

This may have been a debugging hack that accidentally made it through
to the accepted patch: it has been in the code since it was originally
added back in 2008.

This is also particularly problematic as the "40:" prefix isn't a
reserved prefix for MAC addresses (IEEE OUI).  There are a number of
valid allocations out there which use this prefix, meaning that QEMU
may be causing MAC address conflicts.

Cc: qemu-stable@nongnu.org
Fixes: 6c9f886cea ("Add CDC-Ethernet usb NIC (original patch from Thomas Sailer)"
Signed-off-by: Stéphane Graber <stgraber@stgraber.org>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2951
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
[PMM: beef up commit message based on mailing list discussion]
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit aaf042299a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-17 23:17:39 +03:00
Alex Bennée dfaeca306b .gitmodules: move u-boot mirrors to qemu-project-mirrors
To continue our GitLab Open Source Program license we need to pass an
automated license check for all repos under qemu-project. While U-Boot
is clearly GPLv2 rather than fight with the automated validation
script just move the mirror across to a separate project.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250908141911.2546063-1-alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
(cherry picked from commit a11d1847d5)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-17 07:52:11 +03:00
Daniel P. Berrangé dd6c96219c iotests/check: always enable all python warnings
Of most importance is that this gives us a heads-up if anything
we rely on has been deprecated. The default python behaviour
only emits a warning if triggered from __main__ which is very
limited.

Setting the env variable further ensures that any python child
processes will also display warnings.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 9a494d8353)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:35:00 +03:00
Daniel P. Berrangé a1e094db8b iotests/151: ensure subprocesses are cleaned up
The iotest 151 creates a bunch of subprocesses, with their stdout
connected to a pipe but never reads any data from them and does
not gurantee the processes are killed on cleanup.

This triggers resource leak warnings from python when the
subprocess.Popen object is garbage collected.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 2b2fb25c2a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:35:00 +03:00
Daniel P. Berrangé de9b387a5b iotests/147: ensure temporary sockets are closed before exiting
This avoids the python resource leak detector from issuing warnings
in the iotests.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit d4d0ebfcc9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:35:00 +03:00
Daniel P. Berrangé 6a59e3c5b0 python: ensure QEMUQtestProtocol closes its socket
While QEMUQtestMachine closes the socket that was passed to
QEMUQtestProtocol, the python resource leak manager still
believes that the copy QEMUQtestProtocol holds is open. We
must explicitly call close to avoid this leak warnnig.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 6ccb48ffc1)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:35:00 +03:00
Daniel P. Berrangé 8d7385b2a7 iotests: drop compat for old version context manager
Our minimum python is now 3.9, so back compat with prior
python versions is no longer required.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 82c7cb93c7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:35:00 +03:00
John Snow 7c9d65f9e4 python: backport 'avoid creating additional event loops per thread'
This commit is two backports squashed into one to avoid regressions.

python: *really* remove get_event_loop

A prior commit, aa1ff990, switched away from using get_event_loop *by
default*, but this is not good enough to avoid deprecation warnings as
`asyncio.get_event_loop_policy().get_event_loop()` is *also*
deprecated. Replace this mechanism with explicit calls to
asyncio.get_new_loop() and revise the cleanup mechanisms in __del__ to
match.

python: avoid creating additional event loops per thread

"Too hasty by far!", commit 21ce2ee4 attempted to avoid deprecated
behavior altogether by calling new_event_loop() directly if there was no
loop currently running, but this has the unfortunate side effect of
potentially creating multiple event loops per thread if tests
instantiate multiple QMP connections in a single thread. This behavior
is apparently not well-defined and causes problems in some, but not all,
combinations of Python interpreter version and platform environment.

Partially revert to Daniel Berrange's original patch, which calls
get_event_loop and simply suppresses the deprecation warning in
Python<=3.13. This time, however, additionally register new loops
created with new_event_loop() so that future calls to get_event_loop()
will return the loop already created.

Reported-by: Richard W.M. Jones <rjones@redhat.com>
Reported-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
cherry picked from commit python-qemu-qmp@21ce2ee4f2df87efe84a27b9c5112487f4670622
cherry picked from commit python-qemu-qmp@c08fb82b38212956ccffc03fc6d015c3979f42fe
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 85f223e5b0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:34:00 +03:00
John Snow 1034cd169c python: backport 'Remove deprecated get_event_loop calls'
This method was deprecated in 3.12 because it ordinarily should not be
used from coroutines; if there is not a currently running event loop,
this automatically creates a new event loop - which is usually not what
you want from code that would ever run in the bottom half.

In our case, we do want this behavior in two places:

(1) The synchronous shim, for convenience: this allows fully sync
programs to use QEMUMonitorProtocol() without needing to set up an event
loop beforehand. This is intentional to fully box in the async
complexities into the legacy sync shim.

(2) The qmp_tui shell; instead of relying on asyncio.run to create and
run an asyncio program, we need to be able to pass the current asyncio
loop to urwid setup functions. For convenience, again, we create one if
one is not present to simplify the creation of the TUI appliance.

The remaining user of get_event_loop() was in fact one of the erroneous
users that should not have been using this function: if there's no
running event loop inside of a coroutine, you're in big trouble :)

Signed-off-by: John Snow <jsnow@redhat.com>
cherry picked from commit python-qemu-qmp@aa1ff9907603a3033296027e1bd021133df86ef1
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 5d99044d09)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:34:00 +03:00
John Snow 67d9347194 python: backport 'qmp-tui: Do not crash if optional dependencies are not met'
Based on the discussion at https://github.com/pypa/pip/issues/9726 -
even though the setuptools documentation implies that it is possible to
guard script execution with optional dependency groups, this is not true
in practice with the scripts generated by pip.

Just do the simple thing and guard the import statements.

Signed-off-by: John Snow <jsnow@redhat.com>
cherry picked from commit python-qemu-qmp@df520dcacf9a75dd4c82ab1129768de4128b554c
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit fd0ed46d4e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:34:00 +03:00
John Snow 677a4e9d54 python: backport 'qmp-shell-wrap: handle missing binary gracefully'
Signed-off-by: John Snow <jsnow@redhat.com>
cherry picked from commit python-qemu-qmp@9c889dcbd58817b0c917a9d2dd16161f48ac8203
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit fcaeeb7653)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:34:00 +03:00
John Snow 5f39565103 python: backport 'Use @asynciocontextmanager'
This removes a non-idiomatic use of a "coroutine callback" in favor of
something a bit more standardized.

Signed-off-by: John Snow <jsnow@redhat.com>
cherry picked from commit python-qemu-qmp@commit 97f7ffa3be17a50544b52767d14b6fd478c07b9e
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 0408b8d7a0)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:34:00 +03:00
John Snow f246e6efc7 python: backport 'drop Python3.6 workarounds'
Now that the minimum version is 3.7, drop some of the 3.6-specific hacks
we've been carrying. A single remaining compatibility hack concerning
3.6's lack of @asynccontextmanager is addressed in the following commit.

Signed-off-by: John Snow <jsnow@redhat.com>
cherry picked from commit python-qemu-qmp@3e8e34e594cfc6b707e6f67959166acde4b421b8
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit f9d2e0a3bd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:34:00 +03:00
John Snow e2826959a8 python: backport 'kick event queue on legacy event_pull()'
This corrects an oversight in qmp-shell operation where new events will
not accumulate in the event queue when pressing "enter" with an empty
command buffer, so no new events show up.

Reported-by: Jag Raman <jag.raman@oracle.com>
Signed-off-by: John Snow <jsnow@redhat.com>
cherry picked from commit python-qemu-qmp@0443582d16cf9efd52b2c41a7b5be7af42c856cd
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
(cherry picked from commit 1e343714bf)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-16 23:34:00 +03:00
Thomas Huth 571a7414e7 ui/vnc: Fix crash when specifying [vnc] without id in the config file
QEMU currently crashes when there is a [vnc] section in the config
file that does not have an "id = ..." line:

 $ echo "[vnc]" > /tmp/qemu.conf
 $ ./qemu-system-x86_64 -readconfig /tmp/qemu.conf
 qemu-system-x86_64: ../../devel/qemu/ui/vnc.c:4347: vnc_init_func:
  Assertion `id' failed.
 Aborted (core dumped)

The required "id" is only set up automatically while parsing the command
line, but not when reading the options from the config file.
Thus let's move code that automatically adds the id (if it does not
exist yet) to the init function that needs the id for the first time,
replacing the assert() statement there.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2836
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20250821145130.845104-1-thuth@redhat.com>
(cherry picked from commit 38dd513263)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-11 17:23:08 +03:00
John Levon 4709ca196f hw/vfio-user: add x-pci-class-code
This new option was not added to vfio_user_pci_dev_properties, which
caused an incorrect class code for vfio-user devices.

Fixes: a59d06305f ("vfio/pci: Introduce x-pci-class-code option")
Signed-off-by: John Levon <john.levon@nutanix.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20250827190810.1645340-1-john.levon@nutanix.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
(cherry picked from commit 1b50621881)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-11 17:20:51 +03:00
Thomas Huth c03d5e11ee hw/intc/loongarch_pch_pic: Fix ubsan warning and endianness issue
When booting the Linux kernel from tests/functional/test_loongarch64_virt.py
with a QEMU that has been compiled with --enable-ubsan, there is
a warning like this:

 .../hw/intc/loongarch_pch_pic.c:171:46: runtime error: index 512 out of
  bounds for type 'uint8_t[64]' (aka 'unsigned char[64]')
 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
  .../hw/intc/loongarch_pch_pic.c:171:46
 .../hw/intc/loongarch_pch_pic.c:175:45: runtime error: index 256 out of
  bounds for type 'uint8_t[64]' (aka 'unsigned char[64]')
 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
  .../hw/intc/loongarch_pch_pic.c:175:45

It happens because "addr" is added first before substracting the base
(PCH_PIC_HTMSI_VEC or PCH_PIC_ROUTE_ENTRY).
Additionally, this code looks like it is not endianness safe, since
it uses a 64-bit pointer to write values into an array of 8-bit values.

Thus rework the code to use the stq_le_p / ldq_le_p helpers here
and make sure that we do not create pointers with undefined behavior
by accident.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Song Gao <gaosong@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
(cherry picked from commit 86bca40402)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-11 12:26:08 +03:00
WANG Rui 95de88feac target/loongarch: Guard 64-bit-only insn translation with TRANS64 macro
This patch replaces uses of the generic TRANS macro with TRANS64 for
instructions that are only valid when 64-bit support is available.

This improves correctness and avoids potential assertion failures or
undefined behavior during translation on 32-bit-only configurations.

Signed-off-by: WANG Rui <wangrui@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Reviewed-by: Song Gao <gaosong@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
(cherry picked from commit 96e7448c1f)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-11 12:26:08 +03:00
Michael Tokarev 1b1d46fef8 block/curl: fix curl internal handles handling
block/curl.c uses CURLMOPT_SOCKETFUNCTION to register a socket callback.
According to the documentation, this callback is called not just with
application-created sockets but also with internal curl sockets, - and
for such sockets, user data pointer is not set by the application, so
the result qemu crashing.

Pass BDRVCURLState directly to the callback function as user pointer,
instead of relying on CURLINFO_PRIVATE.

This problem started happening with update of libcurl from 8.9 to 8.10 --
apparently with this change curl started using private handles more.

(CURLINFO_PRIVATE is used in one more place, in curl_multi_check_completion() -
it might need a similar fix too)

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3081
Cc: qemu-stable@qemu.org
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
(cherry picked from commit 606978500c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-04 23:17:16 +03:00
Peter Maydell 7527e29c06 hw/char/max78000_uart: Destroy FIFO on deinit
In the max78000_uart we create a FIFO in the instance_init function,
but we don't destroy it on deinit, so ASAN reports a leak in the
device-introspect-test:

    #0 0x561cc92d5de3 in malloc (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/qemu-system-arm+0x21f1de3) (BuildId: 98fdf9fc85c3beaeca8eda0be8412f1e11b9c6ad)
    #1 0x70cbf2afab09 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62b09) (BuildId: 1eb6131419edb83b2178b682829a6913cf682d75)
    #2 0x561ccc4c884d in fifo8_create /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../util/fifo8.c:27:18
    #3 0x561cc9744ec9 in max78000_uart_init /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/char/max78000_uart.c:241:5

Add an instance_finalize method to destroy the FIFO.

Cc: qemu-stable@nongnu.org
Fixes: d447e4b702 ("MAX78000: UART Implementation")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20250821154358.2417744-1-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit ac6b124180)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-04 23:17:16 +03:00
Peter Maydell d1d60d7588 hw/gpio/pca9554: Avoid leak in pca9554_set_pin()
In pca9554_set_pin() we have a string property which we parse in
order to set some non-string fields in the device state.  So we call
visit_type_str(), passing it the address of the local variable
state_str.

visit_type_str() will allocate a new copy of the string; we
never free this string, so the result is a memory leak, detected
by ASAN during a "make check" run:

Direct leak of 5 byte(s) in 1 object(s) allocated from:
    #0 0x5d605212ede3 in malloc (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/qemu-system-arm+0x21f1de3) (
BuildId: 3d5373c89317f58bfcd191a33988c7347714be14)
    #1 0x7f7edea57b09 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62b09) (BuildId: 1eb6131419edb83b2178b68282
9a6913cf682d75)
    #2 0x7f7edea6d4d8 in g_strdup (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x784d8) (BuildId: 1eb6131419edb83b2178b68282
9a6913cf682d75)
    #3 0x5d6055289a91 in g_strdup_inline /usr/include/glib-2.0/glib/gstrfuncs.h:321:10
    #4 0x5d6055289a91 in qobject_input_type_str /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qapi/qo
bject-input-visitor.c:542:12
    #5 0x5d605528479c in visit_type_str /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qapi/qapi-visit
-core.c:349:10
    #6 0x5d60528bdd87 in pca9554_set_pin /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/gpio/pca9554.c:179:10
    #7 0x5d60549bcbbb in object_property_set /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:1450:5
    #8 0x5d60549d2055 in object_property_set_qobject /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/qom-qobject.c:28:10
    #9 0x5d60549bcdf1 in object_property_set_str /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:1458:15
    #10 0x5d605439d077 in gb200nvl_bmc_i2c_init /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/arm/aspeed.c:1267:5
    #11 0x5d60543a3bbc in aspeed_machine_init /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/arm/aspeed.c:493:9

Make the state_str g_autofree, so that we will always free
it, on both error-exit and success codepaths.

Cc: qemu-stable@nongnu.org
Fixes: de0c7d543b ("misc: Add a pca9554 GPIO device model")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20250821154459.2417976-1-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 3284d1c07c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-04 23:17:16 +03:00
Aditya Gupta 4715a0e9e6 hw/ppc: Fix build error with CONFIG_POWERNV disabled
Currently when CONFIG_POWERNV is not enabled, the build fails, such as
with --without-default-devices:

    $ ./configure --without-default-devices
    $ make

    [281/283] Linking target qemu-system-ppc64
    FAILED: qemu-system-ppc64
    cc -m64 @qemu-system-ppc64.rsp
    /usr/bin/ld: libqemu-ppc64-softmmu.a.p/target_ppc_misc_helper.c.o: in function `helper_load_sprd':
    .../target/ppc/misc_helper.c:335:(.text+0xcdc): undefined reference to `pnv_chip_find_core'
    /usr/bin/ld: libqemu-ppc64-softmmu.a.p/target_ppc_misc_helper.c.o: in function `helper_store_sprd':
    .../target/ppc/misc_helper.c:375:(.text+0xdf4): undefined reference to `pnv_chip_find_core'
    collect2: error: ld returned 1 exit status
    ...

This is since target/ppc/misc_helper.c references PowerNV specific
'pnv_chip_find_core' call.

Split the PowerNV specific SPRD code out of the generic PowerPC code, by
moving the SPRD code to pnv.c

Fixes: 9808ce6d5c ("target/ppc: Big-core scratch register fix")
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
Reported-by: Thomas Huth <thuth@redhat.com>
Suggested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Acked-by: Cédric Le Goater <clg@redhat.com>
Message-ID: <20250820122516.949766-2-adityag@linux.ibm.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 46d03bb23d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-04 23:17:16 +03:00
Denis Rastyogin 63bfc916de target/mips: fix TLB huge page check to use 64-bit shift
Use extract64(entry, psn, 1) instead of (entry & (1 << psn)) to avoid
undefined behavior for shifts by 32–63 and to make bit extraction intent explicit.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Signed-off-by: Denis Rastyogin <gerben@altlinux.org>
Message-ID: <20250814104914.13101-1-gerben@altlinux.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 1f82ca7234)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-04 23:17:16 +03:00
Philippe Mathieu-Daudé 046f1ae6fd linux-user/mips: Select M14Kc CPU to run microMIPS binaries
The M14Kc is our latest CPU supporting the microMIPS ASE.

Note, currently QEMU doesn't have 64-bit CPU supporting microMIPS ASE.

Cc: qemu-stable@nongnu.org
Fixes: 3c824109da ("target-mips: microMIPS ASE support")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3054
Reported-by: Justin Applegate <justink.applegate@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250814070650.78657-4-philmd@linaro.org>
(cherry picked from commit 51c3aebfda)
(Mjt: in 10.1 and before, the code is in linux-user/mips/target_elf.h)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-04 23:17:16 +03:00
Philippe Mathieu-Daudé a490b66ae4 linux-user/mips: Select 74Kf CPU to run MIPS16e binaries
The 74Kf is our latest CPU supporting MIPS16e ASE.

Note, currently QEMU doesn't have 64-bit CPU supporting MIPS16e ASE.

Cc: qemu-stable@nongnu.org
Fixes: 6ea219d0196..d19954f46df ("target-mips: MIPS16 support")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3054
Reported-by: Justin Applegate <justink.applegate@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250814070650.78657-3-philmd@linaro.org>
(cherry picked from commit 7a09b3cc70)
(Mjt: in 10.1 and before the code is in linux-user/mips/target_elf.h)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-04 23:17:16 +03:00
Philippe Mathieu-Daudé 0bb9ee4750 elf: Add EF_MIPS_ARCH_ASE definitions
Include MIPS ASE ELF definitions from binutils:
https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=include/elf/mips.h;h=4fc190f404d828ded84e621bfcece5fa9f9c23c8;hb=HEAD#l210

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250814070650.78657-2-philmd@linaro.org>
(cherry picked from commit 14ab44b96d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-04 23:17:16 +03:00
Laurent Vivier a84e2e04e8 e1000e: Prevent crash from legacy interrupt firing after MSI-X enable
A race condition between guest driver actions and QEMU timers can lead
to an assertion failure when the guest switches the e1000e from legacy
interrupt mode to MSI-X. If a legacy interrupt delay timer (TIDV or
RDTR) is active, but the guest enables MSI-X before the timer fires,
the pending interrupt cause can trigger an assert in
e1000e_intmgr_collect_delayed_causes().

This patch removes the assertion and executes the code that clears the
pending legacy causes. This change is safe and introduces no unintended
behavioral side effects, as it only alters a state that previously led
to termination.

- when core->delayed_causes == 0 the function was already a no-op and
  remains so.

- when core->delayed_causes != 0 the function would previously
  crash due to the assertion failure. The patch now defines a safe
  outcome by clearing the cause and returning. Since behavior after
  the assertion never existed, this simply corrects the crash.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1863
Suggested-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Message-ID: <20250807110806.409065-1-lvivier@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
(cherry picked from commit 8e4649cac9)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-04 18:26:14 +03:00
Markus Armbruster b7f2bff3ff Revert "tests/qtest: use qos_printf instead of g_test_message"
This reverts commit 30ea13e9d9.

Also rewrites qos_printf() calls added later.

"make check" prints many lines like

    stdout: 138: UNKNOWN:     # # qos_test running single test in subprocess
    stdout: 139: UNKNOWN:     # # set_protocol_features: 0x42
    stdout: 140: UNKNOWN:     # # set_owner: start of session
    stdout: 141: UNKNOWN:     # # vhost-user: un-handled message: 14
    stdout: 142: UNKNOWN:     # # vhost-user: un-handled message: 14
    stdout: 143: UNKNOWN:     # # set_vring(0)=enabled
    stdout: 144: UNKNOWN:     # # set_vring(1)=enabled
    stdout: 145: UNKNOWN:     # # set_vring(0)=enabled
    stdout: 146: UNKNOWN:     # # set_vring(1)=enabled
    stdout: 147: UNKNOWN:     # # set_vring(0)=enabled
    stdout: 148: UNKNOWN:     # # set_vring(1)=enabled
    stdout: 149: UNKNOWN:     # # set_vring(0)=enabled
    stdout: 150: UNKNOWN:     # # set_vring(1)=enabled
    stdout: 151: UNKNOWN:     # # set_vring(0)=enabled
    stdout: 152: UNKNOWN:     # # set_vring(1)=enabled
    stdout: 153: UNKNOWN:     # # set_vring_num: 0/256
    stdout: 154: UNKNOWN:     # # set_vring_addr: 0x7f9060000000/0x7f905ffff000/0x7f9060001000

Turns out this is qos-test, and the culprit is a commit meant to ease
debugging.  Revert it until a better solution is found.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <20250728145747.3165315-1-armbru@redhat.com>
[Commit message clarified]
(cherry picked from commit c9a1ea9c52)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-03 11:05:25 +03:00
Markus Armbruster 2dd52baff2 vfio scsi ui: Error-check qio_channel_socket_connect_sync() the same way
qio_channel_socket_connect_sync() returns 0 on success, and -1 on
failure, with errp set.  Some callers check the return value, and some
check whether errp was set.

For consistency, always check the return value, and always check it's
negative.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <20250723133257.1497640-3-armbru@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
(cherry picked from commit ec14a3de62)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-03 11:05:25 +03:00
Markus Armbruster 2a2b6ae097 i386/kvm/vmsr_energy: Plug memory leak on failure to connect socket
vmsr_open_socket() leaks the Error set by
qio_channel_socket_connect_sync().  Plug the leak by not creating the
Error.

Fixes: 0418f90809 (Add support for RAPL MSRs in KVM/Qemu)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <20250723133257.1497640-2-armbru@redhat.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
(cherry picked from commit b2e4534a2c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-03 11:05:25 +03:00
minglei.liu b4048a3d25 qga: Fix truncated output handling in guest-exec status reporting
Signed-off-by: minglei.liu <minglei.liu@smartx.com>
Fixes: a1853dca74
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Kostiantyn Kostiuk <kkostiuk@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20250711021714.91258-1-minglei.liu@smartx.com
Signed-off-by: Kostiantyn Kostiuk <kkostiuk@redhat.com>
(cherry picked from commit 28c5d27dd4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-03 11:05:24 +03:00
Kostiantyn Kostiuk 7f730ad785 qga-vss: Write hex value of error in log
QGA-VSS writes error using error_setg_win32_internal,
which call g_win32_error_message.

g_win32_error_message - translate a Win32 error code
(as returned by GetLastError()) into the corresponding message.

In the same time, we call error_setg_win32_internal with
error codes from different Windows componets like VSS or
Performance monitor that provides different codes and
can't be converted with g_win32_error_message. In this
case, the empty suffix will be returned so error will be
masked.

This commit directly add hex value of error code.

Reproduce:
 - Run QGA command: {"execute": "guest-fsfreeze-freeze-list", "arguments": {"mountpoints": ["D:"]}}

QGA error example:
 - before changes:
  {"error": {"class": "GenericError", "desc": "failed to add D: to snapshot set: "}}
 - after changes:
  {"error": {"class": "GenericError", "desc": "failed to add D: to snapshot set: Windows error 0x8004230e: "}}

Reviewed-by: Yan Vugenfirer <yvugenfi@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20250825135311.138330-1-kkostiuk@redhat.com
Signed-off-by: Kostiantyn Kostiuk <kkostiuk@redhat.com>
(cherry picked from commit edf3780a7d)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-03 11:05:24 +03:00
Kostiantyn Kostiuk f132112273 qga/installer: Remove QGA VSS if QGA installation failed
When QGA Installer failed to install QGA service but install
QGA VSS provider, provider should be removed before installer
exits. Otherwise QGA VSS will has broken infomation and
prevent QGA installation in next run.

Reviewed-by: Yan Vugenfirer <yvugenfi@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20250825143155.160913-1-kkostiuk@redhat.com
Signed-off-by: Kostiantyn Kostiuk <kkostiuk@redhat.com>
(cherry picked from commit 85ff0e956b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-09-03 09:49:34 +03:00
Peter Maydell b6fdef9c99 hw/arm/stm32f205_soc: Don't leak TYPE_OR_IRQ objects
In stm32f250_soc_initfn() we mostly use the standard pattern
for child objects of calling object_initialize_child(). However
for s->adc_irqs we call object_new() and then later qdev_realize(),
and we never unref the object on deinit. This causes a leak,
detected by ASAN on the device-introspect-test:

Indirect leak of 10 byte(s) in 1 object(s) allocated from:
    #0 0x5b9fc4789de3 in malloc (/mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/qemu-system-arm+0x21f1de3) (BuildId: 267a2619a026ed91c78a07b1eb2ef15381538efe)
    #1 0x740de3f28b09 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x62b09) (BuildId: 1eb6131419edb83b2178b682829a6913cf682d75)
    #2 0x740de3f3e4d8 in g_strdup (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x784d8) (BuildId: 1eb6131419edb83b2178b682829a6913cf682d75)
    #3 0x5b9fc70159e1 in g_strdup_inline /usr/include/glib-2.0/glib/gstrfuncs.h:321:10
    #4 0x5b9fc70159e1 in object_property_try_add /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:1276:18
    #5 0x5b9fc7015f94 in object_property_add /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:1294:12
    #6 0x5b9fc701b900 in object_add_link_prop /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:2021:10
    #7 0x5b9fc701b3fc in object_property_add_link /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:2037:12
    #8 0x5b9fc4c299fb in qdev_init_gpio_out_named /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/core/gpio.c:90:9
    #9 0x5b9fc4c29b26 in qdev_init_gpio_out /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/core/gpio.c:101:5
    #10 0x5b9fc4c0f77a in or_irq_init /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/core/or-irq.c:70:5
    #11 0x5b9fc70257e1 in object_init_with_type /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:428:9
    #12 0x5b9fc700cd4b in object_initialize_with_type /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:570:5
    #13 0x5b9fc700e66d in object_new_with_type /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:774:5
    #14 0x5b9fc700e750 in object_new /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../qom/object.c:789:12
    #15 0x5b9fc68b2162 in stm32f205_soc_initfn /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/arm-asan/../../hw/arm/stm32f205_soc.c:69:26

Switch to using object_initialize_child() like all our
other child objects for this SoC object.

Cc: qemu-stable@nongnu.org
Fixes: b63041c8f6 ("STM32F205: Connect the ADC devices")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20250821154229.2417453-1-peter.maydell@linaro.org
(cherry picked from commit 2e27650bdd)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-31 08:08:33 +03:00
Richard Henderson 28682949f2 qemu/atomic: Finish renaming atomic128-cas.h headers
The aarch64 header was not renamed with the others, meaning it
was skipped in favor of the generic version.

Cc: qemu-stable@nongnu.org
Fixes: 1560696540 ("qemu/atomic: Rename atomic128-cas.h headers using .h.inc suffix")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20250815122653.701782-2-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 1748c0d592)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-31 08:07:48 +03:00
Peter Maydell 067af4f784 scripts/kernel-doc: Avoid new Perl precedence warning
Newer versions of Perl (5.41.x and up) emit a warning for code in
kernel-doc:
 Possible precedence problem between ! and pattern match (m//) at /scripts/kernel-doc line 1597.

This is because the code does:
            if (!$param =~ /\w\.\.\.$/) {

In Perl, the !  operator has higher precedence than the =~
pattern-match binding, so the effect of this condition is to first
logically-negate the string $param into a true-or-false value and
then try to pattern match it against the regex, which in this case
will always fail.  This is almost certainly not what the author
intended.

In the new Python version of kernel-doc in the Linux kernel,
the equivalent code is written:

            if KernRe(r'\w\.\.\.$').search(param):
                # For named variable parameters of the form `x...`,
                # remove the dots
                param = param[:-3]
            else:
                # Handles unnamed variable parameters
                param = "..."

which is a more sensible way of writing the behaviour you would
get if you put in brackets to make the regex match first and
then negate the result.

Take this as the intended behaviour, and update the Perl to match.

For QEMU, this produces no change in output, presumably because we
never used the "unnamed variable parameters" syntax.

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Message-id: 20250819115648.2125709-1-peter.maydell@linaro.org
(cherry picked from commit 5ffd387e9e)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-31 08:06:26 +03:00
Smail AIDER a4f01a0878 target/arm: Trap PMCR when MDCR_EL2.TPMCR is set
Trap PMCR_EL0 or PMCR accesses to EL2 when MDCR_EL2.TPMCR is set.
Similar to MDCR_EL2.TPM, MDCR_EL2.TPMCR allows trapping EL0 and EL1
accesses to the PMCR register to EL2.

Cc: qemu-stable@nongnu.org
Signed-off-by: Smail AIDER <smail.aider@huawei.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20250811112143.1577055-2-smail.aider@huawei.com
Message-Id: <20250722131925.2119169-1-smail.aider@huawei.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 186db6a73b)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-31 07:47:32 +03:00
Steve Sistare 9084479e3b hw/intc/arm_gicv3_kvm: preserve pending interrupts during cpr
Close a race condition that causes cpr-transfer to lose VFIO
interrupts on ARM.

CPR stops VCPUs but does not disable VFIO interrupts, which may continue
to arrive throughout the transition to new QEMU.

CPR calls kvm_irqchip_remove_irqfd_notifier_gsi in old QEMU to force
future interrupts to the producer eventfd, where they are preserved.
Old QEMU then destroys the old KVM instance.  However, interrupts may
already be pending in KVM state.  To preserve them, call ioctl
KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES to flush them to guest RAM, where
they will be picked up when the new KVM+VCPU instance is created.

Cc: qemu-stable@nongnu.org
Signed-off-by: Steve Sistare <steven.sistare@oracle.com>
Reviewed-by: Fabiano Rosas <farosas@suse.de>
Message-id: 1754936384-278328-1-git-send-email-steven.sistare@oracle.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 376cdd7e9c)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-31 07:47:05 +03:00
Gustavo Romero 2cba99e9f8 tests/functional: Fix reverse_debugging asset precaching
This commit fixes the asset precaching in the reverse_debugging test on
aarch64.

QemuBaseTest.main() precaches assets (kernel, rootfs, DT blobs, etc.)
that are defined in variables with the ASSET_ prefix. This works because
it ultimately calls Asset.precache_test(), which relies on introspection
to locate these variables.

If an asset variable is not named with the ASSET_ prefix, precache_test
cannot find the asset and precaching silently fails. Hence, fix the
asset precaching by fixing the asset variable name.

Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Message-ID: <20250827001008.22112-1-gustavo.romero@linaro.org>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 36fb979666)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-29 11:44:33 +03:00
Joel Stanley 673d54cabf linux-user: Add strace for rseq
build/qemu-riscv64 -cpu rv64,v=on -d strace  build/tests/tcg/riscv64-linux-user/test-vstart-overflow
 1118081 riscv_hwprobe(0xffffbc038200,1,0,0,0,0) = 0
 1118081 brk(NULL) = 0x0000000000085000
 1118081 brk(0x0000000000085b00) = 0x0000000000085b00
 1118081 set_tid_address(0x850f0) = 1118081
 1118081 set_robust_list(0x85100,24) = -1 errno=38 (Function not implemented)
 1118081 rseq(0x857c0,32,0,0xf1401073) = -1 errno=38 (Function not implemented)

Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250826060341.1118670-1-joel@jms.id.au>
(cherry picked from commit f91563d011)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-29 10:25:44 +03:00
Zero Tang 408eeeacb3 i386/tcg/svm: fix incorrect canonicalization
For all 32-bit systems and 64-bit Windows systems, "long" is 4 bytes long.
Due to using "long" for a linear address, svm_canonicalization would
set all high bits to 1 when (assuming 48-bit linear address) the segment
base is bigger than 0x7FFF.

This fixes booting guests under TCG when the guest IDT and GDT bases are
above 0x7FFF, thereby resulting in incorrect bases. When an interrupt
arrives, it would trigger a #PF exception; the #PF would trigger again,
resulting in a #DF exception; the #PF would trigger for the third time,
resulting in triple-fault, and eventually causes a shutdown VM-Exit to
the hypervisor right after guest boot.

Cc: qemu-stable@nongnu.org
Signed-off-by: Zero Tang <zero.tangptr@gmail.com>
(cherry picked from commit c12cbaa007)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-29 10:22:57 +03:00
Paolo Bonzini a854320fde python: mkvenv: fix messages printed by mkvenv
The new Matcher class does not have a __str__ implementation, and therefore
it prints the debugging representation of the internal object:

  $ ../configure --enable-rust && make qemu-system-arm --enable-download
  python determined to be '/usr/bin/python3'
  python version: Python 3.13.6
  mkvenv: Creating non-isolated virtual environment at 'pyvenv'
  mkvenv: checking for LegacyMatcher('meson>=1.5.0')
  mkvenv: checking for LegacyMatcher('pycotap>=1.1.0')

Add the method to print the nicer

  mkvenv: checking for meson>=1.5.0
  mkvenv: checking for pycotap>=1.1.0

Cc: qemu-stable@nongnu.org
Cc: John Snow <jsnow@redhat.com>
Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit ab85146ac4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2025-08-29 10:21:27 +03:00
128 changed files with 1267 additions and 668 deletions
+1 -1
View File
@@ -736,7 +736,7 @@ pages:
- make gtags
# We unset variables to work around a bug in some htags versions
# which causes it to fail when the environment is large
- CI_COMMIT_MESSAGE= CI_COMMIT_TAG_MESSAGE= htags
- CI_COMMIT_MESSAGE= CI_COMMIT_TAG_MESSAGE= CI_COMMIT_DESCRIPTION= htags
-anT --tree-view=filetree -m qemu_init
-t "Welcome to the QEMU sourcecode"
- mv HTML public/src
+2 -2
View File
@@ -15,7 +15,7 @@
url = https://gitlab.com/qemu-project/qemu-palcode.git
[submodule "roms/u-boot"]
path = roms/u-boot
url = https://gitlab.com/qemu-project/u-boot.git
url = https://gitlab.com/qemu-project-mirrors/u-boot.git
[submodule "roms/skiboot"]
path = roms/skiboot
url = https://gitlab.com/qemu-project/skiboot.git
@@ -27,7 +27,7 @@
url = https://gitlab.com/qemu-project/seabios-hppa.git
[submodule "roms/u-boot-sam460ex"]
path = roms/u-boot-sam460ex
url = https://gitlab.com/qemu-project/u-boot-sam460ex.git
url = https://gitlab.com/qemu-project-mirrors/u-boot-sam460ex.git
[submodule "roms/edk2"]
path = roms/edk2
url = https://gitlab.com/qemu-project/edk2.git
+1 -1
View File
@@ -1 +1 @@
10.1.0
10.1.2
+13 -10
View File
@@ -1744,6 +1744,7 @@ static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
uintptr_t ra, MMUAccessType type, MMULookupLocals *l)
{
bool crosspage;
vaddr last;
int flags;
l->memop = get_memop(oi);
@@ -1753,13 +1754,15 @@ static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
l->page[0].addr = addr;
l->page[0].size = memop_size(l->memop);
l->page[1].addr = (addr + l->page[0].size - 1) & TARGET_PAGE_MASK;
l->page[1].addr = 0;
l->page[1].size = 0;
crosspage = (addr ^ l->page[1].addr) & TARGET_PAGE_MASK;
/* Lookup and recognize exceptions from the first page. */
mmu_lookup1(cpu, &l->page[0], l->memop, l->mmu_idx, type, ra);
last = addr + l->page[0].size - 1;
crosspage = (addr ^ last) & TARGET_PAGE_MASK;
if (likely(!crosspage)) {
mmu_lookup1(cpu, &l->page[0], l->memop, l->mmu_idx, type, ra);
flags = l->page[0].flags;
if (unlikely(flags & (TLB_WATCHPOINT | TLB_NOTDIRTY))) {
mmu_watch_or_dirty(cpu, &l->page[0], type, ra);
@@ -1769,18 +1772,18 @@ static bool mmu_lookup(CPUState *cpu, vaddr addr, MemOpIdx oi,
}
} else {
/* Finish compute of page crossing. */
int size0 = l->page[1].addr - addr;
vaddr addr1 = last & TARGET_PAGE_MASK;
int size0 = addr1 - addr;
l->page[1].size = l->page[0].size - size0;
l->page[0].size = size0;
l->page[1].addr = cpu->cc->tcg_ops->pointer_wrap(cpu, l->mmu_idx,
l->page[1].addr, addr);
addr1, addr);
/*
* Lookup both pages, recognizing exceptions from either. If the
* second lookup potentially resized, refresh first CPUTLBEntryFull.
* Lookup and recognize exceptions from the second page.
* If the lookup potentially resized the table, refresh the
* first CPUTLBEntryFull pointer.
*/
mmu_lookup1(cpu, &l->page[0], l->memop, l->mmu_idx, type, ra);
if (mmu_lookup1(cpu, &l->page[1], 0, l->mmu_idx, type, ra)) {
uintptr_t index = tlb_index(cpu, l->mmu_idx, addr);
l->page[0].full = &cpu->neg.tlb.d[l->mmu_idx].fulltlb[index];
+8
View File
@@ -836,6 +836,14 @@ static inline void tb_remove_from_jmp_list(TranslationBlock *orig, int n_orig)
* We first acquired the lock, and since the destination pointer matches,
* we know for sure that @orig is in the jmp list.
*/
if (dest == orig) {
/*
* In the case of a TB that links to itself, removing the entry
* from the list means that it won't be present later during
* tb_jmp_unlink -- unlink now.
*/
tb_reset_jump(orig, n_orig);
}
pprev = &dest->jmp_list_head;
TB_FOR_EACH_JMP(dest, tb, n) {
if (tb == orig && n == n_orig) {
+7 -10
View File
@@ -162,13 +162,9 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
void *userp, void *sp)
{
BDRVCURLState *s;
CURLState *state = NULL;
BDRVCURLState *s = userp;
CURLSocket *socket;
curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
s = state->s;
socket = g_hash_table_lookup(s->sockets, GINT_TO_POINTER(fd));
if (!socket) {
socket = g_new0(CURLSocket, 1);
@@ -475,11 +471,11 @@ static int curl_init_state(BDRVCURLState *s, CURLState *state)
(void *)curl_read_cb) ||
curl_easy_setopt(state->curl, CURLOPT_WRITEDATA, (void *)state) ||
curl_easy_setopt(state->curl, CURLOPT_PRIVATE, (void *)state) ||
curl_easy_setopt(state->curl, CURLOPT_AUTOREFERER, 1) ||
curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1) ||
curl_easy_setopt(state->curl, CURLOPT_NOSIGNAL, 1) ||
curl_easy_setopt(state->curl, CURLOPT_AUTOREFERER, 1L) ||
curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1L) ||
curl_easy_setopt(state->curl, CURLOPT_NOSIGNAL, 1L) ||
curl_easy_setopt(state->curl, CURLOPT_ERRORBUFFER, state->errmsg) ||
curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1)) {
curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1L)) {
goto err;
}
if (s->username) {
@@ -605,6 +601,7 @@ static void curl_attach_aio_context(BlockDriverState *bs,
assert(!s->multi);
s->multi = curl_multi_init();
s->aio_context = new_context;
curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, s);
curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
@@ -803,7 +800,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
}
s->accept_range = false;
if (curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1) ||
if (curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1L) ||
curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION, curl_header_cb) ||
curl_easy_setopt(state->curl, CURLOPT_HEADERDATA, s)) {
pstrcpy(state->errmsg, CURL_ERROR_SIZE,
+2 -2
View File
@@ -27,8 +27,8 @@ bool download_url(const char *name, const char *url)
if (curl_easy_setopt(curl, CURLOPT_URL, url) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_WRITEDATA, file) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L) != CURLE_OK
|| curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L) != CURLE_OK
|| curl_easy_perform(curl) != CURLE_OK) {
unlink(name);
fclose(file);
+2 -2
View File
@@ -34,7 +34,7 @@ configures the shared buffer location and size, and traps to the host
to process the requests.
The ``uefi-vars`` device implements the UEFI virtual device. It comes
in ``uefi-vars-x86`` and ``uefi-vars-sysbus`` flavours. The device
in ``uefi-vars-x64`` and ``uefi-vars-sysbus`` flavours. The device
reimplements the handlers needed, specifically
``EfiSmmVariableProtocol`` and ``VarCheckPolicyLibMmiHandler``. It
also consumes events (``EfiEndOfDxeEventGroup``,
@@ -57,7 +57,7 @@ usage on x86_64
.. code::
qemu-system-x86_64 \
-device uefi-vars-x86,jsonfile=/path/to/vars.json
-device uefi-vars-x64,jsonfile=/path/to/vars.json
usage on aarch64
----------------
+3 -1
View File
@@ -85,12 +85,14 @@
#
# @loongarch64: 64-bit LoongArch. (since: 7.1)
#
# @riscv64: 64-bit RISC-V.
#
# @x86_64: 64-bit x86.
#
# Since: 3.0
##
{ 'enum' : 'FirmwareArchitecture',
'data' : [ 'aarch64', 'arm', 'i386', 'loongarch64', 'x86_64' ] }
'data' : [ 'aarch64', 'arm', 'i386', 'loongarch64', 'riscv64', 'x86_64' ] }
##
# @FirmwareTarget:
+2 -3
View File
@@ -72,8 +72,7 @@ setting up a BAR for a VF.
2) Similarly in the implementation of the virtual function, you need to
make it a PCI Express device and add a similar set of capabilities
except for the SR/IOV capability. Then you need to set up the VF BARs as
subregions of the PFs SR/IOV VF BARs by calling
pcie_sriov_vf_register_bar() instead of the normal pci_register_bar() call:
subregions of the PFs SR/IOV VF BARs by calling pci_register_bar():
pci_your_vf_dev_realize( ... )
{
@@ -83,7 +82,7 @@ setting up a BAR for a VF.
pcie_ari_init(d, 0x100);
...
memory_region_init(mr, ... )
pcie_sriov_vf_register_bar(d, bar_nr, mr);
pci_register_bar(d, bar_nr, bar_type, mr);
...
}
+5 -5
View File
@@ -66,7 +66,7 @@ static void stm32f205_soc_initfn(Object *obj)
TYPE_STM32F2XX_TIMER);
}
s->adc_irqs = OR_IRQ(object_new(TYPE_OR_IRQ));
object_initialize_child(obj, "adc-irq-orgate", &s->adc_irqs, TYPE_OR_IRQ);
for (i = 0; i < STM_NUM_ADCS; i++) {
object_initialize_child(obj, "adc[*]", &s->adc[i], TYPE_STM32F2XX_ADC);
@@ -171,12 +171,12 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
}
/* ADC 1 to 3 */
object_property_set_int(OBJECT(s->adc_irqs), "num-lines", STM_NUM_ADCS,
object_property_set_int(OBJECT(&s->adc_irqs), "num-lines", STM_NUM_ADCS,
&error_abort);
if (!qdev_realize(DEVICE(s->adc_irqs), NULL, errp)) {
if (!qdev_realize(DEVICE(&s->adc_irqs), NULL, errp)) {
return;
}
qdev_connect_gpio_out(DEVICE(s->adc_irqs), 0,
qdev_connect_gpio_out(DEVICE(&s->adc_irqs), 0,
qdev_get_gpio_in(armv7m, ADC_IRQ));
for (i = 0; i < STM_NUM_ADCS; i++) {
@@ -187,7 +187,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
busdev = SYS_BUS_DEVICE(dev);
sysbus_mmio_map(busdev, 0, adc_addr[i]);
sysbus_connect_irq(busdev, 0,
qdev_get_gpio_in(DEVICE(s->adc_irqs), i));
qdev_get_gpio_in(DEVICE(&s->adc_irqs), i));
}
/* SPI 1 and 2 */
+7
View File
@@ -247,6 +247,12 @@ static void max78000_uart_init(Object *obj)
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
}
static void max78000_uart_finalize(Object *obj)
{
Max78000UartState *s = MAX78000_UART(obj);
fifo8_destroy(&s->rx_fifo);
}
static void max78000_uart_realize(DeviceState *dev, Error **errp)
{
Max78000UartState *s = MAX78000_UART(dev);
@@ -274,6 +280,7 @@ static const TypeInfo max78000_uart_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(Max78000UartState),
.instance_init = max78000_uart_init,
.instance_finalize = max78000_uart_finalize,
.class_init = max78000_uart_class_init,
};
+12 -12
View File
@@ -35,16 +35,17 @@
*/
/* Returns the state of the IP (interrupt pending) register */
static uint64_t sifive_uart_ip(SiFiveUARTState *s)
static uint32_t sifive_uart_ip(SiFiveUARTState *s)
{
uint64_t ret = 0;
uint32_t ret = 0;
uint64_t txcnt = SIFIVE_UART_GET_TXCNT(s->txctrl);
uint64_t rxcnt = SIFIVE_UART_GET_RXCNT(s->rxctrl);
uint32_t txcnt = SIFIVE_UART_GET_TXCNT(s->txctrl);
uint32_t rxcnt = SIFIVE_UART_GET_RXCNT(s->rxctrl);
if (txcnt != 0) {
if (fifo8_num_used(&s->tx_fifo) < txcnt) {
ret |= SIFIVE_UART_IP_TXWM;
}
if (s->rx_fifo_len > rxcnt) {
ret |= SIFIVE_UART_IP_RXWM;
}
@@ -55,15 +56,14 @@ static uint64_t sifive_uart_ip(SiFiveUARTState *s)
static void sifive_uart_update_irq(SiFiveUARTState *s)
{
int cond = 0;
if ((s->ie & SIFIVE_UART_IE_TXWM) ||
((s->ie & SIFIVE_UART_IE_RXWM) && s->rx_fifo_len)) {
uint32_t ip = sifive_uart_ip(s);
if (((ip & SIFIVE_UART_IP_TXWM) && (s->ie & SIFIVE_UART_IE_TXWM)) ||
((ip & SIFIVE_UART_IP_RXWM) && (s->ie & SIFIVE_UART_IE_RXWM))) {
cond = 1;
}
if (cond) {
qemu_irq_raise(s->irq);
} else {
qemu_irq_lower(s->irq);
}
qemu_set_irq(s->irq, cond);
}
static gboolean sifive_uart_xmit(void *do_not_use, GIOCondition cond,
+1
View File
@@ -295,6 +295,7 @@ void cpu_exec_unrealizefn(CPUState *cpu)
* accel_cpu_common_unrealize, which may free fields using call_rcu.
*/
accel_cpu_common_unrealize(cpu);
cpu_destroy_address_spaces(cpu);
}
static void cpu_common_initfn(Object *obj)
+1 -1
View File
@@ -174,7 +174,7 @@ static void pca9554_set_pin(Object *obj, Visitor *v, const char *name,
PCA9554State *s = PCA9554(obj);
int pin, rc, val;
uint8_t state, mask;
char *state_str;
g_autofree char *state_str = NULL;
if (!visit_type_str(v, name, &state_str, errp)) {
return;
+2
View File
@@ -84,6 +84,8 @@
GlobalProperty pc_compat_10_0[] = {
{ TYPE_X86_CPU, "x-consistent-cache", "false" },
{ TYPE_X86_CPU, "x-vendor-cpuid-only-v2", "false" },
{ TYPE_X86_CPU, "x-arch-cap-always-on", "true" },
{ TYPE_X86_CPU, "x-pdcm-on-even-without-pmu", "true" },
};
const size_t pc_compat_10_0_len = G_N_ELEMENTS(pc_compat_10_0);
+1
View File
@@ -478,6 +478,7 @@ int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len)
ledstate |= QEMU_CAPS_LOCK_LED;
}
kbd_put_ledstate(ledstate);
return 1;
}
return 0;
}
-2
View File
@@ -645,8 +645,6 @@ void apic_sipi(DeviceState *dev)
{
APICCommonState *s = APIC(dev);
cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI);
if (!s->wait_for_sipi)
return;
cpu_x86_load_seg_cache_sipi(s->cpu, s->sipi_vector);
+15
View File
@@ -31,6 +31,7 @@
#include "gicv3_internal.h"
#include "vgic_common.h"
#include "migration/blocker.h"
#include "migration/misc.h"
#include "qom/object.h"
#include "target/arm/cpregs.h"
@@ -776,6 +777,17 @@ static void vm_change_state_handler(void *opaque, bool running,
}
}
static int kvm_arm_gicv3_notifier(NotifierWithReturn *notifier,
MigrationEvent *e, Error **errp)
{
if (e->type == MIG_EVENT_PRECOPY_DONE) {
GICv3State *s = container_of(notifier, GICv3State, cpr_notifier);
return kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES,
NULL, true, errp);
}
return 0;
}
static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
{
@@ -917,6 +929,9 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES)) {
qemu_add_vm_change_state_handler(vm_change_state_handler, s);
migration_add_notifier_mode(&s->cpr_notifier,
kvm_arm_gicv3_notifier,
MIG_MODE_CPR_TRANSFER);
}
}
+8 -7
View File
@@ -110,10 +110,10 @@ static uint64_t pch_pic_read(void *opaque, hwaddr addr, uint64_t field_mask)
val = s->int_polarity;
break;
case PCH_PIC_HTMSI_VEC ... PCH_PIC_HTMSI_VEC_END:
val = *(uint64_t *)(s->htmsi_vector + addr - PCH_PIC_HTMSI_VEC);
val = ldq_le_p(&s->htmsi_vector[addr - PCH_PIC_HTMSI_VEC]);
break;
case PCH_PIC_ROUTE_ENTRY ... PCH_PIC_ROUTE_ENTRY_END:
val = *(uint64_t *)(s->route_entry + addr - PCH_PIC_ROUTE_ENTRY);
val = ldq_le_p(&s->route_entry[addr - PCH_PIC_ROUTE_ENTRY]);
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
@@ -129,7 +129,8 @@ static void pch_pic_write(void *opaque, hwaddr addr, uint64_t value,
{
LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque);
uint32_t offset;
uint64_t old, mask, data, *ptemp;
uint64_t old, mask, data;
void *ptemp;
offset = addr & 7;
addr -= offset;
@@ -168,12 +169,12 @@ static void pch_pic_write(void *opaque, hwaddr addr, uint64_t value,
s->int_polarity = (s->int_polarity & ~mask) | data;
break;
case PCH_PIC_HTMSI_VEC ... PCH_PIC_HTMSI_VEC_END:
ptemp = (uint64_t *)(s->htmsi_vector + addr - PCH_PIC_HTMSI_VEC);
*ptemp = (*ptemp & ~mask) | data;
ptemp = &s->htmsi_vector[addr - PCH_PIC_HTMSI_VEC];
stq_le_p(ptemp, (ldq_le_p(ptemp) & ~mask) | data);
break;
case PCH_PIC_ROUTE_ENTRY ... PCH_PIC_ROUTE_ENTRY_END:
ptemp = (uint64_t *)(s->route_entry + addr - PCH_PIC_ROUTE_ENTRY);
*ptemp = (*ptemp & ~mask) | data;
ptemp = (uint64_t *)&s->route_entry[addr - PCH_PIC_ROUTE_ENTRY];
stq_le_p(ptemp, (ldq_le_p(ptemp) & ~mask) | data);
break;
default:
qemu_log_mask(LOG_GUEST_ERROR,
+2
View File
@@ -335,6 +335,8 @@ static void icp_realize(DeviceState *dev, Error **errp)
return;
}
}
vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp);
}
static void icp_unrealize(DeviceState *dev)
-5
View File
@@ -341,11 +341,6 @@ e1000e_intmgr_collect_delayed_causes(E1000ECore *core)
{
uint32_t res;
if (msix_enabled(core->owner)) {
assert(core->delayed_causes == 0);
return 0;
}
res = core->delayed_causes;
core->delayed_causes = 0;
+4 -2
View File
@@ -251,10 +251,12 @@ static void igbvf_pci_realize(PCIDevice *dev, Error **errp)
memory_region_init_io(&s->mmio, OBJECT(dev), &mmio_ops, s, "igbvf-mmio",
IGBVF_MMIO_SIZE);
pcie_sriov_vf_register_bar(dev, IGBVF_MMIO_BAR_IDX, &s->mmio);
pci_register_bar(dev, IGBVF_MMIO_BAR_IDX, PCI_BASE_ADDRESS_MEM_TYPE_64 |
PCI_BASE_ADDRESS_MEM_PREFETCH, &s->mmio);
memory_region_init(&s->msix, OBJECT(dev), "igbvf-msix", IGBVF_MSIX_SIZE);
pcie_sriov_vf_register_bar(dev, IGBVF_MSIX_BAR_IDX, &s->msix);
pci_register_bar(dev, IGBVF_MSIX_BAR_IDX, PCI_BASE_ADDRESS_MEM_TYPE_64 |
PCI_BASE_ADDRESS_MEM_PREFETCH, &s->msix);
ret = msix_init(dev, IGBVF_MSIX_VEC_NUM, &s->msix, IGBVF_MSIX_BAR_IDX, 0,
&s->msix, IGBVF_MSIX_BAR_IDX, 0x2000, 0x70, errp);
+2 -6
View File
@@ -8708,12 +8708,8 @@ static bool nvme_init_pci(NvmeCtrl *n, PCIDevice *pci_dev, Error **errp)
msix_table_offset);
memory_region_add_subregion(&n->bar0, 0, &n->iomem);
if (pci_is_vf(pci_dev)) {
pcie_sriov_vf_register_bar(pci_dev, 0, &n->bar0);
} else {
pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_TYPE_64, &n->bar0);
}
pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_TYPE_64, &n->bar0);
ret = msix_init(pci_dev, nr_vectors,
&n->bar0, 0, msix_table_offset,
+14 -13
View File
@@ -424,22 +424,23 @@ static void elroy_reset(DeviceState *dev)
}
}
static void elroy_pcihost_init(Object *obj)
static void elroy_pcihost_realize(DeviceState *dev, Error **errp)
{
ElroyState *s = ELROY_PCI_HOST_BRIDGE(obj);
PCIHostState *phb = PCI_HOST_BRIDGE(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
ElroyState *s = ELROY_PCI_HOST_BRIDGE(dev);
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
Object *obj = OBJECT(s);
/* Elroy config access from CPU. */
memory_region_init_io(&s->this_mem, OBJECT(s), &elroy_chip_ops,
memory_region_init_io(&s->this_mem, obj, &elroy_chip_ops,
s, "elroy", 0x2000);
/* Elroy PCI config. */
memory_region_init_io(&phb->conf_mem, OBJECT(phb),
&elroy_config_addr_ops, DEVICE(s),
memory_region_init_io(&phb->conf_mem, obj,
&elroy_config_addr_ops, dev,
"pci-conf-idx", 8);
memory_region_init_io(&phb->data_mem, OBJECT(phb),
&elroy_config_data_ops, DEVICE(s),
memory_region_init_io(&phb->data_mem, obj,
&elroy_config_data_ops, dev,
"pci-conf-data", 8);
memory_region_add_subregion(&s->this_mem, 0x40,
&phb->conf_mem);
@@ -447,8 +448,8 @@ static void elroy_pcihost_init(Object *obj)
&phb->data_mem);
/* Elroy PCI bus memory. */
memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", UINT64_MAX);
memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj,
memory_region_init(&s->pci_mmio, obj, "pci-mmio", UINT64_MAX);
memory_region_init_io(&s->pci_io, obj, &unassigned_io_ops, obj,
"pci-isa-mmio",
((uint32_t) IOS_DIST_BASE_SIZE) / ROPES_PER_IOC);
@@ -459,7 +460,7 @@ static void elroy_pcihost_init(Object *obj)
sysbus_init_mmio(sbd, &s->this_mem);
qdev_init_gpio_in(DEVICE(obj), elroy_set_irq, ELROY_IRQS);
qdev_init_gpio_in(dev, elroy_set_irq, ELROY_IRQS);
}
static const VMStateDescription vmstate_elroy = {
@@ -487,6 +488,7 @@ static void elroy_pcihost_class_init(ObjectClass *klass, const void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
device_class_set_legacy_reset(dc, elroy_reset);
dc->realize = elroy_pcihost_realize;
dc->vmsd = &vmstate_elroy;
dc->user_creatable = false;
}
@@ -494,7 +496,6 @@ static void elroy_pcihost_class_init(ObjectClass *klass, const void *data)
static const TypeInfo elroy_pcihost_info = {
.name = TYPE_ELROY_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_init = elroy_pcihost_init,
.instance_size = sizeof(ElroyState),
.class_init = elroy_pcihost_class_init,
};
+41 -49
View File
@@ -413,6 +413,47 @@ static void dino_pcihost_reset(DeviceState *dev)
static void dino_pcihost_realize(DeviceState *dev, Error **errp)
{
DinoState *s = DINO_PCI_HOST_BRIDGE(dev);
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
/* Dino PCI access from main memory. */
memory_region_init_io(&s->this_mem, OBJECT(s), &dino_chip_ops,
s, "dino", 4096);
/* Dino PCI config. */
memory_region_init_io(&phb->conf_mem, OBJECT(phb),
&dino_config_addr_ops, DEVICE(s),
"pci-conf-idx", 4);
memory_region_init_io(&phb->data_mem, OBJECT(phb),
&dino_config_data_ops, DEVICE(s),
"pci-conf-data", 4);
memory_region_add_subregion(&s->this_mem, DINO_PCI_CONFIG_ADDR,
&phb->conf_mem);
memory_region_add_subregion(&s->this_mem, DINO_CONFIG_DATA,
&phb->data_mem);
/* Dino PCI bus memory. */
memory_region_init(&s->pci_mem, OBJECT(s), "pci-memory", 4 * GiB);
phb->bus = pci_register_root_bus(DEVICE(s), "pci",
dino_set_irq, dino_pci_map_irq, s,
&s->pci_mem, get_system_io(),
PCI_DEVFN(0, 0), 32, TYPE_PCI_BUS);
/* Set up windows into PCI bus memory. */
for (int i = 1; i < 31; i++) {
uint32_t addr = 0xf0000000 + i * DINO_MEM_CHUNK_SIZE;
char *name = g_strdup_printf("PCI Outbound Window %d", i);
memory_region_init_alias(&s->pci_mem_alias[i], OBJECT(s),
name, &s->pci_mem, addr,
DINO_MEM_CHUNK_SIZE);
g_free(name);
}
pci_setup_iommu(phb->bus, &dino_iommu_ops, s);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->this_mem);
qdev_init_gpio_in(dev, dino_set_irq, DINO_IRQS);
/* Set up PCI view of memory: Bus master address space. */
memory_region_init(&s->bm, OBJECT(s), "bm-dino", 4 * GiB);
@@ -444,54 +485,6 @@ static void dino_pcihost_unrealize(DeviceState *dev)
address_space_destroy(&s->bm_as);
}
static void dino_pcihost_init(Object *obj)
{
DinoState *s = DINO_PCI_HOST_BRIDGE(obj);
PCIHostState *phb = PCI_HOST_BRIDGE(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
int i;
/* Dino PCI access from main memory. */
memory_region_init_io(&s->this_mem, OBJECT(s), &dino_chip_ops,
s, "dino", 4096);
/* Dino PCI config. */
memory_region_init_io(&phb->conf_mem, OBJECT(phb),
&dino_config_addr_ops, DEVICE(s),
"pci-conf-idx", 4);
memory_region_init_io(&phb->data_mem, OBJECT(phb),
&dino_config_data_ops, DEVICE(s),
"pci-conf-data", 4);
memory_region_add_subregion(&s->this_mem, DINO_PCI_CONFIG_ADDR,
&phb->conf_mem);
memory_region_add_subregion(&s->this_mem, DINO_CONFIG_DATA,
&phb->data_mem);
/* Dino PCI bus memory. */
memory_region_init(&s->pci_mem, OBJECT(s), "pci-memory", 4 * GiB);
phb->bus = pci_register_root_bus(DEVICE(s), "pci",
dino_set_irq, dino_pci_map_irq, s,
&s->pci_mem, get_system_io(),
PCI_DEVFN(0, 0), 32, TYPE_PCI_BUS);
/* Set up windows into PCI bus memory. */
for (i = 1; i < 31; i++) {
uint32_t addr = 0xf0000000 + i * DINO_MEM_CHUNK_SIZE;
char *name = g_strdup_printf("PCI Outbound Window %d", i);
memory_region_init_alias(&s->pci_mem_alias[i], OBJECT(s),
name, &s->pci_mem, addr,
DINO_MEM_CHUNK_SIZE);
g_free(name);
}
pci_setup_iommu(phb->bus, &dino_iommu_ops, s);
sysbus_init_mmio(sbd, &s->this_mem);
qdev_init_gpio_in(DEVICE(obj), dino_set_irq, DINO_IRQS);
}
static const Property dino_pcihost_properties[] = {
DEFINE_PROP_LINK("memory-as", DinoState, memory_as, TYPE_MEMORY_REGION,
MemoryRegion *),
@@ -511,7 +504,6 @@ static void dino_pcihost_class_init(ObjectClass *klass, const void *data)
static const TypeInfo dino_pcihost_info = {
.name = TYPE_DINO_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_init = dino_pcihost_init,
.instance_size = sizeof(DinoState),
.class_init = dino_pcihost_class_init,
};
-3
View File
@@ -1490,9 +1490,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
: pci_get_bus(pci_dev)->address_space_mem;
if (pci_is_vf(pci_dev)) {
PCIDevice *pf = pci_dev->exp.sriov_vf.pf;
assert(!pf || type == pf->exp.sriov_pf.vf_bar_type[region_num]);
r->addr = pci_bar_address(pci_dev, region_num, r->type, r->size);
if (r->addr != PCI_BAR_UNMAPPED) {
memory_region_add_subregion_overlap(r->address_space,
+5 -12
View File
@@ -195,7 +195,9 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset,
void pcie_sriov_pf_exit(PCIDevice *dev)
{
uint8_t *cfg = dev->config + dev->exp.sriov_cap;
if (dev->exp.sriov_cap == 0) {
return;
}
if (dev->exp.sriov_pf.vf_user_created) {
uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID);
@@ -211,6 +213,8 @@ void pcie_sriov_pf_exit(PCIDevice *dev)
pci_config_set_device_id(dev->exp.sriov_pf.vf[i]->config, vf_dev_id);
}
} else {
uint8_t *cfg = dev->config + dev->exp.sriov_cap;
unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF));
}
}
@@ -242,17 +246,6 @@ void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
dev->exp.sriov_pf.vf_bar_type[region_num] = type;
}
void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
MemoryRegion *memory)
{
uint8_t type;
assert(dev->exp.sriov_vf.pf);
type = dev->exp.sriov_vf.pf->exp.sriov_pf.vf_bar_type[region_num];
return pci_register_bar(dev, region_num, type, memory);
}
static gint compare_vf_devfns(gconstpointer a, gconstpointer b)
{
return (*(PCIDevice **)a)->devfn - (*(PCIDevice **)b)->devfn;
+86
View File
@@ -21,6 +21,7 @@
#include "qemu/osdep.h"
#include "qemu/datadir.h"
#include "qemu/log.h"
#include "qemu/units.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
@@ -1794,12 +1795,83 @@ static void pnv_chip_power9_pec_realize(PnvChip *chip, Error **errp)
}
}
static uint64_t pnv_handle_sprd_load(CPUPPCState *env)
{
PowerPCCPU *cpu = env_archcpu(env);
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
uint64_t sprc = env->spr[SPR_POWER_SPRC];
if (pc->big_core) {
pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
}
switch (sprc & 0x3e0) {
case 0: /* SCRATCH0-3 */
case 1: /* SCRATCH4-7 */
return pc->scratch[(sprc >> 3) & 0x7];
case 0x1e0: /* core thread state */
if (env->excp_model == POWERPC_EXCP_POWER9) {
/*
* Only implement for POWER9 because skiboot uses it to check
* big-core mode. Other bits are unimplemented so we would
* prefer to get unimplemented message on POWER10 if it were
* used anywhere.
*/
if (pc->big_core) {
return PPC_BIT(63);
} else {
return 0;
}
}
/* fallthru */
default:
qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"
TARGET_FMT_lx"\n", sprc);
break;
}
return 0;
}
static void pnv_handle_sprd_store(CPUPPCState *env, uint64_t val)
{
PowerPCCPU *cpu = env_archcpu(env);
uint64_t sprc = env->spr[SPR_POWER_SPRC];
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
int nr;
if (pc->big_core) {
pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
}
switch (sprc & 0x3e0) {
case 0: /* SCRATCH0-3 */
case 1: /* SCRATCH4-7 */
/*
* Log stores to SCRATCH, because some firmware uses these for
* debugging and logging, but they would normally be read by the BMC,
* which is not implemented in QEMU yet. This gives a way to get at the
* information. Could also dump these upon checkstop.
*/
nr = (sprc >> 3) & 0x7;
pc->scratch[nr] = val;
break;
default:
qemu_log_mask(LOG_UNIMP, "mtSPRD: Unimplemented SPRC:0x"
TARGET_FMT_lx"\n", sprc);
break;
}
}
static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
{
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
Pnv9Chip *chip9 = PNV9_CHIP(dev);
PnvChip *chip = PNV_CHIP(dev);
Pnv9Psi *psi9 = &chip9->psi;
PowerPCCPU *cpu;
PowerPCCPUClass *cpu_class;
Error *local_err = NULL;
int i;
@@ -1827,6 +1899,12 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
return;
}
/* Set handlers for Special registers, such as SPRD */
cpu = chip->cores[0]->threads[0];
cpu_class = POWERPC_CPU_GET_CLASS(cpu);
cpu_class->load_sprd = pnv_handle_sprd_load;
cpu_class->store_sprd = pnv_handle_sprd_store;
/* XIVE interrupt controller (POWER9) */
object_property_set_int(OBJECT(&chip9->xive), "ic-bar",
PNV9_XIVE_IC_BASE(chip), &error_fatal);
@@ -2078,6 +2156,8 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
PnvChip *chip = PNV_CHIP(dev);
Pnv10Chip *chip10 = PNV10_CHIP(dev);
PowerPCCPU *cpu;
PowerPCCPUClass *cpu_class;
Error *local_err = NULL;
int i;
@@ -2105,6 +2185,12 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
return;
}
/* Set handlers for Special registers, such as SPRD */
cpu = chip->cores[0]->threads[0];
cpu_class = POWERPC_CPU_GET_CLASS(cpu);
cpu_class->load_sprd = pnv_handle_sprd_load;
cpu_class->store_sprd = pnv_handle_sprd_store;
/* XIVE2 interrupt controller (POWER10) */
object_property_set_int(OBJECT(&chip10->xive), "ic-bar",
PNV10_XIVE2_IC_BASE(chip), &error_fatal);
+7 -4
View File
@@ -907,6 +907,7 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
int rtas;
GString *hypertas = g_string_sized_new(256);
GString *qemu_hypertas = g_string_sized_new(256);
uint64_t max_device_addr = 0;
uint32_t lrdr_capacity[] = {
0,
0,
@@ -917,13 +918,15 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
/* Do we have device memory? */
if (MACHINE(spapr)->device_memory) {
uint64_t max_device_addr = MACHINE(spapr)->device_memory->base +
max_device_addr = MACHINE(spapr)->device_memory->base +
memory_region_size(&MACHINE(spapr)->device_memory->mr);
lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
} else if (ms->ram_size == ms->maxram_size) {
max_device_addr = ms->ram_size;
}
lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
_FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
/* hypertas */
+148 -6
View File
@@ -558,6 +558,7 @@ static MemTxResult riscv_iommu_msi_write(RISCVIOMMUState *s,
MemTxResult res;
dma_addr_t addr;
uint64_t intn;
size_t offset;
uint32_t n190;
uint64_t pte[2];
int fault_type = RISCV_IOMMU_FQ_TTYPE_UADDR_WR;
@@ -565,16 +566,18 @@ static MemTxResult riscv_iommu_msi_write(RISCVIOMMUState *s,
/* Interrupt File Number */
intn = riscv_iommu_pext_u64(PPN_DOWN(gpa), ctx->msi_addr_mask);
if (intn >= 256) {
offset = intn * sizeof(pte);
/* fetch MSI PTE */
addr = PPN_PHYS(get_field(ctx->msiptp, RISCV_IOMMU_DC_MSIPTP_PPN));
if (addr & offset) {
/* Interrupt file number out of range */
res = MEMTX_ACCESS_ERROR;
cause = RISCV_IOMMU_FQ_CAUSE_MSI_LOAD_FAULT;
goto err;
}
/* fetch MSI PTE */
addr = PPN_PHYS(get_field(ctx->msiptp, RISCV_IOMMU_DC_MSIPTP_PPN));
addr = addr | (intn * sizeof(pte));
addr |= offset;
res = dma_memory_read(s->target_as, addr, &pte, sizeof(pte),
MEMTXATTRS_UNSPECIFIED);
if (res != MEMTX_OK) {
@@ -866,6 +869,145 @@ static bool riscv_iommu_validate_process_ctx(RISCVIOMMUState *s,
return true;
}
/**
* pdt_memory_read: PDT wrapper of dma_memory_read.
*
* @s: IOMMU Device State
* @ctx: Device Translation Context with devid and pasid set
* @addr: address within that address space
* @buf: buffer with the data transferred
* @len: length of the data transferred
* @attrs: memory transaction attributes
*/
static MemTxResult pdt_memory_read(RISCVIOMMUState *s,
RISCVIOMMUContext *ctx,
dma_addr_t addr,
void *buf, dma_addr_t len,
MemTxAttrs attrs)
{
uint64_t gatp_mode, pte;
struct {
unsigned char step;
unsigned char levels;
unsigned char ptidxbits;
unsigned char ptesize;
} sc;
MemTxResult ret;
dma_addr_t base = addr;
/* G stages translation mode */
gatp_mode = get_field(ctx->gatp, RISCV_IOMMU_ATP_MODE_FIELD);
if (gatp_mode == RISCV_IOMMU_DC_IOHGATP_MODE_BARE) {
goto out;
}
/* G stages translation tables root pointer */
base = PPN_PHYS(get_field(ctx->gatp, RISCV_IOMMU_ATP_PPN_FIELD));
/* Start at step 0 */
sc.step = 0;
if (s->fctl & RISCV_IOMMU_FCTL_GXL) {
/* 32bit mode for GXL == 1 */
switch (gatp_mode) {
case RISCV_IOMMU_DC_IOHGATP_MODE_SV32X4:
if (!(s->cap & RISCV_IOMMU_CAP_SV32X4)) {
return MEMTX_ACCESS_ERROR;
}
sc.levels = 2;
sc.ptidxbits = 10;
sc.ptesize = 4;
break;
default:
return MEMTX_ACCESS_ERROR;
}
} else {
/* 64bit mode for GXL == 0 */
switch (gatp_mode) {
case RISCV_IOMMU_DC_IOHGATP_MODE_SV39X4:
if (!(s->cap & RISCV_IOMMU_CAP_SV39X4)) {
return MEMTX_ACCESS_ERROR;
}
sc.levels = 3;
sc.ptidxbits = 9;
sc.ptesize = 8;
break;
case RISCV_IOMMU_DC_IOHGATP_MODE_SV48X4:
if (!(s->cap & RISCV_IOMMU_CAP_SV48X4)) {
return MEMTX_ACCESS_ERROR;
}
sc.levels = 4;
sc.ptidxbits = 9;
sc.ptesize = 8;
break;
case RISCV_IOMMU_DC_IOHGATP_MODE_SV57X4:
if (!(s->cap & RISCV_IOMMU_CAP_SV57X4)) {
return MEMTX_ACCESS_ERROR;
}
sc.levels = 5;
sc.ptidxbits = 9;
sc.ptesize = 8;
break;
default:
return MEMTX_ACCESS_ERROR;
}
}
do {
const unsigned va_bits = (sc.step ? 0 : 2) + sc.ptidxbits;
const unsigned va_skip = TARGET_PAGE_BITS + sc.ptidxbits *
(sc.levels - 1 - sc.step);
const unsigned idx = (addr >> va_skip) & ((1 << va_bits) - 1);
const dma_addr_t pte_addr = base + idx * sc.ptesize;
/* Address range check before first level lookup */
if (!sc.step) {
const uint64_t va_mask = (1ULL << (va_skip + va_bits)) - 1;
if ((addr & va_mask) != addr) {
return MEMTX_ACCESS_ERROR;
}
}
/* Read page table entry */
if (sc.ptesize == 4) {
uint32_t pte32 = 0;
ret = ldl_le_dma(s->target_as, pte_addr, &pte32, attrs);
pte = pte32;
} else {
ret = ldq_le_dma(s->target_as, pte_addr, &pte, attrs);
}
if (ret != MEMTX_OK) {
return ret;
}
sc.step++;
hwaddr ppn = pte >> PTE_PPN_SHIFT;
if (!(pte & PTE_V)) {
return MEMTX_ACCESS_ERROR; /* Invalid PTE */
} else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
base = PPN_PHYS(ppn); /* Inner PTE, continue walking */
} else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
return MEMTX_ACCESS_ERROR; /* Reserved leaf PTE flags: PTE_W */
} else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
return MEMTX_ACCESS_ERROR; /* Reserved leaf PTE flags: PTE_W + PTE_X */
} else if (ppn & ((1ULL << (va_skip - TARGET_PAGE_BITS)) - 1)) {
return MEMTX_ACCESS_ERROR; /* Misaligned PPN */
} else {
/* Leaf PTE, translation completed. */
base = PPN_PHYS(ppn) | (addr & ((1ULL << va_skip) - 1));
break;
}
if (sc.step == sc.levels) {
return MEMTX_ACCESS_ERROR; /* Can't find leaf PTE */
}
} while (1);
out:
return dma_memory_read(s->target_as, base, buf, len, attrs);
}
/*
* RISC-V IOMMU Device Context Loopkup - Device Directory Tree Walk
*
@@ -1038,7 +1180,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx)
*/
const int split = depth * 9 + 8;
addr |= ((ctx->process_id >> split) << 3) & ~TARGET_PAGE_MASK;
if (dma_memory_read(s->target_as, addr, &de, sizeof(de),
if (pdt_memory_read(s, ctx, addr, &de, sizeof(de),
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT;
}
@@ -1053,7 +1195,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx)
/* Leaf entry in PDT */
addr |= (ctx->process_id << 4) & ~TARGET_PAGE_MASK;
if (dma_memory_read(s->target_as, addr, &dc.ta, sizeof(uint64_t) * 2,
if (pdt_memory_read(s, ctx, addr, &dc.ta, sizeof(uint64_t) * 2,
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT;
}
+1 -1
View File
@@ -1383,7 +1383,7 @@ static void usb_net_realize(USBDevice *dev, Error **errp)
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
snprintf(s->usbstring_mac, sizeof(s->usbstring_mac),
"%02x%02x%02x%02x%02x%02x",
0x40,
s->conf.macaddr.a[0],
s->conf.macaddr.a[1],
s->conf.macaddr.a[2],
s->conf.macaddr.a[3],
+8 -2
View File
@@ -735,6 +735,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
bool spd;
bool queuing = (q != NULL);
uint8_t pid = td->token & 0xff;
uint8_t ep_id = (td->token >> 15) & 0xf;
UHCIAsync *async;
async = uhci_async_find_td(s, td_addr);
@@ -778,9 +779,14 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
switch (pid) {
case USB_TOKEN_OUT:
case USB_TOKEN_SETUP:
case USB_TOKEN_IN:
break;
case USB_TOKEN_SETUP:
/* SETUP is only valid to endpoint 0 */
if (ep_id == 0) {
break;
}
/* fallthrough */
default:
/* invalid pid : frame interrupted */
s->status |= UHCI_STS_HCPERR;
@@ -829,7 +835,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
return uhci_handle_td_error(s, td, td_addr, USB_RET_NODEV,
int_mask);
}
ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf);
ep = usb_ep_get(dev, pid, ep_id);
q = uhci_queue_new(s, qh_addr, td, ep);
}
async = uhci_async_alloc(q, td_addr);
+2
View File
@@ -406,6 +406,8 @@ static const Property vfio_user_pci_dev_properties[] = {
sub_vendor_id, PCI_ANY_ID),
DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
sub_device_id, PCI_ANY_ID),
DEFINE_PROP_UINT32("x-pci-class-code", VFIOPCIDevice,
class_code, PCI_ANY_ID),
DEFINE_PROP_BOOL("x-send-queued", VFIOUserPCIDevice, send_queued, false),
DEFINE_PROP_UINT32("x-msg-timeout", VFIOUserPCIDevice, wait_time, 5000),
DEFINE_PROP_BOOL("x-no-posted-writes", VFIOUserPCIDevice, no_post, false),
+1 -1
View File
@@ -885,7 +885,7 @@ VFIOUserProxy *vfio_user_connect_dev(SocketAddress *addr, Error **errp)
sioc = qio_channel_socket_new();
ioc = QIO_CHANNEL(sioc);
if (qio_channel_socket_connect_sync(sioc, addr, errp)) {
if (qio_channel_socket_connect_sync(sioc, addr, errp) < 0) {
object_unref(OBJECT(ioc));
return NULL;
}
+7
View File
@@ -56,6 +56,13 @@ typedef int64_t Elf64_Sxword;
#define EF_MIPS_ARCH_32R6 0x90000000 /* MIPS32r6 code. */
#define EF_MIPS_ARCH_64R6 0xa0000000 /* MIPS64r6 code. */
/* MIPS Architectural Extensions. */
#define EF_MIPS_ARCH_ASE 0x0f000000
#define EF_MIPS_ARCH_ASE_MICROMIPS 0x02000000
#define EF_MIPS_ARCH_ASE_M16 0x04000000
#define EF_MIPS_ARCH_ASE_MDMX 0x08000000
/* The ABI of a file. */
#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */
#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */
+5 -5
View File
@@ -123,13 +123,13 @@ size_t qemu_ram_pagesize_largest(void);
void cpu_address_space_init(CPUState *cpu, int asidx,
const char *prefix, MemoryRegion *mr);
/**
* cpu_address_space_destroy:
* @cpu: CPU for which address space needs to be destroyed
* @asidx: integer index of this address space
* cpu_destroy_address_spaces:
* @cpu: CPU for which address spaces need to be destroyed
*
* Note that with KVM only one address space is supported.
* Destroy all address spaces associated with this CPU; this
* is called as part of unrealizing the CPU.
*/
void cpu_address_space_destroy(CPUState *cpu, int asidx);
void cpu_destroy_address_spaces(CPUState *cpu);
void cpu_physical_memory_rw(hwaddr addr, void *buf,
hwaddr len, bool is_write);
+1 -1
View File
@@ -59,7 +59,7 @@ struct STM32F205State {
STM32F2XXADCState adc[STM_NUM_ADCS];
STM32F2XXSPIState spi[STM_NUM_SPIS];
OrIRQState *adc_irqs;
OrIRQState adc_irqs;
MemoryRegion sram;
MemoryRegion flash;
-1
View File
@@ -506,7 +506,6 @@ struct CPUState {
QSIMPLEQ_HEAD(, qemu_work_item) work_list;
struct CPUAddressSpace *cpu_ases;
int cpu_ases_count;
int num_ases;
AddressSpace *as;
MemoryRegion *memory;
+3
View File
@@ -27,6 +27,7 @@
#include "hw/sysbus.h"
#include "hw/intc/arm_gic_common.h"
#include "qom/object.h"
#include "qemu/notify.h"
/*
* Maximum number of possible interrupts, determined by the GIC architecture.
@@ -271,6 +272,8 @@ struct GICv3State {
GICv3CPUState *cpu;
/* List of all ITSes connected to this GIC */
GPtrArray *itslist;
NotifierWithReturn cpr_notifier;
};
#define GICV3_BITMAP_ACCESSORS(BMP) \
-4
View File
@@ -37,10 +37,6 @@ void pcie_sriov_pf_exit(PCIDevice *dev);
void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num,
uint8_t type, dma_addr_t size);
/* Instantiate a bar for a VF */
void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num,
MemoryRegion *memory);
/**
* pcie_sriov_pf_init_from_user_created_vfs() - Initialize PF with user-created
* VFs, adding ARI to PF
+21 -3
View File
@@ -2715,14 +2715,32 @@ void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name);
/**
* address_space_destroy: destroy an address space
*
* Releases all resources associated with an address space. After an address space
* is destroyed, its root memory region (given by address_space_init()) may be destroyed
* as well.
* Releases all resources associated with an address space. After an
* address space is destroyed, the reference the AddressSpace had to
* its root memory region is dropped, which may result in the
* destruction of that memory region as well.
*
* Note that destruction of the AddressSpace is done via RCU;
* it is therefore not valid to free the memory the AddressSpace
* struct is in until after that RCU callback has completed.
* If you want to g_free() the AddressSpace after destruction you
* can do that with address_space_destroy_free().
*
* @as: address space to be destroyed
*/
void address_space_destroy(AddressSpace *as);
/**
* address_space_destroy_free: destroy an address space and free it
*
* This does the same thing as address_space_destroy(), and then also
* frees (via g_free()) the AddressSpace itself once the destruction
* is complete.
*
* @as: address space to be destroyed
*/
void address_space_destroy_free(AddressSpace *as);
/**
* address_space_remove_listeners: unregister all listeners of an address space
*
+2 -1
View File
@@ -9,6 +9,7 @@
#define MICROBLAZE_TARGET_ELF_H
static inline const char *cpu_get_model(uint32_t eflags)
{
return "any";
return TARGET_BIG_ENDIAN ? "any,little-endian=off"
: "any,little-endian=on";
}
#endif
+6
View File
@@ -12,6 +12,12 @@ static inline const char *cpu_get_model(uint32_t eflags)
if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
return "mips32r6-generic";
}
if ((eflags & EF_MIPS_ARCH_ASE) == EF_MIPS_ARCH_ASE_MICROMIPS) {
return "M14Kc";
}
if ((eflags & EF_MIPS_ARCH_ASE) == EF_MIPS_ARCH_ASE_M16) {
return "74Kf";
}
if (eflags & EF_MIPS_NAN2008) {
return "P5600";
}
+1 -1
View File
@@ -54,7 +54,7 @@ struct flags {
};
/* No 'struct flags' element should have a zero mask. */
#define FLAG_BASIC(V, M, N) { V, M | QEMU_BUILD_BUG_ON_ZERO(!(M)), N }
#define FLAG_BASIC(V, M, N) { V, M | QEMU_BUILD_BUG_ON_ZERO((M) == 0), N }
/* common flags for all architectures */
#define FLAG_GENERIC_MASK(V, M) FLAG_BASIC(V, M, #V)
+3
View File
@@ -1719,3 +1719,6 @@
#ifdef TARGET_NR_riscv_hwprobe
{ TARGET_NR_riscv_hwprobe, "riscv_hwprobe" , "%s(%p,%d,%d,%d,%d,%d)", NULL, NULL },
#endif
#ifdef TARGET_NR_rseq
{ TARGET_NR_rseq, "rseq" , "%s(%p,%u,%d,%#x)", NULL, NULL },
#endif
+1
View File
@@ -1287,6 +1287,7 @@ endif
enable_passt = get_option('passt') \
.require(host_os == 'linux', error_message: 'passt is supported only on Linux') \
.require(gio.found(), error_message: 'passt requires gio') \
.allowed()
vde = not_found
+3 -2
View File
@@ -2872,8 +2872,9 @@ static int postcopy_start(MigrationState *ms, Error **errp)
fail_closefb:
qemu_fclose(fb);
fail:
migrate_set_state(&ms->state, MIGRATION_STATUS_POSTCOPY_ACTIVE,
MIGRATION_STATUS_FAILED);
if (ms->state != MIGRATION_STATUS_CANCELLING) {
migrate_set_state(&ms->state, ms->state, MIGRATION_STATUS_FAILED);
}
migration_block_activate(NULL);
migration_call_notifiers(ms, MIG_EVENT_PRECOPY_FAILED, NULL);
bql_unlock();
Binary file not shown.
+1 -1
View File
@@ -208,7 +208,7 @@ ljmp2:
prot_jump: .long prot_mode
.short 8
.align 4, 0
.align 8, 0
gdt:
/* 0x00 */
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+2
View File
@@ -177,6 +177,8 @@ class QEMUQtestMachine(QEMUMachine):
self._qtest_sock_pair[0].close()
self._qtest_sock_pair[1].close()
self._qtest_sock_pair = None
if self._qtest is not None:
self._qtest.close()
super()._post_shutdown()
def qtest(self, cmd: str) -> str:
+31 -11
View File
@@ -38,6 +38,7 @@ from typing import (
from .error import QMPError
from .protocol import Runstate, SocketAddrT
from .qmp_client import QMPClient
from .util import get_or_create_event_loop
#: QMPMessage is an entire QMP message of any kind.
@@ -86,10 +87,13 @@ class QEMUMonitorProtocol:
"server argument should be False when passing a socket")
self._qmp = QMPClient(nickname)
self._aloop = asyncio.get_event_loop()
self._address = address
self._timeout: Optional[float] = None
# This is a sync shim intended for use in fully synchronous
# programs. Create and set an event loop if necessary.
self._aloop = get_or_create_event_loop()
if server:
assert not isinstance(self._address, socket.socket)
self._sync(self._qmp.start_server(self._address))
@@ -231,6 +235,9 @@ class QEMUMonitorProtocol:
:return: The first available QMP event, or None.
"""
# Kick the event loop to allow events to accumulate
self._sync(asyncio.sleep(0))
if not wait:
# wait is False/0: "do not wait, do not except."
if self._qmp.events.empty():
@@ -303,17 +310,30 @@ class QEMUMonitorProtocol:
self._qmp.send_fd_scm(fd)
def __del__(self) -> None:
if self._qmp.runstate == Runstate.IDLE:
return
if self._qmp.runstate != Runstate.IDLE:
self._qmp.logger.warning(
"QEMUMonitorProtocol object garbage collected without a prior "
"call to close()"
)
if not self._aloop.is_running():
self.close()
else:
# Garbage collection ran while the event loop was running.
# Nothing we can do about it now, but if we don't raise our
# own error, the user will be treated to a lot of traceback
# they might not understand.
if self._qmp.runstate != Runstate.IDLE:
# If the user neglected to close the QMP session and we
# are not currently running in an asyncio context, we
# have the opportunity to close the QMP session. If we
# do not do this, the error messages presented over
# dangling async resources may not make any sense to the
# user.
self.close()
if self._qmp.runstate != Runstate.IDLE:
# If QMP is still not quiesced, it means that the garbage
# collector ran from a context within the event loop and we
# are simply too late to take any corrective action. Raise
# our own error to give meaningful feedback to the user in
# order to prevent pages of asyncio stacktrace jargon.
raise QMPError(
"QEMUMonitorProtocol.close()"
" was not called before object was garbage collected"
"QEMUMonitorProtocol.close() was not called before object was "
"garbage collected, and could not be closed due to GC running "
"in the event loop"
)
+21 -27
View File
@@ -15,6 +15,7 @@ class.
import asyncio
from asyncio import StreamReader, StreamWriter
from contextlib import asynccontextmanager
from enum import Enum
from functools import wraps
import logging
@@ -22,6 +23,7 @@ import socket
from ssl import SSLContext
from typing import (
Any,
AsyncGenerator,
Awaitable,
Callable,
Generic,
@@ -36,13 +38,10 @@ from typing import (
from .error import QMPError
from .util import (
bottom_half,
create_task,
exception_summary,
flush,
is_closing,
pretty_traceback,
upper_half,
wait_closed,
)
@@ -321,9 +320,8 @@ class AsyncProtocol(Generic[T]):
This exception will wrap a more concrete one. In most cases,
the wrapped exception will be `OSError`.
"""
await self._session_guard(
self._do_start_server(address, ssl),
'Failed to establish connection')
async with self._session_guard('Failed to establish connection'):
await self._do_start_server(address, ssl)
assert self.runstate == Runstate.CONNECTING
@upper_half
@@ -346,12 +344,10 @@ class AsyncProtocol(Generic[T]):
"""
if self._accepted is None:
raise QMPError("Cannot call accept() before start_server().")
await self._session_guard(
self._do_accept(),
'Failed to establish connection')
await self._session_guard(
self._establish_session(),
'Failed to establish session')
async with self._session_guard('Failed to establish connection'):
await self._do_accept()
async with self._session_guard('Failed to establish session'):
await self._establish_session()
assert self.runstate == Runstate.RUNNING
@upper_half
@@ -376,12 +372,10 @@ class AsyncProtocol(Generic[T]):
protocol-level failure occurs while establishing a new
session, the wrapped error may also be an `QMPError`.
"""
await self._session_guard(
self._do_connect(address, ssl),
'Failed to establish connection')
await self._session_guard(
self._establish_session(),
'Failed to establish session')
async with self._session_guard('Failed to establish connection'):
await self._do_connect(address, ssl)
async with self._session_guard('Failed to establish session'):
await self._establish_session()
assert self.runstate == Runstate.RUNNING
@upper_half
@@ -402,7 +396,8 @@ class AsyncProtocol(Generic[T]):
# Section: Session machinery
# --------------------------
async def _session_guard(self, coro: Awaitable[None], emsg: str) -> None:
@asynccontextmanager
async def _session_guard(self, emsg: str) -> AsyncGenerator[None, None]:
"""
Async guard function used to roll back to `IDLE` on any error.
@@ -419,10 +414,9 @@ class AsyncProtocol(Generic[T]):
:raise ConnectError:
When any other error is encountered in the guarded block.
"""
# Note: After Python 3.6 support is removed, this should be an
# @asynccontextmanager instead of accepting a callback.
try:
await coro
# Caller's code runs here.
yield
except BaseException as err:
self.logger.error("%s: %s", emsg, exception_summary(err))
self.logger.debug("%s:\n%s\n", emsg, pretty_traceback())
@@ -663,8 +657,8 @@ class AsyncProtocol(Generic[T]):
reader_coro = self._bh_loop_forever(self._bh_recv_message, 'Reader')
writer_coro = self._bh_loop_forever(self._bh_send_message, 'Writer')
self._reader_task = create_task(reader_coro)
self._writer_task = create_task(writer_coro)
self._reader_task = asyncio.create_task(reader_coro)
self._writer_task = asyncio.create_task(writer_coro)
self._bh_tasks = asyncio.gather(
self._reader_task,
@@ -689,7 +683,7 @@ class AsyncProtocol(Generic[T]):
if not self._dc_task:
self._set_state(Runstate.DISCONNECTING)
self.logger.debug("Scheduling disconnect.")
self._dc_task = create_task(self._bh_disconnect())
self._dc_task = asyncio.create_task(self._bh_disconnect())
@upper_half
async def _wait_disconnect(self) -> None:
@@ -825,13 +819,13 @@ class AsyncProtocol(Generic[T]):
if not self._writer:
return
if not is_closing(self._writer):
if not self._writer.is_closing():
self.logger.debug("Closing StreamWriter.")
self._writer.close()
self.logger.debug("Waiting for StreamWriter to close ...")
try:
await wait_closed(self._writer)
await self._writer.wait_closed()
except Exception: # pylint: disable=broad-except
# It's hard to tell if the Stream is already closed or
# not. Even if one of the tasks has failed, it may have
+2
View File
@@ -610,6 +610,8 @@ def main_wrap() -> None:
for _ in qemu.repl():
pass
except FileNotFoundError:
sys.stderr.write(f"ERROR: QEMU executable '{cmd[0]}' not found.\n")
finally:
os.unlink(sockpath)
+20 -10
View File
@@ -21,6 +21,7 @@ import json
import logging
from logging import Handler, LogRecord
import signal
import sys
from typing import (
List,
Optional,
@@ -30,17 +31,27 @@ from typing import (
cast,
)
from pygments import lexers
from pygments import token as Token
import urwid
import urwid_readline
try:
from pygments import lexers
from pygments import token as Token
import urwid
import urwid_readline
except ModuleNotFoundError as exc:
print(
f"Module '{exc.name}' not found.",
"You need the optional 'tui' group: pip install qemu.qmp[tui]",
sep='\n',
file=sys.stderr,
)
sys.exit(1)
from .error import ProtocolError
from .legacy import QEMUMonitorProtocol, QMPBadPortError
from .message import DeserializationError, Message, UnexpectedTypeError
from .protocol import ConnectError, Runstate
from .qmp_client import ExecInterruptedError, QMPClient
from .util import create_task, pretty_traceback
from .util import get_or_create_event_loop, pretty_traceback
# The name of the signal that is used to update the history list
@@ -225,7 +236,7 @@ class App(QMPClient):
"""
try:
msg = Message(bytes(raw_msg, encoding='utf-8'))
create_task(self._send_to_server(msg))
asyncio.create_task(self._send_to_server(msg))
except (DeserializationError, UnexpectedTypeError) as err:
raw_msg = format_json(raw_msg)
logging.info('Invalid message: %s', err.error_message)
@@ -246,7 +257,7 @@ class App(QMPClient):
Initiates killing of app. A bridge between asynchronous and synchronous
code.
"""
create_task(self._kill_app())
asyncio.create_task(self._kill_app())
async def _kill_app(self) -> None:
"""
@@ -376,8 +387,7 @@ class App(QMPClient):
"""
screen = urwid.raw_display.Screen()
screen.set_terminal_properties(256)
self.aloop = asyncio.get_event_loop()
self.aloop = get_or_create_event_loop()
self.aloop.set_debug(debug)
# Gracefully handle SIGTERM and SIGINT signals
@@ -393,7 +403,7 @@ class App(QMPClient):
handle_mouse=True,
event_loop=event_loop)
create_task(self.manage_connection(), self.aloop)
self.aloop.create_task(self.manage_connection())
try:
main_loop.run()
except Exception as err:
+31 -103
View File
@@ -1,25 +1,16 @@
"""
Miscellaneous Utilities
This module provides asyncio utilities and compatibility wrappers for
Python 3.6 to provide some features that otherwise become available in
Python 3.7+.
Various logging and debugging utilities are also provided, such as
`exception_summary()` and `pretty_traceback()`, used primarily for
adding information into the logging stream.
This module provides asyncio and various logging and debugging
utilities, such as `exception_summary()` and `pretty_traceback()`, used
primarily for adding information into the logging stream.
"""
import asyncio
import sys
import traceback
from typing import (
Any,
Coroutine,
Optional,
TypeVar,
cast,
)
from typing import TypeVar, cast
import warnings
T = TypeVar('T')
@@ -30,6 +21,32 @@ T = TypeVar('T')
# --------------------------
def get_or_create_event_loop() -> asyncio.AbstractEventLoop:
"""
Return this thread's current event loop, or create a new one.
This function behaves similarly to asyncio.get_event_loop() in
Python<=3.13, where if there is no event loop currently associated
with the current context, it will create and register one. It should
generally not be used in any asyncio-native applications.
"""
try:
with warnings.catch_warnings():
# Python <= 3.13 will trigger deprecation warnings if no
# event loop is set, but will create and set a new loop.
warnings.simplefilter("ignore")
loop = asyncio.get_event_loop()
except RuntimeError:
# Python 3.14+: No event loop set for this thread,
# create and set one.
loop = asyncio.new_event_loop()
# Set this loop as the current thread's loop, to be returned
# by calls to get_event_loop() in the future.
asyncio.set_event_loop(loop)
return loop
async def flush(writer: asyncio.StreamWriter) -> None:
"""
Utility function to ensure a StreamWriter is *fully* drained.
@@ -79,95 +96,6 @@ def bottom_half(func: T) -> T:
return func
# -------------------------------
# Section: Compatibility Wrappers
# -------------------------------
def create_task(coro: Coroutine[Any, Any, T],
loop: Optional[asyncio.AbstractEventLoop] = None
) -> 'asyncio.Future[T]':
"""
Python 3.6-compatible `asyncio.create_task` wrapper.
:param coro: The coroutine to execute in a task.
:param loop: Optionally, the loop to create the task in.
:return: An `asyncio.Future` object.
"""
if sys.version_info >= (3, 7):
if loop is not None:
return loop.create_task(coro)
return asyncio.create_task(coro) # pylint: disable=no-member
# Python 3.6:
return asyncio.ensure_future(coro, loop=loop)
def is_closing(writer: asyncio.StreamWriter) -> bool:
"""
Python 3.6-compatible `asyncio.StreamWriter.is_closing` wrapper.
:param writer: The `asyncio.StreamWriter` object.
:return: `True` if the writer is closing, or closed.
"""
if sys.version_info >= (3, 7):
return writer.is_closing()
# Python 3.6:
transport = writer.transport
assert isinstance(transport, asyncio.WriteTransport)
return transport.is_closing()
async def wait_closed(writer: asyncio.StreamWriter) -> None:
"""
Python 3.6-compatible `asyncio.StreamWriter.wait_closed` wrapper.
:param writer: The `asyncio.StreamWriter` to wait on.
"""
if sys.version_info >= (3, 7):
await writer.wait_closed()
return
# Python 3.6
transport = writer.transport
assert isinstance(transport, asyncio.WriteTransport)
while not transport.is_closing():
await asyncio.sleep(0)
# This is an ugly workaround, but it's the best I can come up with.
sock = transport.get_extra_info('socket')
if sock is None:
# Our transport doesn't have a socket? ...
# Nothing we can reasonably do.
return
while sock.fileno() != -1:
await asyncio.sleep(0)
def asyncio_run(coro: Coroutine[Any, Any, T], *, debug: bool = False) -> T:
"""
Python 3.6-compatible `asyncio.run` wrapper.
:param coro: A coroutine to execute now.
:return: The return value from the coroutine.
"""
if sys.version_info >= (3, 7):
return asyncio.run(coro, debug=debug)
# Python 3.6
loop = asyncio.get_event_loop()
loop.set_debug(debug)
ret = loop.run_until_complete(coro)
loop.close()
return ret
# ----------------------------
# Section: Logging & Debugging
# ----------------------------
+4
View File
@@ -184,6 +184,10 @@ class Matcher:
)
)
def __str__(self) -> str:
"""String representation delegated to the backend."""
return str(self._m)
def __repr__(self) -> str:
"""Stable debug representation delegated to the backend."""
return repr(self._m)
+5 -5
View File
@@ -8,7 +8,6 @@ import avocado
from qemu.qmp import ConnectError, Runstate
from qemu.qmp.protocol import AsyncProtocol, StateError
from qemu.qmp.util import asyncio_run, create_task
class NullProtocol(AsyncProtocol[None]):
@@ -124,7 +123,7 @@ def run_as_task(coro, allow_cancellation=False):
if allow_cancellation:
return
raise
return create_task(_runner())
return asyncio.create_task(_runner())
@contextmanager
@@ -228,7 +227,7 @@ class TestBase(avocado.Test):
Decorator; adds SetUp and TearDown to async tests.
"""
async def _wrapper(self, *args, **kwargs):
loop = asyncio.get_event_loop()
loop = asyncio.get_running_loop()
loop.set_debug(True)
await self._asyncSetUp()
@@ -271,7 +270,7 @@ class TestBase(avocado.Test):
msg=f"Expected state '{state.name}'",
)
self.runstate_watcher = create_task(_watcher())
self.runstate_watcher = asyncio.create_task(_watcher())
# Kick the loop and force the task to block on the event.
await asyncio.sleep(0)
@@ -589,7 +588,8 @@ class SimpleSession(TestBase):
async def testSmoke(self):
with TemporaryDirectory(suffix='.qmp') as tmpdir:
sock = os.path.join(tmpdir, type(self.proto).__name__ + ".sock")
server_task = create_task(self.server.start_server_and_accept(sock))
server_task = asyncio.create_task(
self.server.start_server_and_accept(sock))
# give the server a chance to start listening [...]
await asyncio.sleep(0)
+4 -2
View File
@@ -205,13 +205,15 @@ GuestExecStatus *qmp_guest_exec_status(int64_t pid, Error **errp)
#endif
if (gei->out.length > 0) {
ges->out_data = g_base64_encode(gei->out.data, gei->out.length);
ges->has_out_truncated = gei->out.truncated;
ges->has_out_truncated = true;
ges->out_truncated = gei->out.truncated;
}
g_free(gei->out.data);
if (gei->err.length > 0) {
ges->err_data = g_base64_encode(gei->err.data, gei->err.length);
ges->has_err_truncated = gei->err.truncated;
ges->has_err_truncated = true;
ges->err_truncated = gei->err.truncated;
}
g_free(gei->err.data);
+21 -2
View File
@@ -151,6 +151,14 @@
Return="check"
>
</CustomAction>
<CustomAction Id="UnRegisterCom_Rollback"
ExeCommand='"[qemu_ga_directory]qga-vss.dll",DLLCOMUnregister'
Execute="rollback"
Property="rundll"
Impersonate="no"
Return="check"
>
</CustomAction>
<?endif?>
<Feature Id="QEMUFeature" Title="QEMU Guest Agent" Level="1">
@@ -174,8 +182,19 @@
<InstallExecuteSequence>
<?ifdef var.InstallVss?>
<Custom Action="UnRegisterCom" After="StopServices">Installed</Custom>
<Custom Action="RegisterCom" After="InstallServices">NOT REMOVE</Custom>
<!-- Use explicit Sequence number to provide an absolute position in the sequence-->
<!-- This is needed to set "UnRegisterCom_Rollback" before "RegisterCom" and after "InstallFiles"-->
<!-- but, Wix detect this double condition incorrectly -->
<!-- UnRegisterCom_Rollback (for install rollback): at 5849, right before RegisterCom (5850)-->
<!-- Runs only if the installation fails and rolls back-->
<Custom Action="UnRegisterCom_Rollback" Sequence="5849">NOT REMOVE</Custom>
<!-- RegisterCom (for install): at 5850, right after InstallFiles (5849) (old: After="InstallServices")-->
<Custom Action="RegisterCom" Sequence="5850">NOT REMOVE</Custom>
<!-- UnRegisterCom (for uninstall): at 1901, right after StopServices (1900) (old: After="StopServices")-->
<Custom Action="UnRegisterCom" Sequence="1901">Installed</Custom>
<?endif?>
</InstallExecuteSequence>
</Product>
+3 -2
View File
@@ -28,8 +28,9 @@
#define err_set(e, err, fmt, ...) { \
(e)->error_setg_win32_wrapper((e)->errp, __FILE__, __LINE__, __func__, \
err, fmt, ## __VA_ARGS__); \
qga_debug(fmt, ## __VA_ARGS__); \
err, fmt ": Windows error 0x%lx", \
## __VA_ARGS__, err); \
qga_debug(fmt ": Windows error 0x%lx", ## __VA_ARGS__, err); \
}
/* Bad idea, works only when (e)->errp != NULL: */
#define err_is_set(e) ((e)->errp && *(e)->errp)
+4 -5
View File
@@ -1594,13 +1594,12 @@ sub push_parameter($$$$$) {
if ($type eq "" && $param =~ /\.\.\.$/)
{
if (!$param =~ /\w\.\.\.$/) {
# handles unnamed variable parameters
$param = "...";
}
elsif ($param =~ /\w\.\.\.$/) {
if ($param =~ /\w\.\.\.$/) {
# for named variable parameters of the form `x...`, remove the dots
$param =~ s/\.\.\.$//;
} else {
# handles unnamed variable parameters
$param = "...";
}
if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
$parameterdescs{$param} = "variable arguments";
+2 -7
View File
@@ -105,20 +105,15 @@ static int pr_manager_helper_initialize(PRManagerHelper *pr_mgr,
.u.q_unix.path = path
};
QIOChannelSocket *sioc = qio_channel_socket_new();
Error *local_err = NULL;
uint32_t flags;
int r;
assert(!pr_mgr->ioc);
qio_channel_set_name(QIO_CHANNEL(sioc), "pr-manager-helper");
qio_channel_socket_connect_sync(sioc,
&saddr,
&local_err);
r = qio_channel_socket_connect_sync(sioc, &saddr, errp);
g_free(path);
if (local_err) {
if (r < 0) {
object_unref(OBJECT(sioc));
error_propagate(errp, local_err);
return -ENOTCONN;
}
+15
View File
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "exec/cpu-common.h"
/*
* user-mode CPUs never create address spaces with
* cpu_address_space_init(), so the cleanup function doesn't
* need to do anything. We need this stub because cpu-common.c
* is built-once so it can't #ifndef CONFIG_USER around the
* call; the real function is in physmem.c which is system-only.
*/
void cpu_destroy_address_spaces(CPUState *cpu)
{
}
+1
View File
@@ -55,6 +55,7 @@ endif
if have_user
# Symbols that are used by hw/core.
stub_ss.add(files('cpu-synchronize-state.c'))
stub_ss.add(files('cpu-destroy-address-spaces.c'))
# Stubs for QAPI events. Those can always be included in the build, but
# they are not built at all for --disable-system builds.
+19 -1
View File
@@ -3235,7 +3235,14 @@ static void do_address_space_destroy(AddressSpace *as)
memory_region_unref(as->root);
}
void address_space_destroy(AddressSpace *as)
static void do_address_space_destroy_free(AddressSpace *as)
{
do_address_space_destroy(as);
g_free(as);
}
/* Detach address space from global view, notify all listeners */
static void address_space_detach(AddressSpace *as)
{
MemoryRegion *root = as->root;
@@ -3250,9 +3257,20 @@ void address_space_destroy(AddressSpace *as)
* values to expire before freeing the data.
*/
as->root = root;
}
void address_space_destroy(AddressSpace *as)
{
address_space_detach(as);
call_rcu(as, do_address_space_destroy, rcu);
}
void address_space_destroy_free(AddressSpace *as)
{
address_space_detach(as);
call_rcu(as, do_address_space_destroy_free, rcu);
}
static const char *memory_region_type(MemoryRegion *mr)
{
if (mr->alias) {
+16 -23
View File
@@ -793,12 +793,8 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
cpu->as = as;
}
/* KVM cannot currently support multiple address spaces. */
assert(asidx == 0 || !kvm_enabled());
if (!cpu->cpu_ases) {
cpu->cpu_ases = g_new0(CPUAddressSpace, cpu->num_ases);
cpu->cpu_ases_count = cpu->num_ases;
}
newas = &cpu->cpu_ases[asidx];
@@ -812,32 +808,29 @@ void cpu_address_space_init(CPUState *cpu, int asidx,
}
}
void cpu_address_space_destroy(CPUState *cpu, int asidx)
void cpu_destroy_address_spaces(CPUState *cpu)
{
CPUAddressSpace *cpuas;
int asidx;
assert(cpu->cpu_ases);
assert(asidx >= 0 && asidx < cpu->num_ases);
/* KVM cannot currently support multiple address spaces. */
assert(asidx == 0 || !kvm_enabled());
cpuas = &cpu->cpu_ases[asidx];
if (tcg_enabled()) {
memory_listener_unregister(&cpuas->tcg_as_listener);
/* convenience alias just points to some cpu_ases[n] */
cpu->as = NULL;
for (asidx = 0; asidx < cpu->num_ases; asidx++) {
cpuas = &cpu->cpu_ases[asidx];
if (!cpuas->as) {
/* This index was never initialized; no deinit needed */
continue;
}
if (tcg_enabled()) {
memory_listener_unregister(&cpuas->tcg_as_listener);
}
g_clear_pointer(&cpuas->as, address_space_destroy_free);
}
address_space_destroy(cpuas->as);
g_free_rcu(cpuas->as, rcu);
if (asidx == 0) {
/* reset the convenience alias for address space 0 */
cpu->as = NULL;
}
if (--cpu->cpu_ases_count == 0) {
g_free(cpu->cpu_ases);
cpu->cpu_ases = NULL;
}
g_clear_pointer(&cpu->cpu_ases, g_free);
}
AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx)
+26 -8
View File
@@ -228,22 +228,27 @@ static bool event_supported(uint16_t number)
return supported_event_map[number] != UNSUPPORTED_EVENT;
}
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
static CPAccessResult do_pmreg_access(CPUARMState *env, bool is_pmcr)
{
/*
* Performance monitor registers user accessibility is controlled
* by PMUSERENR. MDCR_EL2.TPM and MDCR_EL3.TPM allow configurable
* by PMUSERENR. MDCR_EL2.TPM/TPMCR and MDCR_EL3.TPM allow configurable
* trapping to EL2 or EL3 for other accesses.
*/
int el = arm_current_el(env);
uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
if (el == 0 && !(env->cp15.c9_pmuserenr & 1)) {
return CP_ACCESS_TRAP_EL1;
}
if (el < 2 && (mdcr_el2 & MDCR_TPM)) {
return CP_ACCESS_TRAP_EL2;
if (el < 2) {
uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
if (mdcr_el2 & MDCR_TPM) {
return CP_ACCESS_TRAP_EL2;
}
if (is_pmcr && (mdcr_el2 & MDCR_TPMCR)) {
return CP_ACCESS_TRAP_EL2;
}
}
if (el < 3 && (env->cp15.mdcr_el3 & MDCR_TPM)) {
return CP_ACCESS_TRAP_EL3;
@@ -252,6 +257,19 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
return CP_ACCESS_OK;
}
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
{
return do_pmreg_access(env, false);
}
static CPAccessResult pmreg_access_pmcr(CPUARMState *env,
const ARMCPRegInfo *ri,
bool isread)
{
return do_pmreg_access(env, true);
}
static CPAccessResult pmreg_access_xevcntr(CPUARMState *env,
const ARMCPRegInfo *ri,
bool isread)
@@ -1187,14 +1205,14 @@ void define_pm_cpregs(ARMCPU *cpu)
.fgt = FGT_PMCR_EL0,
.type = ARM_CP_IO | ARM_CP_ALIAS,
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
.accessfn = pmreg_access,
.accessfn = pmreg_access_pmcr,
.readfn = pmcr_read, .raw_readfn = raw_read,
.writefn = pmcr_write, .raw_writefn = raw_write,
};
const ARMCPRegInfo pmcr64 = {
.name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
.access = PL0_RW, .accessfn = pmreg_access,
.access = PL0_RW, .accessfn = pmreg_access_pmcr,
.fgt = FGT_PMCR_EL0,
.type = ARM_CP_IO,
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
+2 -1
View File
@@ -3728,7 +3728,8 @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
value &= valid_mask;
/* RW is RAO/WI if EL1 is AArch64 only */
if (!cpu_isar_feature(aa64_aa32_el1, cpu)) {
if (arm_feature(env, ARM_FEATURE_AARCH64) &&
!cpu_isar_feature(aa64_aa32_el1, cpu)) {
value |= HCR_RW;
}
+4 -4
View File
@@ -365,10 +365,10 @@ fstd 011100 ..... ..... .. ............1. @ldstim11
&mpyadd rm1 rm2 ta ra tm
@mpyadd ...... rm1:5 rm2:5 ta:5 ra:5 . tm:5 &mpyadd
fmpyadd_f 000110 ..... ..... ..... ..... 0 ..... @mpyadd
fmpyadd_d 000110 ..... ..... ..... ..... 1 ..... @mpyadd
fmpysub_f 100110 ..... ..... ..... ..... 0 ..... @mpyadd
fmpysub_d 100110 ..... ..... ..... ..... 1 ..... @mpyadd
fmpyadd_f 000110 ..... ..... ..... ..... 1 ..... @mpyadd
fmpyadd_d 000110 ..... ..... ..... ..... 0 ..... @mpyadd
fmpysub_f 100110 ..... ..... ..... ..... 1 ..... @mpyadd
fmpysub_d 100110 ..... ..... ..... ..... 0 ..... @mpyadd
####
# Conditional Branches
+33 -3
View File
@@ -7539,6 +7539,20 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
#endif
break;
case FEAT_7_0_EDX:
/*
* Windows does not like ARCH_CAPABILITIES on AMD machines at all.
* Do not show the fake ARCH_CAPABILITIES MSR that KVM sets up,
* except if needed for migration.
*
* When arch_cap_always_on is removed, this tweak can move to
* kvm_arch_get_supported_cpuid.
*/
if (cpu && IS_AMD_CPU(&cpu->env) && !cpu->arch_cap_always_on) {
unavail = CPUID_7_0_EDX_ARCH_CAPABILITIES;
}
break;
default:
break;
}
@@ -7894,6 +7908,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
/* Fixup overflow: max value for bits 23-16 is 255. */
*ebx |= MIN(num, 255) << 16;
}
if (cpu->pdcm_on_even_without_pmu) {
if (!cpu->enable_pmu) {
*ecx &= ~CPUID_EXT_PDCM;
}
}
break;
case 2: { /* cache info: needed for Pentium Pro compatibility */
const CPUCaches *caches;
@@ -8613,7 +8632,11 @@ static void x86_cpu_reset_hold(Object *obj, ResetType type)
env->idt.limit = 0xffff;
env->gdt.limit = 0xffff;
#if defined(CONFIG_USER_ONLY)
env->ldt.limit = 0;
#else
env->ldt.limit = 0xffff;
#endif
env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
env->tr.limit = 0xffff;
env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
@@ -8944,9 +8967,11 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
}
}
/* PDCM is fixed1 bit for TDX */
if (!cpu->enable_pmu && !is_tdx_vm()) {
env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM;
if (!cpu->pdcm_on_even_without_pmu) {
/* PDCM is fixed1 bit for TDX */
if (!cpu->enable_pmu && !is_tdx_vm()) {
env->features[FEAT_1_ECX] &= ~CPUID_EXT_PDCM;
}
}
for (i = 0; i < ARRAY_SIZE(feature_dependencies); i++) {
@@ -10004,6 +10029,11 @@ static const Property x86_cpu_properties[] = {
true),
DEFINE_PROP_BOOL("x-l1-cache-per-thread", X86CPU, l1_cache_per_core, true),
DEFINE_PROP_BOOL("x-force-cpuid-0x1f", X86CPU, force_cpuid_0x1f, false),
DEFINE_PROP_BOOL("x-arch-cap-always-on", X86CPU,
arch_cap_always_on, false),
DEFINE_PROP_BOOL("x-pdcm-on-even-without-pmu", X86CPU,
pdcm_on_even_without_pmu, false),
};
#ifndef CONFIG_USER_ONLY
+17
View File
@@ -2314,6 +2314,18 @@ struct ArchCPU {
/* Forcefully disable KVM PV features not exposed in guest CPUIDs */
bool kvm_pv_enforce_cpuid;
/*
* Expose arch-capabilities unconditionally even on AMD models, for backwards
* compatibility with QEMU <10.1.
*/
bool arch_cap_always_on;
/*
* Backwards compatibility with QEMU <10.1. The PDCM feature is now disabled when
* PMU is not available, but prior to 10.1 it was enabled even if PMU is off.
*/
bool pdcm_on_even_without_pmu;
/* Number of physical address bits supported */
uint32_t phys_bits;
@@ -2574,6 +2586,11 @@ static inline bool x86_has_cpuid_0x1f(X86CPU *cpu)
void x86_cpu_set_a20(X86CPU *cpu, int a20_state);
void cpu_sync_avx_hflag(CPUX86State *env);
typedef enum X86ASIdx {
X86ASIdx_MEM = 0,
X86ASIdx_SMM = 1,
} X86ASIdx;
#ifndef CONFIG_USER_ONLY
static inline int x86_asidx_from_attrs(CPUState *cs, MemTxAttrs attrs)
{
+4
View File
@@ -619,6 +619,10 @@ void do_cpu_init(X86CPU *cpu)
void do_cpu_sipi(X86CPU *cpu)
{
CPUX86State *env = &cpu->env;
if (env->hflags & HF_SMM_MASK) {
return;
}
apic_sipi(cpu->apic_state);
}
+10
View File
@@ -13,6 +13,7 @@
#include "qapi/error.h"
#include "system/system.h"
#include "hw/boards.h"
#include "hw/i386/x86.h"
#include "kvm_i386.h"
#include "accel/accel-cpu-target.h"
@@ -91,6 +92,15 @@ static bool kvm_cpu_realizefn(CPUState *cs, Error **errp)
kvm_set_guest_phys_bits(cs);
}
/*
* When SMM is enabled, there is 2 address spaces. Otherwise only 1.
*
* Only initialize address space 0 here, the second one for SMM is
* initialized at register_smram_listener() after machine init done.
*/
cs->num_ases = x86_machine_is_smm_enabled(X86_MACHINE(current_machine)) ? 2 : 1;
cpu_address_space_init(cs, X86ASIdx_MEM, "cpu-memory", cs->memory);
return true;
}
+24 -6
View File
@@ -503,12 +503,8 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
* Linux v4.17-v4.20 incorrectly return ARCH_CAPABILITIES on SVM hosts.
* We can detect the bug by checking if MSR_IA32_ARCH_CAPABILITIES is
* returned by KVM_GET_MSR_INDEX_LIST.
*
* But also, because Windows does not like ARCH_CAPABILITIES on AMD
* mcahines at all, do not show the fake ARCH_CAPABILITIES MSR that
* KVM sets up.
*/
if (!has_msr_arch_capabs || !(edx & CPUID_7_0_EDX_ARCH_CAPABILITIES)) {
if (!has_msr_arch_capabs) {
ret &= ~CPUID_7_0_EDX_ARCH_CAPABILITIES;
}
} else if (function == 7 && index == 1 && reg == R_EAX) {
@@ -657,6 +653,23 @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
must_be_one = (uint32_t)value;
can_be_one = (uint32_t)(value >> 32);
return can_be_one & ~must_be_one;
case MSR_IA32_ARCH_CAPABILITIES:
/*
* Special handling for fb-clear bit in ARCH_CAPABILITIES MSR.
* KVM will only report the bit if it is enabled in the host,
* but, for live migration capability purposes, we want to
* expose the bit to the guest even if it is disabled in the
* host, as long as the host itself is not vulnerable to
* the issue that the fb-clear bit is meant to mitigate.
*/
if ((value & MSR_ARCH_CAP_MDS_NO) &&
(value & MSR_ARCH_CAP_TAA_NO) &&
(value & MSR_ARCH_CAP_SBDR_SSDP_NO) &&
(value & MSR_ARCH_CAP_FBSDP_NO) &&
(value & MSR_ARCH_CAP_PSDP_NO)) {
value |= MSR_ARCH_CAP_FB_CLEAR;
}
return value;
default:
return value;
@@ -2704,6 +2717,7 @@ static MemoryRegion smram_as_mem;
static void register_smram_listener(Notifier *n, void *unused)
{
CPUState *cpu;
MemoryRegion *smram =
(MemoryRegion *) object_resolve_path("/machine/smram", NULL);
@@ -2727,7 +2741,11 @@ static void register_smram_listener(Notifier *n, void *unused)
address_space_init(&smram_address_space, &smram_as_root, "KVM-SMRAM");
kvm_memory_listener_register(kvm_state, &smram_listener,
&smram_address_space, 1, "kvm-smram");
&smram_address_space, X86ASIdx_SMM, "kvm-smram");
CPU_FOREACH(cpu) {
cpu_address_space_init(cpu, X86ASIdx_SMM, "cpu-smm", &smram_as_root);
}
}
static void *kvm_msr_energy_thread(void *data)
+1 -5
View File
@@ -57,13 +57,9 @@ QIOChannelSocket *vmsr_open_socket(const char *path)
};
QIOChannelSocket *sioc = qio_channel_socket_new();
Error *local_err = NULL;
qio_channel_set_name(QIO_CHANNEL(sioc), "vmsr-helper");
qio_channel_socket_connect_sync(sioc,
&saddr,
&local_err);
if (local_err) {
if (qio_channel_socket_connect_sync(sioc, &saddr, NULL) < 0) {
/* Close socket. */
qio_channel_close(QIO_CHANNEL(sioc), NULL);
object_unref(OBJECT(sioc));
+1 -1
View File
@@ -1541,7 +1541,7 @@ static void decode_group4_5(DisasContext *s, CPUX86State *env, X86OpEntry *entry
[0x0b] = X86_OP_ENTRYr(CALLF_m, M,p),
[0x0c] = X86_OP_ENTRYr(JMP_m, E,f64, zextT0),
[0x0d] = X86_OP_ENTRYr(JMPF_m, M,p),
[0x0e] = X86_OP_ENTRYr(PUSH, E,f64),
[0x0e] = X86_OP_ENTRYr(PUSH, E,d64),
};
int w = (*b & 1);
+1 -1
View File
@@ -456,7 +456,7 @@ static void switch_tss_ra(CPUX86State *env, int tss_selector,
new_segs[i] = access_ldw(&new, tss_base + (0x48 + i * 4));
}
new_ldt = access_ldw(&new, tss_base + 0x60);
new_trap = access_ldl(&new, tss_base + 0x64);
new_trap = access_ldw(&new, tss_base + 0x64) & 1;
} else {
/* 16 bit */
new_cr3 = 0;
+2 -1
View File
@@ -592,7 +592,8 @@ static bool get_physical_address(CPUX86State *env, vaddr addr,
if (sext != 0 && sext != -1) {
*err = (TranslateFault){
.exception_index = EXCP0D_GPF,
.cr2 = addr,
/* non-canonical #GP doesn't change CR2 */
.cr2 = env->cr[2],
};
return false;
}
+1
View File
@@ -182,6 +182,7 @@ bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
apic_poll_irq(cpu->apic_state);
break;
case CPU_INTERRUPT_SIPI:
cpu_reset_interrupt(cs, CPU_INTERRUPT_SIPI);
do_cpu_sipi(cpu);
break;
case CPU_INTERRUPT_SMI:
+5 -5
View File
@@ -168,7 +168,7 @@ void do_smm_enter(X86CPU *cpu)
env->cr[0] & ~(CR0_PE_MASK | CR0_EM_MASK | CR0_TS_MASK |
CR0_PG_MASK));
cpu_x86_update_cr4(env, 0);
env->dr[7] = 0x00000400;
helper_set_dr(env, 7, 0x00000400);
cpu_x86_load_seg_cache(env, R_CS, (env->smbase >> 4) & 0xffff, env->smbase,
0xffffffff,
@@ -233,8 +233,8 @@ void helper_rsm(CPUX86State *env)
env->eip = x86_ldq_phys(cs, sm_state + 0x7f78);
cpu_load_eflags(env, x86_ldl_phys(cs, sm_state + 0x7f70),
~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));
env->dr[6] = x86_ldl_phys(cs, sm_state + 0x7f68);
env->dr[7] = x86_ldl_phys(cs, sm_state + 0x7f60);
helper_set_dr(env, 6, x86_ldl_phys(cs, sm_state + 0x7f68));
helper_set_dr(env, 7, x86_ldl_phys(cs, sm_state + 0x7f60));
cpu_x86_update_cr4(env, x86_ldl_phys(cs, sm_state + 0x7f48));
cpu_x86_update_cr3(env, x86_ldq_phys(cs, sm_state + 0x7f50));
@@ -268,8 +268,8 @@ void helper_rsm(CPUX86State *env)
env->regs[R_EDX] = x86_ldl_phys(cs, sm_state + 0x7fd8);
env->regs[R_ECX] = x86_ldl_phys(cs, sm_state + 0x7fd4);
env->regs[R_EAX] = x86_ldl_phys(cs, sm_state + 0x7fd0);
env->dr[6] = x86_ldl_phys(cs, sm_state + 0x7fcc);
env->dr[7] = x86_ldl_phys(cs, sm_state + 0x7fc8);
helper_set_dr(env, 6, x86_ldl_phys(cs, sm_state + 0x7fcc));
helper_set_dr(env, 7, x86_ldl_phys(cs, sm_state + 0x7fc8));
env->tr.selector = x86_ldl_phys(cs, sm_state + 0x7fc4) & 0xffff;
env->tr.base = x86_ldl_phys(cs, sm_state + 0x7f64);
+1 -1
View File
@@ -49,7 +49,7 @@ static void svm_save_seg(CPUX86State *env, int mmu_idx, hwaddr addr,
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);
*seg_base = (((int64_t) *seg_base) << shift_amt) >> shift_amt;
}
static void svm_load_seg(CPUX86State *env, int mmu_idx, hwaddr addr,
+2 -2
View File
@@ -74,8 +74,8 @@ bool tcg_cpu_realizefn(CPUState *cs, Error **errp)
memory_region_set_enabled(cpu->cpu_as_mem, true);
cs->num_ases = 2;
cpu_address_space_init(cs, 0, "cpu-memory", cs->memory);
cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root);
cpu_address_space_init(cs, X86ASIdx_MEM, "cpu-memory", cs->memory);
cpu_address_space_init(cs, X86ASIdx_SMM, "cpu-smm", cpu->cpu_as_root);
/* ... SMRAM with higher priority, linked from /machine/smram. */
cpu->machine_done.notify = tcg_cpu_machine_done;
@@ -74,38 +74,38 @@ TRANS(sc_w, ALL, gen_sc, MO_TESL)
TRANS(ll_d, 64, gen_ll, MO_TEUQ)
TRANS(sc_d, 64, gen_sc, MO_TEUQ)
TRANS(amswap_w, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
TRANS(amswap_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS64(amswap_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS(amadd_w, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
TRANS(amadd_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS64(amadd_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS(amand_w, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
TRANS(amand_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS64(amand_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS(amor_w, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
TRANS(amor_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS64(amor_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS(amxor_w, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
TRANS(amxor_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS64(amxor_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS(ammax_w, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
TRANS(ammax_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS64(ammax_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS(ammin_w, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
TRANS(ammin_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS64(ammin_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS(ammax_wu, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
TRANS(ammax_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS64(ammax_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS(ammin_wu, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
TRANS(ammin_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
TRANS64(ammin_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
TRANS(amswap_db_w, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL)
TRANS(amswap_db_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS64(amswap_db_d, LAM, gen_am, tcg_gen_atomic_xchg_tl, MO_TEUQ)
TRANS(amadd_db_w, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL)
TRANS(amadd_db_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS64(amadd_db_d, LAM, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEUQ)
TRANS(amand_db_w, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL)
TRANS(amand_db_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS64(amand_db_d, LAM, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEUQ)
TRANS(amor_db_w, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL)
TRANS(amor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS64(amor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEUQ)
TRANS(amxor_db_w, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL)
TRANS(amxor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS64(amxor_db_d, LAM, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEUQ)
TRANS(ammax_db_w, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL)
TRANS(ammax_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS64(ammax_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEUQ)
TRANS(ammin_db_w, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL)
TRANS(ammin_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS64(ammin_db_d, LAM, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEUQ)
TRANS(ammax_db_wu, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL)
TRANS(ammax_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS64(ammax_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEUQ)
TRANS(ammin_db_wu, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL)
TRANS(ammin_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
TRANS64(ammin_db_du, LAM, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEUQ)
@@ -69,6 +69,10 @@ static bool trans_rdtimeh_w(DisasContext *ctx, arg_rdtimeh_w *a)
static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a)
{
if (!avail_64(ctx)) {
return false;
}
return gen_rdtime(ctx, a, 0, 0);
}
@@ -100,8 +104,8 @@ static bool gen_crc(DisasContext *ctx, arg_rrr *a,
TRANS(crc_w_b_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(1))
TRANS(crc_w_h_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(2))
TRANS(crc_w_w_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(4))
TRANS(crc_w_d_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(8))
TRANS64(crc_w_d_w, CRC, gen_crc, gen_helper_crc32, tcg_constant_tl(8))
TRANS(crcc_w_b_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(1))
TRANS(crcc_w_h_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(2))
TRANS(crcc_w_w_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(4))
TRANS(crcc_w_d_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(8))
TRANS64(crcc_w_d_w, CRC, gen_crc, gen_helper_crc32c, tcg_constant_tl(8))
@@ -183,16 +183,16 @@ TRANS(fmaxa_s, FP_SP, gen_fff, gen_helper_fmaxa_s)
TRANS(fmaxa_d, FP_DP, gen_fff, gen_helper_fmaxa_d)
TRANS(fmina_s, FP_SP, gen_fff, gen_helper_fmina_s)
TRANS(fmina_d, FP_DP, gen_fff, gen_helper_fmina_d)
TRANS(fscaleb_s, FP_SP, gen_fff, gen_helper_fscaleb_s)
TRANS(fscaleb_d, FP_DP, gen_fff, gen_helper_fscaleb_d)
TRANS64(fscaleb_s, FP_SP, gen_fff, gen_helper_fscaleb_s)
TRANS64(fscaleb_d, FP_DP, gen_fff, gen_helper_fscaleb_d)
TRANS(fsqrt_s, FP_SP, gen_ff, gen_helper_fsqrt_s)
TRANS(fsqrt_d, FP_DP, gen_ff, gen_helper_fsqrt_d)
TRANS(frecip_s, FP_SP, gen_ff, gen_helper_frecip_s)
TRANS(frecip_d, FP_DP, gen_ff, gen_helper_frecip_d)
TRANS(frsqrt_s, FP_SP, gen_ff, gen_helper_frsqrt_s)
TRANS(frsqrt_d, FP_DP, gen_ff, gen_helper_frsqrt_d)
TRANS(flogb_s, FP_SP, gen_ff, gen_helper_flogb_s)
TRANS(flogb_d, FP_DP, gen_ff, gen_helper_flogb_d)
TRANS64(flogb_s, FP_SP, gen_ff, gen_helper_flogb_s)
TRANS64(flogb_d, FP_DP, gen_ff, gen_helper_flogb_d)
TRANS(fclass_s, FP_SP, gen_ff, gen_helper_fclass_s)
TRANS(fclass_d, FP_DP, gen_ff, gen_helper_fclass_d)
TRANS(fmadd_s, FP_SP, gen_muladd, gen_helper_fmuladd_s, 0)
@@ -29,5 +29,5 @@ TRANS(ffint_s_w, FP_SP, gen_ff, gen_helper_ffint_s_w)
TRANS(ffint_s_l, FP_SP, gen_ff, gen_helper_ffint_s_l)
TRANS(ffint_d_w, FP_DP, gen_ff, gen_helper_ffint_d_w)
TRANS(ffint_d_l, FP_DP, gen_ff, gen_helper_ffint_d_l)
TRANS(frint_s, FP_SP, gen_ff, gen_helper_frint_s)
TRANS(frint_d, FP_DP, gen_ff, gen_helper_frint_d)
TRANS64(frint_s, FP_SP, gen_ff, gen_helper_frint_s)
TRANS64(frint_d, FP_DP, gen_ff, gen_helper_frint_d)
@@ -148,11 +148,11 @@ TRANS(fldx_s, FP_SP, gen_floadx, MO_TEUL)
TRANS(fldx_d, FP_DP, gen_floadx, MO_TEUQ)
TRANS(fstx_s, FP_SP, gen_fstorex, MO_TEUL)
TRANS(fstx_d, FP_DP, gen_fstorex, MO_TEUQ)
TRANS(fldgt_s, FP_SP, gen_fload_gt, MO_TEUL)
TRANS(fldgt_d, FP_DP, gen_fload_gt, MO_TEUQ)
TRANS(fldle_s, FP_SP, gen_fload_le, MO_TEUL)
TRANS(fldle_d, FP_DP, gen_fload_le, MO_TEUQ)
TRANS(fstgt_s, FP_SP, gen_fstore_gt, MO_TEUL)
TRANS(fstgt_d, FP_DP, gen_fstore_gt, MO_TEUQ)
TRANS(fstle_s, FP_SP, gen_fstore_le, MO_TEUL)
TRANS(fstle_d, FP_DP, gen_fstore_le, MO_TEUQ)
TRANS64(fldgt_s, FP_SP, gen_fload_gt, MO_TEUL)
TRANS64(fldgt_d, FP_DP, gen_fload_gt, MO_TEUQ)
TRANS64(fldle_s, FP_SP, gen_fload_le, MO_TEUL)
TRANS64(fldle_d, FP_DP, gen_fload_le, MO_TEUQ)
TRANS64(fstgt_s, FP_SP, gen_fstore_gt, MO_TEUL)
TRANS64(fstgt_d, FP_DP, gen_fstore_gt, MO_TEUQ)
TRANS64(fstle_s, FP_SP, gen_fstore_le, MO_TEUL)
TRANS64(fstle_d, FP_DP, gen_fstore_le, MO_TEUQ)
@@ -233,11 +233,11 @@ static bool gen_iocsrwr(DisasContext *ctx, arg_rr *a,
TRANS(iocsrrd_b, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_b)
TRANS(iocsrrd_h, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_h)
TRANS(iocsrrd_w, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_w)
TRANS(iocsrrd_d, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_d)
TRANS64(iocsrrd_d, IOCSR, gen_iocsrrd, gen_helper_iocsrrd_d)
TRANS(iocsrwr_b, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_b)
TRANS(iocsrwr_h, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_h)
TRANS(iocsrwr_w, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_w)
TRANS(iocsrwr_d, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_d)
TRANS64(iocsrwr_d, IOCSR, gen_iocsrwr, gen_helper_iocsrwr_d)
static void check_mmu_idx(DisasContext *ctx)
{
@@ -78,7 +78,7 @@ TRANS(sra_w, ALL, gen_rrr, EXT_SIGN, EXT_NONE, EXT_SIGN, gen_sra_w)
TRANS(sll_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sll_d)
TRANS(srl_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_srl_d)
TRANS(sra_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sra_d)
TRANS(rotr_w, 64, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_rotr_w)
TRANS(rotr_w, ALL, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_rotr_w)
TRANS(rotr_d, 64, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rotr_d)
TRANS(slli_w, ALL, gen_rri_c, EXT_NONE, EXT_SIGN, tcg_gen_shli_tl)
TRANS(slli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shli_tl)
@@ -86,5 +86,5 @@ TRANS(srli_w, ALL, gen_rri_c, EXT_ZERO, EXT_SIGN, tcg_gen_shri_tl)
TRANS(srli_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_shri_tl)
TRANS(srai_w, ALL, gen_rri_c, EXT_NONE, EXT_NONE, gen_sari_w)
TRANS(srai_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_sari_tl)
TRANS(rotri_w, 64, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w)
TRANS(rotri_w, ALL, gen_rri_v, EXT_NONE, EXT_NONE, gen_rotr_w)
TRANS(rotri_d, 64, gen_rri_c, EXT_NONE, EXT_NONE, tcg_gen_rotri_tl)
+4
View File
@@ -14,6 +14,10 @@
static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \
{ return avail_##AVAIL(ctx) && FUNC(ctx, a, __VA_ARGS__); }
#define TRANS64(NAME, AVAIL, FUNC, ...) \
static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \
{ return avail_64(ctx) && avail_##AVAIL(ctx) && FUNC(ctx, a, __VA_ARGS__); }
#define avail_ALL(C) true
#define avail_64(C) (FIELD_EX32((C)->cpucfg1, CPUCFG1, ARCH) == \
CPUCFG1_ARCH_LA64)
+1 -1
View File
@@ -652,7 +652,7 @@ static int walk_directory(CPUMIPSState *env, uint64_t *vaddr,
return 0;
}
if ((entry & (1 << psn)) && hugepg) {
if (extract64(entry, psn, 1) && hugepg) {
*huge_page = true;
*hgpg_directory_hit = true;
entry = get_tlb_entry_layout(env, entry, leaf_mop, pf_ptew);
+4
View File
@@ -1522,6 +1522,10 @@ struct PowerPCCPUClass {
void (*init_proc)(CPUPPCState *env);
int (*check_pow)(CPUPPCState *env);
int (*check_attn)(CPUPPCState *env);
/* Handlers to be set by the machine initialising the chips */
uint64_t (*load_sprd)(CPUPPCState *env);
void (*store_sprd)(CPUPPCState *env, uint64_t val);
};
static inline bool ppc_cpu_core_single_threaded(CPUState *cs)
+6 -53
View File
@@ -328,69 +328,22 @@ target_ulong helper_load_sprd(CPUPPCState *env)
* accessed by powernv machines.
*/
PowerPCCPU *cpu = env_archcpu(env);
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
target_ulong sprc = env->spr[SPR_POWER_SPRC];
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
if (pc->big_core) {
pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
if (pcc->load_sprd) {
return pcc->load_sprd(env);
}
switch (sprc & 0x3e0) {
case 0: /* SCRATCH0-3 */
case 1: /* SCRATCH4-7 */
return pc->scratch[(sprc >> 3) & 0x7];
case 0x1e0: /* core thread state */
if (env->excp_model == POWERPC_EXCP_POWER9) {
/*
* Only implement for POWER9 because skiboot uses it to check
* big-core mode. Other bits are unimplemented so we would
* prefer to get unimplemented message on POWER10 if it were
* used anywhere.
*/
if (pc->big_core) {
return PPC_BIT(63);
} else {
return 0;
}
}
/* fallthru */
default:
qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"
TARGET_FMT_lx"\n", sprc);
break;
}
return 0;
}
void helper_store_sprd(CPUPPCState *env, target_ulong val)
{
target_ulong sprc = env->spr[SPR_POWER_SPRC];
PowerPCCPU *cpu = env_archcpu(env);
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
int nr;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
if (pc->big_core) {
pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
}
switch (sprc & 0x3e0) {
case 0: /* SCRATCH0-3 */
case 1: /* SCRATCH4-7 */
/*
* Log stores to SCRATCH, because some firmware uses these for
* debugging and logging, but they would normally be read by the BMC,
* which is not implemented in QEMU yet. This gives a way to get at the
* information. Could also dump these upon checkstop.
*/
nr = (sprc >> 3) & 0x7;
pc->scratch[nr] = val;
break;
default:
qemu_log_mask(LOG_UNIMP, "mtSPRD: Unimplemented SPRC:0x"
TARGET_FMT_lx"\n", sprc);
break;
if (pcc->store_sprd) {
return pcc->store_sprd(env, val);
}
}
+1 -1
View File
@@ -604,7 +604,7 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
}
}
}
if (riscv_has_ext(env, RVV) && (flags & CPU_DUMP_VPU)) {
if (riscv_cpu_cfg(env)->ext_zve32x && (flags & CPU_DUMP_VPU)) {
static const int dump_rvv_csrs[] = {
CSR_VSTART,
CSR_VXSAT,
+1 -1
View File
@@ -873,7 +873,7 @@ static inline void riscv_csr_write(CPURISCVState *env, int csrno,
static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
{
target_ulong val = 0;
riscv_csrrw(env, csrno, &val, 0, 0, 0);
riscv_csrr(env, csrno, &val);
return val;
}
+4 -1
View File
@@ -204,6 +204,8 @@ static RISCVException cfi_ss(CPURISCVState *env, int csrno)
#if !defined(CONFIG_USER_ONLY)
if (env->debugger) {
return RISCV_EXCP_NONE;
} else if (env->virt_enabled) {
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
}
#endif
return RISCV_EXCP_ILLEGAL_INST;
@@ -2004,7 +2006,8 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
if (riscv_has_ext(env, RVF)) {
mask |= MSTATUS_FS;
}
if (riscv_has_ext(env, RVV)) {
if (riscv_cpu_cfg(env)->ext_zve32x) {
mask |= MSTATUS_VS;
}
+13 -8
View File
@@ -1101,14 +1101,14 @@ DEF_HELPER_6(vslidedown_vx_b, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslidedown_vx_h, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslidedown_vx_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslidedown_vx_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslide1up_vx_b, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslide1up_vx_h, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslide1up_vx_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslide1up_vx_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslide1down_vx_b, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32)
DEF_HELPER_6(vslide1up_vx_b, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vslide1up_vx_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vslide1up_vx_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vslide1up_vx_d, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vslide1down_vx_b, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfslide1up_vf_h, void, ptr, ptr, i64, ptr, env, i32)
DEF_HELPER_6(vfslide1up_vf_w, void, ptr, ptr, i64, ptr, env, i32)
@@ -1284,3 +1284,8 @@ DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
/* CFI (zicfiss) helpers */
#ifndef CONFIG_USER_ONLY
DEF_HELPER_1(ssamoswap_disabled, void, env)
#endif
+48 -2
View File
@@ -3561,7 +3561,6 @@ static bool slideup_check(DisasContext *s, arg_rmrr *a)
}
GEN_OPIVX_TRANS(vslideup_vx, slideup_check)
GEN_OPIVX_TRANS(vslide1up_vx, slideup_check)
GEN_OPIVI_TRANS(vslideup_vi, IMM_ZX, vslideup_vx, slideup_check)
static bool slidedown_check(DisasContext *s, arg_rmrr *a)
@@ -3572,9 +3571,56 @@ static bool slidedown_check(DisasContext *s, arg_rmrr *a)
}
GEN_OPIVX_TRANS(vslidedown_vx, slidedown_check)
GEN_OPIVX_TRANS(vslide1down_vx, slidedown_check)
GEN_OPIVI_TRANS(vslidedown_vi, IMM_ZX, vslidedown_vx, slidedown_check)
typedef void gen_helper_vslide1_vx(TCGv_ptr, TCGv_ptr, TCGv_i64, TCGv_ptr,
TCGv_env, TCGv_i32);
#define GEN_OPIVX_VSLIDE1_TRANS(NAME, CHECK) \
static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
{ \
if (CHECK(s, a)) { \
static gen_helper_vslide1_vx * const fns[4] = { \
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
}; \
\
TCGv_ptr dest, src2, mask; \
TCGv_i64 src1; \
TCGv_i32 desc; \
uint32_t data = 0; \
\
dest = tcg_temp_new_ptr(); \
mask = tcg_temp_new_ptr(); \
src2 = tcg_temp_new_ptr(); \
src1 = tcg_temp_new_i64(); \
\
data = FIELD_DP32(data, VDATA, VM, a->vm); \
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
data = FIELD_DP32(data, VDATA, VTA, s->vta); \
data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
data = FIELD_DP32(data, VDATA, VMA, s->vma); \
desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb, \
s->cfg_ptr->vlenb, data)); \
\
tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd)); \
tcg_gen_addi_ptr(src2, tcg_env, vreg_ofs(s, a->rs2)); \
tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0)); \
tcg_gen_ext_tl_i64(src1, get_gpr(s, a->rs1, EXT_SIGN)); \
\
fns[s->sew](dest, mask, src1, src2, tcg_env, desc); \
\
tcg_gen_movi_tl(cpu_vstart, 0); \
finalize_rvv_inst(s); \
\
return true; \
} \
return false; \
}
GEN_OPIVX_VSLIDE1_TRANS(vslide1up_vx, slideup_check)
GEN_OPIVX_VSLIDE1_TRANS(vslide1down_vx, slidedown_check)
/* Vector Floating-Point Slide Instructions */
static bool fslideup_check(DisasContext *s, arg_rmrr *a)
{

Some files were not shown because too many files have changed in this diff Show More