Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
7257a8efac
!968 QEMU update to version 6.2.0-95
From: @liu-pingwei 
Reviewed-by: @aven6 
Signed-off-by: @aven6
2024-06-21 03:04:25 +00:00
liupingwei
bad58948c0 QEMU update to version 6.2.0-95
- cvm: bug-fix for disable DTB randomness for confidential VMs

Signed-off-by: liupingwei <liupingwei0317@outlook.com>
2024-06-21 09:48:48 +08:00
openeuler-ci-bot
542c7c192d
!967 QEMU update to version 6.2.0-94
From: @liu-pingwei 
Reviewed-by: @aven6 
Signed-off-by: @aven6
2024-06-18 08:47:32 +00:00
tujipei
c85e7c13d4 QEMU update to version 6.2.0-94
- hw/arm/virt: Disable DTB randomness for confidential VMs

Signed-off-by: liupingwei <liupingwei0317@outlook.com>
2024-06-18 10:50:22 +08:00
openeuler-ci-bot
894939f4aa
!962 QEMU update to version 6.2.0-93
From: @JiaboFeng 
Reviewed-by: @imxcc 
Signed-off-by: @imxcc
2024-06-17 01:34:20 +00:00
Jiabo Feng
018c809557 QEMU update to version 8.2.0-93:
- cvm: bug-fix for macro isolation
- tests/qtest: ahci-test: add test exposing reset issue with pending callback (Fix CVE-2023-5088)
- hw/ide: reset: cancel async DMA operation before resetting state (Fix CVE-2023-5088)
- Add support for the virtcca cvm feature.

Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
2024-06-17 09:11:12 +08:00
openeuler-ci-bot
47d5eebac1
!955 QEMU update to version 6.2.0-92
From: @JiaboFeng 
Reviewed-by: @imxcc 
Signed-off-by: @imxcc
2024-06-13 07:19:28 +00:00
Jiabo Feng
90057151bb QEMU update to version 6.2.0-92:
- s390x/sclp: Simplify get_sclp_device()
- target/ppc: Remove msr_pr macro
- docs/system/target-arm: Re-alphabetize board list
- migration: Extend query-migrate to provide dirty page limit info
- migration: Implement dirty-limit convergence algo
- migration: Put the detection logic before auto-converge checking
- migration: Refactor auto-converge capability logic
- migration: Introduce dirty-limit capability
- qapi/migration: Introduce vcpu-dirty-limit parameters
- qapi/migration: Introduce x-vcpu-dirty-limit-period parameter
- Change the value of no_ged from true to false
- Allow UNIX socket option for VNC websocket
- tpm_emulator: Avoid double initialization during
- chardev/char-socket: Update AF_UNIX for Windows
- KVM: dirty ring: add missing memory barrier
- i386: reset KVM nested state upon CPU reset
- esp: Handle CMD_BUSRESET by resetting the SCSI bus
- dbus-vmstate: Restrict error checks to registered proxies in dbus_get_proxies
- vfio/pci: Add Ascend310b scend910b support
- target/i386: Export RFDS bit to guests
- target/i386: Add new CPU model SierraForest
- target/i386: Introduce Icelake-Server-v7 to enable TSX
- hw/virtio: handle un-configured shutdown in virtio-pci
- target/s390x: display deprecation status in '-cpu  help'
- target/i386: display deprecation status in '-cpu  help'
- pc-bios/s390-ccw: Fix booting with logical block size < physical block size

Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
2024-06-13 14:32:49 +08:00
openeuler-ci-bot
9270babf6d
!935 [sync] PR-929: QEMU update to version 6.2.0-91
From: @openeuler-sync-bot 
Reviewed-by: @aven6 
Signed-off-by: @aven6
2024-04-24 06:03:44 +00:00
Jiabo Feng
9803c6ed12 QEMU update to version 6.2.0-91
- hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs(CVE-2024-3446)
- hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs(CVE-2024-3446)
- hw/display/virtio-gpu: Protect from DMA re-entrancy bugs(CVE-2024-3446)
- hw/virtio: Introduce virtio_bh_new_guarded() helper
- hw: replace most qemu_bh_new calls with qemu_bh_new_guarded
- checkpatch: add qemu_bh_new/aio_bh_new checks
- async: avoid use-after-free on re-entrancy guard
- async: Add an optional reentrancy guard to the BH API
- hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set(CVE-2024-3447)
- rtl8139: Remove unused variable
- tulip: Remove unused variable
- virtio-mem: Fix the bitmap index of the section offset
- virtio-mem: Fix the iterator variable in a vmem->rdl_list loop
- system/memory: use ldn_he_p/stn_he_p
- block: Fix crash when loading snapshot on inactive node
- smmu: Clear SMMUPciBus pointer cache when system reset
- block/mirror: Fix NULL s->job in active writes
- amd_iommu: Fix APIC address check
- virtio-crypto: fix NULL pointer dereference in virtio_crypto_free_reques
- libqos/virtio.c: Correct 'flags' reading in qvirtqueue_kick cherry-pick from 66e411885a23c96ff73742d06b793fec3ceaebb7
- ivshmem-test.c: enable test_ivshmem_server for ppc64 arch
- ivshmem.c: change endianness to LITTLE_ENDIAN
- hw/ppc/mac.h: Remove MAX_CPUS macro
- configure: remove dead variables
- virtio-gpu: do not byteswap padding
- hw/intc: clean-up error reporting for failed ITS cmd
- qemu-iotests: Discard stderr when probing devices
- linux-user: un-parent OBJECT(cpu) when closing thread
- hw/net/rocker: Avoid undefined shifts with more than 31 ports
- contrib/vhost-user-blk: Clean up deallocation of VuVirtqElement
- scsi-disk: fix overflow when block size is not a multiple of BDRV_SECTOR_SIZE

Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
(cherry picked from commit bf54b48c2963c869dfdc89977c57be4bd9e772aa)
2024-04-24 10:57:37 +08:00
64 changed files with 6511 additions and 1 deletions

View File

@ -0,0 +1,994 @@
From 12d0d099aecbebefc7d221ae645283984bf8f649 Mon Sep 17 00:00:00 2001
From: liupingwei <liupingwei0317@outlook.com>
Date: Fri, 31 May 2024 15:07:20 +0800
Subject: [PATCH] Add support for the virtcca cvm feature. With this commit,we
can append new startup parameters :"cma=64M cvm_guest=1" and "kvm_type=cvm"
to use virtcca cvm feature. Here is a full example of the append parameters
for a cvm : -M virt,gic-version=3,accel=kvm,kernel_irqchip=on,kvm_type=cvm \
-append "swiotlb=force console=tty0 console=ttyAMA0 kaslr.disabled=1 cma=64M
cvm_guest=1 rodata=off rootfstype=ext4 root=/dev/vad rw" \
Additionally,the SVE and PMU are optional configurations for cvm,here is
an example:
-object tmm-guest,id=tmm0,sve-vector-length=128,num-pmu-counters=1
Signed-off-by: liupingwei <liupingwei0317@outlook.com>
---
accel/kvm/kvm-all.c | 36 ++++
hw/arm/boot.c | 49 +++++
hw/arm/virt.c | 51 ++++-
include/hw/arm/boot.h | 1 +
include/hw/arm/virt.h | 1 +
include/sysemu/kvm.h | 8 +
linux-headers/asm-arm64/kvm.h | 62 ++++++
linux-headers/linux/kvm.h | 31 ++-
qapi/qom.json | 30 ++-
target/arm/kvm-tmm.c | 344 ++++++++++++++++++++++++++++++++++
target/arm/kvm.c | 6 +-
target/arm/kvm64.c | 5 +
target/arm/kvm_arm.h | 10 +
target/arm/meson.build | 1 +
14 files changed, 628 insertions(+), 7 deletions(-)
create mode 100644 target/arm/kvm-tmm.c
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index e55b2b6a16..381e3c8552 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -49,6 +49,8 @@
#include "hw/boards.h"
+#include "sysemu/kvm.h"
+
/* This check must be after config-host.h is included */
#ifdef CONFIG_EVENTFD
#include <sys/eventfd.h>
@@ -79,6 +81,9 @@ struct KVMParkedVcpu {
};
KVMState *kvm_state;
+
+bool virtcca_cvm_allowed = false;
+
bool kvm_kernel_irqchip;
bool kvm_split_irqchip;
bool kvm_async_interrupts_allowed;
@@ -2272,6 +2277,11 @@ uint32_t kvm_dirty_ring_size(void)
return kvm_state->kvm_dirty_ring_size;
}
+static inline bool kvm_is_virtcca_cvm_type(int type)
+{
+ return type & VIRTCCA_CVM_TYPE;
+}
+
static int kvm_init(MachineState *ms)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
@@ -2356,6 +2366,10 @@ static int kvm_init(MachineState *ms)
type = mc->kvm_type(ms, NULL);
}
+ if (kvm_is_virtcca_cvm_type(type)) {
+ virtcca_cvm_allowed = true;
+ }
+
do {
ret = kvm_ioctl(s, KVM_CREATE_VM, type);
} while (ret == -EINTR);
@@ -3455,6 +3469,28 @@ int kvm_get_one_reg(CPUState *cs, uint64_t id, void *target)
return r;
}
+int kvm_load_user_data(hwaddr loader_start, hwaddr image_end, hwaddr initrd_start, hwaddr dtb_end, hwaddr ram_size,
+ struct kvm_numa_info *numa_info)
+{
+ KVMState *state = kvm_state;
+ struct kvm_user_data data;
+ int ret;
+
+ data.loader_start = loader_start;
+ data.image_end = image_end;
+ data.initrd_start = initrd_start;
+ data.dtb_end = dtb_end;
+ data.ram_size = ram_size;
+ memcpy(&data.numa_info, numa_info, sizeof(struct kvm_numa_info));
+
+ ret = kvm_vm_ioctl(state, KVM_LOAD_USER_DATA, &data);
+ if (ret < 0) {
+ error_report("%s: KVM_LOAD_USER_DATA failed!\n", __func__);
+ }
+
+ return ret;
+}
+
static bool kvm_accel_has_memory(MachineState *ms, AddressSpace *as,
hwaddr start_addr, hwaddr size)
{
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 3d45de1772..db69ec648a 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -27,6 +27,7 @@
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/units.h"
+#include "kvm_arm.h"
/* Kernel boot protocol is specified in the kernel docs
* Documentation/arm/Booting and Documentation/arm64/booting.txt
@@ -1255,6 +1256,16 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
ARM_CPU(cs)->env.boot_info = info;
}
+
+ if (kvm_enabled() && virtcca_cvm_enabled()) {
+ if (info->dtb_limit == 0) {
+ info->dtb_limit = info->dtb_start + 0x200000;
+ }
+ kvm_load_user_data(info->loader_start, image_high_addr, info->initrd_start,
+ info->dtb_limit, info->ram_size, (struct kvm_numa_info *)info->numa_info);
+ tmm_add_ram_region(info->loader_start, image_high_addr - info->loader_start,
+ info->initrd_start, info->dtb_limit - info->initrd_start, true);
+ }
}
static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info)
@@ -1344,6 +1355,39 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info)
info->initrd_filename = ms->initrd_filename;
info->dtb_filename = ms->dtb;
info->dtb_limit = 0;
+ if (kvm_enabled() && virtcca_cvm_enabled()) {
+ info->ram_size = ms->ram_size;
+ info->numa_info = g_malloc(sizeof(struct kvm_numa_info));
+ struct kvm_numa_info *numa_info = (struct kvm_numa_info *) info->numa_info;
+ if (ms->numa_state != NULL && ms->numa_state->num_nodes > 0) {
+ numa_info->numa_cnt = ms->numa_state->num_nodes;
+ uint64_t mem_base = info->loader_start;
+ for (int64_t i = 0; i < ms->numa_state->num_nodes && i < MAX_NUMA_NODE; i++) {
+ uint64_t mem_len = ms->numa_state->nodes[i].node_mem;
+ numa_info->numa_nodes[i].numa_id = i;
+ numa_info->numa_nodes[i].ipa_start = mem_base;
+ numa_info->numa_nodes[i].ipa_size = mem_len;
+ memcpy(numa_info->numa_nodes[i].host_numa_nodes, ms->numa_state->nodes[i].node_memdev->host_nodes,
+ MAX_NODES / BITS_PER_LONG * sizeof(uint64_t));
+ mem_base += mem_len;
+ }
+ } else {
+ numa_info->numa_cnt = 1;
+ numa_info->numa_nodes[0].numa_id = 0;
+ numa_info->numa_nodes[0].ipa_start = info->loader_start;
+ numa_info->numa_nodes[0].ipa_size = info->ram_size;
+ memset(numa_info->numa_nodes[0].host_numa_nodes, 0, MAX_NODES / BITS_PER_LONG * sizeof(uint64_t));
+ }
+
+ for (int cpu = ms->smp.cpus - 1; cpu >= 0; cpu--) {
+ ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
+ CPUState *cs = CPU(armcpu);
+ uint64_t node_id = 0;
+ if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id)
+ node_id = ms->possible_cpus->cpus[cs->cpu_index].props.node_id;
+ bitmap_set((unsigned long *)numa_info->numa_nodes[node_id].cpu_id, cpu, 1);
+ }
+ }
/* Load the kernel. */
if (!info->kernel_filename || info->firmware_loaded) {
@@ -1352,6 +1396,11 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info)
arm_setup_direct_kernel_boot(cpu, info);
}
+ if (kvm_enabled() && virtcca_cvm_enabled()) {
+ g_free(info->numa_info);
+ info->numa_info = NULL;
+ }
+
if (!info->skip_dtb_autoload && have_dtb(info)) {
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms) < 0) {
exit(1);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 93554cccf1..26dc5681c2 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1801,6 +1801,19 @@ static void virt_set_memmap(VirtMachineState *vms)
vms->memmap[i] = base_memmap[i];
}
+ /* fix VIRT_MEM range */
+ if (object_property_find(OBJECT(current_machine), "kvm-type")) {
+ g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
+ "kvm-type", &error_abort);
+
+ if (!strcmp(kvm_type, "cvm")) {
+ vms->memmap[VIRT_MEM].base = 3 * GiB;
+ vms->memmap[VIRT_MEM].size = ms->ram_size;
+ info_report("[qemu] fix VIRT_MEM range 0x%llx - 0x%llx\n", (unsigned long long)(vms->memmap[VIRT_MEM].base),
+ (unsigned long long)(vms->memmap[VIRT_MEM].base + ms->ram_size));
+ }
+ }
+
if (ms->ram_slots > ACPI_MAX_RAM_SLOTS) {
error_report("unsupported number of memory slots: %"PRIu64,
ms->ram_slots);
@@ -2072,7 +2085,7 @@ static void machvirt_init(MachineState *machine)
*/
if (vms->secure && firmware_loaded) {
vms->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
- } else if (vms->virt) {
+ } else if (vms->virt || virtcca_cvm_enabled()) {
vms->psci_conduit = QEMU_PSCI_CONDUIT_SMC;
} else {
vms->psci_conduit = QEMU_PSCI_CONDUIT_HVC;
@@ -2118,6 +2131,13 @@ static void machvirt_init(MachineState *machine)
exit(1);
}
+ if (virtcca_cvm_enabled()) {
+ int ret = kvm_arm_tmm_init(machine->cgs, &error_fatal);
+ if (ret != 0) {
+ error_report("fail to initialize TMM");
+ exit(1);
+ }
+ }
create_fdt(vms);
qemu_log("cpu init start\n");
@@ -2991,6 +3011,15 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
static int virt_kvm_type(MachineState *ms, const char *type_str)
{
VirtMachineState *vms = VIRT_MACHINE(ms);
+ int virtcca_cvm_type = 0;
+ if (object_property_find(OBJECT(current_machine), "kvm-type")) {
+ g_autofree char *kvm_type = object_property_get_str(OBJECT(current_machine),
+ "kvm-type", &error_abort);
+
+ if (!strcmp(kvm_type, "cvm")) {
+ virtcca_cvm_type = VIRTCCA_CVM_TYPE;
+ }
+ }
int max_vm_pa_size, requested_pa_size;
bool fixed_ipa;
@@ -3020,7 +3049,9 @@ static int virt_kvm_type(MachineState *ms, const char *type_str)
* the implicit legacy 40b IPA setting, in which case the kvm_type
* must be 0.
*/
- return fixed_ipa ? 0 : requested_pa_size;
+ return strcmp(type_str, "cvm") == 0 ?
+ ((fixed_ipa ? 0 : requested_pa_size) | virtcca_cvm_type) :
+ (fixed_ipa ? 0 : requested_pa_size);
}
static void virt_machine_class_init(ObjectClass *oc, void *data)
@@ -3143,6 +3174,19 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
}
+static char *virt_get_kvm_type(Object *obj, Error **errp G_GNUC_UNUSED)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+ return g_strdup(vms->kvm_type);
+}
+
+static void virt_set_kvm_type(Object *obj, const char *value, Error **errp G_GNUC_UNUSED)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+ g_free(vms->kvm_type);
+ vms->kvm_type = g_strdup(value);
+}
+
static void virt_instance_init(Object *obj)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -3194,6 +3238,9 @@ static void virt_instance_init(Object *obj)
vms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
vms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
+
+ object_property_add_str(obj, "kvm-type", virt_get_kvm_type, virt_set_kvm_type);
+ object_property_set_description(obj, "kvm-type", "CVM or Normal VM");
}
static const TypeInfo virt_machine_info = {
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
index c3c4d3ea79..36aa5dd5c6 100644
--- a/include/hw/arm/boot.h
+++ b/include/hw/arm/boot.h
@@ -36,6 +36,7 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size);
/* arm_boot.c */
struct arm_boot_info {
uint64_t ram_size;
+ void *numa_info;
const char *kernel_filename;
const char *kernel_cmdline;
const char *initrd_filename;
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 4ddee19b18..3fc1adcb42 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -176,6 +176,7 @@ struct VirtMachineState {
PCIBus *bus;
char *oem_id;
char *oem_table_id;
+ char *kvm_type;
};
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 9f52d08ce0..0b5319b4e3 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -19,6 +19,7 @@
#include "exec/memattrs.h"
#include "qemu/accel.h"
#include "qom/object.h"
+#include "linux-headers/linux/kvm.h"
#ifdef NEED_CPU_H
# ifdef CONFIG_KVM
@@ -32,6 +33,7 @@
#ifdef CONFIG_KVM_IS_POSSIBLE
extern bool kvm_allowed;
+extern bool virtcca_cvm_allowed;
extern bool kvm_kernel_irqchip;
extern bool kvm_split_irqchip;
extern bool kvm_async_interrupts_allowed;
@@ -48,6 +50,8 @@ extern bool kvm_ioeventfd_any_length_allowed;
extern bool kvm_msi_use_devid;
#define kvm_enabled() (kvm_allowed)
+#define virtcca_cvm_enabled() (virtcca_cvm_allowed)
+#define VIRTCCA_CVM_TYPE (1UL << 8)
/**
* kvm_irqchip_in_kernel:
*
@@ -170,6 +174,7 @@ extern bool kvm_msi_use_devid;
#else
#define kvm_enabled() (0)
+#define virtcca_cvm_enabled() (0)
#define kvm_irqchip_in_kernel() (false)
#define kvm_irqchip_is_split() (false)
#define kvm_async_interrupts_enabled() (false)
@@ -554,6 +559,9 @@ bool kvm_dirty_ring_enabled(void);
uint32_t kvm_dirty_ring_size(void);
+int kvm_load_user_data(hwaddr loader_start, hwaddr image_end, hwaddr initrd_start, hwaddr dtb_end, hwaddr ram_size,
+ struct kvm_numa_info *numa_info);
+
#ifdef __aarch64__
int kvm_create_shadow_device(PCIDevice *dev);
int kvm_delete_shadow_device(PCIDevice *dev);
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
index 3d2ce9912d..4e98a829f7 100644
--- a/linux-headers/asm-arm64/kvm.h
+++ b/linux-headers/asm-arm64/kvm.h
@@ -106,6 +106,7 @@ struct kvm_regs {
#define KVM_ARM_VCPU_SVE 4 /* enable SVE for this CPU */
#define KVM_ARM_VCPU_PTRAUTH_ADDRESS 5 /* VCPU uses address authentication */
#define KVM_ARM_VCPU_PTRAUTH_GENERIC 6 /* VCPU uses generic authentication */
+#define KVM_ARM_VCPU_TEC 8 /* VCPU TEC state as part of cvm */
struct kvm_vcpu_init {
__u32 target;
@@ -411,6 +412,67 @@ struct kvm_arm_copy_mte_tags {
#define KVM_PSCI_RET_INVAL PSCI_RET_INVALID_PARAMS
#define KVM_PSCI_RET_DENIED PSCI_RET_DENIED
+/* KVM_CAP_ARM_TMM on VM fd */
+#define KVM_CAP_ARM_TMM_CONFIG_CVM 0
+#define KVM_CAP_ARM_TMM_CREATE_RD 1
+#define KVM_CAP_ARM_TMM_POPULATE_CVM 2
+#define KVM_CAP_ARM_TMM_ACTIVATE_CVM 3
+
+#define KVM_CAP_ARM_TMM_MEASUREMENT_ALGO_SHA256 0
+#define KVM_CAP_ARM_TMM_MEASUREMENT_ALGO_SHA512 1
+
+#define KVM_CAP_ARM_TMM_RPV_SIZE 64
+
+/* List of configuration items accepted for KVM_CAP_ARM_RME_CONFIG_REALM */
+#define KVM_CAP_ARM_TMM_CFG_RPV 0
+#define KVM_CAP_ARM_TMM_CFG_HASH_ALGO 1
+#define KVM_CAP_ARM_TMM_CFG_SVE 2
+#define KVM_CAP_ARM_TMM_CFG_DBG 3
+#define KVM_CAP_ARM_TMM_CFG_PMU 4
+
+struct kvm_cap_arm_tmm_config_item {
+ __u32 cfg;
+ union {
+ /* cfg == KVM_CAP_ARM_TMM_CFG_RPV */
+ struct {
+ __u8 rpv[KVM_CAP_ARM_TMM_RPV_SIZE];
+ };
+
+ /* cfg == KVM_CAP_ARM_TMM_CFG_HASH_ALGO */
+ struct {
+ __u32 hash_algo;
+ };
+
+ /* cfg == KVM_CAP_ARM_TMM_CFG_SVE */
+ struct {
+ __u32 sve_vq;
+ };
+
+ /* cfg == KVM_CAP_ARM_TMM_CFG_DBG */
+ struct {
+ __u32 num_brps;
+ __u32 num_wrps;
+ };
+
+ /* cfg == KVM_CAP_ARM_TMM_CFG_PMU */
+ struct {
+ __u32 num_pmu_cntrs;
+ };
+ /* Fix the size of the union */
+ __u8 reserved[256];
+ };
+};
+
+#define KVM_ARM_TMM_POPULATE_FLAGS_MEASURE (1U << 0)
+struct kvm_cap_arm_tmm_populate_region_args {
+ __u64 populate_ipa_base1;
+ __u64 populate_ipa_size1;
+ __u64 populate_ipa_base2;
+ __u64 populate_ipa_size2;
+ __u32 flags;
+ __u32 reserved[3];
+};
+
#endif
#endif /* __ARM_KVM_H__ */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index cd0885f523..fa22d85adf 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -14,6 +14,8 @@
#include <linux/ioctl.h>
#include <asm/kvm.h>
+#include "sysemu/numa.h"
+
#define KVM_API_VERSION 12
/* *** Deprecated interfaces *** */
@@ -1126,6 +1128,7 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_X86_NOTIFY_VMEXIT 219
#define KVM_CAP_ARM_CPU_FEATURE 555
+#define KVM_CAP_ARM_TMM 300
#define KVM_CAP_ARM_VIRT_MSI_BYPASS 799
@@ -1370,6 +1373,32 @@ struct kvm_vfio_spapr_tce {
__s32 tablefd;
};
+#define MAX_NUMA_NODE 8
+#define MAX_CPU_BIT_MAP 4
+#define MAX_NODE_BIT_MAP (MAX_NODES / BITS_PER_LONG)
+
+struct kvm_numa_node {
+ __u64 numa_id;
+ __u64 ipa_start;
+ __u64 ipa_size;
+ __u64 host_numa_nodes[MAX_NODE_BIT_MAP];
+ __u64 cpu_id[MAX_CPU_BIT_MAP];
+};
+
+struct kvm_numa_info {
+ __u64 numa_cnt;
+ struct kvm_numa_node numa_nodes[MAX_NUMA_NODE];
+};
+
+struct kvm_user_data {
+ __u64 loader_start;
+ __u64 image_end;
+ __u64 initrd_start;
+ __u64 dtb_end;
+ __u64 ram_size;
+ struct kvm_numa_info numa_info;
+};
+
/*
* ioctls for VM fds
*/
@@ -1388,7 +1417,7 @@ struct kvm_vfio_spapr_tce {
struct kvm_userspace_memory_region)
#define KVM_SET_TSS_ADDR _IO(KVMIO, 0x47)
#define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO, 0x48, __u64)
-
+#define KVM_LOAD_USER_DATA _IOW(KVMIO, 0x49, struct kvm_user_data)
/* enable ucontrol for s390 */
struct kvm_s390_ucas_mapping {
__u64 user_addr;
diff --git a/qapi/qom.json b/qapi/qom.json
index eeb5395ff3..a0450f7494 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -785,6 +785,30 @@
'reduced-phys-bits': 'uint32',
'*kernel-hashes': 'bool' } }
+##
+# @TmmGuestMeasurementAlgo:
+#
+# Algorithm to use for cvm measurements
+#
+# Since: FIXME
+##
+{ 'enum': 'TmmGuestMeasurementAlgo',
+'data': ['default', 'sha256', 'sha512'] }
+
+##
+# @TmmGuestProperties:
+#
+# Properties for tmm-guest objects.
+#
+# @sve-vector-length: SVE vector length (default: 0, SVE disabled)
+#
+# Since: FIXME
+##
+{ 'struct': 'TmmGuestProperties',
+ 'data': { '*sve-vector-length': 'uint32',
+ '*num-pmu-counters': 'uint32',
+ '*measurement-algo': 'TmmGuestMeasurementAlgo' } }
+
##
# @ObjectType:
#
@@ -842,7 +866,8 @@
'tls-creds-psk',
'tls-creds-x509',
'tls-cipher-suites',
- { 'name': 'x-remote-object', 'features': [ 'unstable' ] }
+ { 'name': 'x-remote-object', 'features': [ 'unstable' ] },
+ 'tmm-guest'
] }
##
@@ -905,7 +930,8 @@
'tls-creds-psk': 'TlsCredsPskProperties',
'tls-creds-x509': 'TlsCredsX509Properties',
'tls-cipher-suites': 'TlsCredsProperties',
- 'x-remote-object': 'RemoteObjectProperties'
+ 'x-remote-object': 'RemoteObjectProperties',
+ 'tmm-guest': 'TmmGuestProperties'
} }
##
diff --git a/target/arm/kvm-tmm.c b/target/arm/kvm-tmm.c
new file mode 100644
index 0000000000..e7df485979
--- /dev/null
+++ b/target/arm/kvm-tmm.c
@@ -0,0 +1,344 @@
+/*
+ * QEMU add virtcca cvm feature.
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "exec/confidential-guest-support.h"
+#include "hw/boards.h"
+#include "hw/core/cpu.h"
+#include "kvm_arm.h"
+#include "migration/blocker.h"
+#include "qapi/error.h"
+#include "qom/object_interfaces.h"
+#include "sysemu/kvm.h"
+#include "sysemu/runstate.h"
+#include "hw/loader.h"
+
+#define TYPE_TMM_GUEST "tmm-guest"
+OBJECT_DECLARE_SIMPLE_TYPE(TmmGuest, TMM_GUEST)
+
+#define TMM_PAGE_SIZE qemu_real_host_page_size
+#define TMM_MAX_PMU_CTRS 0x20
+#define TMM_MAX_CFG 5
+
+struct TmmGuest {
+ ConfidentialGuestSupport parent_obj;
+ GSList *ram_regions;
+ TmmGuestMeasurementAlgo measurement_algo;
+ uint32_t sve_vl;
+ uint32_t num_pmu_cntrs;
+};
+
+typedef struct {
+ hwaddr base1;
+ hwaddr len1;
+ hwaddr base2;
+ hwaddr len2;
+ bool populate;
+} TmmRamRegion;
+
+static TmmGuest *tmm_guest;
+
+bool kvm_arm_tmm_enabled(void)
+{
+ return !!tmm_guest;
+}
+
+static int tmm_configure_one(TmmGuest *guest, uint32_t cfg, Error **errp)
+{
+ int ret = 1;
+ const char *cfg_str;
+ struct kvm_cap_arm_tmm_config_item args = {
+ .cfg = cfg,
+ };
+
+ switch (cfg) {
+ case KVM_CAP_ARM_TMM_CFG_RPV:
+ return 0;
+ case KVM_CAP_ARM_TMM_CFG_HASH_ALGO:
+ switch (guest->measurement_algo) {
+ case TMM_GUEST_MEASUREMENT_ALGO_DEFAULT:
+ return 0;
+ case TMM_GUEST_MEASUREMENT_ALGO_SHA256:
+ args.hash_algo = KVM_CAP_ARM_TMM_MEASUREMENT_ALGO_SHA256;
+ break;
+ case TMM_GUEST_MEASUREMENT_ALGO_SHA512:
+ args.hash_algo = KVM_CAP_ARM_TMM_MEASUREMENT_ALGO_SHA512;
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ cfg_str = "hash algorithm";
+ break;
+ case KVM_CAP_ARM_TMM_CFG_SVE:
+ if (!guest->sve_vl) {
+ return 0;
+ }
+ args.sve_vq = guest->sve_vl / 128;
+ cfg_str = "SVE";
+ break;
+ case KVM_CAP_ARM_TMM_CFG_DBG:
+ return 0;
+ case KVM_CAP_ARM_TMM_CFG_PMU:
+ if (!guest->num_pmu_cntrs) {
+ return 0;
+ }
+ args.num_pmu_cntrs = guest->num_pmu_cntrs;
+ cfg_str = "PMU";
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_TMM, 0,
+ KVM_CAP_ARM_TMM_CONFIG_CVM, (intptr_t)&args);
+ if (ret) {
+ error_setg_errno(errp, -ret, "TMM: failed to configure %s", cfg_str);
+ }
+
+ return ret;
+}
+
+static gint tmm_compare_ram_regions(gconstpointer a, gconstpointer b)
+{
+ const TmmRamRegion *ra = a;
+ const TmmRamRegion *rb = b;
+
+ g_assert(ra->base1 != rb->base1);
+ return ra->base1 < rb->base1 ? -1 : 1;
+}
+
+void tmm_add_ram_region(hwaddr base1, hwaddr len1, hwaddr base2, hwaddr len2, bool populate)
+{
+ TmmRamRegion *region;
+
+ region = g_new0(TmmRamRegion, 1);
+ region->base1 = QEMU_ALIGN_DOWN(base1, TMM_PAGE_SIZE);
+ region->len1 = QEMU_ALIGN_UP(len1, TMM_PAGE_SIZE);
+ region->base2 = QEMU_ALIGN_DOWN(base2, TMM_PAGE_SIZE);
+ region->len2 = QEMU_ALIGN_UP(len2, TMM_PAGE_SIZE);
+ region->populate = populate;
+
+ tmm_guest->ram_regions = g_slist_insert_sorted(tmm_guest->ram_regions,
+ region, tmm_compare_ram_regions);
+}
+
+static void tmm_populate_region(gpointer data, gpointer unused)
+{
+ int ret;
+ const TmmRamRegion *region = data;
+ struct kvm_cap_arm_tmm_populate_region_args populate_args = {
+ .populate_ipa_base1 = region->base1,
+ .populate_ipa_size1 = region->len1,
+ .populate_ipa_base2 = region->base2,
+ .populate_ipa_size2 = region->len2,
+ .flags = KVM_ARM_TMM_POPULATE_FLAGS_MEASURE,
+ };
+
+ if (!region->populate) {
+ return;
+ }
+
+ ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_TMM, 0,
+ KVM_CAP_ARM_TMM_POPULATE_CVM,
+ (intptr_t)&populate_args);
+ if (ret) {
+ error_report("TMM: failed to populate cvm region (0x%"HWADDR_PRIx", 0x%"HWADDR_PRIx", 0x%"HWADDR_PRIx", 0x%"HWADDR_PRIx"): %s",
+ region->base1, region->len1, region->base2, region->len2, strerror(-ret));
+ exit(1);
+ }
+}
+
+static int tmm_create_rd(Error **errp)
+{
+ int ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_TMM, 0,
+ KVM_CAP_ARM_TMM_CREATE_RD);
+ if (ret) {
+ error_setg_errno(errp, -ret, "TMM: failed to create tmm Descriptor");
+ }
+ return ret;
+}
+
+static void tmm_vm_state_change(void *opaque, bool running, RunState state)
+{
+ int ret;
+ CPUState *cs;
+
+ if (!running) {
+ return;
+ }
+
+ g_slist_foreach(tmm_guest->ram_regions, tmm_populate_region, NULL);
+ g_slist_free_full(g_steal_pointer(&tmm_guest->ram_regions), g_free);
+
+ CPU_FOREACH(cs) {
+ ret = kvm_arm_vcpu_finalize(cs, KVM_ARM_VCPU_TEC);
+ if (ret) {
+ error_report("TMM: failed to finalize vCPU: %s", strerror(-ret));
+ exit(1);
+ }
+ }
+
+ ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_TMM, 0,
+ KVM_CAP_ARM_TMM_ACTIVATE_CVM);
+ if (ret) {
+ error_report("TMM: failed to activate cvm: %s", strerror(-ret));
+ exit(1);
+ }
+}
+
+int kvm_arm_tmm_init(ConfidentialGuestSupport *cgs, Error **errp)
+{
+ int ret;
+ int cfg;
+
+ if (!tmm_guest) {
+ return -ENODEV;
+ }
+
+ if (!kvm_check_extension(kvm_state, KVM_CAP_ARM_TMM)) {
+ error_setg(errp, "KVM does not support TMM");
+ return -ENODEV;
+ }
+
+ for (cfg = 0; cfg < TMM_MAX_CFG; cfg++) {
+ ret = tmm_configure_one(tmm_guest, cfg, &error_abort);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ ret = tmm_create_rd(&error_abort);
+ if (ret) {
+ return ret;
+ }
+
+ qemu_add_vm_change_state_handler(tmm_vm_state_change, NULL);
+ return 0;
+}
+
+static void tmm_get_sve_vl(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ TmmGuest *guest = TMM_GUEST(obj);
+
+ visit_type_uint32(v, name, &guest->sve_vl, errp);
+}
+
+static void tmm_set_sve_vl(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ TmmGuest *guest = TMM_GUEST(obj);
+ uint32_t value;
+
+ if (!visit_type_uint32(v, name, &value, errp)) {
+ return;
+ }
+
+ if (value & 0x7f || value >= ARM_MAX_VQ * 128) {
+ error_setg(errp, "invalid SVE vector length");
+ return;
+ }
+
+ guest->sve_vl = value;
+}
+
+static void tmm_get_num_pmu_cntrs(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ TmmGuest *guest = TMM_GUEST(obj);
+
+ visit_type_uint32(v, name, &guest->num_pmu_cntrs, errp);
+}
+
+static void tmm_set_num_pmu_cntrs(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ TmmGuest *guest = TMM_GUEST(obj);
+ uint32_t value;
+
+ if (!visit_type_uint32(v, name, &value, errp)) {
+ return;
+ }
+
+ if (value >= TMM_MAX_PMU_CTRS) {
+ error_setg(errp, "invalid number of PMU counters");
+ return;
+ }
+
+ guest->num_pmu_cntrs = value;
+}
+
+static int tmm_get_measurement_algo(Object *obj, Error **errp G_GNUC_UNUSED)
+{
+ TmmGuest *guest = TMM_GUEST(obj);
+
+ return guest->measurement_algo;
+}
+
+static void tmm_set_measurement_algo(Object *obj, int algo, Error **errp G_GNUC_UNUSED)
+{
+ TmmGuest *guest = TMM_GUEST(obj);
+
+ guest->measurement_algo = algo;
+}
+
+static void tmm_guest_class_init(ObjectClass *oc, void *data)
+{
+ object_class_property_add_enum(oc, "measurement-algo",
+ "TmmGuestMeasurementAlgo",
+ &TmmGuestMeasurementAlgo_lookup,
+ tmm_get_measurement_algo,
+ tmm_set_measurement_algo);
+ object_class_property_set_description(oc, "measurement-algo",
+ "cvm measurement algorithm ('sha256', 'sha512')");
+ /*
+ * This is not ideal. Normally SVE parameters are given to -cpu, but the
+ * cvm parameters are needed much earlier than CPU initialization. We also
+ * don't have a way to discover what is supported at the moment, the idea is
+ * that the user knows exactly what hardware it is running on because these
+ * parameters are part of the measurement and play in the attestation.
+ */
+ object_class_property_add(oc, "sve-vector-length", "uint32", tmm_get_sve_vl,
+ tmm_set_sve_vl, NULL, NULL);
+ object_class_property_set_description(oc, "sve-vector-length",
+ "SVE vector length. 0 disables SVE (the default)");
+ object_class_property_add(oc, "num-pmu-counters", "uint32",
+ tmm_get_num_pmu_cntrs, tmm_set_num_pmu_cntrs,
+ NULL, NULL);
+ object_class_property_set_description(oc, "num-pmu-counters",
+ "Number of PMU counters");
+}
+
+static void tmm_guest_instance_init(Object *obj)
+{
+ if (tmm_guest) {
+ error_report("a single instance of TmmGuest is supported");
+ exit(1);
+ }
+ tmm_guest = TMM_GUEST(obj);
+}
+
+static const TypeInfo tmm_guest_info = {
+ .parent = TYPE_CONFIDENTIAL_GUEST_SUPPORT,
+ .name = TYPE_TMM_GUEST,
+ .instance_size = sizeof(struct TmmGuest),
+ .instance_init = tmm_guest_instance_init,
+ .class_init = tmm_guest_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_USER_CREATABLE },
+ { }
+ }
+};
+
+static void tmm_register_types(void)
+{
+ type_register_static(&tmm_guest_info);
+}
+type_init(tmm_register_types);
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 38d80adfb7..f62d9ece3c 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -605,7 +605,9 @@ bool write_list_to_kvmstate(ARMCPU *cpu, int level)
if (kvm_arm_cpreg_level(regidx) > level) {
continue;
}
-
+ if (virtcca_cvm_enabled() && regidx == KVM_REG_ARM_TIMER_CNT) {
+ continue;
+ }
r.id = regidx;
switch (regidx & KVM_REG_SIZE_MASK) {
case KVM_REG_SIZE_U32:
@@ -1140,7 +1142,7 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
bool kvm_arch_cpu_check_are_resettable(void)
{
- return true;
+ return !virtcca_cvm_enabled();
}
void kvm_arch_accel_class_init(ObjectClass *oc)
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 0f67b8ba96..38d519846c 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -818,6 +818,11 @@ static int kvm_arm_sve_set_vls(CPUState *cs)
assert(cpu->sve_max_vq <= KVM_ARM64_SVE_VQ_MAX);
+ if (virtcca_cvm_enabled()) {
+ /* Already set through tmm config */
+ return 0;
+ }
+
for (vq = 1; vq <= cpu->sve_max_vq; ++vq) {
if (test_bit(vq - 1, cpu->sve_vq_map)) {
i = (vq - 1) / 64;
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 8b644b3924..5a49383031 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -377,6 +377,11 @@ void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa);
int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
+void tmm_add_ram_region(hwaddr base1, hwaddr len1, hwaddr base2, hwaddr len2, bool populate);
+
+int kvm_arm_tmm_init(ConfidentialGuestSupport *cgs, Error **errp);
+bool kvm_arm_tmm_enabled(void);
+
int kvm_arm_get_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *target);
int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx, uint64_t *source);
@@ -471,6 +476,11 @@ static inline int kvm_arm_set_one_reg(ARMCPU *cpu, uint64_t regidx,
g_assert_not_reached();
}
+static inline int kvm_arm_tmm_init(ConfidentialGuestSupport *cgs, Error **errp G_GNUC_UNUSED)
+{
+ g_assert_not_reached();
+}
+
#endif
static inline const char *gic_class_name(void)
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 50f152214a..bb950fbffe 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -39,6 +39,7 @@ arm_ss.add(files(
arm_ss.add(zlib)
arm_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c', 'kvm64.c'), if_false: files('kvm-stub.c'))
+arm_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c', 'kvm64.c', 'kvm-tmm.c'), if_false: files('kvm-stub.c'))
arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
'cpu64.c',
--
2.41.0.windows.1

View File

@ -0,0 +1,57 @@
From b149e82858eb16bcede32b86518a7a2f6f259b5b Mon Sep 17 00:00:00 2001
From: dinglimin <dinglimin@cmss.chinamobile.com>
Date: Thu, 23 May 2024 16:45:25 +0800
Subject: [PATCH] Allow UNIX socket option for VNC websocket
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
cheery-pick from 41582637b1577c261f19634bdd1bb5e7ed6e258d
- Remove unix socket option limitation for VNC websocket
- Reflect websocket option changes in documentation
Signed-off-by: Sergii Zasenko <sergii@zasenko.name>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20230724100353.16628-1-sergii@zasenko.name>
Signed-off-by: dinglimin <dinglimin@cmss.chinamobile.com>
---
qemu-options.hx | 4 ++++
ui/vnc.c | 5 -----
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/qemu-options.hx b/qemu-options.hx
index d940b4aea5..ab82ad4150 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2339,6 +2339,10 @@ SRST
host. It is possible to control the websocket listen address
independently, using the syntax ``websocket``\ =host:port.
+ Websocket could be allowed over UNIX domain socket, using the syntax
+ ``websocket``\ =unix:path, where path is the location of a unix socket
+ to listen for connections on.
+
If no TLS credentials are provided, the websocket connection
runs in unencrypted mode. If TLS credentials are provided, the
websocket connection requires encrypted client connections.
diff --git a/ui/vnc.c b/ui/vnc.c
index 71e3627be2..3cb24badf6 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -3725,11 +3725,6 @@ static int vnc_display_get_address(const char *addrstr,
addr->type = SOCKET_ADDRESS_TYPE_UNIX;
addr->u.q_unix.path = g_strdup(addrstr + 5);
- if (websocket) {
- error_setg(errp, "UNIX sockets not supported with websock");
- goto cleanup;
- }
-
if (to) {
error_setg(errp, "Port range not support with UNIX socket");
goto cleanup;
--
2.27.0

View File

@ -0,0 +1,29 @@
From 96e753e741a21d8bc1f59120dd70ce140129b737 Mon Sep 17 00:00:00 2001
From: weishaokun <weishaokun@kylinos.cn>
Date: Fri, 31 May 2024 13:48:59 +0800
Subject: [PATCH] Change the value of no_ged from true to false
It fixes the issue of the `no_ged` parameter mismatch
when migrating a virtual machine started with QEMU 4.1 to a QEMU 6.2
Signed-off-by: Shaokun Wei <weishaokun@kylinos.cn>
---
hw/arm/virt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 93554cccf1..eadba9535e 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3290,7 +3290,7 @@ static void virt_machine_4_1_options(MachineClass *mc)
virt_machine_4_2_options(mc);
compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len);
- vmc->no_ged = true;
+ vmc->no_ged = false;
mc->auto_enable_numa_with_memhp = false;
}
DEFINE_VIRT_MACHINE(4, 1)
--
2.27.0

View File

@ -0,0 +1,45 @@
From 63d3efed81ddf36acfec73910a84dee426450012 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Wed, 15 May 2024 01:03:38 +0000
Subject: [PATCH] KVM: dirty ring: add missing memory barrier mainline
inclusion commit 4802bf910eee98312c4a9777ac2567e6a0445c46 category: bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
The KVM_DIRTY_GFN_F_DIRTY flag ensures that the entry is valid. If
the read of the fields are not ordered after the read of the flag,
QEMU might see stale values.
Cc: Gavin Shan <gshan@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
accel/kvm/kvm-all.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index c477f7a635..e55b2b6a16 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -661,7 +661,11 @@ static void kvm_dirty_ring_mark_page(KVMState *s, uint32_t as_id,
static bool dirty_gfn_is_dirtied(struct kvm_dirty_gfn *gfn)
{
- return gfn->flags == KVM_DIRTY_GFN_F_DIRTY;
+ /*
+ * Read the flags before the value. Pairs with barrier in
+ * KVM's kvm_dirty_ring_push() function.
+ */
+ return qatomic_load_acquire(&gfn->flags) == KVM_DIRTY_GFN_F_DIRTY;
}
static void dirty_gfn_set_collected(struct kvm_dirty_gfn *gfn)
--
2.27.0

View File

@ -0,0 +1,57 @@
From ea8049e63b663cab607d1f900ce593547485b33b Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Wed, 10 Apr 2024 20:02:38 -0700
Subject: [PATCH] amd_iommu: Fix APIC address check
An MSI from I/O APIC may not exactly equal to APIC_DEFAULT_ADDRESS. In
fact, Windows 17763.3650 configures I/O APIC to set the dest_mode bit.
Cover the range assigned to APIC.
Fixes: 577c470f43 ("x86_iommu/amd: Prepare for interrupt remap support")
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-Id: <20230921114612.40671-1-akihiko.odaki@daynix.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 0114c4513095598cdf1cd8d7dacdfff757628121)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/i386/amd_iommu.c | 9 ++-------
hw/i386/amd_iommu.h | 2 --
2 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c
index 4d13d8e697..dfb9a2d8e6 100644
--- a/hw/i386/amd_iommu.c
+++ b/hw/i386/amd_iommu.c
@@ -1245,13 +1245,8 @@ static int amdvi_int_remap_msi(AMDVIState *iommu,
return -AMDVI_IR_ERR;
}
- if (origin->address & AMDVI_MSI_ADDR_HI_MASK) {
- trace_amdvi_err("MSI address high 32 bits non-zero when "
- "Interrupt Remapping enabled.");
- return -AMDVI_IR_ERR;
- }
-
- if ((origin->address & AMDVI_MSI_ADDR_LO_MASK) != APIC_DEFAULT_ADDRESS) {
+ if (origin->address < AMDVI_INT_ADDR_FIRST ||
+ origin->address + sizeof(origin->data) > AMDVI_INT_ADDR_LAST + 1) {
trace_amdvi_err("MSI is not from IOAPIC.");
return -AMDVI_IR_ERR;
}
diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h
index 79d38a3e41..210a37dfb1 100644
--- a/hw/i386/amd_iommu.h
+++ b/hw/i386/amd_iommu.h
@@ -210,8 +210,6 @@
#define AMDVI_INT_ADDR_FIRST 0xfee00000
#define AMDVI_INT_ADDR_LAST 0xfeefffff
#define AMDVI_INT_ADDR_SIZE (AMDVI_INT_ADDR_LAST - AMDVI_INT_ADDR_FIRST + 1)
-#define AMDVI_MSI_ADDR_HI_MASK (0xffffffff00000000ULL)
-#define AMDVI_MSI_ADDR_LO_MASK (0x00000000ffffffffULL)
/* SB IOAPIC is always on this device in AMD systems */
#define AMDVI_IOAPIC_SB_DEVID PCI_BUILD_BDF(0, PCI_DEVFN(0x14, 0))
--
2.27.0

View File

@ -0,0 +1,214 @@
From 2a9e9bb0201c513a085d51cb1d7b2cc83cad1d3b Mon Sep 17 00:00:00 2001
From: Alexander Bulekov <alxndr@bu.edu>
Date: Thu, 27 Apr 2023 17:10:07 -0400
Subject: [PATCH] async: Add an optional reentrancy guard to the BH API
Devices can pass their MemoryReentrancyGuard (from their DeviceState),
when creating new BHes. Then, the async API will toggle the guard
before/after calling the BH call-back. This prevents bh->mmio reentrancy
issues.
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Message-Id: <20230427211013.2994127-3-alxndr@bu.edu>
[thuth: Fix "line over 90 characters" checkpatch.pl error]
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: liuxiangdong <liuxiangdong5@huawei.com>
---
docs/devel/multiple-iothreads.txt | 7 +++++++
include/block/aio.h | 18 ++++++++++++++++--
include/qemu/main-loop.h | 7 +++++--
tests/unit/ptimer-test-stubs.c | 3 ++-
util/async.c | 18 +++++++++++++++++-
util/main-loop.c | 6 ++++--
util/trace-events | 1 +
7 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/docs/devel/multiple-iothreads.txt b/docs/devel/multiple-iothreads.txt
index aeb997bed5..a11576bc74 100644
--- a/docs/devel/multiple-iothreads.txt
+++ b/docs/devel/multiple-iothreads.txt
@@ -61,6 +61,7 @@ There are several old APIs that use the main loop AioContext:
* LEGACY qemu_aio_set_event_notifier() - monitor an event notifier
* LEGACY timer_new_ms() - create a timer
* LEGACY qemu_bh_new() - create a BH
+ * LEGACY qemu_bh_new_guarded() - create a BH with a device re-entrancy guard
* LEGACY qemu_aio_wait() - run an event loop iteration
Since they implicitly work on the main loop they cannot be used in code that
@@ -72,8 +73,14 @@ Instead, use the AioContext functions directly (see include/block/aio.h):
* aio_set_event_notifier() - monitor an event notifier
* aio_timer_new() - create a timer
* aio_bh_new() - create a BH
+ * aio_bh_new_guarded() - create a BH with a device re-entrancy guard
* aio_poll() - run an event loop iteration
+The qemu_bh_new_guarded/aio_bh_new_guarded APIs accept a "MemReentrancyGuard"
+argument, which is used to check for and prevent re-entrancy problems. For
+BHs associated with devices, the reentrancy-guard is contained in the
+corresponding DeviceState and named "mem_reentrancy_guard".
+
The AioContext can be obtained from the IOThread using
iothread_get_aio_context() or for the main loop using qemu_get_aio_context().
Code that takes an AioContext argument works both in IOThreads or the main
diff --git a/include/block/aio.h b/include/block/aio.h
index 47fbe9d81f..c7da152985 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -22,6 +22,8 @@
#include "qemu/event_notifier.h"
#include "qemu/thread.h"
#include "qemu/timer.h"
+#include "hw/qdev-core.h"
+
typedef struct BlockAIOCB BlockAIOCB;
typedef void BlockCompletionFunc(void *opaque, int ret);
@@ -321,9 +323,11 @@ void aio_bh_schedule_oneshot_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
* is opaque and must be allocated prior to its use.
*
* @name: A human-readable identifier for debugging purposes.
+ * @reentrancy_guard: A guard set when entering a cb to prevent
+ * device-reentrancy issues
*/
QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
- const char *name);
+ const char *name, MemReentrancyGuard *reentrancy_guard);
/**
* aio_bh_new: Allocate a new bottom half structure
@@ -332,7 +336,17 @@ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
* string.
*/
#define aio_bh_new(ctx, cb, opaque) \
- aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)))
+ aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)), NULL)
+
+/**
+ * aio_bh_new_guarded: Allocate a new bottom half structure with a
+ * reentrancy_guard
+ *
+ * A convenience wrapper for aio_bh_new_full() that uses the cb as the name
+ * string.
+ */
+#define aio_bh_new_guarded(ctx, cb, opaque, guard) \
+ aio_bh_new_full((ctx), (cb), (opaque), (stringify(cb)), guard)
/**
* aio_notify: Force processing of pending events.
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index 8dbc6fcb89..85dd5ada9e 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -294,9 +294,12 @@ void qemu_cond_timedwait_iothread(QemuCond *cond, int ms);
void qemu_fd_register(int fd);
+#define qemu_bh_new_guarded(cb, opaque, guard) \
+ qemu_bh_new_full((cb), (opaque), (stringify(cb)), guard)
#define qemu_bh_new(cb, opaque) \
- qemu_bh_new_full((cb), (opaque), (stringify(cb)))
-QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name);
+ qemu_bh_new_full((cb), (opaque), (stringify(cb)), NULL)
+QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name,
+ MemReentrancyGuard *reentrancy_guard);
void qemu_bh_schedule_idle(QEMUBH *bh);
enum {
diff --git a/tests/unit/ptimer-test-stubs.c b/tests/unit/ptimer-test-stubs.c
index 2a3ef58799..a7a2d08e7e 100644
--- a/tests/unit/ptimer-test-stubs.c
+++ b/tests/unit/ptimer-test-stubs.c
@@ -108,7 +108,8 @@ int64_t qemu_clock_deadline_ns_all(QEMUClockType type, int attr_mask)
return deadline;
}
-QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name)
+QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name,
+ MemReentrancyGuard *reentrancy_guard)
{
QEMUBH *bh = g_new(QEMUBH, 1);
diff --git a/util/async.c b/util/async.c
index 6f6717a34b..3eb6b50163 100644
--- a/util/async.c
+++ b/util/async.c
@@ -62,6 +62,7 @@ struct QEMUBH {
void *opaque;
QSLIST_ENTRY(QEMUBH) next;
unsigned flags;
+ MemReentrancyGuard *reentrancy_guard;
};
/* Called concurrently from any thread */
@@ -123,7 +124,7 @@ void aio_bh_schedule_oneshot_full(AioContext *ctx, QEMUBHFunc *cb,
}
QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
- const char *name)
+ const char *name, MemReentrancyGuard *reentrancy_guard)
{
QEMUBH *bh;
bh = g_new(QEMUBH, 1);
@@ -132,13 +133,28 @@ QEMUBH *aio_bh_new_full(AioContext *ctx, QEMUBHFunc *cb, void *opaque,
.cb = cb,
.opaque = opaque,
.name = name,
+ .reentrancy_guard = reentrancy_guard,
};
return bh;
}
void aio_bh_call(QEMUBH *bh)
{
+ bool last_engaged_in_io = false;
+
+ if (bh->reentrancy_guard) {
+ last_engaged_in_io = bh->reentrancy_guard->engaged_in_io;
+ if (bh->reentrancy_guard->engaged_in_io) {
+ trace_reentrant_aio(bh->ctx, bh->name);
+ }
+ bh->reentrancy_guard->engaged_in_io = true;
+ }
+
bh->cb(bh->opaque);
+
+ if (bh->reentrancy_guard) {
+ bh->reentrancy_guard->engaged_in_io = last_engaged_in_io;
+ }
}
/* Multiple occurrences of aio_bh_poll cannot be called concurrently. */
diff --git a/util/main-loop.c b/util/main-loop.c
index 06b18b195c..1eacf04691 100644
--- a/util/main-loop.c
+++ b/util/main-loop.c
@@ -544,9 +544,11 @@ void main_loop_wait(int nonblocking)
/* Functions to operate on the main QEMU AioContext. */
-QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name)
+QEMUBH *qemu_bh_new_full(QEMUBHFunc *cb, void *opaque, const char *name,
+ MemReentrancyGuard *reentrancy_guard)
{
- return aio_bh_new_full(qemu_aio_context, cb, opaque, name);
+ return aio_bh_new_full(qemu_aio_context, cb, opaque, name,
+ reentrancy_guard);
}
/*
diff --git a/util/trace-events b/util/trace-events
index c8f53d7d9f..dc3b1eb3bf 100644
--- a/util/trace-events
+++ b/util/trace-events
@@ -11,6 +11,7 @@ poll_remove(void *ctx, void *node, int fd) "ctx %p node %p fd %d"
# async.c
aio_co_schedule(void *ctx, void *co) "ctx %p co %p"
aio_co_schedule_bh_cb(void *ctx, void *co) "ctx %p co %p"
+reentrant_aio(void *ctx, const char *name) "ctx %p name %s"
# thread-pool.c
thread_pool_submit(void *pool, void *req, void *opaque) "pool %p req %p opaque %p"
--
2.27.0

View File

@ -0,0 +1,52 @@
From b2b00599451de0c9fe4dcdf7c47fb1d585ab7d23 Mon Sep 17 00:00:00 2001
From: Alexander Bulekov <alxndr@bu.edu>
Date: Mon, 1 May 2023 10:19:56 -0400
Subject: [PATCH] async: avoid use-after-free on re-entrancy guard
A BH callback can free the BH, causing a use-after-free in aio_bh_call.
Fix that by keeping a local copy of the re-entrancy guard pointer.
Buglink: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58513
Fixes: 9c86c97f12 ("async: Add an optional reentrancy guard to the BH API")
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Message-Id: <20230501141956.3444868-1-alxndr@bu.edu>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
util/async.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/util/async.c b/util/async.c
index 3eb6b50163..760ad73404 100644
--- a/util/async.c
+++ b/util/async.c
@@ -142,18 +142,20 @@ void aio_bh_call(QEMUBH *bh)
{
bool last_engaged_in_io = false;
- if (bh->reentrancy_guard) {
- last_engaged_in_io = bh->reentrancy_guard->engaged_in_io;
- if (bh->reentrancy_guard->engaged_in_io) {
+ /* Make a copy of the guard-pointer as cb may free the bh */
+ MemReentrancyGuard *reentrancy_guard = bh->reentrancy_guard;
+ if (reentrancy_guard) {
+ last_engaged_in_io = reentrancy_guard->engaged_in_io;
+ if (reentrancy_guard->engaged_in_io) {
trace_reentrant_aio(bh->ctx, bh->name);
}
- bh->reentrancy_guard->engaged_in_io = true;
+ reentrancy_guard->engaged_in_io = true;
}
bh->cb(bh->opaque);
- if (bh->reentrancy_guard) {
- bh->reentrancy_guard->engaged_in_io = last_engaged_in_io;
+ if (reentrancy_guard) {
+ reentrancy_guard->engaged_in_io = last_engaged_in_io;
}
}
--
2.27.0

View File

@ -0,0 +1,49 @@
From aad76e8af00e2d507de9a2e562bdbc43a3bc2bc8 Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Mon, 8 Apr 2024 00:42:25 -0700
Subject: [PATCH] block: Fix crash when loading snapshot on inactive node
bdrv_is_read_only() only checks if the node is configured to be
read-only eventually, but even if it returns false, writing to the node
may not be permitted at the moment (because it's inactive).
bdrv_is_writable() checks that the node can be written to right now, and
this is what the snapshot operations really need.
Change bdrv_can_snapshot() to use bdrv_is_writable() to fix crashes like
the following:
$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer
qemu-system-x86_64: ../block/io.c:1990: int bdrv_co_write_req_prepare(BdrvChild *, int64_t, int64_t, BdrvTrackedRequest *, int): Assertion `!(bs->open_flags & BDRV_O_INACTIVE)' failed.
The resulting error message after this patch isn't perfect yet, but at
least it doesn't crash any more:
$ ./qemu-system-x86_64 -hda /tmp/test.qcow2 -loadvm foo -incoming defer
qemu-system-x86_64: Device 'ide0-hd0' is writable but does not support snapshots
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20231201142520.32255-2-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit d3007d348adaaf04ee8b099a475282034a662414)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
block/snapshot.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/snapshot.c b/block/snapshot.c
index ccacda8bd5..f5703aa28b 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -200,7 +200,7 @@ static BlockDriverState *bdrv_snapshot_fallback(BlockDriverState *bs)
int bdrv_can_snapshot(BlockDriverState *bs)
{
BlockDriver *drv = bs->drv;
- if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
+ if (!drv || !bdrv_is_inserted(bs) || !bdrv_is_writable(bs)) {
return 0;
}
--
2.27.0

View File

@ -0,0 +1,66 @@
From ed1ffd883ab3bfbcd3a11d63a7aba6a3a3f53372 Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Thu, 11 Apr 2024 01:04:58 -0700
Subject: [PATCH] block/mirror: Fix NULL s->job in active writes
There is a small gap in mirror_start_job() before putting the mirror
filter node into the block graph (bdrv_append() call) and the actual job
being created. Before the job is created, MirrorBDSOpaque.job is NULL.
It is possible that requests come in when bdrv_drained_end() is called,
and those requests would see MirrorBDSOpaque.job == NULL. Have our
filter node handle that case gracefully.
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20221109165452.67927-4-hreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit da93d5c84e56e6b4e84aa8e98b6b984c9b6bb528)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
block/mirror.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/block/mirror.c b/block/mirror.c
index d1863565c4..de020bdb3e 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1420,11 +1420,13 @@ static int coroutine_fn bdrv_mirror_top_do_write(BlockDriverState *bs,
MirrorOp *op = NULL;
MirrorBDSOpaque *s = bs->opaque;
int ret = 0;
- bool copy_to_target;
+ bool copy_to_target = false;
- copy_to_target = s->job->ret >= 0 &&
- !job_is_cancelled(&s->job->common.job) &&
- s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING;
+ if (s->job) {
+ copy_to_target = s->job->ret >= 0 &&
+ !job_is_cancelled(&s->job->common.job) &&
+ s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING;
+ }
if (copy_to_target) {
op = active_write_prepare(s->job, offset, bytes);
@@ -1469,11 +1471,13 @@ static int coroutine_fn bdrv_mirror_top_pwritev(BlockDriverState *bs,
QEMUIOVector bounce_qiov;
void *bounce_buf;
int ret = 0;
- bool copy_to_target;
+ bool copy_to_target = false;
- copy_to_target = s->job->ret >= 0 &&
- !job_is_cancelled(&s->job->common.job) &&
- s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING;
+ if (s->job) {
+ copy_to_target = s->job->ret >= 0 &&
+ !job_is_cancelled(&s->job->common.job) &&
+ s->job->copy_mode == MIRROR_COPY_MODE_WRITE_BLOCKING;
+ }
if (copy_to_target) {
/* The guest might concurrently modify the data to write; but
--
2.27.0

View File

@ -0,0 +1,56 @@
From 83a0636d6eb42c223ca4d6c0d26ca3a2075de532 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Wed, 15 May 2024 01:21:57 +0000
Subject: [PATCH] chardev/char-socket: Update AF_UNIX for Windows mainline
inclusion commit 120fa5e0e6ebacd811e4d830cff8a405806d305c category: bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
Now that AF_UNIX has come to Windows, update the existing logic in
qemu_chr_compute_filename() and qmp_chardev_open_socket() for Windows.
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20220802075200.907360-4-bmeng.cn@gmail.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
chardev/char-socket.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index ef5d3053f3..278190dd93 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -632,12 +632,10 @@ static char *qemu_chr_compute_filename(SocketChardev *s)
const char *left = "", *right = "";
switch (ss->ss_family) {
-#ifndef _WIN32
case AF_UNIX:
return g_strdup_printf("unix:%s%s",
((struct sockaddr_un *)(ss))->sun_path,
s->is_listen ? ",server=on" : "");
-#endif
case AF_INET6:
left = "[";
right = "]";
@@ -1450,10 +1448,12 @@ static void qmp_chardev_open_socket(Chardev *chr,
}
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_RECONNECTABLE);
+#ifndef _WIN32
/* TODO SOCKET_ADDRESS_FD where fd has AF_UNIX */
if (addr->type == SOCKET_ADDRESS_TYPE_UNIX) {
qemu_chr_set_feature(chr, QEMU_CHAR_FEATURE_FD_PASS);
}
+#endif
/*
* In the chardev-change special-case, we shouldn't register a new yank
--
2.27.0

View File

@ -0,0 +1,37 @@
From f537178e29501b93349362bc46a0463550ff2206 Mon Sep 17 00:00:00 2001
From: Alexander Bulekov <alxndr@bu.edu>
Date: Thu, 27 Apr 2023 17:10:08 -0400
Subject: [PATCH] checkpatch: add qemu_bh_new/aio_bh_new checks
Advise authors to use the _guarded versions of the APIs, instead.
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Message-Id: <20230427211013.2994127-4-alxndr@bu.edu>
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
scripts/checkpatch.pl | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index cb8eff233e..b2428e80cc 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2858,6 +2858,14 @@ sub process {
if ($line =~ /\bsignal\s*\(/ && !($line =~ /SIG_(?:IGN|DFL)/)) {
ERROR("use sigaction to establish signal handlers; signal is not portable\n" . $herecurr);
}
+# recommend qemu_bh_new_guarded instead of qemu_bh_new
+ if ($realfile =~ /.*\/hw\/.*/ && $line =~ /\bqemu_bh_new\s*\(/) {
+ ERROR("use qemu_bh_new_guarded() instead of qemu_bh_new() to avoid reentrancy problems\n" . $herecurr);
+ }
+# recommend aio_bh_new_guarded instead of aio_bh_new
+ if ($realfile =~ /.*\/hw\/.*/ && $line =~ /\baio_bh_new\s*\(/) {
+ ERROR("use aio_bh_new_guarded() instead of aio_bh_new() to avoid reentrancy problems\n" . $herecurr);
+ }
# check for module_init(), use category-specific init macros explicitly please
if ($line =~ /^module_init\s*\(/) {
ERROR("please use block_init(), type_init() etc. instead of module_init()\n" . $herecurr);
--
2.27.0

View File

@ -0,0 +1,46 @@
From 259d232f7273fca7e703fc03a449516e1ab3aa7f Mon Sep 17 00:00:00 2001
From: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
Date: Thu, 28 Mar 2024 11:00:36 +0800
Subject: [PATCH] configure: remove dead variables
cherry picked from commit cbe08c35cfa8f96125512a8aa3e1bf251b1410a5
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
---
configure | 5 -----
1 file changed, 5 deletions(-)
diff --git a/configure b/configure
index 8c9abd0e6e..991fe67886 100755
--- a/configure
+++ b/configure
@@ -630,7 +630,6 @@ fi
case $targetos in
MINGW32*)
mingw32="yes"
- supported_os="yes"
plugins="no"
pie="no"
;;
@@ -672,7 +671,6 @@ SunOS)
QEMU_CFLAGS="-D__EXTENSIONS__ $QEMU_CFLAGS"
;;
Haiku)
- haiku="yes"
pie="no"
QEMU_CFLAGS="-DB_USE_POSITIVE_POSIX_ERRORS -D_BSD_SOURCE -fPIC $QEMU_CFLAGS"
;;
@@ -3388,9 +3386,6 @@ fi
if test "$solaris" = "yes" ; then
echo "CONFIG_SOLARIS=y" >> $config_host_mak
fi
-if test "$haiku" = "yes" ; then
- echo "CONFIG_HAIKU=y" >> $config_host_mak
-fi
if test "$static" = "yes" ; then
echo "CONFIG_STATIC=y" >> $config_host_mak
fi
--
2.27.0

View File

@ -0,0 +1,68 @@
From 37e47eef108920f6afad0c575bc658520bf5f3e2 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 25 Mar 2024 08:43:30 +0000
Subject: [PATCH] contrib/vhost-user-blk: Clean up deallocation of VuVirtqElement
mainline inclusion
commit a32086de4919b9affb2ab2d0112d400eaf89f607
category: bugfix
---------------------------------------------------------------
We allocate VuVirtqElement with g_malloc() in
virtqueue_alloc_element(), but free it with free() in
vhost-user-blk.c. Harmless, but use g_free() anyway.
One of the calls is guarded by a "not null" condition. Useless,
because it cannot be null (it's dereferenced right before), and even
it it could be, free() and g_free() do the right thing. Drop the
conditional.
Fixes: Coverity CID 1490290
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20220630085219.1305519-1-armbru@redhat.com>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
contrib/vhost-user-blk/vhost-user-blk.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/contrib/vhost-user-blk/vhost-user-blk.c b/contrib/vhost-user-blk/vhost-user-blk.c
index d14b2896bf..91c4462659 100644
--- a/contrib/vhost-user-blk/vhost-user-blk.c
+++ b/contrib/vhost-user-blk/vhost-user-blk.c
@@ -106,10 +106,7 @@ static void vub_req_complete(VubReq *req)
req->size + 1);
vu_queue_notify(vu_dev, req->vq);
- if (req->elem) {
- free(req->elem);
- }
-
+ g_free(req->elem);
g_free(req);
}
@@ -243,7 +240,7 @@ static int vub_virtio_process_req(VubDev *vdev_blk,
/* refer to hw/block/virtio_blk.c */
if (elem->out_num < 1 || elem->in_num < 1) {
fprintf(stderr, "virtio-blk request missing headers\n");
- free(elem);
+ g_free(elem);
return -1;
}
@@ -325,7 +322,7 @@ static int vub_virtio_process_req(VubDev *vdev_blk,
return 0;
err:
- free(elem);
+ g_free(elem);
g_free(req);
return -1;
}
--
2.27.0

View File

@ -0,0 +1,40 @@
From 892657386e36e72395c23cec61457dfa0e1bb8f4 Mon Sep 17 00:00:00 2001
From: liupingwei <liupingwei0317@outlook.com>
Date: Wed, 19 Jun 2024 17:43:35 +0800
Subject: [PATCH] cvm: bug-fix for disable DTB randomness for confidential VMs
The previous condition relied on virtcca_cvm_enabled,which was not
initialized in time.
Now,we directly check the KVM type and disable DTB randomness if the
type is "cvm".
Fixes:2830db7bec600915e88bb22847a66d99b047a308("hw/arm/virt:Disable DTB
randomness for confidential VMs")
Signed-off-by: liupingwei <liupingwei0317@outlook.com>
---
hw/arm/virt.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e0de08e2c1..dc119732f0 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -261,7 +261,13 @@ static void create_fdt(VirtMachineState *vms)
/* /chosen must exist for load_dtb to fill in necessary properties later */
qemu_fdt_add_subnode(fdt, "/chosen");
- if (!virtcca_cvm_enabled()) {
+
+ g_autofree char *kvm_type = NULL;
+ if (object_property_find(OBJECT(current_machine), "kvm-type")) {
+ kvm_type = object_property_get_str(OBJECT(current_machine),
+ "kvm-type", &error_abort);
+ }
+ if (!(kvm_type && !strcmp(kvm_type, "cvm"))) {
create_kaslr_seed(ms, "/chosen");
}
--
2.31.1.windows.1

View File

@ -0,0 +1,48 @@
From c3e350aa92bbce2954b908a6bd8481adf222c840 Mon Sep 17 00:00:00 2001
From: fuju <fuju1@huawei.com>
Date: Sat, 15 Jun 2024 16:42:19 +0800
Subject: [PATCH] cvm: bug-fix for macro isolation
1. add else branch for CONFIG_KVM_IS_POSSIBLE macro isolation.
2. add else branch for CONFIG_KVM macro isolation.
Fixes: 12d0d099aecb("Add support for the virtcca cvm feature")
Signed-off-by: Fu Ju <fuju1@huawei.com>
---
include/sysemu/kvm.h | 1 +
target/arm/kvm_arm.h | 6 ++++++
2 files changed, 7 insertions(+)
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 0b5319b4e3..5860228034 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -175,6 +175,7 @@ extern bool kvm_msi_use_devid;
#define kvm_enabled() (0)
#define virtcca_cvm_enabled() (0)
+#define VIRTCCA_CVM_TYPE (0)
#define kvm_irqchip_in_kernel() (false)
#define kvm_irqchip_is_split() (false)
#define kvm_async_interrupts_enabled() (false)
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
index 5a49383031..475531dad4 100644
--- a/target/arm/kvm_arm.h
+++ b/target/arm/kvm_arm.h
@@ -481,6 +481,12 @@ static inline int kvm_arm_tmm_init(ConfidentialGuestSupport *cgs, Error **errp G
g_assert_not_reached();
}
+static inline void tmm_add_ram_region(hwaddr base1, hwaddr len1, hwaddr base2,
+ hwaddr len2, bool populate)
+{
+ g_assert_not_reached();
+}
+
#endif
static inline const char *gic_class_name(void)
--
2.41.0.windows.1

View File

@ -0,0 +1,67 @@
From a5a46593ade242686a670756530026914ed51eaf Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 14 May 2024 09:27:10 +0000
Subject: [PATCH] dbus-vmstate: Restrict error checks to registered proxies in
dbus_get_proxies mainline inclusion commit
2748583211d6e4d14f8862c65276b2d6cc1681ad category: bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
The purpose of dbus_get_proxies to construct the proxies corresponding to the
IDs registered to dbus-vmstate.
Currenty, this function returns an error in case there is any failure
while instantiating proxy for "all" the names on dbus.
Ideally this function should error out only if it is not able to find and
validate the proxies registered to the backend otherwise any offending
process(for eg: the process purposefully may not export its Id property on
the dbus) may connect to the dbus and can lead to migration failures.
This commit ensures that dbus_get_proxies returns an error if it is not
able to find and validate the proxies of interest(the IDs registered
during the dbus-vmstate instantiation).
Signed-off-by: Priyankar Jain <priyankar.jain@nutanix.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <1637936117-37977-1-git-send-email-priyankar.jain@nutanix.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
backends/dbus-vmstate.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/backends/dbus-vmstate.c b/backends/dbus-vmstate.c
index 9cfd758c42..57369ec0f2 100644
--- a/backends/dbus-vmstate.c
+++ b/backends/dbus-vmstate.c
@@ -114,14 +114,19 @@ dbus_get_proxies(DBusVMState *self, GError **err)
"org.qemu.VMState1",
NULL, err);
if (!proxy) {
- return NULL;
+ if (err != NULL && *err != NULL) {
+ warn_report("%s: Failed to create proxy: %s",
+ __func__, (*err)->message);
+ g_clear_error(err);
+ }
+ continue;
}
result = g_dbus_proxy_get_cached_property(proxy, "Id");
if (!result) {
- g_set_error_literal(err, G_IO_ERROR, G_IO_ERROR_FAILED,
- "VMState Id property is missing.");
- return NULL;
+ warn_report("%s: VMState Id property is missing.", __func__);
+ g_clear_object(&proxy);
+ continue;
}
id = g_variant_dup_string(result, &size);
--
2.27.0

View File

@ -0,0 +1,54 @@
From 5f9795e17706aa4bcac46724330761c74cc767c4 Mon Sep 17 00:00:00 2001
From: tangzhongrui <tangzhongrui@cmss.chinamobile.com>
Date: Mon, 3 Jun 2024 20:58:36 +0800
Subject: [PATCH] docs/system/target-arm: Re-alphabetize board list
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The board list in target-arm.rst is supposed to be in alphabetical
order by the title text of each file (which is not the same as
alphabetical order by filename). A few items had got out of order;
correct them.
The entry for
"Facebook Yosemite v3.5 Platform and CraterLake Server (fby35)"
remains out-of-order, because this is not its own file
but is currently part of the aspeed.rst file.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20240520141421.1895138-1-peter.maydell@linaro.org
Signed-off-by: Zhongrui Tang <tangzhongrui_yewu@cmss.chinamobile.com>
---
docs/system/target-arm.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index 91ebc26c6d..d3d2c28417 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -84,16 +84,16 @@ undocumented; you can get a complete list by running
arm/vexpress
arm/aspeed
arm/sabrelite
+ arm/highbank
arm/digic
arm/cubieboard
arm/emcraft-sf2
- arm/highbank
arm/musicpal
arm/gumstix
arm/mainstone
arm/kzm
- arm/nrf
arm/nseries
+ arm/nrf
arm/nuvoton
arm/imx25-pdk
arm/orangepi
--
2.27.0

View File

@ -0,0 +1,53 @@
From 3f186cb242429e6d19f95e259e226658f0d605a9 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 14 May 2024 09:53:37 +0000
Subject: [PATCH] esp: Handle CMD_BUSRESET by resetting the SCSI bus mainline
inclusion commit c6e51f1bb28ed762d2039c063cbb71a8ad29762d category: bugfix
---------------------------------------------------------------
Per investigation on the linked ticket, SunOS issues a SCSI bus reset
to the ESP as part of its boot sequence. If this ESP command doesn't
cause devices to assert sense flag UNIT ATTENTION, SunOS will consider
the CD-ROM device to be non-compliant with Common Command Set (CCS).
In this condition, the SunOS installer's early userspace doesn't set
the installation source location to sr0 and the miniroot copy fails.
Signed-off-by: John Millikin <john@john-millikin.com>
Suggested-by: Bill Paul <noisetube@gmail.com>
Buglink: https://gitlab.com/qemu-project/qemu/-/issues/1127
Message-Id: <20220817053846.699310-1-john@john-millikin.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
hw/scsi/esp.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 435a81bbfd..9f071e7218 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -912,6 +912,11 @@ static void esp_soft_reset(ESPState *s)
esp_hard_reset(s);
}
+static void esp_bus_reset(ESPState *s)
+{
+ qbus_reset_all(BUS(&s->bus));
+}
+
static void parent_esp_reset(ESPState *s, int irq, int level)
{
if (level) {
@@ -1040,6 +1045,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
break;
case CMD_BUSRESET:
trace_esp_mem_writeb_cmd_bus_reset(val);
+ esp_bus_reset(s);
if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
s->rregs[ESP_RINTR] |= INTR_RST;
esp_raise_irq(s);
--
2.27.0

View File

@ -0,0 +1,35 @@
From 2830db7bec600915e88bb22847a66d99b047a308 Mon Sep 17 00:00:00 2001
From: liupingwei <liupingwei0317@outlook.com>
Date: Mon, 17 Jun 2024 19:56:48 +0800
Subject: [PATCH] hw/arm/virt:Disable DTB randomness for confidential VMs
The dtb-randomness feature,which adds random seeds to the DTB,isn't
really compatible with confidential VMs since it randomizes the
TMM.Enabling it is not an error,but it prevents attestation.It also
isn't useful to TMM,which dosn't trust host input.
Fixes:12d0d099aecb("Add support for the virtcca cvm feature")
Signed-off-by: liupingwei <liupingwei0317@outlook.com>
---
hw/arm/virt.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index f20775f44c..e0de08e2c1 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -261,7 +261,9 @@ static void create_fdt(VirtMachineState *vms)
/* /chosen must exist for load_dtb to fill in necessary properties later */
qemu_fdt_add_subnode(fdt, "/chosen");
- create_kaslr_seed(ms, "/chosen");
+ if (!virtcca_cvm_enabled()) {
+ create_kaslr_seed(ms, "/chosen");
+ }
if (vms->secure) {
qemu_fdt_add_subnode(fdt, "/secure-chosen");
--
2.31.1.windows.1

View File

@ -0,0 +1,42 @@
From 4d1cd3fcaa2939da851e39e419c433adcd672145 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
Date: Thu, 4 Apr 2024 20:56:35 +0200
Subject: [PATCH] hw/char/virtio-serial-bus: Protect from DMA re-entrancy
bugs(CVE-2024-3446)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed.
Fixes: CVE-2024-3446
Cc: qemu-stable@nongnu.org
Suggested-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20240409105537.18308-4-philmd@linaro.org>
---
hw/char/virtio-serial-bus.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 14716b66cc..e7f3e1eb87 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -990,8 +990,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp)
return;
}
- port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port,
- &dev->mem_reentrancy_guard);
+ port->bh = virtio_bh_new_guarded(dev, flush_queued_data_bh, port);
port->elem = NULL;
}
--
2.27.0

View File

@ -0,0 +1,143 @@
From c2f82029db6fe278c45e421ba6fece412f084516 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
Date: Thu, 4 Apr 2024 20:56:27 +0200
Subject: [PATCH] hw/display/virtio-gpu: Protect from DMA re-entrancy
bugs(CVE-2024-3446)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed:
$ cat << EOF | qemu-system-i386 -display none -nodefaults \
-machine q35,accel=qtest \
-m 512M \
-device virtio-gpu \
-qtest stdio
outl 0xcf8 0x80000820
outl 0xcfc 0xe0004000
outl 0xcf8 0x80000804
outw 0xcfc 0x06
write 0xe0004030 0x4 0x024000e0
write 0xe0004028 0x1 0xff
write 0xe0004020 0x4 0x00009300
write 0xe000401c 0x1 0x01
write 0x101 0x1 0x04
write 0x103 0x1 0x1c
write 0x9301c8 0x1 0x18
write 0x105 0x1 0x1c
write 0x107 0x1 0x1c
write 0x109 0x1 0x1c
write 0x10b 0x1 0x00
write 0x10d 0x1 0x00
write 0x10f 0x1 0x00
write 0x111 0x1 0x00
write 0x113 0x1 0x00
write 0x115 0x1 0x00
write 0x117 0x1 0x00
write 0x119 0x1 0x00
write 0x11b 0x1 0x00
write 0x11d 0x1 0x00
write 0x11f 0x1 0x00
write 0x121 0x1 0x00
write 0x123 0x1 0x00
write 0x125 0x1 0x00
write 0x127 0x1 0x00
write 0x129 0x1 0x00
write 0x12b 0x1 0x00
write 0x12d 0x1 0x00
write 0x12f 0x1 0x00
write 0x131 0x1 0x00
write 0x133 0x1 0x00
write 0x135 0x1 0x00
write 0x137 0x1 0x00
write 0x139 0x1 0x00
write 0xe0007003 0x1 0x00
EOF
...
=================================================================
==276099==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d000011178
at pc 0x562cc3b736c7 bp 0x7ffed49dee60 sp 0x7ffed49dee58
READ of size 8 at 0x60d000011178 thread T0
#0 0x562cc3b736c6 in virtio_gpu_ctrl_response hw/display/virtio-gpu.c:180:42
#1 0x562cc3b7c40b in virtio_gpu_ctrl_response_nodata hw/display/virtio-gpu.c:192:5
#2 0x562cc3b7c40b in virtio_gpu_simple_process_cmd hw/display/virtio-gpu.c:1015:13
#3 0x562cc3b82873 in virtio_gpu_process_cmdq hw/display/virtio-gpu.c:1050:9
#4 0x562cc4a85514 in aio_bh_call util/async.c:169:5
#5 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13
#6 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5
#7 0x562cc4a8a2da in aio_ctx_dispatch util/async.c:358:5
#8 0x7f36840547a8 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x547a8)
#9 0x562cc4a8b753 in glib_pollfds_poll util/main-loop.c:290:9
#10 0x562cc4a8b753 in os_host_main_loop_wait util/main-loop.c:313:5
#11 0x562cc4a8b753 in main_loop_wait util/main-loop.c:592:11
#12 0x562cc3938186 in qemu_main_loop system/runstate.c:782:9
#13 0x562cc43b7af5 in qemu_default_main system/main.c:37:14
#14 0x7f3683a6c189 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#15 0x7f3683a6c244 in __libc_start_main csu/../csu/libc-start.c:381:3
#16 0x562cc2a58ac0 in _start (qemu-system-i386+0x231bac0)
0x60d000011178 is located 56 bytes inside of 136-byte region [0x60d000011140,0x60d0000111c8)
freed by thread T0 here:
#0 0x562cc2adb662 in __interceptor_free (qemu-system-i386+0x239e662)
#1 0x562cc3b86b21 in virtio_gpu_reset hw/display/virtio-gpu.c:1524:9
#2 0x562cc416e20e in virtio_reset hw/virtio/virtio.c:2145:9
#3 0x562cc37c5644 in virtio_pci_reset hw/virtio/virtio-pci.c:2249:5
#4 0x562cc4233758 in memory_region_write_accessor system/memory.c:497:5
#5 0x562cc4232eea in access_with_adjusted_size system/memory.c:573:18
previously allocated by thread T0 here:
#0 0x562cc2adb90e in malloc (qemu-system-i386+0x239e90e)
#1 0x7f368405a678 in g_malloc (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5a678)
#2 0x562cc4163ffc in virtqueue_split_pop hw/virtio/virtio.c:1612:12
#3 0x562cc4163ffc in virtqueue_pop hw/virtio/virtio.c:1783:16
#4 0x562cc3b91a95 in virtio_gpu_handle_ctrl hw/display/virtio-gpu.c:1112:15
#5 0x562cc4a85514 in aio_bh_call util/async.c:169:5
#6 0x562cc4a85c52 in aio_bh_poll util/async.c:216:13
#7 0x562cc4a1a79b in aio_dispatch util/aio-posix.c:423:5
SUMMARY: AddressSanitizer: heap-use-after-free hw/display/virtio-gpu.c:180:42 in virtio_gpu_ctrl_response
With this change, the same reproducer triggers:
qemu-system-i386: warning: Blocked re-entrant IO on MemoryRegion: virtio-pci-common-virtio-gpu at addr: 0x6
Fixes: CVE-2024-3446
Cc: qemu-stable@nongnu.org
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Reported-by: Yongkang Jia <kangel@zju.edu.cn>
Reported-by: Xiao Lei <nop.leixiao@gmail.com>
Reported-by: Yiming Tao <taoym@zju.edu.cn>
Buglink: https://bugs.launchpad.net/qemu/+bug/1888606
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20240409105537.18308-3-philmd@linaro.org>
Signed-off-by: liuxiangdong <liuxiangdong5@huawei.com>
---
hw/display/virtio-gpu.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 897042c3dc..0e5f5045b5 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1335,10 +1335,8 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
g->ctrl_vq = virtio_get_queue(vdev, 0);
g->cursor_vq = virtio_get_queue(vdev, 1);
- g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g,
- &qdev->mem_reentrancy_guard);
- g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g,
- &qdev->mem_reentrancy_guard);
+ g->ctrl_bh = virtio_bh_new_guarded(qdev, virtio_gpu_ctrl_bh, g);
+ g->cursor_bh = virtio_bh_new_guarded(qdev, virtio_gpu_cursor_bh, g);
QTAILQ_INIT(&g->reslist);
QTAILQ_INIT(&g->cmdq);
QTAILQ_INIT(&g->fenceq);
--
2.27.0

View File

@ -0,0 +1,110 @@
From fac003085b4e294ae60c579a2e74087ea019f4b7 Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Wed, 6 Sep 2023 15:09:21 +0200
Subject: [PATCH] hw/ide: reset: cancel async DMA operation before resetting
state (Fix CVE-2023-5088)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If there is a pending DMA operation during ide_bus_reset(), the fact
that the IDEState is already reset before the operation is canceled
can be problematic. In particular, ide_dma_cb() might be called and
then use the reset IDEState which contains the signature after the
reset. When used to construct the IO operation this leads to
ide_get_sector() returning 0 and nsector being 1. This is particularly
bad, because a write command will thus destroy the first sector which
often contains a partition table or similar.
Traces showing the unsolicited write happening with IDEState
0x5595af6949d0 being used after reset:
> ahci_port_write ahci(0x5595af6923f0)[0]: port write [reg:PxSCTL] @ 0x2c: 0x00000300
> ahci_reset_port ahci(0x5595af6923f0)[0]: reset port
> ide_reset IDEstate 0x5595af6949d0
> ide_reset IDEstate 0x5595af694da8
> ide_bus_reset_aio aio_cancel
> dma_aio_cancel dbs=0x7f64600089a0
> dma_blk_cb dbs=0x7f64600089a0 ret=0
> dma_complete dbs=0x7f64600089a0 ret=0 cb=0x5595acd40b30
> ahci_populate_sglist ahci(0x5595af6923f0)[0]
> ahci_dma_prepare_buf ahci(0x5595af6923f0)[0]: prepare buf limit=512 prepared=512
> ide_dma_cb IDEState 0x5595af6949d0; sector_num=0 n=1 cmd=DMA WRITE
> dma_blk_io dbs=0x7f6420802010 bs=0x5595ae2c6c30 offset=0 to_dev=1
> dma_blk_cb dbs=0x7f6420802010 ret=0
> (gdb) p *qiov
> $11 = {iov = 0x7f647c76d840, niov = 1, {{nalloc = 1, local_iov = {iov_base = 0x0,
> iov_len = 512}}, {__pad = "\001\000\000\000\000\000\000\000\000\000\000",
> size = 512}}}
> (gdb) bt
> #0 blk_aio_pwritev (blk=0x5595ae2c6c30, offset=0, qiov=0x7f6420802070, flags=0,
> cb=0x5595ace6f0b0 <dma_blk_cb>, opaque=0x7f6420802010)
> at ../block/block-backend.c:1682
> #1 0x00005595ace6f185 in dma_blk_cb (opaque=0x7f6420802010, ret=<optimized out>)
> at ../softmmu/dma-helpers.c:179
> #2 0x00005595ace6f778 in dma_blk_io (ctx=0x5595ae0609f0,
> sg=sg@entry=0x5595af694d00, offset=offset@entry=0, align=align@entry=512,
> io_func=io_func@entry=0x5595ace6ee30 <dma_blk_write_io_func>,
> io_func_opaque=io_func_opaque@entry=0x5595ae2c6c30,
> cb=0x5595acd40b30 <ide_dma_cb>, opaque=0x5595af6949d0,
> dir=DMA_DIRECTION_TO_DEVICE) at ../softmmu/dma-helpers.c:244
> #3 0x00005595ace6f90a in dma_blk_write (blk=0x5595ae2c6c30,
> sg=sg@entry=0x5595af694d00, offset=offset@entry=0, align=align@entry=512,
> cb=cb@entry=0x5595acd40b30 <ide_dma_cb>, opaque=opaque@entry=0x5595af6949d0)
> at ../softmmu/dma-helpers.c:280
> #4 0x00005595acd40e18 in ide_dma_cb (opaque=0x5595af6949d0, ret=<optimized out>)
> at ../hw/ide/core.c:953
> #5 0x00005595ace6f319 in dma_complete (ret=0, dbs=0x7f64600089a0)
> at ../softmmu/dma-helpers.c:107
> #6 dma_blk_cb (opaque=0x7f64600089a0, ret=0) at ../softmmu/dma-helpers.c:127
> #7 0x00005595ad12227d in blk_aio_complete (acb=0x7f6460005b10)
> at ../block/block-backend.c:1527
> #8 blk_aio_complete (acb=0x7f6460005b10) at ../block/block-backend.c:1524
> #9 blk_aio_write_entry (opaque=0x7f6460005b10) at ../block/block-backend.c:1594
> #10 0x00005595ad258cfb in coroutine_trampoline (i0=<optimized out>,
> i1=<optimized out>) at ../util/coroutine-ucontext.c:177
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: simon.rowe@nutanix.com
Message-ID: <20230906130922.142845-1-f.ebner@proxmox.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/ide/core.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 14283a84a5..5e5c6e2cf3 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2456,19 +2456,19 @@ static void ide_dummy_transfer_stop(IDEState *s)
void ide_bus_reset(IDEBus *bus)
{
- bus->unit = 0;
- bus->cmd = 0;
- ide_reset(&bus->ifs[0]);
- ide_reset(&bus->ifs[1]);
- ide_clear_hob(bus);
-
- /* pending async DMA */
+ /* pending async DMA - needs the IDEState before it is reset */
if (bus->dma->aiocb) {
trace_ide_bus_reset_aio();
blk_aio_cancel(bus->dma->aiocb);
bus->dma->aiocb = NULL;
}
+ bus->unit = 0;
+ bus->cmd = 0;
+ ide_reset(&bus->ifs[0]);
+ ide_reset(&bus->ifs[1]);
+ ide_clear_hob(bus);
+
/* reset dma provider too */
if (bus->dma->ops->reset) {
bus->dma->ops->reset(bus->dma);
--
2.41.0.windows.1

View File

@ -0,0 +1,94 @@
From 227f7f8b076ac11ff5959ddebc16569665b68e21 Mon Sep 17 00:00:00 2001
From: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
Date: Thu, 28 Mar 2024 10:17:35 +0800
Subject: [PATCH] hw/intc: clean-up error reporting for failed ITS cmd
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
cherry picked from commit 229c57b1986484ea2cd1eb744e3492af7eee063e
While trying to debug a GIC ITS failure I saw some guest errors that
had poor formatting as well as leaving me confused as to what failed.
As most of the checks aren't possible without a valid dte split that
check apart and then check the other conditions in steps. This avoids
us relying on undefined data.
I still get a failure with the current kvm-unit-tests but at least I
know (partially) why now:
Exception return from AArch64 EL1 to AArch64 EL1 PC 0x40080588
PASS: gicv3: its-trigger: inv/invall: dev2/eventid=20 now triggers an LPI
ITS: MAPD devid=2 size = 0x8 itt=0x40430000 valid=0
INT dev_id=2 event_id=20
process_its_cmd: invalid command attributes: invalid dte: 0 for 2 (MEM_TX: 0)
PASS: gicv3: its-trigger: mapd valid=false: no LPI after device unmap
SUMMARY: 6 tests, 1 unexpected failures
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20211112170454.3158925-1-alex.bennee@linaro.org
Cc: Shashi Mallela <shashi.mallela@linaro.org>
Cc: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
---
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++++++++++++++------------
1 file changed, 27 insertions(+), 12 deletions(-)
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
index c929a9cb5c..b99e63d58f 100644
--- a/hw/intc/arm_gicv3_its.c
+++ b/hw/intc/arm_gicv3_its.c
@@ -274,21 +274,36 @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
if (res != MEMTX_OK) {
return result;
}
+ } else {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid command attributes: "
+ "invalid dte: %"PRIx64" for %d (MEM_TX: %d)\n",
+ __func__, dte, devid, res);
+ return result;
}
- if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
- !cte_valid || (eventid > max_eventid)) {
+
+ /*
+ * In this implementation, in case of guest errors we ignore the
+ * command and move onto the next command in the queue.
+ */
+ if (devid > s->dt.maxids.max_devids) {
qemu_log_mask(LOG_GUEST_ERROR,
- "%s: invalid command attributes "
- "devid %d or eventid %d or invalid dte %d or"
- "invalid cte %d or invalid ite %d\n",
- __func__, devid, eventid, dte_valid, cte_valid,
- ite_valid);
- /*
- * in this implementation, in case of error
- * we ignore this command and move onto the next
- * command in the queue
- */
+ "%s: invalid command attributes: devid %d>%d",
+ __func__, devid, s->dt.maxids.max_devids);
+
+ } else if (!dte_valid || !ite_valid || !cte_valid) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid command attributes: "
+ "dte: %s, ite: %s, cte: %s\n",
+ __func__,
+ dte_valid ? "valid" : "invalid",
+ ite_valid ? "valid" : "invalid",
+ cte_valid ? "valid" : "invalid");
+ } else if (eventid > max_eventid) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid command attributes: eventid %d > %d\n",
+ __func__, eventid, max_eventid);
} else {
/*
* Current implementation only supports rdbase == procnum
--
2.27.0

View File

@ -0,0 +1,55 @@
From 4b01fe41d731409b8bf2b569a38aa5959ed473c4 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 25 Mar 2024 08:58:38 +0000
Subject: [PATCH] hw/net/rocker: Avoid undefined shifts with more than 31 ports
mainline inclusion
commit 7cf745dd9c25f0740dc1009598b58dd8dd989876
category: bugfix
---------------------------------------------------------------
In rocker_port_phys_link_status() and rocker_port_phys_enable_read()
we construct a 64-bit value with one bit per front-panel port.
However we accidentally do the shift as 32-bit arithmetic, which
means that if there are more than 31 front-panel ports this is
undefined behaviour.
Fix the problem by ensuring we use 64-bit arithmetic for the whole
calculation. (We won't ever shift off the 64-bit value because
ROCKER_FP_PORTS_MAX is 62.)
Resolves: Coverity CID 1487121, 1487160
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
hw/net/rocker/rocker.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index 31f2340fb9..d8f3f16fe8 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -1010,7 +1010,7 @@ static uint64_t rocker_port_phys_link_status(Rocker *r)
FpPort *port = r->fp_port[i];
if (fp_port_get_link_up(port)) {
- status |= 1 << (i + 1);
+ status |= 1ULL << (i + 1);
}
}
return status;
@@ -1025,7 +1025,7 @@ static uint64_t rocker_port_phys_enable_read(Rocker *r)
FpPort *port = r->fp_port[i];
if (fp_port_enabled(port)) {
- ret |= 1 << (i + 1);
+ ret |= 1ULL << (i + 1);
}
}
return ret;
--
2.27.0

View File

@ -0,0 +1,79 @@
From a2c1183a858ff592e0efb1886bbe6941b4ce018b Mon Sep 17 00:00:00 2001
From: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
Date: Thu, 28 Mar 2024 13:54:29 +0800
Subject: [PATCH] hw/ppc/mac.h: Remove MAX_CPUS macro
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
cherry picked from commit 83234b8289e64fc359a5bf02d886a333d65b8f8c
The mac.h header defines a MAX_CPUS macro. This is confusingly named,
because it suggests it's a generic setting, but in fact it's used
by only the g3beige and mac99 machines. It's also using a single
macro for two values which aren't inherently the same -- if one
of these two machines was updated to support SMP configurations
then it would want a different max_cpus value to the other.
Since the macro is used in only two places, just expand it out
and get rid of it. If hypothetical future work to support SMP
in these boards needs a compile-time-known limit on the number
of CPUs, we can give it a suitable name at that point.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20211105184216.120972-1-peter.maydell@linaro.org>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
---
hw/ppc/mac.h | 3 ---
hw/ppc/mac_newworld.c | 3 ++-
hw/ppc/mac_oldworld.c | 3 ++-
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 22c8408078..a1fa8f8e41 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -36,9 +36,6 @@
#include "hw/pci-host/uninorth.h"
#include "qom/object.h"
-/* SMP is not enabled, for now */
-#define MAX_CPUS 1
-
#define NVRAM_SIZE 0x2000
#define PROM_FILENAME "openbios-ppc"
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 7bb7ac3997..4bddb529c2 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -581,7 +581,8 @@ static void core99_machine_class_init(ObjectClass *oc, void *data)
mc->desc = "Mac99 based PowerMAC";
mc->init = ppc_core99_init;
mc->block_default_type = IF_IDE;
- mc->max_cpus = MAX_CPUS;
+ /* SMP is not supported currently */
+ mc->max_cpus = 1;
mc->default_boot_order = "cd";
mc->default_display = "std";
mc->kvm_type = core99_kvm_type;
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index de2be960e6..7016979a7c 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -423,7 +423,8 @@ static void heathrow_class_init(ObjectClass *oc, void *data)
mc->desc = "Heathrow based PowerMAC";
mc->init = ppc_heathrow_init;
mc->block_default_type = IF_IDE;
- mc->max_cpus = MAX_CPUS;
+ /* SMP is not supported currently */
+ mc->max_cpus = 1;
#ifndef TARGET_PPC64
mc->is_default = true;
#endif
--
2.27.0

View File

@ -0,0 +1,427 @@
From 458b3f30a4e5d7b6361e6040061c9e30b4d75d1d Mon Sep 17 00:00:00 2001
From: Alexander Bulekov <alxndr@bu.edu>
Date: Thu, 27 Apr 2023 17:10:09 -0400
Subject: [PATCH] hw: replace most qemu_bh_new calls with qemu_bh_new_guarded
This protects devices from bh->mmio reentrancy issues.
Thanks: Thomas Huth <thuth@redhat.com> for diagnosing OS X test failure.
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Paul Durrant <paul@xen.org>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20230427211013.2994127-5-alxndr@bu.edu>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: liuxiangdong <liuxiangdong5@huawei.com>
---
hw/9pfs/xen-9p-backend.c | 5 ++++-
hw/block/dataplane/virtio-blk.c | 3 ++-
hw/block/dataplane/xen-block.c | 5 +++--
hw/char/virtio-serial-bus.c | 3 ++-
hw/display/qxl.c | 9 ++++++---
hw/display/virtio-gpu.c | 6 ++++--
hw/ide/ahci.c | 3 ++-
hw/ide/ahci_internal.h | 1 +
hw/ide/core.c | 4 +++-
hw/misc/imx_rngc.c | 6 ++++--
hw/misc/macio/mac_dbdma.c | 2 +-
hw/net/virtio-net.c | 3 ++-
hw/scsi/mptsas.c | 3 ++-
hw/scsi/scsi-bus.c | 3 ++-
hw/scsi/vmw_pvscsi.c | 3 ++-
hw/usb/dev-uas.c | 3 ++-
hw/usb/hcd-dwc2.c | 3 ++-
hw/usb/hcd-ehci.c | 3 ++-
hw/usb/hcd-uhci.c | 2 +-
hw/usb/host-libusb.c | 6 ++++--
hw/usb/redirect.c | 6 ++++--
hw/usb/xen-usb.c | 3 ++-
hw/virtio/virtio-balloon.c | 5 +++--
hw/virtio/virtio-crypto.c | 3 ++-
24 files changed, 62 insertions(+), 31 deletions(-)
diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
index 65c4979c3c..09f7c13588 100644
--- a/hw/9pfs/xen-9p-backend.c
+++ b/hw/9pfs/xen-9p-backend.c
@@ -60,6 +60,7 @@ typedef struct Xen9pfsDev {
int num_rings;
Xen9pfsRing *rings;
+ MemReentrancyGuard mem_reentrancy_guard;
} Xen9pfsDev;
static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev);
@@ -441,7 +442,9 @@ static int xen_9pfs_connect(struct XenLegacyDevice *xendev)
xen_9pdev->rings[i].ring.out = xen_9pdev->rings[i].data +
XEN_FLEX_RING_SIZE(ring_order);
- xen_9pdev->rings[i].bh = qemu_bh_new(xen_9pfs_bh, &xen_9pdev->rings[i]);
+ xen_9pdev->rings[i].bh = qemu_bh_new_guarded(xen_9pfs_bh,
+ &xen_9pdev->rings[i],
+ &xen_9pdev->mem_reentrancy_guard);
xen_9pdev->rings[i].out_cons = 0;
xen_9pdev->rings[i].out_size = 0;
xen_9pdev->rings[i].inprogress = false;
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index ee5a5352dc..5f0de7da1e 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -127,7 +127,8 @@ bool virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
} else {
s->ctx = qemu_get_aio_context();
}
- s->bh = aio_bh_new(s->ctx, notify_guest_bh, s);
+ s->bh = aio_bh_new_guarded(s->ctx, notify_guest_bh, s,
+ &DEVICE(vdev)->mem_reentrancy_guard);
s->batch_notify_vqs = bitmap_new(conf->num_queues);
*dataplane = s;
diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
index 860787580a..07855feea6 100644
--- a/hw/block/dataplane/xen-block.c
+++ b/hw/block/dataplane/xen-block.c
@@ -631,8 +631,9 @@ XenBlockDataPlane *xen_block_dataplane_create(XenDevice *xendev,
} else {
dataplane->ctx = qemu_get_aio_context();
}
- dataplane->bh = aio_bh_new(dataplane->ctx, xen_block_dataplane_bh,
- dataplane);
+ dataplane->bh = aio_bh_new_guarded(dataplane->ctx, xen_block_dataplane_bh,
+ dataplane,
+ &DEVICE(xendev)->mem_reentrancy_guard);
return dataplane;
}
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index edb7a44ee9..14716b66cc 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -990,7 +990,8 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp)
return;
}
- port->bh = qemu_bh_new(flush_queued_data_bh, port);
+ port->bh = qemu_bh_new_guarded(flush_queued_data_bh, port,
+ &dev->mem_reentrancy_guard);
port->elem = NULL;
}
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index bcd9e8716a..0f663b9912 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -2206,11 +2206,14 @@ static void qxl_realize_common(PCIQXLDevice *qxl, Error **errp)
qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
- qxl->update_irq = qemu_bh_new(qxl_update_irq_bh, qxl);
+ qxl->update_irq = qemu_bh_new_guarded(qxl_update_irq_bh, qxl,
+ &DEVICE(qxl)->mem_reentrancy_guard);
qxl_reset_state(qxl);
- qxl->update_area_bh = qemu_bh_new(qxl_render_update_area_bh, qxl);
- qxl->ssd.cursor_bh = qemu_bh_new(qemu_spice_cursor_refresh_bh, &qxl->ssd);
+ qxl->update_area_bh = qemu_bh_new_guarded(qxl_render_update_area_bh, qxl,
+ &DEVICE(qxl)->mem_reentrancy_guard);
+ qxl->ssd.cursor_bh = qemu_bh_new_guarded(qemu_spice_cursor_refresh_bh, &qxl->ssd,
+ &DEVICE(qxl)->mem_reentrancy_guard);
}
static void qxl_realize_primary(PCIDevice *dev, Error **errp)
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 9ccc0575e3..897042c3dc 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1335,8 +1335,10 @@ void virtio_gpu_device_realize(DeviceState *qdev, Error **errp)
g->ctrl_vq = virtio_get_queue(vdev, 0);
g->cursor_vq = virtio_get_queue(vdev, 1);
- g->ctrl_bh = qemu_bh_new(virtio_gpu_ctrl_bh, g);
- g->cursor_bh = qemu_bh_new(virtio_gpu_cursor_bh, g);
+ g->ctrl_bh = qemu_bh_new_guarded(virtio_gpu_ctrl_bh, g,
+ &qdev->mem_reentrancy_guard);
+ g->cursor_bh = qemu_bh_new_guarded(virtio_gpu_cursor_bh, g,
+ &qdev->mem_reentrancy_guard);
QTAILQ_INIT(&g->reslist);
QTAILQ_INIT(&g->cmdq);
QTAILQ_INIT(&g->fenceq);
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 1e482738de..36d050aafc 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1510,7 +1510,8 @@ static void ahci_cmd_done(const IDEDMA *dma)
ahci_write_fis_d2h(ad);
if (ad->port_regs.cmd_issue && !ad->check_bh) {
- ad->check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
+ ad->check_bh = qemu_bh_new_guarded(ahci_check_cmd_bh, ad,
+ &ad->mem_reentrancy_guard);
qemu_bh_schedule(ad->check_bh);
}
}
diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h
index 109de9e2d1..a7768dd69e 100644
--- a/hw/ide/ahci_internal.h
+++ b/hw/ide/ahci_internal.h
@@ -321,6 +321,7 @@ struct AHCIDevice {
bool init_d2h_sent;
AHCICmdHdr *cur_cmd;
NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
+ MemReentrancyGuard mem_reentrancy_guard;
};
struct AHCIPCIState {
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 0d925c5ca5..14283a84a5 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -510,6 +510,7 @@ BlockAIOCB *ide_issue_trim(
BlockCompletionFunc *cb, void *cb_opaque, void *opaque)
{
IDEState *s = opaque;
+ IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master;
TrimAIOCB *iocb;
/* Paired with a decrement in ide_trim_bh_cb() */
@@ -517,7 +518,8 @@ BlockAIOCB *ide_issue_trim(
iocb = blk_aio_get(&trim_aiocb_info, s->blk, cb, cb_opaque);
iocb->s = s;
- iocb->bh = qemu_bh_new(ide_trim_bh_cb, iocb);
+ iocb->bh = qemu_bh_new_guarded(ide_trim_bh_cb, iocb,
+ &DEVICE(dev)->mem_reentrancy_guard);
iocb->ret = 0;
iocb->qiov = qiov;
iocb->i = -1;
diff --git a/hw/misc/imx_rngc.c b/hw/misc/imx_rngc.c
index 632c03779c..082c6980ad 100644
--- a/hw/misc/imx_rngc.c
+++ b/hw/misc/imx_rngc.c
@@ -228,8 +228,10 @@ static void imx_rngc_realize(DeviceState *dev, Error **errp)
sysbus_init_mmio(sbd, &s->iomem);
sysbus_init_irq(sbd, &s->irq);
- s->self_test_bh = qemu_bh_new(imx_rngc_self_test, s);
- s->seed_bh = qemu_bh_new(imx_rngc_seed, s);
+ s->self_test_bh = qemu_bh_new_guarded(imx_rngc_self_test, s,
+ &dev->mem_reentrancy_guard);
+ s->seed_bh = qemu_bh_new_guarded(imx_rngc_seed, s,
+ &dev->mem_reentrancy_guard);
}
static void imx_rngc_reset(DeviceState *dev)
diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c
index efcc02609f..cc7e02203d 100644
--- a/hw/misc/macio/mac_dbdma.c
+++ b/hw/misc/macio/mac_dbdma.c
@@ -914,7 +914,7 @@ static void mac_dbdma_realize(DeviceState *dev, Error **errp)
{
DBDMAState *s = MAC_DBDMA(dev);
- s->bh = qemu_bh_new(DBDMA_run_bh, s);
+ s->bh = qemu_bh_new_guarded(DBDMA_run_bh, s, &dev->mem_reentrancy_guard);
}
static void mac_dbdma_class_init(ObjectClass *oc, void *data)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index cdf1313053..f3fb9393b3 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2812,7 +2812,8 @@ static void virtio_net_add_queue(VirtIONet *n, int index)
n->vqs[index].tx_vq =
virtio_add_queue(vdev, n->net_conf.tx_queue_size,
virtio_net_handle_tx_bh);
- n->vqs[index].tx_bh = qemu_bh_new(virtio_net_tx_bh, &n->vqs[index]);
+ n->vqs[index].tx_bh = qemu_bh_new_guarded(virtio_net_tx_bh, &n->vqs[index],
+ &DEVICE(vdev)->mem_reentrancy_guard);
}
n->vqs[index].tx_waiting = 0;
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index 5181b0c0b0..8487138cb6 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -1321,7 +1321,8 @@ static void mptsas_scsi_realize(PCIDevice *dev, Error **errp)
}
s->max_devices = MPTSAS_NUM_PORTS;
- s->request_bh = qemu_bh_new(mptsas_fetch_requests, s);
+ s->request_bh = qemu_bh_new_guarded(mptsas_fetch_requests, s,
+ &DEVICE(dev)->mem_reentrancy_guard);
scsi_bus_init(&s->bus, sizeof(s->bus), &dev->qdev, &mptsas_scsi_info);
}
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 2b613ad2b3..89c4693cc2 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -199,7 +199,8 @@ static void scsi_dma_restart_cb(void *opaque, bool running, RunState state)
AioContext *ctx = blk_get_aio_context(s->conf.blk);
/* The reference is dropped in scsi_dma_restart_bh.*/
object_ref(OBJECT(s));
- s->bh = aio_bh_new(ctx, scsi_dma_restart_bh, s);
+ s->bh = aio_bh_new_guarded(ctx, scsi_dma_restart_bh, s,
+ &DEVICE(s)->mem_reentrancy_guard);
qemu_bh_schedule(s->bh);
}
}
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 4d9969f3b1..d5c6293a21 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1184,7 +1184,8 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp)
pcie_endpoint_cap_init(pci_dev, PVSCSI_EXP_EP_OFFSET);
}
- s->completion_worker = qemu_bh_new(pvscsi_process_completion_queue, s);
+ s->completion_worker = qemu_bh_new_guarded(pvscsi_process_completion_queue, s,
+ &DEVICE(pci_dev)->mem_reentrancy_guard);
scsi_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev), &pvscsi_scsi_info);
/* override default SCSI bus hotplug-handler, with pvscsi's one */
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index c9f295e7e4..67bcfac626 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -936,7 +936,8 @@ static void usb_uas_realize(USBDevice *dev, Error **errp)
QTAILQ_INIT(&uas->results);
QTAILQ_INIT(&uas->requests);
- uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas);
+ uas->status_bh = qemu_bh_new_guarded(usb_uas_send_status_bh, uas,
+ &d->mem_reentrancy_guard);
dev->flags |= (1 << USB_DEV_FLAG_IS_SCSI_STORAGE);
scsi_bus_init(&uas->bus, sizeof(uas->bus), DEVICE(dev), &usb_uas_scsi_info);
diff --git a/hw/usb/hcd-dwc2.c b/hw/usb/hcd-dwc2.c
index 8755e9cbb0..a0c4e782b2 100644
--- a/hw/usb/hcd-dwc2.c
+++ b/hw/usb/hcd-dwc2.c
@@ -1364,7 +1364,8 @@ static void dwc2_realize(DeviceState *dev, Error **errp)
s->fi = USB_FRMINTVL - 1;
s->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_frame_boundary, s);
s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, dwc2_work_timer, s);
- s->async_bh = qemu_bh_new(dwc2_work_bh, s);
+ s->async_bh = qemu_bh_new_guarded(dwc2_work_bh, s,
+ &dev->mem_reentrancy_guard);
sysbus_init_irq(sbd, &s->irq);
}
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index f9aa567f5d..3fbb06e248 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2535,7 +2535,8 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
}
s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ehci_work_timer, s);
- s->async_bh = qemu_bh_new(ehci_work_bh, s);
+ s->async_bh = qemu_bh_new_guarded(ehci_work_bh, s,
+ &dev->mem_reentrancy_guard);
s->device = dev;
s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 693c68f445..00a8de2fba 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1236,7 +1236,7 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
}
}
- s->bh = qemu_bh_new(uhci_bh, s);
+ s->bh = qemu_bh_new_guarded(uhci_bh, s, &DEVICE(dev)->mem_reentrancy_guard);
s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s);
s->num_ports_vmstate = NB_PORTS;
s->frame_time = NANOSECONDS_PER_SECOND / uhci_frame_timer_freq;
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 3394b04f50..13e83a3050 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1178,7 +1178,8 @@ static void usb_host_nodev_bh(void *opaque)
static void usb_host_nodev(USBHostDevice *s)
{
if (!s->bh_nodev) {
- s->bh_nodev = qemu_bh_new(usb_host_nodev_bh, s);
+ s->bh_nodev = qemu_bh_new_guarded(usb_host_nodev_bh, s,
+ &DEVICE(s)->mem_reentrancy_guard);
}
qemu_bh_schedule(s->bh_nodev);
}
@@ -1776,7 +1777,8 @@ static int usb_host_post_load(void *opaque, int version_id)
USBHostDevice *dev = opaque;
if (!dev->bh_postld) {
- dev->bh_postld = qemu_bh_new(usb_host_post_load_bh, dev);
+ dev->bh_postld = qemu_bh_new_guarded(usb_host_post_load_bh, dev,
+ &DEVICE(dev)->mem_reentrancy_guard);
}
qemu_bh_schedule(dev->bh_postld);
dev->bh_postld_pending = true;
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 5f0ef9cb3b..59cd3cd7c4 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1437,8 +1437,10 @@ static void usbredir_realize(USBDevice *udev, Error **errp)
}
}
- dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
- dev->device_reject_bh = qemu_bh_new(usbredir_device_reject_bh, dev);
+ dev->chardev_close_bh = qemu_bh_new_guarded(usbredir_chardev_close_bh, dev,
+ &DEVICE(dev)->mem_reentrancy_guard);
+ dev->device_reject_bh = qemu_bh_new_guarded(usbredir_device_reject_bh, dev,
+ &DEVICE(dev)->mem_reentrancy_guard);
dev->attach_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, usbredir_do_attach, dev);
packet_id_queue_init(&dev->cancelled, dev, "cancelled");
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index 0f7369e7ed..dec91294ad 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -1021,7 +1021,8 @@ static void usbback_alloc(struct XenLegacyDevice *xendev)
QTAILQ_INIT(&usbif->req_free_q);
QSIMPLEQ_INIT(&usbif->hotplug_q);
- usbif->bh = qemu_bh_new(usbback_bh, usbif);
+ usbif->bh = qemu_bh_new_guarded(usbback_bh, usbif,
+ &DEVICE(xendev)->mem_reentrancy_guard);
}
static int usbback_free(struct XenLegacyDevice *xendev)
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 9a4f491b54..f503572e27 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -917,8 +917,9 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
precopy_add_notifier(&s->free_page_hint_notify);
object_ref(OBJECT(s->iothread));
- s->free_page_bh = aio_bh_new(iothread_get_aio_context(s->iothread),
- virtio_ballloon_get_free_page_hints, s);
+ s->free_page_bh = aio_bh_new_guarded(iothread_get_aio_context(s->iothread),
+ virtio_ballloon_get_free_page_hints, s,
+ &dev->mem_reentrancy_guard);
}
if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) {
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 8c2047f4e0..bcca4fb72a 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -829,7 +829,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
vcrypto->vqs[i].dataq =
virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh);
vcrypto->vqs[i].dataq_bh =
- qemu_bh_new(virtio_crypto_dataq_bh, &vcrypto->vqs[i]);
+ qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i],
+ &dev->mem_reentrancy_guard);
vcrypto->vqs[i].vcrypto = vcrypto;
}
--
2.27.0

View File

@ -0,0 +1,135 @@
From da4d478b1ae6082b6ca333ece1985e014f58fd5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
Date: Tue, 9 Apr 2024 16:19:27 +0200
Subject: [PATCH] hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT)
is set(CVE-2024-3447)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Per "SD Host Controller Standard Specification Version 3.00":
* 2.2.5 Transfer Mode Register (Offset 00Ch)
Writes to this register shall be ignored when the Command
Inhibit (DAT) in the Present State register is 1.
Do not update the TRNMOD register when Command Inhibit (DAT)
bit is set to avoid the present-status register going out of
sync, leading to malicious guest using DMA mode and overflowing
the FIFO buffer:
$ cat << EOF | qemu-system-i386 \
-display none -nographic -nodefaults \
-machine accel=qtest -m 512M \
-device sdhci-pci,sd-spec-version=3 \
-device sd-card,drive=mydrive \
-drive if=none,index=0,file=null-co://,format=raw,id=mydrive \
-qtest stdio
outl 0xcf8 0x80001013
outl 0xcfc 0x91
outl 0xcf8 0x80001001
outl 0xcfc 0x06000000
write 0x9100002c 0x1 0x05
write 0x91000058 0x1 0x16
write 0x91000005 0x1 0x04
write 0x91000028 0x1 0x08
write 0x16 0x1 0x21
write 0x19 0x1 0x20
write 0x9100000c 0x1 0x01
write 0x9100000e 0x1 0x20
write 0x9100000f 0x1 0x00
write 0x9100000c 0x1 0x00
write 0x91000020 0x1 0x00
EOF
Stack trace (part):
=================================================================
==89993==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x615000029900 at pc 0x55d5f885700d bp 0x7ffc1e1e9470 sp 0x7ffc1e1e9468
WRITE of size 1 at 0x615000029900 thread T0
#0 0x55d5f885700c in sdhci_write_dataport hw/sd/sdhci.c:564:39
#1 0x55d5f8849150 in sdhci_write hw/sd/sdhci.c:1223:13
#2 0x55d5fa01db63 in memory_region_write_accessor system/memory.c:497:5
#3 0x55d5fa01d245 in access_with_adjusted_size system/memory.c:573:18
#4 0x55d5fa01b1a9 in memory_region_dispatch_write system/memory.c:1521:16
#5 0x55d5fa09f5c9 in flatview_write_continue system/physmem.c:2711:23
#6 0x55d5fa08f78b in flatview_write system/physmem.c:2753:12
#7 0x55d5fa08f258 in address_space_write system/physmem.c:2860:18
...
0x615000029900 is located 0 bytes to the right of 512-byte region
[0x615000029700,0x615000029900) allocated by thread T0 here:
#0 0x55d5f7237b27 in __interceptor_calloc
#1 0x7f9e36dd4c50 in g_malloc0
#2 0x55d5f88672f7 in sdhci_pci_realize hw/sd/sdhci-pci.c:36:5
#3 0x55d5f844b582 in pci_qdev_realize hw/pci/pci.c:2092:9
#4 0x55d5fa2ee74b in device_set_realized hw/core/qdev.c:510:13
#5 0x55d5fa325bfb in property_set_bool qom/object.c:2358:5
#6 0x55d5fa31ea45 in object_property_set qom/object.c:1472:5
#7 0x55d5fa332509 in object_property_set_qobject om/qom-qobject.c:28:10
#8 0x55d5fa31f6ed in object_property_set_bool qom/object.c:1541:15
#9 0x55d5fa2e2948 in qdev_realize hw/core/qdev.c:292:12
#10 0x55d5f8eed3f1 in qdev_device_add_from_qdict system/qdev-monitor.c:719:10
#11 0x55d5f8eef7ff in qdev_device_add system/qdev-monitor.c:738:11
#12 0x55d5f8f211f0 in device_init_func system/vl.c:1200:11
#13 0x55d5fad0877d in qemu_opts_foreach util/qemu-option.c:1135:14
#14 0x55d5f8f0df9c in qemu_create_cli_devices system/vl.c:2638:5
#15 0x55d5f8f0db24 in qmp_x_exit_preconfig system/vl.c:2706:5
#16 0x55d5f8f14dc0 in qemu_init system/vl.c:3737:9
...
SUMMARY: AddressSanitizer: heap-buffer-overflow hw/sd/sdhci.c:564:39
in sdhci_write_dataport
Add assertions to ensure the fifo_buffer[] is not overflowed by
malicious accesses to the Buffer Data Port register.
Fixes: CVE-2024-3447
Cc: qemu-stable@nongnu.org
Fixes: d7dfca0807 ("hw/sdhci: introduce standard SD host controller")
Buglink: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=58813
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Reported-by: Chuhong Yuan <hslester96@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <CAFEAcA9iLiv1XGTGKeopgMa8Y9+8kvptvsb8z2OBeuy+5=NUfg@mail.gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240409145524.27913-1-philmd@linaro.org>
---
hw/sd/sdhci.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index e0bbc90344..211daa4bb0 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -471,6 +471,7 @@ static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
}
for (i = 0; i < size; i++) {
+ assert(s->data_count < s->buf_maxsz);
value |= s->fifo_buffer[s->data_count] << i * 8;
s->data_count++;
/* check if we've read all valid data (blksize bytes) from buffer */
@@ -559,6 +560,7 @@ static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
}
for (i = 0; i < size; i++) {
+ assert(s->data_count < s->buf_maxsz);
s->fifo_buffer[s->data_count] = value & 0xFF;
s->data_count++;
value >>= 8;
@@ -1184,6 +1186,12 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
if (!(s->capareg & R_SDHC_CAPAB_SDMA_MASK)) {
value &= ~SDHC_TRNS_DMA;
}
+
+ /* TRNMOD writes are inhibited while Command Inhibit (DAT) is true */
+ if (s->prnsts & SDHC_DATA_INHIBIT) {
+ mask |= 0xffff;
+ }
+
MASKED_WRITE(s->trnmod, mask, value & SDHC_TRNMOD_MASK);
MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);
--
2.27.0

View File

@ -0,0 +1,68 @@
From 53203b7c0c933bd0ce07c58bdd7113e2fba62fa3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
Date: Thu, 4 Apr 2024 20:56:11 +0200
Subject: [PATCH] hw/virtio: Introduce virtio_bh_new_guarded() helper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce virtio_bh_new_guarded(), similar to qemu_bh_new_guarded()
but using the transport memory guard, instead of the device one
(there can only be one virtio device per virtio bus).
Inspired-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20240409105537.18308-2-philmd@linaro.org>
Signed-off-by: liuxiangdong <liuxiangdong5@huawei.com>
---
hw/virtio/virtio.c | 10 ++++++++++
include/hw/virtio/virtio.h | 7 +++++++
2 files changed, 17 insertions(+)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index e3f392fc59..80156bfbd5 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3960,3 +3960,13 @@ static void virtio_register_types(void)
}
type_init(virtio_register_types)
+
+QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
+ QEMUBHFunc *cb, void *opaque,
+ const char *name)
+{
+ DeviceState *transport = qdev_get_parent_bus(dev)->parent;
+
+ return qemu_bh_new_full(cb, opaque, name,
+ &transport->mem_reentrancy_guard);
+}
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 43509b33ff..4cc278f12c 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -23,6 +23,7 @@
#include "standard-headers/linux/virtio_ring.h"
#include "qom/object.h"
#include "hw/virtio/vhost.h"
+#include "block/aio.h"
/* A guest should never accept this. It implies negotiation is broken. */
#define VIRTIO_F_BAD_FEATURE 30
@@ -409,4 +410,10 @@ static inline bool virtio_device_disabled(VirtIODevice *vdev)
bool virtio_legacy_allowed(VirtIODevice *vdev);
bool virtio_legacy_check_disabled(VirtIODevice *vdev);
+QEMUBH *virtio_bh_new_guarded_full(DeviceState *dev,
+ QEMUBHFunc *cb, void *opaque,
+ const char *name);
+#define virtio_bh_new_guarded(dev, cb, opaque) \
+ virtio_bh_new_guarded_full((dev), (cb), (opaque), (stringify(cb)))
+
#endif
--
2.27.0

View File

@ -0,0 +1,51 @@
From 8e15820dcf4f343ad21e01d8a6c9516b79ee4e7c Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 30 Apr 2024 09:42:08 +0000
Subject: [PATCH] hw/virtio: handle un-configured shutdown in virtio-pci
mainline inclusion commit 5a9d5f09b1f61bc7072c2389ba5b11350ae76b0d category:
bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
The assert() protecting against leakage is a little aggressive and
causes needless crashes if a device is shutdown without having been
configured. In this case no descriptors are lost because none have
been assigned.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20220728135503.1060062-4-alex.bennee@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
hw/virtio/virtio-pci.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 6b45683280..389a8db0ec 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1213,9 +1213,14 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
nvqs = MIN(nvqs, VIRTIO_QUEUE_MAX);
- /* When deassigning, pass a consistent nvqs value
- * to avoid leaking notifiers.
+ /*
+ * When deassigning, pass a consistent nvqs value to avoid leaking
+ * notifiers. But first check we've actually been configured, exit
+ * early if we haven't.
*/
+ if (!assign && !proxy->nvqs_with_notifiers) {
+ return 0;
+ }
assert(assign || nvqs == proxy->nvqs_with_notifiers);
proxy->nvqs_with_notifiers = nvqs;
--
2.27.0

View File

@ -0,0 +1,43 @@
From 13eea576219af3919ac31f7e63818b46c4fcbab6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@linaro.org>
Date: Thu, 4 Apr 2024 20:56:41 +0200
Subject: [PATCH] hw/virtio/virtio-crypto: Protect from DMA re-entrancy
bugs(CVE-2024-3446)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Replace qemu_bh_new_guarded() by virtio_bh_new_guarded()
so the bus and device use the same guard. Otherwise the
DMA-reentrancy protection can be bypassed.
Fixes: CVE-2024-3446
Cc: qemu-stable@nongnu.org
Suggested-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20240409105537.18308-5-philmd@linaro.org>
---
hw/virtio/virtio-crypto.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index bcca4fb72a..07566f0d46 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -829,8 +829,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
vcrypto->vqs[i].dataq =
virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh);
vcrypto->vqs[i].dataq_bh =
- qemu_bh_new_guarded(virtio_crypto_dataq_bh, &vcrypto->vqs[i],
- &dev->mem_reentrancy_guard);
+ virtio_bh_new_guarded(dev, virtio_crypto_dataq_bh,
+ &vcrypto->vqs[i]);
vcrypto->vqs[i].vcrypto = vcrypto;
}
--
2.27.0

View File

@ -0,0 +1,90 @@
From 6257f125bc58952f49cbbc28210099a6333152a8 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 14 May 2024 10:05:16 +0000
Subject: [PATCH] i386: reset KVM nested state upon CPU reset mainline
inclusion commit 3cafdb67504a34a0305260f0c86a73d5a3fb000b category: bugfix
---------------------------------------------------------------
Make sure env->nested_state is cleaned up when a vCPU is reset, it may
be stale after an incoming migration, kvm_arch_put_registers() may
end up failing or putting vCPU in a weird state.
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Message-Id: <20220818150113.479917-2-vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
target/i386/kvm/kvm.c | 37 +++++++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 99be7f6155..9f3ddd5da2 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -1623,6 +1623,30 @@ static void kvm_init_xsave(CPUX86State *env)
env->xsave_buf_len);
}
+static void kvm_init_nested_state(CPUX86State *env)
+{
+ struct kvm_vmx_nested_state_hdr *vmx_hdr;
+ uint32_t size;
+
+ if (!env->nested_state) {
+ return;
+ }
+
+ size = env->nested_state->size;
+
+ memset(env->nested_state, 0, size);
+ env->nested_state->size = size;
+
+ if (cpu_has_vmx(env)) {
+ env->nested_state->format = KVM_STATE_NESTED_FORMAT_VMX;
+ vmx_hdr = &env->nested_state->hdr.vmx;
+ vmx_hdr->vmxon_pa = -1ull;
+ vmx_hdr->vmcs12_pa = -1ull;
+ } else if (cpu_has_svm(env)) {
+ env->nested_state->format = KVM_STATE_NESTED_FORMAT_SVM;
+ }
+}
+
int kvm_arch_init_vcpu(CPUState *cs)
{
struct {
@@ -2051,19 +2075,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
assert(max_nested_state_len >= offsetof(struct kvm_nested_state, data));
if (cpu_has_vmx(env) || cpu_has_svm(env)) {
- struct kvm_vmx_nested_state_hdr *vmx_hdr;
-
env->nested_state = g_malloc0(max_nested_state_len);
env->nested_state->size = max_nested_state_len;
- if (cpu_has_vmx(env)) {
- env->nested_state->format = KVM_STATE_NESTED_FORMAT_VMX;
- vmx_hdr = &env->nested_state->hdr.vmx;
- vmx_hdr->vmxon_pa = -1ull;
- vmx_hdr->vmcs12_pa = -1ull;
- } else {
- env->nested_state->format = KVM_STATE_NESTED_FORMAT_SVM;
- }
+ kvm_init_nested_state(env);
}
}
@@ -2126,6 +2141,8 @@ void kvm_arch_reset_vcpu(X86CPU *cpu)
/* enabled by default */
env->poll_control_msr = 1;
+ kvm_init_nested_state(env);
+
sev_es_set_reset_vector(CPU(cpu));
}
--
2.27.0

View File

@ -0,0 +1,69 @@
From d193565aa9b9b293337a82f347fa1c877814d871 Mon Sep 17 00:00:00 2001
From: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
Date: Thu, 28 Mar 2024 14:00:37 +0800
Subject: [PATCH] ivshmem-test.c: enable test_ivshmem_server for ppc64 arch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
cherry picked from commit d04aeb6862a18540b7f72617b05be19846e1b047
This test, if enabled by hand, was failing when the ivhsmem device was
being declared as DEVICE_NATIVE_ENDIAN with the following error:
/ppc64/ivshmem/pair: OK
/ppc64/ivshmem/server:
**
ERROR:/home/danielhb/qemu/tests/qtest/ivshmem-test.c:367:test_ivshmem_server:
assertion failed (ret != 0): (0 != 0)
Aborted
After the endianness change done in the previous patch, we can verify in
both a a Power 9 little-endian host and in a Power 8 big-endian host
that this test is now passing:
$ QTEST_QEMU_BINARY=./ppc64-softmmu/qemu-system-ppc64 ./tests/qtest/ivshmem-test -m slow
/ppc64/ivshmem/single: OK
/ppc64/ivshmem/hotplug: OK
/ppc64/ivshmem/memdev: OK
/ppc64/ivshmem/pair: OK
/ppc64/ivshmem/server: OK
Let's keep it that way by officially enabling it for ppc64.
Acked-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211124092948.335389-3-danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
---
tests/qtest/ivshmem-test.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/tests/qtest/ivshmem-test.c b/tests/qtest/ivshmem-test.c
index dfa69424ed..fe94dd3b96 100644
--- a/tests/qtest/ivshmem-test.c
+++ b/tests/qtest/ivshmem-test.c
@@ -463,7 +463,6 @@ static gchar *mktempshm(int size, int *fd)
int main(int argc, char **argv)
{
int ret, fd;
- const char *arch = qtest_get_arch();
gchar dir[] = "/tmp/ivshmem-test.XXXXXX";
g_test_init(&argc, &argv, NULL);
@@ -488,9 +487,7 @@ int main(int argc, char **argv)
qtest_add_func("/ivshmem/memdev", test_ivshmem_memdev);
if (g_test_slow()) {
qtest_add_func("/ivshmem/pair", test_ivshmem_pair);
- if (strcmp(arch, "ppc64") != 0) {
- qtest_add_func("/ivshmem/server", test_ivshmem_server);
- }
+ qtest_add_func("/ivshmem/server", test_ivshmem_server);
}
out:
--
2.27.0

View File

@ -0,0 +1,56 @@
From b2120f0a316470369451103d9d1b50b2d13cd68b Mon Sep 17 00:00:00 2001
From: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
Date: Thu, 28 Mar 2024 13:58:20 +0800
Subject: [PATCH] ivshmem.c: change endianness to LITTLE_ENDIAN
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
cherry picked from commit ef80a708b57ddc8f605d9982bfaa0536e720ed9f
The ivshmem device, as with most PCI devices, uses little endian byte
order. However, the endianness of its mmio_ops is marked as
DEVICE_NATIVE_ENDIAN. This presents not only the usual problems with big
endian hosts but also with PowerPC little endian hosts as well, since
the Power architecture in QEMU uses big endian hardware (XIVE controller,
PCI Host Bridges, etc) even if the host is in little endian byte order.
As it is today, the IVPosition of the device will be byte swapped when
running in Power BE and LE. This can be seen by changing the existing
qtest 'ivshmem-test' to run in ppc64 hosts and printing the IVPOSITION
regs in test_ivshmem_server() right after the VM ids assert. For x86_64
the VM id values read are '0' and '1', for ppc64 (tested in a Power8
RHEL 7.9 BE server) and ppc64le (tested in a Power9 RHEL 8.6 LE server)
the ids will be '0' and '0x1000000'.
Change this device to LITTLE_ENDIAN fixes the issue for Power hosts of
both endianness, and every other big-endian architecture that might use
this device, without impacting x86 users.
Fixes: cb06608e17f8 ("ivshmem: convert to memory API")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/168
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211124092948.335389-2-danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
---
hw/misc/ivshmem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 05f06ed6cf..4093c59079 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -243,7 +243,7 @@ static uint64_t ivshmem_io_read(void *opaque, hwaddr addr,
static const MemoryRegionOps ivshmem_mmio_ops = {
.read = ivshmem_io_read,
.write = ivshmem_io_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
+ .endianness = DEVICE_LITTLE_ENDIAN,
.impl = {
.min_access_size = 4,
.max_access_size = 4,
--
2.27.0

View File

@ -0,0 +1,40 @@
From c4acd87e379d6b6c3a9b8e381c91af255d96aeaa Mon Sep 17 00:00:00 2001
From: guping <guping_yewu@cmss.chinamobile.com>
Date: Sat, 30 Mar 2024 14:59:51 +0000
Subject: [PATCH] libqos/virtio.c: Correct 'flags' reading in qvirtqueue_kick
cherry-pick from 66e411885a23c96ff73742d06b793fec3ceaebb7
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
In qvirtqueue_kick(), the 'flags' were previously being incorrectly read from
vq->avail instead of the correct vq->used location. This update ensures 'flags'
are read from the correct location as per the virtio standard.
Signed-off-by: default avatarZheyu Ma <zheyuma97@gmail.com>
Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Stefan Hajnoczi's avatarStefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20240320090442.267525-1-zheyuma97@gmail.com>
Signed-off-by: Thomas Huth's avatarThomas Huth <thuth@redhat.com>
Signed-off-by: guping <guping_yewu@cmss.chinamobile.com>
---
tests/qtest/libqos/virtio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/qtest/libqos/virtio.c b/tests/qtest/libqos/virtio.c
index 6fe7bf9555..08e5bcdca1 100644
--- a/tests/qtest/libqos/virtio.c
+++ b/tests/qtest/libqos/virtio.c
@@ -377,7 +377,7 @@ void qvirtqueue_kick(QTestState *qts, QVirtioDevice *d, QVirtQueue *vq,
qvirtio_writew(d, qts, vq->avail + 2, idx + 1);
/* Must read after idx is updated */
- flags = qvirtio_readw(d, qts, vq->avail);
+ flags = qvirtio_readw(d, qts, vq->used);
avail_event = qvirtio_readw(d, qts, vq->used + 4 +
sizeof(struct vring_used_elem) * vq->size);
--
2.27.0

View File

@ -0,0 +1,65 @@
From 41f426180f0d5d5a1720166a77a0d741fd072680 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 25 Mar 2024 09:32:04 +0000
Subject: [PATCH] linux-user: un-parent OBJECT(cpu) when closing thread
mainline inclusion
commit 52f0c1607671293afcdb2acc2f83e9bccbfa74bb
category: bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
While forcing the CPU to unrealize by hand does trigger the clean-up
code we never fully free resources because refcount never reaches
zero. This is because QOM automatically added objects without an
explicit parent to /unattached/, incrementing the refcount.
Instead of manually triggering unrealization just unparent the object
and let the device machinery deal with that for us.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/866
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20220811151413.3350684-2-alex.bennee@linaro.org>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
linux-user/syscall.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 92df0f9d8c..a5fe399277 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8345,7 +8345,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
if (CPU_NEXT(first_cpu)) {
TaskState *ts = cpu->opaque;
- object_property_set_bool(OBJECT(cpu), "realized", false, NULL);
+ if (ts->child_tidptr) {
+ put_user_u32(0, ts->child_tidptr);
+ do_sys_futex(g2h(cpu, ts->child_tidptr),
+ FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
+ }
+
+ object_unparent(OBJECT(cpu));
object_unref(OBJECT(cpu));
/*
* At this point the CPU should be unrealized and removed
@@ -8355,11 +8361,6 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
pthread_mutex_unlock(&clone_lock);
- if (ts->child_tidptr) {
- put_user_u32(0, ts->child_tidptr);
- do_sys_futex(g2h(cpu, ts->child_tidptr),
- FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
- }
thread_cpu = NULL;
g_free(ts);
rcu_unregister_thread();
--
2.27.0

View File

@ -0,0 +1,176 @@
From ba8973a75fffa55977dfa12a850827e11081280f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<yong.huang@smartx.com>
Date: Thu, 8 Jun 2023 00:21:58 +0800
Subject: [PATCH] migration: Extend query-migrate to provide dirty page limit
info
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There is a conflict when merging patches in qemu-6.2.0, and there is a phenomenon that the corresponding files and functions cannot be found.Merge after modifying the patch by wangguochun@kylinos.cn
Extend query-migrate to provide throttle time and estimated
ring full time with dirty-limit capability enabled, through which
we can observe if dirty limit take effect during live migration.
Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-ID: <168733225273.5845.15871826788879741674-8@git.sr.ht>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
include/sysemu/dirtylimit.h | 2 ++
migration/migration.c | 10 ++++++++++
monitor/hmp-cmds.c | 10 ++++++++++
qapi/migration.json | 16 ++++++++++++++-
softmmu/dirtylimit.c | 39 +++++++++++++++++++++++++++++++++++++
5 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/include/sysemu/dirtylimit.h b/include/sysemu/dirtylimit.h
index 8d2c1f3a6b..d11ebbbbdb 100644
--- a/include/sysemu/dirtylimit.h
+++ b/include/sysemu/dirtylimit.h
@@ -34,4 +34,6 @@ void dirtylimit_set_vcpu(int cpu_index,
void dirtylimit_set_all(uint64_t quota,
bool enable);
void dirtylimit_vcpu_execute(CPUState *cpu);
+uint64_t dirtylimit_throttle_time_per_round(void);
+uint64_t dirtylimit_ring_full_time(void);
#endif
diff --git a/migration/migration.c b/migration/migration.c
index e6a2e48f7a..3da2ed37f3 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -61,6 +61,7 @@
#include "sysemu/cpus.h"
#include "yank_functions.h"
#include "sysemu/kvm.h"
+#include "sysemu/dirtylimit.h"
#define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */
@@ -1060,6 +1061,15 @@ static void populate_ram_info(MigrationInfo *info, MigrationState *s)
info->ram->remaining = ram_bytes_remaining();
info->ram->dirty_pages_rate = ram_counters.dirty_pages_rate;
}
+
+ if (migrate_dirty_limit() && dirtylimit_in_service()) {
+ info->has_dirty_limit_throttle_time_per_round = true;
+ info->dirty_limit_throttle_time_per_round =
+ dirtylimit_throttle_time_per_round();
+
+ info->has_dirty_limit_ring_full_time = true;
+ info->dirty_limit_ring_full_time = dirtylimit_ring_full_time();
+ }
}
static void populate_disk_info(MigrationInfo *info)
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 01493cd2c0..c139e8087e 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -339,6 +339,16 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
info->cpu_throttle_percentage);
}
+ if (info->has_dirty_limit_throttle_time_per_round) {
+ monitor_printf(mon, "dirty-limit throttle time: %" PRIu64 " us\n",
+ info->dirty_limit_throttle_time_per_round);
+ }
+
+ if (info->has_dirty_limit_ring_full_time) {
+ monitor_printf(mon, "dirty-limit ring full time: %" PRIu64 " us\n",
+ info->dirty_limit_ring_full_time);
+ }
+
if (info->has_postcopy_blocktime) {
monitor_printf(mon, "postcopy blocktime: %u\n",
info->postcopy_blocktime);
diff --git a/qapi/migration.json b/qapi/migration.json
index 4751c5ee53..a36a4e943b 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -228,6 +228,18 @@
# Present and non-empty when migration is blocked.
# (since 6.0)
#
+# @dirty-limit-throttle-time-per-round: Maximum throttle time (in microseconds) of virtual
+# CPUs each dirty ring full round, which shows how
+# MigrationCapability dirty-limit affects the guest
+# during live migration. (since 8.1)
+#
+# @dirty-limit-ring-full-time: Estimated average dirty ring full time (in microseconds)
+# each dirty ring full round, note that the value equals
+# dirty ring memory size divided by average dirty page rate
+# of virtual CPU, which can be used to observe the average
+# memory load of virtual CPU indirectly. Note that zero
+# means guest doesn't dirty memory (since 8.1)
+#
# Since: 0.14
##
{ 'struct': 'MigrationInfo',
@@ -245,7 +257,9 @@
'*postcopy-blocktime' : 'uint32',
'*postcopy-vcpu-blocktime': ['uint32'],
'*compression': 'CompressionStats',
- '*socket-address': ['SocketAddress'] } }
+ '*socket-address': ['SocketAddress'],
+ '*dirty-limit-throttle-time-per-round': 'uint64',
+ '*dirty-limit-ring-full-time': 'uint64'} }
##
# @query-migrate:
diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c
index a3337c0e20..5e6e5aba67 100644
--- a/softmmu/dirtylimit.c
+++ b/softmmu/dirtylimit.c
@@ -564,6 +564,45 @@ out:
hmp_handle_error(mon, err);
}
+/* Return the max throttle time of each virtual CPU */
+uint64_t dirtylimit_throttle_time_per_round(void)
+{
+ CPUState *cpu;
+ int64_t max = 0;
+
+ CPU_FOREACH(cpu) {
+ if (cpu->throttle_us_per_full > max) {
+ max = cpu->throttle_us_per_full;
+ }
+ }
+
+ return max;
+}
+
+/*
+ * Estimate average dirty ring full time of each virtaul CPU.
+ * Return 0 if guest doesn't dirty memory.
+ */
+uint64_t dirtylimit_ring_full_time(void)
+{
+ CPUState *cpu;
+ uint64_t curr_rate = 0;
+ int nvcpus = 0;
+
+ CPU_FOREACH(cpu) {
+ if (cpu->running) {
+ nvcpus++;
+ curr_rate += vcpu_dirty_rate_get(cpu->cpu_index);
+ }
+ }
+
+ if (!curr_rate || !nvcpus) {
+ return 0;
+ }
+
+ return dirtylimit_dirty_ring_full_time(curr_rate / nvcpus);
+}
+
static struct DirtyLimitInfo *dirtylimit_query_vcpu(int cpu_index)
{
DirtyLimitInfo *info = NULL;
--
2.27.0

View File

@ -0,0 +1,183 @@
From 39cdcd0405657abfd81563d1f3801252e0ea8707 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<yong.huang@smartx.com>
Date: Thu, 8 Jun 2023 00:12:40 +0800
Subject: [PATCH] migration: Implement dirty-limit convergence algo
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Implement dirty-limit convergence algo for live migration,
which is kind of like auto-converge algo but using dirty-limit
instead of cpu throttle to make migration convergent.
Enable dirty page limit if dirty_rate_high_cnt greater than 2
when dirty-limit capability enabled, Disable dirty-limit if
migration be canceled.
Note that "set_vcpu_dirty_limit", "cancel_vcpu_dirty_limit"
commands are not allowed during dirty-limit live migration.
Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Message-ID: <168733225273.5845.15871826788879741674-7@git.sr.ht>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
migration/migration.c | 3 +++
migration/ram.c | 36 ++++++++++++++++++++++++++++++++++++
migration/trace-events | 1 +
softmmu/dirtylimit.c | 29 +++++++++++++++++++++++++++++
4 files changed, 69 insertions(+)
diff --git a/migration/migration.c b/migration/migration.c
index 50c33fecf3..e6a2e48f7a 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -224,6 +224,9 @@ void migration_cancel(const Error *error)
if (error) {
migrate_set_error(current_migration, error);
}
+ if (migrate_dirty_limit()) {
+ qmp_cancel_vcpu_dirty_limit(false, -1, NULL);
+ }
migrate_fd_cancel(current_migration);
}
diff --git a/migration/ram.c b/migration/ram.c
index 20f228e6bb..998ee96e63 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -43,6 +43,7 @@
#include "qapi/error.h"
#include "qapi/qapi-types-migration.h"
#include "qapi/qapi-events-migration.h"
+#include "qapi/qapi-commands-migration.h"
#include "qapi/qmp/qerror.h"
#include "trace.h"
#include "exec/ram_addr.h"
@@ -55,6 +56,8 @@
#include "qemu/iov.h"
#include "multifd.h"
#include "sysemu/runstate.h"
+#include "sysemu/dirtylimit.h"
+#include "sysemu/kvm.h"
#include "hw/boards.h" /* for machine_dump_guest_core() */
@@ -1399,6 +1402,37 @@ static void migration_update_rates(RAMState *rs, int64_t end_time)
}
}
+/*
+ * Enable dirty-limit to throttle down the guest
+ */
+static void migration_dirty_limit_guest(void)
+{
+ /*
+ * dirty page rate quota for all vCPUs fetched from
+ * migration parameter 'vcpu_dirty_limit'
+ */
+ static int64_t quota_dirtyrate;
+ MigrationState *s = migrate_get_current();
+
+ /*
+ * If dirty limit already enabled and migration parameter
+ * vcpu-dirty-limit untouched.
+ */
+ if (dirtylimit_in_service() &&
+ quota_dirtyrate == s->parameters.vcpu_dirty_limit) {
+ return;
+ }
+
+ quota_dirtyrate = s->parameters.vcpu_dirty_limit;
+
+ /*
+ * Set all vCPU a quota dirtyrate, note that the second
+ * parameter will be ignored if setting all vCPU for the vm
+ */
+ qmp_set_vcpu_dirty_limit(false, -1, quota_dirtyrate, NULL);
+ trace_migration_dirty_limit_guest(quota_dirtyrate);
+}
+
static void migration_trigger_throttle(RAMState *rs)
{
MigrationState *s = migrate_get_current();
@@ -1429,6 +1463,8 @@ static void migration_trigger_throttle(RAMState *rs)
trace_migration_throttle();
mig_throttle_guest_down(bytes_dirty_period,
bytes_dirty_threshold);
+ } else if (migrate_dirty_limit()) {
+ migration_dirty_limit_guest();
}
}
}
diff --git a/migration/trace-events b/migration/trace-events
index b48d873b8a..246710f488 100644
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -92,6 +92,7 @@ migration_bitmap_sync_start(void) ""
migration_bitmap_sync_end(uint64_t dirty_pages) "dirty_pages %" PRIu64
migration_bitmap_clear_dirty(char *str, uint64_t start, uint64_t size, unsigned long page) "rb %s start 0x%"PRIx64" size 0x%"PRIx64" page 0x%lx"
migration_throttle(void) ""
+migration_dirty_limit_guest(int64_t dirtyrate) "guest dirty page rate limit %" PRIi64 " MB/s"
ram_discard_range(const char *rbname, uint64_t start, size_t len) "%s: start: %" PRIx64 " %zx"
ram_load_loop(const char *rbname, uint64_t addr, int flags, void *host) "%s: addr: 0x%" PRIx64 " flags: 0x%x host: %p"
ram_load_postcopy_loop(uint64_t addr, int flags) "@%" PRIx64 " %x"
diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c
index 4d770aaba4..a3337c0e20 100644
--- a/softmmu/dirtylimit.c
+++ b/softmmu/dirtylimit.c
@@ -435,6 +435,23 @@ static void dirtylimit_cleanup(void)
dirtylimit_state_finalize();
}
+/*
+ * dirty page rate limit is not allowed to set if migration
+ * is running with dirty-limit capability enabled.
+ */
+static bool dirtylimit_is_allowed(void)
+{
+ MigrationState *ms = migrate_get_current();
+
+ if (migration_is_running(ms->state) &&
+ (!qemu_thread_is_self(&ms->thread)) &&
+ migrate_dirty_limit() &&
+ dirtylimit_in_service()) {
+ return false;
+ }
+ return true;
+}
+
void qmp_cancel_vcpu_dirty_limit(bool has_cpu_index,
int64_t cpu_index,
Error **errp)
@@ -448,6 +465,12 @@ void qmp_cancel_vcpu_dirty_limit(bool has_cpu_index,
return;
}
+ if (!dirtylimit_is_allowed()) {
+ error_setg(errp, "can't cancel dirty page rate limit while"
+ " migration is running");
+ return;
+ }
+
if (!dirtylimit_in_service()) {
return;
}
@@ -498,6 +521,12 @@ void qmp_set_vcpu_dirty_limit(bool has_cpu_index,
return;
}
+ if (!dirtylimit_is_allowed()) {
+ error_setg(errp, "can't set dirty page rate limit while"
+ " migration is running");
+ return;
+ }
+
if (!dirty_rate) {
qmp_cancel_vcpu_dirty_limit(has_cpu_index, cpu_index, errp);
return;
--
2.27.0

View File

@ -0,0 +1,183 @@
From c7ae0b39eec728d7f88029f932fdd6d3bfda6e68 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<yong.huang@smartx.com>
Date: Wed, 7 Jun 2023 23:30:50 +0800
Subject: [PATCH] migration: Introduce dirty-limit capability
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There is a conflict when merging patches in qemu-6.2.0, and there is a phenomenon that the corresponding files and functions cannot be found.Merge after modifying the patch by wangguochun@kylinos.cn
Introduce migration dirty-limit capability, which can
be turned on before live migration and limit dirty
page rate durty live migration.
Introduce migrate_dirty_limit function to help check
if dirty-limit capability enabled during live migration.
Meanwhile, refactor vcpu_dirty_rate_stat_collect
so that period can be configured instead of hardcoded.
dirty-limit capability is kind of like auto-converge
but using dirty limit instead of traditional cpu-throttle
to throttle guest down. To enable this feature, turn on
the dirty-limit capability before live migration using
migrate-set-capabilities, and set the parameters
"x-vcpu-dirty-limit-period", "vcpu-dirty-limit" suitably
to speed up convergence.
Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com>
Acked-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <168618975839.6361.17407633874747688653-4@git.sr.ht>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
migration/migration.c | 25 +++++++++++++++++++++++++
migration/migration.h | 1 +
qapi/migration.json | 13 ++++++++++++-
softmmu/dirtylimit.c | 17 +++++++++++++----
4 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 06d9b6a15d..50c33fecf3 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -60,6 +60,7 @@
#include "qemu/yank.h"
#include "sysemu/cpus.h"
#include "yank_functions.h"
+#include "sysemu/kvm.h"
#define MAX_THROTTLE (128 << 20) /* Migration transfer speed throttling */
@@ -1265,6 +1266,20 @@ static bool migrate_caps_check(bool *cap_list,
error_setg(errp, "multifd is not supported by current protocol");
return false;
}
+
+ if (cap_list[MIGRATION_CAPABILITY_DIRTY_LIMIT]) {
+ if (cap_list[MIGRATION_CAPABILITY_AUTO_CONVERGE]) {
+ error_setg(errp, "dirty-limit conflicts with auto-converge"
+ " either of then available currently");
+ return false;
+ }
+
+ if (!kvm_enabled() || !kvm_dirty_ring_enabled()) {
+ error_setg(errp, "dirty-limit requires KVM with accelerator"
+ " property 'dirty-ring-size' set");
+ return false;
+ }
+ }
return true;
}
@@ -2550,6 +2565,15 @@ bool migrate_dirty_bitmaps(void)
return s->enabled_capabilities[MIGRATION_CAPABILITY_DIRTY_BITMAPS];
}
+bool migrate_dirty_limit(void)
+{
+ MigrationState *s;
+
+ s = migrate_get_current();
+
+ return s->enabled_capabilities[MIGRATION_CAPABILITY_DIRTY_LIMIT];
+}
+
bool migrate_ignore_shared(void)
{
MigrationState *s;
@@ -4316,6 +4340,7 @@ static Property migration_properties[] = {
DEFINE_PROP_UINT64("vcpu-dirty-limit", MigrationState,
parameters.vcpu_dirty_limit,
DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT),
+ DEFINE_PROP_MIG_CAP("x-dirty-limit", MIGRATION_CAPABILITY_DIRTY_LIMIT),
/* Migration capabilities */
DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
diff --git a/migration/migration.h b/migration/migration.h
index 6b546a6ac7..9ce1fc8ea0 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -329,6 +329,7 @@ bool migrate_release_ram(void);
bool migrate_postcopy_ram(void);
bool migrate_zero_blocks(void);
bool migrate_dirty_bitmaps(void);
+bool migrate_dirty_limit(void);
bool migrate_ignore_shared(void);
bool migrate_validate_uuid(void);
diff --git a/qapi/migration.json b/qapi/migration.json
index f35f0377dc..4751c5ee53 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -452,6 +452,16 @@
# procedure starts. The VM RAM is saved with running VM.
# (since 6.0)
#
+# @dirty-limit: If enabled, migration will use the dirty-limit algo to
+# throttle down guest instead of auto-converge algo.
+# Throttle algo only works when vCPU's dirtyrate greater
+# than 'vcpu-dirty-limit', read processes in guest os
+# aren't penalized any more, so this algo can improve
+# performance of vCPU during live migration. This is an
+# optional performance feature and should not affect the
+# correctness of the existing auto-converge algo.
+# (since 8.1)
+#
# Features:
# @unstable: Members @x-colo and @x-ignore-shared are experimental.
#
@@ -465,7 +475,8 @@
'block', 'return-path', 'pause-before-switchover', 'multifd',
'dirty-bitmaps', 'postcopy-blocktime', 'late-block-activate',
{ 'name': 'x-ignore-shared', 'features': [ 'unstable' ] },
- 'validate-uuid', 'background-snapshot'] }
+ 'validate-uuid', 'background-snapshot',
+ 'dirty-limit'] }
##
# @MigrationCapabilityStatus:
diff --git a/softmmu/dirtylimit.c b/softmmu/dirtylimit.c
index 5041c230d0..4d770aaba4 100644
--- a/softmmu/dirtylimit.c
+++ b/softmmu/dirtylimit.c
@@ -24,6 +24,8 @@
#include "hw/boards.h"
#include "sysemu/kvm.h"
#include "trace.h"
+#include "migration/misc.h"
+#include "migration/migration.h"
/*
* Dirtylimit stop working if dirty page rate error
@@ -75,14 +77,21 @@ static bool dirtylimit_quit;
static void vcpu_dirty_rate_stat_collect(void)
{
+ MigrationState *s = migrate_get_current();
VcpuStat stat;
int i = 0;
+ int64_t period = DIRTYLIMIT_CALC_TIME_MS;
+
+ if (migrate_dirty_limit() &&
+ migration_is_active(s)) {
+ period = s->parameters.x_vcpu_dirty_limit_period;
+ }
/* calculate vcpu dirtyrate */
- vcpu_calculate_dirtyrate(DIRTYLIMIT_CALC_TIME_MS,
- &stat,
- GLOBAL_DIRTY_LIMIT,
- false);
+ vcpu_calculate_dirtyrate(period,
+ &stat,
+ GLOBAL_DIRTY_LIMIT,
+ false);
for (i = 0; i < stat.nvcpu; i++) {
vcpu_dirty_rate_stat->stat.rates[i].id = i;
--
2.27.0

View File

@ -0,0 +1,61 @@
From 0f564d8940367ccdfb39b33be048f1b85e097e89 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<yong.huang@smartx.com>
Date: Thu, 15 Jun 2023 21:29:44 +0800
Subject: [PATCH] migration: Put the detection logic before auto-converge
checking
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This commit is prepared for the implementation of dirty-limit
convergence algo.
The detection logic of throttling condition can apply to both
auto-converge and dirty-limit algo, putting it's position
before the checking logic for auto-converge feature.
Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-ID: <168733225273.5845.15871826788879741674-6@git.sr.ht>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
migration/ram.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/migration/ram.c b/migration/ram.c
index 87e551913c..20f228e6bb 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1415,17 +1415,18 @@ static void migration_trigger_throttle(RAMState *rs)
return;
}
- if (migrate_auto_converge()) {
- /* The following detection logic can be refined later. For now:
- Check to see if the ratio between dirtied bytes and the approx.
- amount of bytes that just got transferred since the last time
- we were in this routine reaches the threshold. If that happens
- twice, start or increase throttling. */
-
- if ((bytes_dirty_period > bytes_dirty_threshold) &&
- (++rs->dirty_rate_high_cnt >= 2)) {
+ /*
+ * The following detection logic can be refined later. For now:
+ * Check to see if the ratio between dirtied bytes and the approx.
+ * amount of bytes that just got transferred since the last time
+ * we were in this routine reaches the threshold. If that happens
+ * twice, start or increase throttling.
+ */
+ if ((bytes_dirty_period > bytes_dirty_threshold) &&
+ (++rs->dirty_rate_high_cnt >= 2)) {
+ rs->dirty_rate_high_cnt = 0;
+ if (migrate_auto_converge()) {
trace_migration_throttle();
- rs->dirty_rate_high_cnt = 0;
mig_throttle_guest_down(bytes_dirty_period,
bytes_dirty_threshold);
}
--
2.27.0

View File

@ -0,0 +1,45 @@
From b4f95f541ce2d428956508d8ce874377499c200c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<yong.huang@smartx.com>
Date: Wed, 7 Jun 2023 23:32:51 +0800
Subject: [PATCH] migration: Refactor auto-converge capability logic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Check if block migration is running before throttling
guest down in auto-converge way.
Note that this modification is kind of like code clean,
because block migration does not depend on auto-converge
capability, so the order of checks can be adjusted.
Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com>
Acked-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <168618975839.6361.17407633874747688653-5@git.sr.ht>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
migration/ram.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/migration/ram.c b/migration/ram.c
index c245b04cf2..87e551913c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1411,7 +1411,11 @@ static void migration_trigger_throttle(RAMState *rs)
/* During block migration the auto-converge logic incorrectly detects
* that ram migration makes no progress. Avoid this by disabling the
* throttling logic during the bulk phase of block migration. */
- if (migrate_auto_converge() && !blk_mig_bulk_active()) {
+ if (blk_mig_bulk_active()) {
+ return;
+ }
+
+ if (migrate_auto_converge()) {
/* The following detection logic can be refined later. For now:
Check to see if the ratio between dirtied bytes and the approx.
amount of bytes that just got transferred since the last time
--
2.27.0

View File

@ -0,0 +1,60 @@
From e254e3404d9eedcc028c16933052c3fed37eb651 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 30 Apr 2024 08:32:41 +0000
Subject: [PATCH] pc-bios/s390-ccw: Fix booting with logical block size <
physical block size mainline inclusion commit
393296de19650e1400ca265914cfdeb313725363 category: bugfix
---------------------------------------------------------------
For accessing single blocks during boot, it's the logical block size that
matters. (Physical block sizes are rather interesting e.g. for creating
file systems with the correct alignment for speed reasons etc.).
So the s390-ccw bios has to use the logical block size for calculating
sector numbers during the boot phase, the "physical_block_exp" shift
value must not be taken into account. This change fixes the boot process
when the guest hast been installed on a disk where the logical block size
differs from the physical one, e.g. if the guest has been installed
like this:
qemu-system-s390x -nographic -accel kvm -m 2G \
-drive if=none,id=d1,file=fedora.iso,format=raw,media=cdrom \
-device virtio-scsi -device scsi-cd,drive=d1 \
-drive if=none,id=d2,file=test.qcow2,format=qcow2
-device virtio-blk,drive=d2,physical_block_size=4096,logical_block_size=512
Linux correctly uses the logical block size of 512 for the installation,
but the s390-ccw bios tries to boot from a disk with 4096 block size so
far, as long as this patch has not been applied yet (well, it used to work
by accident in the past due to the virtio_assume_scsi() hack that used to
enforce 512 byte sectors on all virtio-block disks, but that hack has been
well removed in commit 5447de2619050a0a4d to fix other scenarios).
Fixes: 5447de2619 ("pc-bios/s390-ccw/virtio-blkdev: Remove virtio_assume_scsi()")
Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=2112303
Message-Id: <20220805094214.285223-1-thuth@redhat.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
pc-bios/s390-ccw/virtio-blkdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pc-bios/s390-ccw/virtio-blkdev.c b/pc-bios/s390-ccw/virtio-blkdev.c
index 7d35050292..263a84d391 100644
--- a/pc-bios/s390-ccw/virtio-blkdev.c
+++ b/pc-bios/s390-ccw/virtio-blkdev.c
@@ -214,7 +214,7 @@ int virtio_get_block_size(void)
switch (vdev->senseid.cu_model) {
case VIRTIO_ID_BLOCK:
- return vdev->config.blk.blk_size << vdev->config.blk.physical_block_exp;
+ return vdev->config.blk.blk_size;
case VIRTIO_ID_SCSI:
return vdev->scsi_block_size;
}
--
2.27.0

View File

@ -0,0 +1,200 @@
From 52201bf437125bb73deb8945491f7f823bdeb64a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<yong.huang@smartx.com>
Date: Wed, 7 Jun 2023 22:58:32 +0800
Subject: [PATCH] qapi/migration: Introduce vcpu-dirty-limit parameters
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There is a conflict when merging patches in qemu-6.2.0, and there is a phenomenon that the corresponding files and functions cannot be found.Merge after modifying the patch by wangguochun@kylinos.cn
Introduce "vcpu-dirty-limit" migration parameter used
to limit dirty page rate during live migration.
"vcpu-dirty-limit" and "x-vcpu-dirty-limit-period" are
two dirty-limit-related migration parameters, which can
be set before and during live migration by qmp
migrate-set-parameters.
This two parameters are used to help implement the dirty
page rate limit algo of migration.
Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com>
Acked-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <168618975839.6361.17407633874747688653-3@git.sr.ht>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
migration/migration.c | 21 +++++++++++++++++++++
monitor/hmp-cmds.c | 8 ++++++++
qapi/migration.json | 18 +++++++++++++++---
3 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 9672266e16..06d9b6a15d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -117,6 +117,7 @@
#define DEFAULT_MIGRATE_ANNOUNCE_STEP 100
#define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD 1000 /* milliseconds */
+#define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT 1 /* MB/s */
static NotifierList migration_state_notifiers =
NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
@@ -920,6 +921,8 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
params->has_x_vcpu_dirty_limit_period = true;
params->x_vcpu_dirty_limit_period = s->parameters.x_vcpu_dirty_limit_period;
+ params->has_vcpu_dirty_limit = true;
+ params->vcpu_dirty_limit = s->parameters.vcpu_dirty_limit;
return params;
}
@@ -1513,6 +1516,14 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp)
return false;
}
+ if (params->has_vcpu_dirty_limit &&
+ (params->vcpu_dirty_limit < 1)) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+ "vcpu_dirty_limit",
+ "is invalid, it must greater then 1 MB/s");
+ return false;
+ }
+
return true;
}
@@ -1621,6 +1632,9 @@ static void migrate_params_test_apply(MigrateSetParameters *params,
dest->x_vcpu_dirty_limit_period =
params->x_vcpu_dirty_limit_period;
}
+ if (params->has_vcpu_dirty_limit) {
+ dest->vcpu_dirty_limit = params->vcpu_dirty_limit;
+ }
}
static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
@@ -1752,6 +1766,9 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
s->parameters.x_vcpu_dirty_limit_period =
params->x_vcpu_dirty_limit_period;
}
+ if (params->has_vcpu_dirty_limit) {
+ s->parameters.vcpu_dirty_limit = params->vcpu_dirty_limit;
+ }
}
void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
@@ -4296,6 +4313,9 @@ static Property migration_properties[] = {
DEFINE_PROP_UINT64("x-vcpu-dirty-limit-period", MigrationState,
parameters.x_vcpu_dirty_limit_period,
DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD),
+ DEFINE_PROP_UINT64("vcpu-dirty-limit", MigrationState,
+ parameters.vcpu_dirty_limit,
+ DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT),
/* Migration capabilities */
DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
@@ -4372,6 +4392,7 @@ void migrate_params_init(MigrationParameters *params)
params->has_announce_rounds = true;
params->has_announce_step = true;
params->has_x_vcpu_dirty_limit_period = true;
+ params->has_vcpu_dirty_limit = true;
}
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 680696ddd5..01493cd2c0 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -520,6 +520,10 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "%s: %" PRIu64 " ms\n",
MigrationParameter_str(MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD),
params->x_vcpu_dirty_limit_period);
+
+ monitor_printf(mon, "%s: %" PRIu64 " MB/s\n",
+ MigrationParameter_str(MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT),
+ params->vcpu_dirty_limit);
}
qapi_free_MigrationParameters(params);
@@ -1353,6 +1357,10 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
p->has_x_vcpu_dirty_limit_period = true;
visit_type_size(v, param, &p->x_vcpu_dirty_limit_period, &err);
break;
+ case MIGRATION_PARAMETER_VCPU_DIRTY_LIMIT:
+ p->has_vcpu_dirty_limit = true;
+ visit_type_size(v, param, &p->vcpu_dirty_limit, &err);
+ break;
default:
assert(0);
}
diff --git a/qapi/migration.json b/qapi/migration.json
index b7dc85f7c1..f35f0377dc 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -770,6 +770,9 @@
# live migration. Should be in the range 1 to 1000ms,
# defaults to 1000ms. (Since 8.1)
#
+# @vcpu-dirty-limit: Dirtyrate limit (MB/s) during live migration.
+# Defaults to 1. (Since 8.1)
+#
# Features:
# @unstable: Members @x-checkpoint-delay and @x-vcpu-dirty-limit-period
# are experimental.
@@ -791,7 +794,8 @@
'max-cpu-throttle', 'multifd-compression',
'multifd-zlib-level', 'multifd-zstd-level',
'block-bitmap-mapping',
- { 'name': 'x-vcpu-dirty-limit-period', 'features': ['unstable'] } ] }
+ { 'name': 'x-vcpu-dirty-limit-period', 'features': ['unstable'] },
+ 'vcpu-dirty-limit'] }
##
# @MigrateSetParameters:
@@ -943,6 +947,9 @@
# live migration. Should be in the range 1 to 1000ms,
# defaults to 1000ms. (Since 8.1)
#
+# @vcpu-dirty-limit: Dirtyrate limit (MB/s) during live migration.
+# Defaults to 1. (Since 8.1)
+#
# Features:
# @unstable: Members @x-checkpoint-delay and @x-vcpu-dirty-limit-period
# are experimental.
@@ -982,7 +989,8 @@
'*multifd-zstd-level': 'uint8',
'*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ],
'*x-vcpu-dirty-limit-period': { 'type': 'uint64',
- 'features': [ 'unstable' ] } } }
+ 'features': [ 'unstable' ] },
+ '*vcpu-dirty-limit': 'uint64'} }
##
# @migrate-set-parameters:
@@ -1154,6 +1162,9 @@
# live migration. Should be in the range 1 to 1000ms,
# defaults to 1000ms. (Since 8.1)
#
+# @vcpu-dirty-limit: Dirtyrate limit (MB/s) during live migration.
+# Defaults to 1. (Since 8.1)
+#
# Features:
# @unstable: Members @x-checkpoint-delay and @x-vcpu-dirty-limit-period
# are experimental.
@@ -1191,7 +1202,8 @@
'*multifd-zstd-level': 'uint8',
'*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ],
'*x-vcpu-dirty-limit-period': { 'type': 'uint64',
- 'features': [ 'unstable' ] } } }
+ 'features': [ 'unstable' ] },
+ '*vcpu-dirty-limit': 'uint64'} }
##
# @query-migrate-parameters:
--
2.27.0

View File

@ -0,0 +1,273 @@
From 6a9933b302c0fb396c6ede78fdef75385e1436e0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hyman=20Huang=28=E9=BB=84=E5=8B=87=29?=
<yong.huang@smartx.com>
Date: Wed, 7 Jun 2023 21:32:59 +0800
Subject: [PATCH] qapi/migration: Introduce x-vcpu-dirty-limit-period parameter
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There is a conflict when merging patches in qemu-6.2.0, and there is a phenomenon that the corresponding files and functions cannot be found.Merge after modifying the patch by wangguochun@kylinos.cn
Introduce "x-vcpu-dirty-limit-period" migration experimental
parameter, which is in the range of 1 to 1000ms and used to
make dirtyrate calculation period configurable.
Currently with the "x-vcpu-dirty-limit-period" varies, the
total time of live migration changes, test results show the
optimal value of "x-vcpu-dirty-limit-period" ranges from
500ms to 1000 ms. "x-vcpu-dirty-limit-period" should be made
stable once it proves best value can not be determined with
developer's experiments.
Signed-off-by: Hyman Huang(黄勇) <yong.huang@smartx.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <168618975839.6361.17407633874747688653-2@git.sr.ht>
Signed-off-by: Juan Quintela <quintela@redhat.com>
---
migration/migration.c | 53 +++++++++++++++++++++++++++++++++++--------
migration/migration.h | 1 +
monitor/hmp-cmds.c | 8 +++++++
qapi/migration.json | 35 +++++++++++++++++++++-------
4 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 7ca5b58839..9672266e16 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -116,6 +116,8 @@
#define DEFAULT_MIGRATE_ANNOUNCE_ROUNDS 5
#define DEFAULT_MIGRATE_ANNOUNCE_STEP 100
+#define DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD 1000 /* milliseconds */
+
static NotifierList migration_state_notifiers =
NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
@@ -916,6 +918,9 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
s->parameters.block_bitmap_mapping);
}
+ params->has_x_vcpu_dirty_limit_period = true;
+ params->x_vcpu_dirty_limit_period = s->parameters.x_vcpu_dirty_limit_period;
+
return params;
}
@@ -1499,6 +1504,15 @@ static bool migrate_params_check(MigrationParameters *params, Error **errp)
return false;
}
+ if (params->has_x_vcpu_dirty_limit_period &&
+ (params->x_vcpu_dirty_limit_period < 1 ||
+ params->x_vcpu_dirty_limit_period > 1000)) {
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+ "x-vcpu-dirty-limit-period",
+ "a value between 1 and 1000");
+ return false;
+ }
+
return true;
}
@@ -1602,6 +1616,11 @@ static void migrate_params_test_apply(MigrateSetParameters *params,
dest->has_block_bitmap_mapping = true;
dest->block_bitmap_mapping = params->block_bitmap_mapping;
}
+
+ if (params->has_x_vcpu_dirty_limit_period) {
+ dest->x_vcpu_dirty_limit_period =
+ params->x_vcpu_dirty_limit_period;
+ }
}
static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
@@ -1728,6 +1747,11 @@ static void migrate_params_apply(MigrateSetParameters *params, Error **errp)
QAPI_CLONE(BitmapMigrationNodeAliasList,
params->block_bitmap_mapping);
}
+
+ if (params->has_x_vcpu_dirty_limit_period) {
+ s->parameters.x_vcpu_dirty_limit_period =
+ params->x_vcpu_dirty_limit_period;
+ }
}
void qmp_migrate_set_parameters(MigrateSetParameters *params, Error **errp)
@@ -4269,6 +4293,9 @@ static Property migration_properties[] = {
DEFINE_PROP_SIZE("announce-step", MigrationState,
parameters.announce_step,
DEFAULT_MIGRATE_ANNOUNCE_STEP),
+ DEFINE_PROP_UINT64("x-vcpu-dirty-limit-period", MigrationState,
+ parameters.x_vcpu_dirty_limit_period,
+ DEFAULT_MIGRATE_VCPU_DIRTY_LIMIT_PERIOD),
/* Migration capabilities */
DEFINE_PROP_MIG_CAP("x-xbzrle", MIGRATION_CAPABILITY_XBZRLE),
@@ -4315,17 +4342,8 @@ static void migration_instance_finalize(Object *obj)
error_free(ms->error);
}
-static void migration_instance_init(Object *obj)
+void migrate_params_init(MigrationParameters *params)
{
- MigrationState *ms = MIGRATION_OBJ(obj);
- MigrationParameters *params = &ms->parameters;
-
- ms->state = MIGRATION_STATUS_NONE;
- ms->mbps = -1;
- ms->pages_per_second = -1;
- qemu_sem_init(&ms->pause_sem, 0);
- qemu_mutex_init(&ms->error_mutex);
-
params->tls_hostname = g_strdup("");
params->tls_creds = g_strdup("");
@@ -4353,6 +4371,21 @@ static void migration_instance_init(Object *obj)
params->has_announce_max = true;
params->has_announce_rounds = true;
params->has_announce_step = true;
+ params->has_x_vcpu_dirty_limit_period = true;
+}
+
+
+static void migration_instance_init(Object *obj)
+{
+ MigrationState *ms = MIGRATION_OBJ(obj);
+
+ ms->state = MIGRATION_STATUS_NONE;
+ ms->mbps = -1;
+ ms->pages_per_second = -1;
+ qemu_sem_init(&ms->pause_sem, 0);
+ qemu_mutex_init(&ms->error_mutex);
+
+ migrate_params_init(&ms->parameters);
qemu_sem_init(&ms->postcopy_pause_sem, 0);
qemu_sem_init(&ms->postcopy_pause_rp_sem, 0);
diff --git a/migration/migration.h b/migration/migration.h
index a87fd54d10..6b546a6ac7 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -317,6 +317,7 @@ bool migration_is_setup_or_active(int state);
bool migration_is_running(int state);
void migrate_init(MigrationState *s);
+void migrate_params_init(MigrationParameters *params);
bool migration_is_blocked(Error **errp);
/* True if outgoing migration has entered postcopy phase */
bool migration_in_postcopy(void);
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 5246c82e14..680696ddd5 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -516,6 +516,10 @@ void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
}
}
}
+
+ monitor_printf(mon, "%s: %" PRIu64 " ms\n",
+ MigrationParameter_str(MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD),
+ params->x_vcpu_dirty_limit_period);
}
qapi_free_MigrationParameters(params);
@@ -1345,6 +1349,10 @@ void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
error_setg(&err, "The block-bitmap-mapping parameter can only be set "
"through QMP");
break;
+ case MIGRATION_PARAMETER_X_VCPU_DIRTY_LIMIT_PERIOD:
+ p->has_x_vcpu_dirty_limit_period = true;
+ visit_type_size(v, param, &p->x_vcpu_dirty_limit_period, &err);
+ break;
default:
assert(0);
}
diff --git a/qapi/migration.json b/qapi/migration.json
index e965f4329b..b7dc85f7c1 100644
--- a/qapi/migration.json
+++ b/qapi/migration.json
@@ -766,9 +766,13 @@
# block device name if there is one, and to their node name
# otherwise. (Since 5.2)
#
-# Features:
-# @unstable: Member @x-checkpoint-delay is experimental.
+# @x-vcpu-dirty-limit-period: Periodic time (in milliseconds) of dirty limit during
+# live migration. Should be in the range 1 to 1000ms,
+# defaults to 1000ms. (Since 8.1)
#
+# Features:
+# @unstable: Members @x-checkpoint-delay and @x-vcpu-dirty-limit-period
+# are experimental.
# Since: 2.4
##
{ 'enum': 'MigrationParameter',
@@ -785,8 +789,9 @@
'multifd-channels',
'xbzrle-cache-size', 'max-postcopy-bandwidth',
'max-cpu-throttle', 'multifd-compression',
- 'multifd-zlib-level' ,'multifd-zstd-level',
- 'block-bitmap-mapping' ] }
+ 'multifd-zlib-level', 'multifd-zstd-level',
+ 'block-bitmap-mapping',
+ { 'name': 'x-vcpu-dirty-limit-period', 'features': ['unstable'] } ] }
##
# @MigrateSetParameters:
@@ -934,8 +939,13 @@
# block device name if there is one, and to their node name
# otherwise. (Since 5.2)
#
+# @x-vcpu-dirty-limit-period: Periodic time (in milliseconds) of dirty limit during
+# live migration. Should be in the range 1 to 1000ms,
+# defaults to 1000ms. (Since 8.1)
+#
# Features:
-# @unstable: Member @x-checkpoint-delay is experimental.
+# @unstable: Members @x-checkpoint-delay and @x-vcpu-dirty-limit-period
+# are experimental.
#
# Since: 2.4
##
@@ -970,7 +980,9 @@
'*multifd-compression': 'MultiFDCompression',
'*multifd-zlib-level': 'uint8',
'*multifd-zstd-level': 'uint8',
- '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ],
+ '*x-vcpu-dirty-limit-period': { 'type': 'uint64',
+ 'features': [ 'unstable' ] } } }
##
# @migrate-set-parameters:
@@ -1138,8 +1150,13 @@
# block device name if there is one, and to their node name
# otherwise. (Since 5.2)
#
+# @x-vcpu-dirty-limit-period: Periodic time (in milliseconds) of dirty limit during
+# live migration. Should be in the range 1 to 1000ms,
+# defaults to 1000ms. (Since 8.1)
+#
# Features:
-# @unstable: Member @x-checkpoint-delay is experimental.
+# @unstable: Members @x-checkpoint-delay and @x-vcpu-dirty-limit-period
+# are experimental.
#
# Since: 2.4
##
@@ -1172,7 +1189,9 @@
'*multifd-compression': 'MultiFDCompression',
'*multifd-zlib-level': 'uint8',
'*multifd-zstd-level': 'uint8',
- '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ] } }
+ '*block-bitmap-mapping': [ 'BitmapMigrationNodeAlias' ],
+ '*x-vcpu-dirty-limit-period': { 'type': 'uint64',
+ 'features': [ 'unstable' ] } } }
##
# @query-migrate-parameters:
--
2.27.0

View File

@ -0,0 +1,68 @@
From ae868555000f3f9a37df2faf2551825381a86b45 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 25 Mar 2024 10:07:25 +0000
Subject: [PATCH] qemu-iotests: Discard stderr when probing devices
mainline inclusion
commit e13fe274bfbc4c5b338854a3519a64b84c2d5517
category: bugfix
---------------------------------------------------------------
qemu-iotests fails in the following setup:
./configure --enable-modules --enable-smartcard \
--target-list=x86_64-softmmu,s390x-softmmu
make
cd build
QEMU_PROG=`pwd`/s390x-softmmu/qemu-system-s390x \
../tests/check-block.sh qcow2
...
--- /home/crobinso/src/qemu/tests/qemu-iotests/127.out
+++ /home/crobinso/src/qemu/build/tests/qemu-iotests/scratch/127.out.bad
//@@ -1,4 +1,18 @@
QA output created by 127
+Failed to open module: /home/crobinso/src/qemu/build/hw-usb-smartcard.so: undefined symbol: ccid_card_ccid_attach
...
--- /home/crobinso/src/qemu/tests/qemu-iotests/267.out
+++ /home/crobinso/src/qemu/build/tests/qemu-iotests/scratch/267.out.bad
//@@ -1,4 +1,11 @@
QA output created by 267
+Failed to open module: /home/crobinso/src/qemu/build/hw-usb-smartcard.so: undefined symbol: ccid_card_ccid_attach
The stderr spew is its own known issue, but seems like iotests should
be discarding stderr in this case.
Signed-off-by: Cole Robinson <crobinso@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
tests/qemu-iotests/common.rc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index d8582454de..4c468675d3 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -973,7 +973,7 @@ _require_large_file()
#
_require_devices()
{
- available=$($QEMU -M none -device help | \
+ available=$($QEMU -M none -device help 2> /dev/null | \
grep ^name | sed -e 's/^name "//' -e 's/".*$//')
for device
do
@@ -985,7 +985,7 @@ _require_devices()
_require_one_device_of()
{
- available=$($QEMU -M none -device help | \
+ available=$($QEMU -M none -device help 2> /dev/null | \
grep ^name | sed -e 's/^name "//' -e 's/".*$//')
for device
do
--
2.27.0

138
qemu.spec
View File

@ -3,7 +3,7 @@
Name: qemu
Version: 6.2.0
Release: 90
Release: 95
Epoch: 10
Summary: QEMU is a generic and open source machine emulator and virtualizer
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
@ -907,6 +907,69 @@ Patch0892: i386-cpu-Clear-FEAT_XSAVE_XSS_LO-HI-leafs-when-CPUID.patch
Patch0893: i386-cpu-Mask-with-XCR0-XSS-mask-for-FEAT_XSAVE_XCR0.patch
Patch0894: i386-cpuid-Decrease-cpuid_i-when-skipping-CPUID-leaf.patch
Patch0895: i386-cpuid-Move-leaf-7-to-correct-group.patch
Patch0896: scsi-disk-fix-overflow-when-block-size-is-not-a-mult.patch
Patch0897: contrib-vhost-user-blk-Clean-up-deallocation-of-VuVi.patch
Patch0898: hw-net-rocker-Avoid-undefined-shifts-with-more-than-.patch
Patch0899: linux-user-un-parent-OBJECT-cpu-when-closing-thread.patch
Patch0900: qemu-iotests-Discard-stderr-when-probing-devices.patch
Patch0901: hw-intc-clean-up-error-reporting-for-failed-ITS-cmd.patch
Patch0902: virtio-gpu-do-not-byteswap-padding.patch
Patch0903: configure-remove-dead-variables.patch
Patch0904: hw-ppc-mac.h-Remove-MAX_CPUS-macro.patch
Patch0905: ivshmem.c-change-endianness-to-LITTLE_ENDIAN.patch
Patch0906: ivshmem-test.c-enable-test_ivshmem_server-for-ppc64-.patch
Patch0907: libqos-virtio.c-Correct-flags-reading-in-qvirtqueue_.patch
Patch0908: virtio-crypto-fix-NULL-pointer-dereference-in-virtio.patch
Patch0909: amd_iommu-Fix-APIC-address-check.patch
Patch0910: block-mirror-Fix-NULL-s-job-in-active-writes.patch
Patch0911: smmu-Clear-SMMUPciBus-pointer-cache-when-system-rese.patch
Patch0912: block-Fix-crash-when-loading-snapshot-on-inactive-no.patch
Patch0913: system-memory-use-ldn_he_p-stn_he_p.patch
Patch0914: virtio-mem-Fix-the-iterator-variable-in-a-vmem-rdl_l.patch
Patch0915: virtio-mem-Fix-the-bitmap-index-of-the-section-offse.patch
Patch0916: tulip-Remove-unused-variable.patch
Patch0917: rtl8139-Remove-unused-variable.patch
Patch0918: hw-sd-sdhci-Do-not-update-TRNMOD-when-Command-Inhibi.patch
Patch0919: async-Add-an-optional-reentrancy-guard-to-the-BH-API.patch
Patch0920: async-avoid-use-after-free-on-re-entrancy-guard.patch
Patch0921: checkpatch-add-qemu_bh_new-aio_bh_new-checks.patch
Patch0922: hw-replace-most-qemu_bh_new-calls-with-qemu_bh_new_g.patch
Patch0923: hw-virtio-Introduce-virtio_bh_new_guarded-helper.patch
Patch0924: hw-display-virtio-gpu-Protect-from-DMA-re-entrancy-b.patch
Patch0925: hw-char-virtio-serial-bus-Protect-from-DMA-re-entran.patch
Patch0926: hw-virtio-virtio-crypto-Protect-from-DMA-re-entrancy.patch
Patch0927: pc-bios-s390-ccw-Fix-booting-with-logical-block-size.patch
Patch0928: target-i386-display-deprecation-status-in-cpu-help.patch
Patch0929: target-s390x-display-deprecation-status-in-cpu-help.patch
Patch0930: hw-virtio-handle-un-configured-shutdown-in-virtio-pc.patch
Patch0931: target-i386-Introduce-Icelake-Server-v7-to-enable-TS.patch
Patch0932: target-i386-Add-new-CPU-model-SierraForest.patch
Patch0933: target-i386-Export-RFDS-bit-to-guests.patch
Patch0934: vfio-pci-Add-Ascend310b-scend910b-support.patch
Patch0935: dbus-vmstate-Restrict-error-checks-to-registered-pro.patch
Patch0936: esp-Handle-CMD_BUSRESET-by-resetting-the-SCSI-bus.patch
Patch0937: i386-reset-KVM-nested-state-upon-CPU-reset.patch
Patch0938: KVM-dirty-ring-add-missing-memory-barrier.patch
Patch0939: chardev-char-socket-Update-AF_UNIX-for-Windows.patch
Patch0940: tpm_emulator-Avoid-double-initialization-during-migr.patch
Patch0941: Allow-UNIX-socket-option-for-VNC-websocket.patch
Patch0942: Change-the-value-of-no_ged-from-true-to-false.patch
Patch0943: qapi-migration-Introduce-x-vcpu-dirty-limit-period-p.patch
Patch0944: qapi-migration-Introduce-vcpu-dirty-limit-parameters.patch
Patch0945: migration-Introduce-dirty-limit-capability.patch
Patch0946: migration-Refactor-auto-converge-capability-logic.patch
Patch0947: migration-Put-the-detection-logic-before-auto-conver.patch
Patch0948: migration-Implement-dirty-limit-convergence-algo.patch
Patch0949: migration-Extend-query-migrate-to-provide-dirty-page.patch
Patch0950: docs-system-target-arm-Re-alphabetize-board-list.patch
Patch0951: target-ppc-Remove-msr_pr-macro.patch
Patch0952: s390x-sclp-Simplify-get_sclp_device.patch
Patch0953: Add-support-for-the-virtcca-cvm-feature.patch
Patch0954: hw-ide-reset-cancel-async-DMA-operation-before-reset.patch
Patch0955: tests-qtest-ahci-test-add-test-exposing-reset-issue-.patch
Patch0956: cvm-bug-fix-for-macro-isolation.patch
Patch0957: hw-arm-virt-Disable-DTB-randomness-for-confidential-.patch
Patch0958: cvm-bug-fix-for-disable-DTB-randomness-for-confident.patch
BuildRequires: flex
BuildRequires: gcc
@ -1505,6 +1568,79 @@ getent passwd qemu >/dev/null || \
%endif
%changelog
* Fri Jun 21 2024 <liupingwei@huawei.com> - 10:6.2.0-95
- cvm: bug-fix for disable DTB randomness for confidential VMs
* Tue Jun 18 2024 <liupingwei@huawei.com> - 10:6.2.0-94
- hw/arm/virt: Disable DTB randomness for confidential VMs
* Sat Jun 15 2024 <fengjiabo1@huawei.com> - 10:6.2.0-93
- cvm: bug-fix for macro isolation
- tests/qtest: ahci-test: add test exposing reset issue with pending callback (Fix CVE-2023-5088)
- hw/ide: reset: cancel async DMA operation before resetting state (Fix CVE-2023-5088)
- Add support for the virtcca cvm feature.
* Thu Jun 13 2024 <fengjiabo1@huawei.com> - 10:6.2.0-92
- s390x/sclp: Simplify get_sclp_device()
- target/ppc: Remove msr_pr macro
- docs/system/target-arm: Re-alphabetize board list
- migration: Extend query-migrate to provide dirty page limit info
- migration: Implement dirty-limit convergence algo
- migration: Put the detection logic before auto-converge checking
- migration: Refactor auto-converge capability logic
- migration: Introduce dirty-limit capability
- qapi/migration: Introduce vcpu-dirty-limit parameters
- qapi/migration: Introduce x-vcpu-dirty-limit-period parameter
- Change the value of no_ged from true to false
- Allow UNIX socket option for VNC websocket
- tpm_emulator: Avoid double initialization during
- chardev/char-socket: Update AF_UNIX for Windows
- KVM: dirty ring: add missing memory barrier
- i386: reset KVM nested state upon CPU reset
- esp: Handle CMD_BUSRESET by resetting the SCSI bus
- dbus-vmstate: Restrict error checks to registered proxies in dbus_get_proxies
- vfio/pci: Add Ascend310b scend910b support
- target/i386: Export RFDS bit to guests
- target/i386: Add new CPU model SierraForest
- target/i386: Introduce Icelake-Server-v7 to enable TSX
- hw/virtio: handle un-configured shutdown in virtio-pci
- target/s390x: display deprecation status in '-cpu help'
- target/i386: display deprecation status in '-cpu help'
- pc-bios/s390-ccw: Fix booting with logical block size < physical block size
* Mon Apr 22 2024 <fengjiabo1@huawei.com> - 10:6.2.0-91
- hw/virtio/virtio-crypto: Protect from DMA re-entrancy bugs(CVE-2024-3446)
- hw/char/virtio-serial-bus: Protect from DMA re-entrancy bugs(CVE-2024-3446)
- hw/display/virtio-gpu: Protect from DMA re-entrancy bugs(CVE-2024-3446)
- hw/virtio: Introduce virtio_bh_new_guarded() helper
- hw: replace most qemu_bh_new calls with qemu_bh_new_guarded
- checkpatch: add qemu_bh_new/aio_bh_new checks
- async: avoid use-after-free on re-entrancy guard
- async: Add an optional reentrancy guard to the BH API
- hw/sd/sdhci: Do not update TRNMOD when Command Inhibit (DAT) is set(CVE-2024-3447)
- rtl8139: Remove unused variable
- tulip: Remove unused variable
- virtio-mem: Fix the bitmap index of the section offset
- virtio-mem: Fix the iterator variable in a vmem->rdl_list loop
- system/memory: use ldn_he_p/stn_he_p
- block: Fix crash when loading snapshot on inactive node
- smmu: Clear SMMUPciBus pointer cache when system reset
- block/mirror: Fix NULL s->job in active writes
- amd_iommu: Fix APIC address check
- virtio-crypto: fix NULL pointer dereference in virtio_crypto_free_reques
- libqos/virtio.c: Correct 'flags' reading in qvirtqueue_kick
- ivshmem-test.c: enable test_ivshmem_server for ppc64 arch
- ivshmem.c: change endianness to LITTLE_ENDIAN
- hw/ppc/mac.h: Remove MAX_CPUS macro
- configure: remove dead variables
- virtio-gpu: do not byteswap padding
- hw/intc: clean-up error reporting for failed ITS cmd
- qemu-iotests: Discard stderr when probing devices
- linux-user: un-parent OBJECT(cpu) when closing thread
- hw/net/rocker: Avoid undefined shifts with more than 31 ports
- contrib/vhost-user-blk: Clean up deallocation of VuVirtqElement
- scsi-disk: fix overflow when block size is not a multiple of BDRV_SECTOR_SIZE
* Sat Mar 23 2024 <fengjiabo1@huawei.com> - 10:6.2.0-90
- i386/cpuid: Move leaf 7 to correct group
- i386/cpuid: Decrease cpuid_i when skipping CPUID leaf 1F

View File

@ -0,0 +1,44 @@
From 9058e3d3fcb3fcb397d72caca54a4d6a8cacbd50 Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Thu, 11 Apr 2024 00:58:48 -0700
Subject: [PATCH] rtl8139: Remove unused variable
Variable send_count used in rtl8139_cplus_transmit_one function is only
incremented but never read. This causes 'Unused but set variable' warning
on Clang 15.0.1 compiler.
Removing the variable to prevent the warning.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <15a32dd06c492216cbf27cd3ddcbe1e9afb8d8f5.1668009030.git.mrezanin@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 7d7238c72b983cff5064734349d2d45be9c6282c)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/net/rtl8139.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 43d65d7252..8af396cf06 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -2156,7 +2156,6 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
ip_data_len, saved_size - ETH_HLEN, large_send_mss);
int tcp_send_offset = 0;
- int send_count = 0;
/* maximum IP header length is 60 bytes */
uint8_t saved_ip_header[60];
@@ -2261,7 +2260,6 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
/* add transferred count to TCP sequence number */
stl_be_p(&p_tcp_hdr->th_seq,
chunk_size + ldl_be_p(&p_tcp_hdr->th_seq));
- ++send_count;
}
/* Stop sending this frame */
--
2.27.0

View File

@ -0,0 +1,46 @@
From d25446c995e2c562d62d832bc8da58d13b731974 Mon Sep 17 00:00:00 2001
From: dinglimin <dinglimin@cmss.chinamobile.com>
Date: Mon, 10 Jun 2024 20:00:42 +0800
Subject: [PATCH] s390x/sclp: Simplify get_sclp_device() cheery-pick from
3d9836e46dbe1e46c39fe76a62d3085a71ddbf7a get_sclp_device() scans the whole
machine to find a TYPE_SCLP object. Now that the SCLPDevice instance is
available under the machine state, use it to simplify the lookup. While at
it, remove the inline to let the compiler decide on how to optimize.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Cédric Le Goater <clg@redhat.com>
Message-ID: <20240502131533.377719-4-clg@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: dinglimin <dinglimin@cmss.chinamobile.com>
---
hw/s390x/sclp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index 89c30a8a91..24e29e8cda 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -20,13 +20,14 @@
#include "hw/s390x/event-facility.h"
#include "hw/s390x/s390-pci-bus.h"
#include "hw/s390x/ipl.h"
+#include "hw/s390x/s390-virtio-ccw.h"
-static inline SCLPDevice *get_sclp_device(void)
+static SCLPDevice *get_sclp_device(void)
{
static SCLPDevice *sclp;
if (!sclp) {
- sclp = SCLP(object_resolve_path_type("", TYPE_SCLP, NULL));
+ sclp = S390_CCW_MACHINE(qdev_get_machine())->sclp;
}
return sclp;
}
--
2.27.0

View File

@ -0,0 +1,59 @@
From 53b627a98b78ac06e7cba29c3614464469e7c11f Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Mon, 25 Mar 2024 08:14:12 +0000
Subject: [PATCH] scsi-disk: fix overflow when block size is not a multiple of BDRV_SECTOR_SIZE
mainline inclusion
commit 54a53a006ed9c1fe027fd89045d6de1e9128d7f4
category: bugfix
---------------------------------------------------------------
In scsi_disk_emulate_write_same() the number of host sectors to transfer is
calculated as (s->qdev.blocksize / BDRV_SECTOR_SIZE) which is then used to
copy data in block size chunks to the iov buffer.
Since the loop copying the data to the iov buffer uses a fixed increment of
s->qdev.blocksize then using a block size that isn't a multiple of
BDRV_SECTOR_SIZE introduces a rounding error in the iov buffer size calculation
such that the iov buffer copy overflows the space allocated.
Update the iov buffer copy for() loop so that it will use the smallest of either
the current block size or the remaining transfer count to prevent the overflow.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Message-Id: <20220730122656.253448-2-mark.cave-ayland@ilande.co.uk>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
hw/scsi/scsi-disk.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index a66d2b0a98..edd2f895e7 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -1800,7 +1800,7 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
uint32_t nb_sectors = scsi_data_cdb_xfer(r->req.cmd.buf);
WriteSameCBData *data;
uint8_t *buf;
- int i;
+ int i, l;
/* Fail if PBDATA=1 or LBDATA=1 or ANCHOR=1. */
if (nb_sectors == 0 || (req->cmd.buf[1] & 0x16)) {
@@ -1842,8 +1842,9 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf)
data->iov.iov_len);
qemu_iovec_init_external(&data->qiov, &data->iov, 1);
- for (i = 0; i < data->iov.iov_len; i += s->qdev.blocksize) {
- memcpy(&buf[i], inbuf, s->qdev.blocksize);
+ for (i = 0; i < data->iov.iov_len; i += l) {
+ l = MIN(s->qdev.blocksize, data->iov.iov_len - i);
+ memcpy(&buf[i], inbuf, l);
}
scsi_req_ref(&r->req);
--
2.27.0

View File

@ -0,0 +1,41 @@
From c7b0d41391267e278a3d7e9297041b29888a461e Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Mon, 8 Apr 2024 00:12:40 -0700
Subject: [PATCH] smmu: Clear SMMUPciBus pointer cache when system reset
s->smmu_pcibus_by_bus_num is a SMMUPciBus pointer cache indexed
by bus number, bus number may not always be a fixed value,
i.e., guest reboot to different kernel which set bus number with
different algorithm.
This could lead to smmu_iommu_mr() providing the wrong iommu MR.
Suggested-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Message-Id: <20240125073706.339369-3-zhenzhong.duan@intel.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 8a6b3f4dc95a064e88adaca86374108da0ecb38d)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/arm/smmu-common.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
index e09b9c13b7..d8fc81c102 100644
--- a/hw/arm/smmu-common.c
+++ b/hw/arm/smmu-common.c
@@ -530,6 +530,8 @@ static void smmu_base_reset(DeviceState *dev)
{
SMMUState *s = ARM_SMMU(dev);
+ memset(s->smmu_pcibus_by_bus_num, 0, sizeof(s->smmu_pcibus_by_bus_num));
+
g_hash_table_remove_all(s->configs);
g_hash_table_remove_all(s->iotlb);
}
--
2.27.0

View File

@ -0,0 +1,78 @@
From 8a0a03a259eec5879a514363e3a80fea5039510f Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Mon, 8 Apr 2024 01:09:55 -0700
Subject: [PATCH] system/memory: use ldn_he_p/stn_he_p
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Using direct pointer dereferencing can allow for unaligned accesses,
which was seen during execution with sanitizers enabled.
Cc: qemu-stable@nongnu.org
Reviewed-by: Chris Rauer <crauer@google.com>
Reviewed-by: Peter Foley <pefoley@google.com>
Signed-off-by: Patrick Venture <venture@google.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>o
Reviewed-by: David Hildenbrand <david@redhat.com>
Message-ID: <20231116163633.276671-1-venture@google.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>o
(cherry picked from commit 2b8fe81b3c2e76d241510a9a85496d544e42f5ec)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
softmmu/memory.c | 32 ++------------------------------
1 file changed, 2 insertions(+), 30 deletions(-)
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 102f0a4248..0bf37f11aa 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -1325,22 +1325,7 @@ static uint64_t memory_region_ram_device_read(void *opaque,
hwaddr addr, unsigned size)
{
MemoryRegion *mr = opaque;
- uint64_t data = (uint64_t)~0;
-
- switch (size) {
- case 1:
- data = *(uint8_t *)(mr->ram_block->host + addr);
- break;
- case 2:
- data = *(uint16_t *)(mr->ram_block->host + addr);
- break;
- case 4:
- data = *(uint32_t *)(mr->ram_block->host + addr);
- break;
- case 8:
- data = *(uint64_t *)(mr->ram_block->host + addr);
- break;
- }
+ uint64_t data = ldn_he_p(mr->ram_block->host + addr, size);
trace_memory_region_ram_device_read(get_cpu_index(), mr, addr, data, size);
@@ -1354,20 +1339,7 @@ static void memory_region_ram_device_write(void *opaque, hwaddr addr,
trace_memory_region_ram_device_write(get_cpu_index(), mr, addr, data, size);
- switch (size) {
- case 1:
- *(uint8_t *)(mr->ram_block->host + addr) = (uint8_t)data;
- break;
- case 2:
- *(uint16_t *)(mr->ram_block->host + addr) = (uint16_t)data;
- break;
- case 4:
- *(uint32_t *)(mr->ram_block->host + addr) = (uint32_t)data;
- break;
- case 8:
- *(uint64_t *)(mr->ram_block->host + addr) = data;
- break;
- }
+ stn_he_p(mr->ram_block->host + addr, size, data);
}
static const MemoryRegionOps ram_device_mem_ops = {
--
2.27.0

View File

@ -0,0 +1,212 @@
From f315e08911bcfdbbb287aa35453acc71867ccd1e Mon Sep 17 00:00:00 2001
From: Tao Su <tao1.su@linux.intel.com>
Date: Wed, 20 Mar 2024 10:10:44 +0800
Subject: [PATCH] target/i386: Add new CPU model SierraForest
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit 6e82d3b6220777667968a04c87e1667f164ebe88 upstream.
According to table 1-2 in Intel Architecture Instruction Set Extensions and
Future Features (rev 051) [1], SierraForest has the following new features
which have already been virtualized:
- CMPCCXADD CPUID.(EAX=7,ECX=1):EAX[bit 7]
- AVX-IFMA CPUID.(EAX=7,ECX=1):EAX[bit 23]
- AVX-VNNI-INT8 CPUID.(EAX=7,ECX=1):EDX[bit 4]
- AVX-NE-CONVERT CPUID.(EAX=7,ECX=1):EDX[bit 5]
Add above features to new CPU model SierraForest. Comparing with GraniteRapids
CPU model, SierraForest bare-metal removes the following features:
- HLE CPUID.(EAX=7,ECX=0):EBX[bit 4]
- RTM CPUID.(EAX=7,ECX=0):EBX[bit 11]
- AVX512F CPUID.(EAX=7,ECX=0):EBX[bit 16]
- AVX512DQ CPUID.(EAX=7,ECX=0):EBX[bit 17]
- AVX512_IFMA CPUID.(EAX=7,ECX=0):EBX[bit 21]
- AVX512CD CPUID.(EAX=7,ECX=0):EBX[bit 28]
- AVX512BW CPUID.(EAX=7,ECX=0):EBX[bit 30]
- AVX512VL CPUID.(EAX=7,ECX=0):EBX[bit 31]
- AVX512_VBMI CPUID.(EAX=7,ECX=0):ECX[bit 1]
- AVX512_VBMI2 CPUID.(EAX=7,ECX=0):ECX[bit 6]
- AVX512_VNNI CPUID.(EAX=7,ECX=0):ECX[bit 11]
- AVX512_BITALG CPUID.(EAX=7,ECX=0):ECX[bit 12]
- AVX512_VPOPCNTDQ CPUID.(EAX=7,ECX=0):ECX[bit 14]
- LA57 CPUID.(EAX=7,ECX=0):ECX[bit 16]
- TSXLDTRK CPUID.(EAX=7,ECX=0):EDX[bit 16]
- AMX-BF16 CPUID.(EAX=7,ECX=0):EDX[bit 22]
- AVX512_FP16 CPUID.(EAX=7,ECX=0):EDX[bit 23]
- AMX-TILE CPUID.(EAX=7,ECX=0):EDX[bit 24]
- AMX-INT8 CPUID.(EAX=7,ECX=0):EDX[bit 25]
- AVX512_BF16 CPUID.(EAX=7,ECX=1):EAX[bit 5]
- fast zero-length MOVSB CPUID.(EAX=7,ECX=1):EAX[bit 10]
- fast short CMPSB, SCASB CPUID.(EAX=7,ECX=1):EAX[bit 12]
- AMX-FP16 CPUID.(EAX=7,ECX=1):EAX[bit 21]
- PREFETCHI CPUID.(EAX=7,ECX=1):EDX[bit 14]
- XFD CPUID.(EAX=0xD,ECX=1):EAX[bit 4]
- EPT_PAGE_WALK_LENGTH_5 VMX_EPT_VPID_CAP(0x48c)[bit 7]
Add all features of GraniteRapids CPU model except above features to
SierraForest CPU model.
SierraForest doesnt support TSX and RTM but supports TAA_NO. When RTM is
not enabled in host, KVM will not report TAA_NO. So, just don't include
TAA_NO in SierraForest CPU model.
[1] https://cdrdv2.intel.com/v1/dl/getContent/671368
Intel-SIG: commit 6e82d3b62207 target/i386: Add new CPU model SierraForest.
6.2.0-Add SRF CPU module support
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Signed-off-by: Tao Su <tao1.su@linux.intel.com>
Message-ID: <20240320021044.508263-1-tao1.su@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 126 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b5bf5ce7aa..eb7fda0299 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3893,6 +3893,132 @@ static const X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ },
},
},
+ {
+ .name = "SierraForest",
+ .level = 0x23,
+ .vendor = CPUID_VENDOR_INTEL,
+ .family = 6,
+ .model = 175,
+ .stepping = 0,
+ /*
+ * please keep the ascending order so that we can have a clear view of
+ * bit position of each feature.
+ */
+ .features[FEAT_1_EDX] =
+ CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC |
+ CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
+ CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
+ CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX | CPUID_FXSR |
+ CPUID_SSE | CPUID_SSE2,
+ .features[FEAT_1_ECX] =
+ CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 |
+ CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 |
+ CPUID_EXT_SSE42 | CPUID_EXT_X2APIC | CPUID_EXT_MOVBE |
+ CPUID_EXT_POPCNT | CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_AES |
+ CPUID_EXT_XSAVE | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+ .features[FEAT_8000_0001_EDX] =
+ CPUID_EXT2_SYSCALL | CPUID_EXT2_NX | CPUID_EXT2_PDPE1GB |
+ CPUID_EXT2_RDTSCP | CPUID_EXT2_LM,
+ .features[FEAT_8000_0001_ECX] =
+ CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | CPUID_EXT3_3DNOWPREFETCH,
+ .features[FEAT_8000_0008_EBX] =
+ CPUID_8000_0008_EBX_WBNOINVD,
+ .features[FEAT_7_0_EBX] =
+ CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 |
+ CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS |
+ CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+ CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_CLWB |
+ CPUID_7_0_EBX_SHA_NI,
+ .features[FEAT_7_0_ECX] =
+ CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_GFNI |
+ CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
+ CPUID_7_0_ECX_RDPID | CPUID_7_0_ECX_BUS_LOCK_DETECT,
+ .features[FEAT_7_0_EDX] =
+ CPUID_7_0_EDX_FSRM | CPUID_7_0_EDX_SERIALIZE |
+ CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_ARCH_CAPABILITIES |
+ CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+ .features[FEAT_ARCH_CAPABILITIES] =
+ MSR_ARCH_CAP_RDCL_NO | MSR_ARCH_CAP_IBRS_ALL |
+ MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY | MSR_ARCH_CAP_MDS_NO |
+ MSR_ARCH_CAP_PSCHANGE_MC_NO | MSR_ARCH_CAP_SBDR_SSDP_NO |
+ MSR_ARCH_CAP_FBSDP_NO | MSR_ARCH_CAP_PSDP_NO |
+ MSR_ARCH_CAP_PBRSB_NO,
+ .features[FEAT_XSAVE] =
+ CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+ CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES,
+ .features[FEAT_6_EAX] =
+ CPUID_6_EAX_ARAT,
+ .features[FEAT_7_1_EAX] =
+ CPUID_7_1_EAX_AVX_VNNI | CPUID_7_1_EAX_CMPCCXADD |
+ CPUID_7_1_EAX_FSRS | CPUID_7_1_EAX_AVX_IFMA,
+ .features[FEAT_7_1_EDX] =
+ CPUID_7_1_EDX_AVX_VNNI_INT8 | CPUID_7_1_EDX_AVX_NE_CONVERT,
+ .features[FEAT_7_2_EDX] =
+ CPUID_7_2_EDX_MCDT_NO,
+ .features[FEAT_VMX_BASIC] =
+ MSR_VMX_BASIC_INS_OUTS | MSR_VMX_BASIC_TRUE_CTLS,
+ .features[FEAT_VMX_ENTRY_CTLS] =
+ VMX_VM_ENTRY_LOAD_DEBUG_CONTROLS | VMX_VM_ENTRY_IA32E_MODE |
+ VMX_VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL |
+ VMX_VM_ENTRY_LOAD_IA32_PAT | VMX_VM_ENTRY_LOAD_IA32_EFER,
+ .features[FEAT_VMX_EPT_VPID_CAPS] =
+ MSR_VMX_EPT_EXECONLY | MSR_VMX_EPT_PAGE_WALK_LENGTH_4 |
+ MSR_VMX_EPT_WB | MSR_VMX_EPT_2MB | MSR_VMX_EPT_1GB |
+ MSR_VMX_EPT_INVEPT | MSR_VMX_EPT_AD_BITS |
+ MSR_VMX_EPT_INVEPT_SINGLE_CONTEXT | MSR_VMX_EPT_INVEPT_ALL_CONTEXT |
+ MSR_VMX_EPT_INVVPID | MSR_VMX_EPT_INVVPID_SINGLE_ADDR |
+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT |
+ MSR_VMX_EPT_INVVPID_ALL_CONTEXT |
+ MSR_VMX_EPT_INVVPID_SINGLE_CONTEXT_NOGLOBALS,
+ .features[FEAT_VMX_EXIT_CTLS] =
+ VMX_VM_EXIT_SAVE_DEBUG_CONTROLS |
+ VMX_VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL |
+ VMX_VM_EXIT_ACK_INTR_ON_EXIT | VMX_VM_EXIT_SAVE_IA32_PAT |
+ VMX_VM_EXIT_LOAD_IA32_PAT | VMX_VM_EXIT_SAVE_IA32_EFER |
+ VMX_VM_EXIT_LOAD_IA32_EFER | VMX_VM_EXIT_SAVE_VMX_PREEMPTION_TIMER,
+ .features[FEAT_VMX_MISC] =
+ MSR_VMX_MISC_STORE_LMA | MSR_VMX_MISC_ACTIVITY_HLT |
+ MSR_VMX_MISC_VMWRITE_VMEXIT,
+ .features[FEAT_VMX_PINBASED_CTLS] =
+ VMX_PIN_BASED_EXT_INTR_MASK | VMX_PIN_BASED_NMI_EXITING |
+ VMX_PIN_BASED_VIRTUAL_NMIS | VMX_PIN_BASED_VMX_PREEMPTION_TIMER |
+ VMX_PIN_BASED_POSTED_INTR,
+ .features[FEAT_VMX_PROCBASED_CTLS] =
+ VMX_CPU_BASED_VIRTUAL_INTR_PENDING |
+ VMX_CPU_BASED_USE_TSC_OFFSETING | VMX_CPU_BASED_HLT_EXITING |
+ VMX_CPU_BASED_INVLPG_EXITING | VMX_CPU_BASED_MWAIT_EXITING |
+ VMX_CPU_BASED_RDPMC_EXITING | VMX_CPU_BASED_RDTSC_EXITING |
+ VMX_CPU_BASED_CR3_LOAD_EXITING | VMX_CPU_BASED_CR3_STORE_EXITING |
+ VMX_CPU_BASED_CR8_LOAD_EXITING | VMX_CPU_BASED_CR8_STORE_EXITING |
+ VMX_CPU_BASED_TPR_SHADOW | VMX_CPU_BASED_VIRTUAL_NMI_PENDING |
+ VMX_CPU_BASED_MOV_DR_EXITING | VMX_CPU_BASED_UNCOND_IO_EXITING |
+ VMX_CPU_BASED_USE_IO_BITMAPS | VMX_CPU_BASED_MONITOR_TRAP_FLAG |
+ VMX_CPU_BASED_USE_MSR_BITMAPS | VMX_CPU_BASED_MONITOR_EXITING |
+ VMX_CPU_BASED_PAUSE_EXITING |
+ VMX_CPU_BASED_ACTIVATE_SECONDARY_CONTROLS,
+ .features[FEAT_VMX_SECONDARY_CTLS] =
+ VMX_SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
+ VMX_SECONDARY_EXEC_ENABLE_EPT | VMX_SECONDARY_EXEC_DESC |
+ VMX_SECONDARY_EXEC_RDTSCP |
+ VMX_SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
+ VMX_SECONDARY_EXEC_ENABLE_VPID | VMX_SECONDARY_EXEC_WBINVD_EXITING |
+ VMX_SECONDARY_EXEC_UNRESTRICTED_GUEST |
+ VMX_SECONDARY_EXEC_APIC_REGISTER_VIRT |
+ VMX_SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
+ VMX_SECONDARY_EXEC_RDRAND_EXITING |
+ VMX_SECONDARY_EXEC_ENABLE_INVPCID |
+ VMX_SECONDARY_EXEC_ENABLE_VMFUNC | VMX_SECONDARY_EXEC_SHADOW_VMCS |
+ VMX_SECONDARY_EXEC_RDSEED_EXITING | VMX_SECONDARY_EXEC_ENABLE_PML |
+ VMX_SECONDARY_EXEC_XSAVES,
+ .features[FEAT_VMX_VMFUNC] =
+ MSR_VMX_VMFUNC_EPT_SWITCHING,
+ .xlevel = 0x80000008,
+ .model_id = "Intel Xeon Processor (SierraForest)",
+ .versions = (X86CPUVersionDefinition[]) {
+ { .version = 1 },
+ { /* end of list */ },
+ },
+ },
{
.name = "Denverton",
.level = 21,
--
2.27.0

View File

@ -0,0 +1,47 @@
From 2ddb661f2566d8835103c0beedf24e36adc2608d Mon Sep 17 00:00:00 2001
From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Date: Wed, 13 Mar 2024 07:53:23 -0700
Subject: [PATCH] target/i386: Export RFDS bit to guests
commit 41bdd9812863c150284a9339a048ed88c40f4df7 upstream.
Register File Data Sampling (RFDS) is a CPU side-channel vulnerability
that may expose stale register value. CPUs that set RFDS_NO bit in MSR
IA32_ARCH_CAPABILITIES indicate that they are not vulnerable to RFDS.
Similarly, RFDS_CLEAR indicates that CPU is affected by RFDS, and has
the microcode to help mitigate RFDS.
Make RFDS_CLEAR and RFDS_NO bits available to guests.
Intel-SIG: commit 41bdd9812863 target/i386: Export RFDS bit to guests.
6.2.0-Add SRF CPU module support
Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Message-ID: <9a38877857392b5c2deae7e7db1b170d15510314.1710341348.git.pawan.kumar.gupta@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index eb7fda0299..a11f3373ea 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1052,8 +1052,8 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
NULL, "sbdr-ssdp-no", "fbsdp-no", "psdp-no",
NULL, "fb-clear", NULL, NULL,
NULL, NULL, NULL, NULL,
- "pbrsb-no", NULL, "gds-no", NULL,
- NULL, NULL, NULL, NULL,
+ "pbrsb-no", NULL, "gds-no", "rfds-no",
+ "rfds-clear", NULL, NULL, NULL,
},
.msr = {
.index = MSR_IA32_ARCH_CAPABILITIES,
--
2.27.0

View File

@ -0,0 +1,64 @@
From 2f722c0308c72223e1fe13caf1a3e5843635c98e Mon Sep 17 00:00:00 2001
From: Zhenzhong Duan <zhenzhong.duan@intel.com>
Date: Wed, 20 Mar 2024 17:31:38 +0800
Subject: [PATCH] target/i386: Introduce Icelake-Server-v7 to enable TSX
commit c895fa54e3060c5ac6f3888dce96c9b78626072b upstream.
When start L2 guest with both L1/L2 using Icelake-Server-v3 or above,
QEMU reports below warning:
"warning: host doesn't support requested feature: MSR(10AH).taa-no [bit 8]"
Reason is QEMU Icelake-Server-v3 has TSX feature disabled but enables taa-no
bit. It's meaningless that TSX isn't supported but still claim TSX is secure.
So L1 KVM doesn't expose taa-no to L2 if TSX is unsupported, then starting L2
triggers the warning.
Fix it by introducing a new version Icelake-Server-v7 which has both TSX
and taa-no features. Then guest can use TSX securely when it see taa-no.
This matches the production Icelake which supports TSX and isn't susceptible
to TSX Async Abort (TAA) vulnerabilities, a.k.a, taa-no.
Ideally, TSX should have being enabled together with taa-no since v3, but for
compatibility, we'd better to add v7 to enable it.
Fixes: d965dc35592d ("target/i386: Add ARCH_CAPABILITIES related bits into Icelake-Server CPU model")
Intel-SIG: commit c895fa54e306 target/i386: Introduce Icelake-Server-v7 to enable TSX.
6.2.0-Add SRF CPU module support
Tested-by: Xiangfei Ma <xiangfeix.ma@intel.com>
Signed-off-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Message-ID: <20240320093138.80267-2-zhenzhong.duan@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
[ Quanxian Wang: amend commit log ]
Signed-off-by: Quanxian Wang <quanxian.wang@intel.com>
---
target/i386/cpu.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 62ac5ed005..b5bf5ce7aa 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3606,6 +3606,16 @@ static const X86CPUDefinition builtin_x86_defs[] = {
{ /* end of list */ }
},
},
+ {
+ .version = 7,
+ .note = "TSX, taa-no",
+ .props = (PropValue[]) {
+ /* Restore TSX features removed by -v2 above */
+ { "hle", "on" },
+ { "rtm", "on" },
+ { /* end of list */ }
+ },
+ },
{ /* end of list */ }
}
},
--
2.27.0

View File

@ -0,0 +1,42 @@
From 7df11d09bea98ef7ef90518030ab6d694b832418 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 30 Apr 2024 09:04:20 +0000
Subject: [PATCH] target/i386: display deprecation status in '-cpu help'
mainline inclusion commit 5dfa9e8689d08c529bf772fc199597efa947fa27 category:
bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
When the user queries CPU models via QMP there is a 'deprecated' flag
present, however, this is not done for the CLI '-cpu help' command.
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
target/i386/cpu.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 62ac5ed005..f4b010c249 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5255,6 +5255,11 @@ static void x86_cpu_list_entry(gpointer data, gpointer user_data)
desc = g_strdup_printf("%s", model_id);
}
+ if (cc->model && cc->model->cpudef->deprecation_note) {
+ g_autofree char *olddesc = desc;
+ desc = g_strdup_printf("%s (deprecated)", olddesc);
+ }
+
qemu_printf("x86 %-20s %s\n", name, desc);
}
--
2.27.0

View File

@ -0,0 +1,236 @@
From d83a066d969070373afe68f32f8584c66f2ee747 Mon Sep 17 00:00:00 2001
From: dinglimin <dinglimin@cmss.chinamobile.com>
Date: Sun, 9 Jun 2024 14:04:03 +0800
Subject: [PATCH] target/ppc: Remove msr_pr macro cheery-pick from
d41ccf6eea918ec121cd38eda6e2526b446013f4 msr_pr macro hides the usage of
env->msr, which is a bad behavior Substitute it with FIELD_EX64 calls that
explicitly use env->msr as a parameter.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Víctor Colombo <victor.colombo@eldorado.org.br>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20220504210541.115256-4-victor.colombo@eldorado.org.br>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: dinglimin <dinglimin@cmss.chinamobile.com>
---
hw/ppc/pegasos2.c | 2 +-
hw/ppc/spapr.c | 2 +-
target/ppc/cpu.h | 4 +++-
target/ppc/cpu_init.c | 4 ++--
target/ppc/excp_helper.c | 3 ++-
target/ppc/mem_helper.c | 5 +++--
target/ppc/mmu-radix64.c | 5 +++--
target/ppc/mmu_common.c | 24 +++++++++++++-----------
8 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 298e6b93e2..7b7eb38152 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -457,7 +457,7 @@ static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
/* The TCG path should also be holding the BQL at this point */
g_assert(qemu_mutex_iothread_locked());
- if (msr_pr) {
+ if (FIELD_EX64(env->msr, MSR, PR)) {
qemu_log_mask(LOG_GUEST_ERROR, "Hypercall made with MSR[PR]=1\n");
env->gpr[3] = H_PRIVILEGE;
} else if (env->gpr[3] == KVMPPC_H_RTAS) {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 7f352ceaaa..d1fbea16e3 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1268,7 +1268,7 @@ static void emulate_spapr_hypercall(PPCVirtualHypervisor *vhyp,
/* The TCG path should also be holding the BQL at this point */
g_assert(qemu_mutex_iothread_locked());
- if (msr_pr) {
+ if (FIELD_EX64(env->msr, MSR, PR)) {
hcall_dprintf("Hypercall made with MSR[PR]=1\n");
env->gpr[3] = H_PRIVILEGE;
} else {
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 26312f9d5f..8b214b2cc1 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -24,6 +24,7 @@
#include "exec/cpu-defs.h"
#include "cpu-qom.h"
#include "qom/object.h"
+#include "hw/registerfields.h"
#define TCG_GUEST_DEFAULT_MO 0
@@ -343,6 +344,8 @@ typedef struct ppc_v3_pate_t {
#define MSR_RI 1 /* Recoverable interrupt 1 */
#define MSR_LE 0 /* Little-endian mode 1 hflags */
+FIELD(MSR, PR, MSR_PR, 1)
+
/* PMU bits */
#define MMCR0_FC PPC_BIT(32) /* Freeze Counters */
#define MMCR0_PMAO PPC_BIT(56) /* Perf Monitor Alert Occurred */
@@ -443,7 +446,6 @@ typedef struct ppc_v3_pate_t {
#define msr_ce ((env->msr >> MSR_CE) & 1)
#define msr_ile ((env->msr >> MSR_ILE) & 1)
#define msr_ee ((env->msr >> MSR_EE) & 1)
-#define msr_pr ((env->msr >> MSR_PR) & 1)
#define msr_fp ((env->msr >> MSR_FP) & 1)
#define msr_me ((env->msr >> MSR_ME) & 1)
#define msr_fe0 ((env->msr >> MSR_FE0) & 1)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 986d16a24d..d3b283dcd2 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7961,7 +7961,7 @@ static bool cpu_has_work_POWER9(CPUState *cs)
if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
(env->spr[SPR_LPCR] & LPCR_EEE)) {
bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
- if (heic == 0 || !msr_hv || msr_pr) {
+ if (!heic || !msr_hv || FIELD_EX64(env->msr, MSR, PR)) {
return true;
}
}
@@ -8170,7 +8170,7 @@ static bool cpu_has_work_POWER10(CPUState *cs)
if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
(env->spr[SPR_LPCR] & LPCR_EEE)) {
bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
- if (heic == 0 || !msr_hv || msr_pr) {
+ if (!heic || !msr_hv || FIELD_EX64(env->msr, MSR, PR)) {
return true;
}
}
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index f66063d55c..3576e87b28 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -976,7 +976,8 @@ static void ppc_hw_interrupt(CPUPPCState *env)
bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
bool heic = !!(env->spr[SPR_LPCR] & LPCR_HEIC);
/* HEIC blocks delivery to the hypervisor */
- if ((async_deliver && !(heic && msr_hv && !msr_pr)) ||
+ if ((async_deliver && !(heic && msr_hv &&
+ !FIELD_EX64(env->msr, MSR, PR))) ||
(env->has_hv_mode && msr_hv == 0 && !lpes0)) {
powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
return;
diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c
index 39945d9ea5..ceb4aa41d7 100644
--- a/target/ppc/mem_helper.c
+++ b/target/ppc/mem_helper.c
@@ -613,10 +613,11 @@ void helper_tbegin(CPUPPCState *env)
(1ULL << TEXASR_FAILURE_PERSISTENT) |
(1ULL << TEXASR_NESTING_OVERFLOW) |
(msr_hv << TEXASR_PRIVILEGE_HV) |
- (msr_pr << TEXASR_PRIVILEGE_PR) |
+ (FIELD_EX64(env->msr, MSR, PR) << TEXASR_PRIVILEGE_PR) |
(1ULL << TEXASR_FAILURE_SUMMARY) |
(1ULL << TEXASR_TFIAR_EXACT);
- env->spr[SPR_TFIAR] = env->nip | (msr_hv << 1) | msr_pr;
+ env->spr[SPR_TFIAR] = env->nip | (msr_hv << 1) |
+ FIELD_EX64(env->msr, MSR, PR);
env->spr[SPR_TFHAR] = env->nip + 4;
env->crf[0] = 0xB; /* 0b1010 = transaction failure */
}
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 5b0e62e676..3f016730cd 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -171,12 +171,13 @@ static bool ppc_radix64_check_prot(PowerPCCPU *cpu, MMUAccessType access_type,
}
/* Determine permissions allowed by Encoded Access Authority */
- if (!partition_scoped && (pte & R_PTE_EAA_PRIV) && msr_pr) {
+ if (!partition_scoped && (pte & R_PTE_EAA_PRIV) &&
+ FIELD_EX64(env->msr, MSR, PR)) {
*prot = 0;
} else if (mmuidx_pr(mmu_idx) || (pte & R_PTE_EAA_PRIV) ||
partition_scoped) {
*prot = ppc_radix64_get_prot_eaa(pte);
- } else { /* !msr_pr && !(pte & R_PTE_EAA_PRIV) && !partition_scoped */
+ } else { /* !MSR_PR && !(pte & R_PTE_EAA_PRIV) && !partition_scoped */
*prot = ppc_radix64_get_prot_eaa(pte);
*prot &= ppc_radix64_get_prot_amr(cpu); /* Least combined permissions */
}
diff --git a/target/ppc/mmu_common.c b/target/ppc/mmu_common.c
index 754509e556..fb1059bcf2 100644
--- a/target/ppc/mmu_common.c
+++ b/target/ppc/mmu_common.c
@@ -292,8 +292,8 @@ static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
bl = (*BATu & 0x00001FFC) << 15;
valid = 0;
prot = 0;
- if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
- ((msr_pr != 0) && (*BATu & 0x00000001))) {
+ if ((!FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000002)) ||
+ (FIELD_EX64(env->msr, MSR, PR) && (*BATu & 0x00000001))) {
valid = 1;
pp = *BATl & 0x00000003;
if (pp != 0) {
@@ -386,16 +386,17 @@ static int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
PowerPCCPU *cpu = env_archcpu(env);
hwaddr hash;
target_ulong vsid;
- int ds, pr, target_page_bits;
+ int ds, target_page_bits;
+ bool pr;
int ret;
target_ulong sr, pgidx;
- pr = msr_pr;
+ pr = FIELD_EX64(env->msr, MSR, PR);
ctx->eaddr = eaddr;
sr = env->sr[eaddr >> 28];
- ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
- ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
+ ctx->key = (((sr & 0x20000000) && pr) ||
+ ((sr & 0x40000000) && !pr)) ? 1 : 0;
ds = sr & 0x80000000 ? 1 : 0;
ctx->nx = sr & 0x10000000 ? 1 : 0;
vsid = sr & 0x00FFFFFF;
@@ -404,8 +405,9 @@ static int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
"Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx
" nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx
" ir=%d dr=%d pr=%d %d t=%d\n",
- eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
- (int)msr_dr, pr != 0 ? 1 : 0, access_type == MMU_DATA_STORE, type);
+ eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr,
+ (int)msr_ir, (int)msr_dr, pr ? 1 : 0,
+ access_type == MMU_DATA_STORE, type);
pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
hash = vsid ^ pgidx;
ctx->ptem = (vsid << 7) | (pgidx >> 10);
@@ -566,7 +568,7 @@ static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
ret = -1;
raddr = (hwaddr)-1ULL;
- pr = msr_pr;
+ pr = FIELD_EX64(env->msr, MSR, PR);
for (i = 0; i < env->nb_tlb; i++) {
tlb = &env->tlb.tlbe[i];
if (ppcemb_tlb_check(env, tlb, &raddr, address,
@@ -651,7 +653,7 @@ static int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
found_tlb:
- if (msr_pr != 0) {
+ if (FIELD_EX64(env->msr, MSR, PR)) {
prot2 = tlb->prot & 0xF;
} else {
prot2 = (tlb->prot >> 4) & 0xF;
@@ -799,7 +801,7 @@ static bool mmubooke206_get_as(CPUPPCState *env,
return true;
} else {
*as_out = msr_ds;
- *pr_out = msr_pr;
+ *pr_out = FIELD_EX64(env->msr, MSR, PR);
return false;
}
}
--
2.27.0

View File

@ -0,0 +1,67 @@
From 054d100649c34dd4e5a13140b09b8c080e85ffde Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Tue, 30 Apr 2024 09:24:09 +0000
Subject: [PATCH] target/s390x: display deprecation status in '-cpu help'
mainline inclusion commit 738cdc2f6ea1ce22bb3f2a4e0fc84fc8121896fb category:
bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
When the user queries CPU models via QMP there is a 'deprecated' flag
present, however, this is not done for the CLI '-cpu help' command.
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
target/s390x/cpu_models.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 11e06cc51f..65908c6d36 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -334,18 +334,31 @@ const S390CPUDef *s390_find_cpu_def(uint16_t type, uint8_t gen, uint8_t ec_ga,
static void s390_print_cpu_model_list_entry(gpointer data, gpointer user_data)
{
const S390CPUClass *scc = S390_CPU_CLASS((ObjectClass *)data);
+ CPUClass *cc = CPU_CLASS(scc);
char *name = g_strdup(object_class_get_name((ObjectClass *)data));
- const char *details = "";
+ g_autoptr(GString) details = g_string_new("");
if (scc->is_static) {
- details = "(static, migration-safe)";
- } else if (scc->is_migration_safe) {
- details = "(migration-safe)";
+ g_string_append(details, "static, ");
+ }
+ if (scc->is_migration_safe) {
+ g_string_append(details, "migration-safe, ");
+ }
+ if (cc->deprecation_note) {
+ g_string_append(details, "deprecated, ");
+ }
+ if (details->len) {
+ /* cull trailing ', ' */
+ g_string_truncate(details, details->len - 2);
}
/* strip off the -s390x-cpu */
g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
- qemu_printf("s390 %-15s %-35s %s\n", name, scc->desc, details);
+ if (details->len) {
+ qemu_printf("s390 %-15s %-35s (%s)\n", name, scc->desc, details->str);
+ } else {
+ qemu_printf("s390 %-15s %-35s\n", name, scc->desc);
+ }
g_free(name);
}
--
2.27.0

View File

@ -0,0 +1,132 @@
From dd38a2080df3aa42519dc94168e37381016ed6cb Mon Sep 17 00:00:00 2001
From: Fiona Ebner <f.ebner@proxmox.com>
Date: Wed, 6 Sep 2023 15:09:22 +0200
Subject: [PATCH] tests/qtest: ahci-test: add test exposing reset issue with
pending callback (Fix CVE-2023-5088)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Before commit "hw/ide: reset: cancel async DMA operation before
resetting state", this test would fail, because a reset with a
pending write operation would lead to an unsolicited write to the
first sector of the disk.
The test writes a pattern to the beginning of the disk and verifies
that it is still intact after a reset with a pending operation. It
also checks that the pending operation actually completes correctly.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-ID: <20230906130922.142845-2-f.ebner@proxmox.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
tests/qtest/ahci-test.c | 86 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 85 insertions(+), 1 deletion(-)
diff --git a/tests/qtest/ahci-test.c b/tests/qtest/ahci-test.c
index f7f69dc4bd..c8657cbdb3 100644
--- a/tests/qtest/ahci-test.c
+++ b/tests/qtest/ahci-test.c
@@ -1425,6 +1425,89 @@ static void test_reset(void)
ahci_shutdown(ahci);
}
+static void test_reset_pending_callback(void)
+{
+ AHCIQState *ahci;
+ AHCICommand *cmd;
+ uint8_t port;
+ uint64_t ptr1;
+ uint64_t ptr2;
+
+ int bufsize = 4 * 1024;
+ int speed = bufsize + (bufsize / 2);
+ int offset1 = 0;
+ int offset2 = bufsize / AHCI_SECTOR_SIZE;
+
+ g_autofree unsigned char *tx1 = g_malloc(bufsize);
+ g_autofree unsigned char *tx2 = g_malloc(bufsize);
+ g_autofree unsigned char *rx1 = g_malloc0(bufsize);
+ g_autofree unsigned char *rx2 = g_malloc0(bufsize);
+
+ /* Uses throttling to make test independent of specific environment. */
+ ahci = ahci_boot_and_enable("-drive if=none,id=drive0,file=%s,"
+ "cache=writeback,format=%s,"
+ "throttling.bps-write=%d "
+ "-M q35 "
+ "-device ide-hd,drive=drive0 ",
+ tmp_path, imgfmt, speed);
+
+ port = ahci_port_select(ahci);
+ ahci_port_clear(ahci, port);
+
+ ptr1 = ahci_alloc(ahci, bufsize);
+ ptr2 = ahci_alloc(ahci, bufsize);
+
+ g_assert(ptr1 && ptr2);
+
+ /* Need two different patterns. */
+ do {
+ generate_pattern(tx1, bufsize, AHCI_SECTOR_SIZE);
+ generate_pattern(tx2, bufsize, AHCI_SECTOR_SIZE);
+ } while (memcmp(tx1, tx2, bufsize) == 0);
+
+ qtest_bufwrite(ahci->parent->qts, ptr1, tx1, bufsize);
+ qtest_bufwrite(ahci->parent->qts, ptr2, tx2, bufsize);
+
+ /* Write to beginning of disk to check it wasn't overwritten later. */
+ ahci_guest_io(ahci, port, CMD_WRITE_DMA_EXT, ptr1, bufsize, offset1);
+
+ /* Issue asynchronously to get a pending callback during reset. */
+ cmd = ahci_command_create(CMD_WRITE_DMA_EXT);
+ ahci_command_adjust(cmd, offset2, ptr2, bufsize, 0);
+ ahci_command_commit(ahci, cmd, port);
+ ahci_command_issue_async(ahci, cmd);
+
+ ahci_set(ahci, AHCI_GHC, AHCI_GHC_HR);
+
+ ahci_command_free(cmd);
+
+ /* Wait for throttled write to finish. */
+ sleep(1);
+
+ /* Start again. */
+ ahci_clean_mem(ahci);
+ ahci_pci_enable(ahci);
+ ahci_hba_enable(ahci);
+ port = ahci_port_select(ahci);
+ ahci_port_clear(ahci, port);
+
+ /* Read and verify. */
+ ahci_guest_io(ahci, port, CMD_READ_DMA_EXT, ptr1, bufsize, offset1);
+ qtest_bufread(ahci->parent->qts, ptr1, rx1, bufsize);
+ g_assert_cmphex(memcmp(tx1, rx1, bufsize), ==, 0);
+
+ ahci_guest_io(ahci, port, CMD_READ_DMA_EXT, ptr2, bufsize, offset2);
+ qtest_bufread(ahci->parent->qts, ptr2, rx2, bufsize);
+ g_assert_cmphex(memcmp(tx2, rx2, bufsize), ==, 0);
+
+ ahci_free(ahci, ptr1);
+ ahci_free(ahci, ptr2);
+
+ ahci_clean_mem(ahci);
+
+ ahci_shutdown(ahci);
+}
+
static void test_ncq_simple(void)
{
AHCIQState *ahci;
@@ -1929,7 +2012,8 @@ int main(int argc, char **argv)
qtest_add_func("/ahci/migrate/dma/halted", test_migrate_halted_dma);
qtest_add_func("/ahci/max", test_max);
- qtest_add_func("/ahci/reset", test_reset);
+ qtest_add_func("/ahci/reset/simple", test_reset);
+ qtest_add_func("/ahci/reset/pending_callback", test_reset_pending_callback);
qtest_add_func("/ahci/io/ncq/simple", test_ncq_simple);
qtest_add_func("/ahci/migrate/ncq/simple", test_migrate_ncq);
--
2.41.0.windows.1

View File

@ -0,0 +1,58 @@
From 65582eea0238d4b833934281fc6580a28cc82694 Mon Sep 17 00:00:00 2001
From: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
Date: Wed, 15 May 2024 01:33:59 +0000
Subject: [PATCH] tpm_emulator: Avoid double initialization during migration
mainline inclusion commit a0bcec03761477371ff7c2e80dc07fff14222d92 category:
bugfix
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---------------------------------------------------------------
When resuming after a migration, the backend sends CMD_INIT to the
emulator from the startup callback, then it sends the migration state
from the vmstate to the emulator, then it sends CMD_INIT again. Skip the
first CMD_INIT during a migration to avoid initializing the TPM twice.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: tangbinzy <tangbin_yewu@cmss.chinamobile.com>
---
backends/tpm/tpm_emulator.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/backends/tpm/tpm_emulator.c b/backends/tpm/tpm_emulator.c
index 87d061e9bb..9b50c5b3e2 100644
--- a/backends/tpm/tpm_emulator.c
+++ b/backends/tpm/tpm_emulator.c
@@ -32,6 +32,7 @@
#include "qemu/sockets.h"
#include "qemu/lockable.h"
#include "io/channel-socket.h"
+#include "sysemu/runstate.h"
#include "sysemu/tpm_backend.h"
#include "sysemu/tpm_util.h"
#include "tpm_int.h"
@@ -383,6 +384,15 @@ err_exit:
static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
{
+ /* TPM startup will be done from post_load hook */
+ if (runstate_check(RUN_STATE_INMIGRATE)) {
+ if (buffersize != 0) {
+ return tpm_emulator_set_buffer_size(tb, buffersize, NULL);
+ }
+
+ return 0;
+ }
+
return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
}
--
2.27.0

View File

@ -0,0 +1,48 @@
From 743ade13f9b675b4a5aa8631235d681fd66ee854 Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Thu, 11 Apr 2024 00:53:25 -0700
Subject: [PATCH] tulip: Remove unused variable
Variable n used in tulip_idblock_crc function is only incremented but never read.
This causes 'Unused but set variable' warning on Clang 15.0.1 compiler.
Removing the variable to prevent the warning.
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-Id: <02e1560d115c208df32236df8916fed98429fda1.1668009030.git.mrezanin@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
(cherry picked from commit 6083dcad80743718620a3f8a72fb76ea8b7c28ca)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/net/tulip.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index d319f9fb80..956093abd7 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -870,11 +870,10 @@ static const MemoryRegionOps tulip_ops = {
static void tulip_idblock_crc(TULIPState *s, uint16_t *srom)
{
- int word, n;
+ int word;
int bit;
unsigned char bitval, crc;
const int len = 9;
- n = 0;
crc = -1;
for (word = 0; word < len; word++) {
@@ -887,7 +886,6 @@ static void tulip_idblock_crc(TULIPState *s, uint16_t *srom)
srom[len - 1] = (srom[len - 1] & 0xff00) | (unsigned short)crc;
break;
}
- n++;
bitval = ((srom[word] >> bit) & 1) ^ ((crc >> 7) & 1);
crc = crc << 1;
if (bitval == 1) {
--
2.27.0

View File

@ -0,0 +1,134 @@
From 0cc777f65565e77100e0a767f6165217246b0226 Mon Sep 17 00:00:00 2001
From: yuxiating <yuxiating@xfusion.com>
Date: Tue, 14 May 2024 11:19:02 +0800
Subject: [PATCH] vfio/pci: Add Ascend310b scend910b support
Reference:https://support.huawei.com/enterprise/zh/doc/EDOC1100349016/63b881f2
Signed-off-by: yuxiating <yuxiating@xfusion.com>
---
hw/vfio/pci-quirks.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index a911e04a79..d83ed21387 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -1211,7 +1211,9 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
#define PCI_VENDOR_ID_HUAWEI 0x19e5
#define PCI_DEVICE_ID_ASCEND910 0xd801
+#define PCI_DEVICE_ID_ASCEND910B 0xd802
#define PCI_DEVICE_ID_ASCEND710 0xd500
+#define PCI_DEVICE_ID_ASCEND310B 0xd105
#define PCI_DEVICE_ID_ASCEND310 0xd100
#define PCI_SUB_DEVICE_ID_ASCEND710_1P_MIN 0x100
#define PCI_SUB_DEVICE_ID_ASCEND710_1P_MAX 0x10f
@@ -1219,11 +1221,15 @@ int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev,
#define PCI_SUB_DEVICE_ID_ASCEND710_2P_MAX 0x11f
#define ASCEND910_XLOADER_SIZE 4
#define ASCEND910_XLOADER_OFFSET 0x80400
+#define ASCEND910B_XLOADER_SIZE 4
+#define ASCEND910B_XLOADER_OFFSET 0x18208430
#define ASCEND710_2P_BASE (128 * 1024 * 1024)
#define ASCEND710_1P_DEVNUM 1
#define ASCEND710_2P_DEVNUM 2
#define ASCEND710_XLOADER_SIZE 4
#define ASCEND710_XLOADER_OFFSET 0x100430
+#define ASCEND310B_XLOADER_SIZE 4
+#define ASCEND310B_XLOADER_OFFSET 0x4430
#define ASCEND310_XLOADER_SIZE 4
#define ASCEND310_XLOADER_OFFSET 0x400
@@ -1263,6 +1269,38 @@ static const MemoryRegionOps vfio_ascend_intercept_regs_quirk = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
+static void vfio_probe_ascend910b_bar2_quirk(VFIOPCIDevice *vdev, int nr)
+{
+ VFIOQuirk *quirk;
+ VFIOAscendBarQuirk *bar2_quirk;
+
+ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2
+ || vdev->device_id != PCI_DEVICE_ID_ASCEND910B) {
+ return;
+ }
+
+ quirk = g_malloc0(sizeof(*quirk));
+ quirk->nr_mem = 1;
+ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem);
+ bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem);
+ bar2_quirk[0].vdev = vdev;
+ bar2_quirk[0].offset = ASCEND910B_XLOADER_OFFSET;
+ bar2_quirk[0].bar = nr;
+
+ /* intercept w/r to the xloader-updating register,
+ * so the vm can't enable xloader-updating
+ */
+ memory_region_init_io(&quirk->mem[0], OBJECT(vdev),
+ &vfio_ascend_intercept_regs_quirk,
+ &bar2_quirk[0],
+ "vfio-ascend910b-bar2-intercept-regs-quirk",
+ ASCEND910B_XLOADER_SIZE);
+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
+ bar2_quirk[0].offset,
+ &quirk->mem[0], 1);
+ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
+}
+
static void vfio_probe_ascend910_bar0_quirk(VFIOPCIDevice *vdev, int nr)
{
VFIOQuirk *quirk;
@@ -1360,6 +1398,38 @@ static void vfio_probe_ascend710_bar2_quirk(VFIOPCIDevice *vdev, int nr)
QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
}
+static void vfio_probe_ascend310b_bar2_quirk(VFIOPCIDevice *vdev, int nr)
+{
+ VFIOQuirk *quirk;
+ VFIOAscendBarQuirk *bar2_quirk;
+
+ if (vdev->vendor_id != PCI_VENDOR_ID_HUAWEI || nr != 2
+ || vdev->device_id != PCI_DEVICE_ID_ASCEND310B) {
+ return;
+ }
+
+ quirk = g_malloc0(sizeof(*quirk));
+ quirk->nr_mem = 1;
+ quirk->mem = g_new0(MemoryRegion, quirk->nr_mem);
+ bar2_quirk = quirk->data = g_new0(typeof(*bar2_quirk), quirk->nr_mem);
+ bar2_quirk[0].vdev = vdev;
+ bar2_quirk[0].offset = ASCEND310B_XLOADER_OFFSET;
+ bar2_quirk[0].bar = nr;
+
+ /* intercept w/r to the xloader-updating register,
+ * so the vm can't enable xloader-updating
+ */
+ memory_region_init_io(&quirk->mem[0], OBJECT(vdev),
+ &vfio_ascend_intercept_regs_quirk,
+ &bar2_quirk[0],
+ "vfio-ascend310b-bar2-intercept-regs-quirk",
+ ASCEND310B_XLOADER_SIZE);
+ memory_region_add_subregion_overlap(vdev->bars[nr].region.mem,
+ bar2_quirk[0].offset,
+ &quirk->mem[0], 1);
+ QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next);
+}
+
static void vfio_probe_ascend310_bar4_quirk(VFIOPCIDevice *vdev, int nr)
{
VFIOQuirk *quirk;
@@ -1445,8 +1515,10 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr)
#ifdef CONFIG_VFIO_IGD
vfio_probe_igd_bar4_quirk(vdev, nr);
#endif
+ vfio_probe_ascend910b_bar2_quirk(vdev, nr);
vfio_probe_ascend910_bar0_quirk(vdev, nr);
vfio_probe_ascend710_bar2_quirk(vdev, nr);
+ vfio_probe_ascend310b_bar2_quirk(vdev, nr);
vfio_probe_ascend310_bar4_quirk(vdev, nr);
}
--
2.27.0

View File

@ -0,0 +1,56 @@
From 7e0e009f5e5b39fc59aaa082cc092cb6438e5842 Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Wed, 10 Apr 2024 23:03:47 -0700
Subject: [PATCH] virtio-crypto: fix NULL pointer dereference in
virtio_crypto_free_reques
Ensure op_info is not NULL in case of QCRYPTODEV_BACKEND_ALG_SYM algtype.
Fixes: 0e660a6f90a ("crypto: Introduce RSA algorithm")
Signed-off-by: Mauro Matteo Cascella <mcascell@redhat.com>
Reported-by: Yiming Tao <taoym@zju.edu.cn>
Message-Id: <20230509075317.1132301-1-mcascell@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: zhenwei pi<pizhenwei@bytedance.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
(cherry picked from commit 3e69908907f8d3dd20d5753b0777a6e3824ba824)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/virtio/virtio-crypto.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 61b421aab3..8c2047f4e0 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -349,15 +349,17 @@ static void virtio_crypto_free_request(VirtIOCryptoReq *req)
size_t max_len;
CryptoDevBackendSymOpInfo *op_info = req->u.sym_op_info;
- max_len = op_info->iv_len +
- op_info->aad_len +
- op_info->src_len +
- op_info->dst_len +
- op_info->digest_result_len;
-
- /* Zeroize and free request data structure */
- memset(op_info, 0, sizeof(*op_info) + max_len);
- g_free(op_info);
+ if (op_info) {
+ max_len = op_info->iv_len +
+ op_info->aad_len +
+ op_info->src_len +
+ op_info->dst_len +
+ op_info->digest_result_len;
+
+ /* Zeroize and free request data structure */
+ memset(op_info, 0, sizeof(*op_info) + max_len);
+ g_free(op_info);
+ }
}
g_free(req);
}
--
2.27.0

View File

@ -0,0 +1,41 @@
From 365d14a81001ac41fd4aa2134b11a23d4a4a0656 Mon Sep 17 00:00:00 2001
From: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
Date: Thu, 28 Mar 2024 10:38:37 +0800
Subject: [PATCH] virtio-gpu: do not byteswap padding
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
cherry picked from commit a4663f1a5506626175fc64c86e52135587c36872
In Linux 5.16, the padding of struct virtio_gpu_ctrl_hdr has become a
single-byte field followed by a uint8_t[3] array of padding bytes,
and virtio_gpu_ctrl_hdr_bswap does not compile anymore.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20211111110604.207376-2-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
---
include/hw/virtio/virtio-gpu-bswap.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/hw/virtio/virtio-gpu-bswap.h b/include/hw/virtio/virtio-gpu-bswap.h
index e2bee8f595..5faac0d8d5 100644
--- a/include/hw/virtio/virtio-gpu-bswap.h
+++ b/include/hw/virtio/virtio-gpu-bswap.h
@@ -24,7 +24,6 @@ virtio_gpu_ctrl_hdr_bswap(struct virtio_gpu_ctrl_hdr *hdr)
le32_to_cpus(&hdr->flags);
le64_to_cpus(&hdr->fence_id);
le32_to_cpus(&hdr->ctx_id);
- le32_to_cpus(&hdr->padding);
}
static inline void
--
2.27.0

View File

@ -0,0 +1,47 @@
From a1afd7b993903510f946a979ff31ccf21b34006c Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Thu, 11 Apr 2024 00:39:56 -0700
Subject: [PATCH] virtio-mem: Fix the bitmap index of the section offset
vmem->bitmap indexes the memory region of the virtio-mem backend at a
granularity of block_size. To calculate the index of target section offset,
the block_size should be divided instead of the bitmap_size.
Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface")
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
Message-Id: <20221216062231.11181-1-chenyi.qiang@intel.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: David Hildenbrand <david@redhat.com>
(cherry picked from commit b11cf32e07a2f7ff0d171b89497381a04c9d07e0)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/virtio/virtio-mem.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index becac0d93b..4dac2c051b 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -205,7 +205,7 @@ static int virtio_mem_for_each_plugged_section(const VirtIOMEM *vmem,
uint64_t offset, size;
int ret = 0;
- first_bit = s->offset_within_region / vmem->bitmap_size;
+ first_bit = s->offset_within_region / vmem->block_size;
first_bit = find_next_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
while (first_bit < vmem->bitmap_size) {
MemoryRegionSection tmp = *s;
@@ -237,7 +237,7 @@ static int virtio_mem_for_each_unplugged_section(const VirtIOMEM *vmem,
uint64_t offset, size;
int ret = 0;
- first_bit = s->offset_within_region / vmem->bitmap_size;
+ first_bit = s->offset_within_region / vmem->block_size;
first_bit = find_next_zero_bit(vmem->bitmap, vmem->bitmap_size, first_bit);
while (first_bit < vmem->bitmap_size) {
MemoryRegionSection tmp = *s;
--
2.27.0

View File

@ -0,0 +1,39 @@
From 9fb38321dbddc7e0e8c18c2cde47bc0261bd8058 Mon Sep 17 00:00:00 2001
From: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
Date: Thu, 11 Apr 2024 00:31:44 -0700
Subject: [PATCH] virtio-mem: Fix the iterator variable in a vmem->rdl_list
loop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It should be the variable rdl2 to revert the already-notified listeners.
Fixes: 2044969f0b ("virtio-mem: Implement RamDiscardManager interface")
Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
Message-Id: <20221228090312.17276-1-chenyi.qiang@intel.com>
Cc: qemu-stable@nongnu.org
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: David Hildenbrand <david@redhat.com>
(cherry picked from commit 29f1b328e3b767cba2661920a8470738469b9e36)
Signed-off-by: zhujun2 <zhujun2_yewu@cmss.chinamobile.com>
---
hw/virtio/virtio-mem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
index becac0d93b..ddf7e2ec12 100644
--- a/hw/virtio/virtio-mem.c
+++ b/hw/virtio/virtio-mem.c
@@ -311,7 +311,7 @@ static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t offset,
if (ret) {
/* Notify all already-notified listeners. */
QLIST_FOREACH(rdl2, &vmem->rdl_list, next) {
- MemoryRegionSection tmp = *rdl->section;
+ MemoryRegionSection tmp = *rdl2->section;
if (rdl2 == rdl) {
break;
--
2.27.0