Update QEMU to v8.2.2 (#63)

* Merge with QEMU v8.2.2
This commit is contained in:
Romain Malmain 2024-04-18 11:53:28 +02:00 committed by GitHub
parent 2edf778b1c
commit 46273983f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
90 changed files with 473 additions and 231 deletions

View File

@ -21,7 +21,7 @@ build_task:
install_script: install_script:
- @UPDATE_COMMAND@ - @UPDATE_COMMAND@
- @INSTALL_COMMAND@ @PKGS@ - @INSTALL_COMMAND@ @PKGS@
- if test -n "@PYPI_PKGS@" ; then @PIP3@ install @PYPI_PKGS@ ; fi - if test -n "@PYPI_PKGS@" ; then PYLIB=$(@PYTHON@ -c 'import sysconfig; print(sysconfig.get_path("stdlib"))'); rm -f $PYLIB/EXTERNALLY-MANAGED; @PIP3@ install @PYPI_PKGS@ ; fi
clone_script: clone_script:
- git clone --depth 100 "$CI_REPOSITORY_URL" . - git clone --depth 100 "$CI_REPOSITORY_URL" .
- git fetch origin "$CI_COMMIT_REF_NAME" - git fetch origin "$CI_COMMIT_REF_NAME"

View File

@ -88,7 +88,6 @@
$MINGW_TARGET-libpng $MINGW_TARGET-libpng
$MINGW_TARGET-libssh $MINGW_TARGET-libssh
$MINGW_TARGET-libtasn1 $MINGW_TARGET-libtasn1
$MINGW_TARGET-libusb
$MINGW_TARGET-lzo2 $MINGW_TARGET-lzo2
$MINGW_TARGET-nettle $MINGW_TARGET-nettle
$MINGW_TARGET-ninja $MINGW_TARGET-ninja
@ -98,9 +97,8 @@
$MINGW_TARGET-SDL2 $MINGW_TARGET-SDL2
$MINGW_TARGET-SDL2_image $MINGW_TARGET-SDL2_image
$MINGW_TARGET-snappy $MINGW_TARGET-snappy
$MINGW_TARGET-spice $MINGW_TARGET-zstd
$MINGW_TARGET-usbredir $EXTRA_PACKAGES "
$MINGW_TARGET-zstd "
- Write-Output "Running build at $(Get-Date -Format u)" - Write-Output "Running build at $(Get-Date -Format u)"
- $env:CHERE_INVOKING = 'yes' # Preserve the current working directory - $env:CHERE_INVOKING = 'yes' # Preserve the current working directory
- $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink - $env:MSYS = 'winsymlinks:native' # Enable native Windows symlink
@ -123,6 +121,8 @@ msys2-64bit:
variables: variables:
MINGW_TARGET: mingw-w64-x86_64 MINGW_TARGET: mingw-w64-x86_64
MSYSTEM: MINGW64 MSYSTEM: MINGW64
# msys2 only ship these packages for 64-bit, not 32-bit
EXTRA_PACKAGES: $MINGW_TARGET-libusb $MINGW_TARGET-usbredir $MINGW_TARGET-spice
# do not remove "--without-default-devices"! # do not remove "--without-default-devices"!
# commit 9f8e6cad65a6 ("gitlab-ci: Speed up the msys2-64bit job by using --without-default-devices" # commit 9f8e6cad65a6 ("gitlab-ci: Speed up the msys2-64bit job by using --without-default-devices"
# changed to compile QEMU with the --without-default-devices switch # changed to compile QEMU with the --without-default-devices switch
@ -131,11 +131,3 @@ msys2-64bit:
# qTests don't run successfully with "--without-default-devices", # qTests don't run successfully with "--without-default-devices",
# so let's exclude the qtests from CI for now. # so let's exclude the qtests from CI for now.
TEST_ARGS: --no-suite qtest TEST_ARGS: --no-suite qtest
msys2-32bit:
extends: .shared_msys2_builder
variables:
MINGW_TARGET: mingw-w64-i686
MSYSTEM: MINGW32
CONFIGURE_ARGS: --target-list=ppc64-softmmu -Ddebug=false -Doptimization=0
TEST_ARGS: --no-suite qtest

View File

@ -1 +1 @@
8.2.1 8.2.2

View File

@ -30,7 +30,8 @@ endforeach
if dbus_display if dbus_display
module_ss = ss.source_set() module_ss = ss.source_set()
module_ss.add(when: [gio, pixman], if_true: files('dbusaudio.c')) module_ss.add(when: [gio, dbus_display1_dep, pixman],
if_true: files('dbusaudio.c'))
audio_modules += {'dbus': module_ss} audio_modules += {'dbus': module_ss}
endif endif

View File

@ -68,7 +68,7 @@ typedef struct {
CoQueue bounce_available; CoQueue bounce_available;
/* The value of the "mem-region-alignment" property */ /* The value of the "mem-region-alignment" property */
size_t mem_region_alignment; uint64_t mem_region_alignment;
/* Can we skip adding/deleting blkio_mem_regions? */ /* Can we skip adding/deleting blkio_mem_regions? */
bool needs_mem_regions; bool needs_mem_regions;

View File

@ -492,9 +492,9 @@ static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
s->max_size <= 0) { s->max_size <= 0) {
return TRUE; return TRUE;
} }
len = tcp_chr_read_poll(opaque);
if (len > sizeof(buf)) {
len = sizeof(buf); len = sizeof(buf);
if (len > s->max_size) {
len = s->max_size;
} }
size = tcp_chr_recv(chr, (void *)buf, len); size = tcp_chr_recv(chr, (void *)buf, len);
if (size == 0 || (size == -1 && errno != EAGAIN)) { if (size == 0 || (size == -1 && errno != EAGAIN)) {

3
configure vendored
View File

@ -1696,6 +1696,9 @@ fi
mkdir -p tests/tcg mkdir -p tests/tcg
echo "# Automatically generated by configure - do not modify" > $config_host_mak echo "# Automatically generated by configure - do not modify" > $config_host_mak
echo "SRC_PATH=$source_path" >> $config_host_mak echo "SRC_PATH=$source_path" >> $config_host_mak
if test "$plugins" = "yes" ; then
echo "CONFIG_PLUGIN=y" >> tests/tcg/$config_host_mak
fi
tcg_tests_targets= tcg_tests_targets=
for target in $target_list; do for target in $target_list; do

View File

@ -327,7 +327,7 @@ virgl_get_resource_info_modifiers(uint32_t resource_id,
#ifdef VIRGL_RENDERER_RESOURCE_INFO_EXT_VERSION #ifdef VIRGL_RENDERER_RESOURCE_INFO_EXT_VERSION
struct virgl_renderer_resource_info_ext info_ext; struct virgl_renderer_resource_info_ext info_ext;
ret = virgl_renderer_resource_get_info_ext(resource_id, &info_ext); ret = virgl_renderer_resource_get_info_ext(resource_id, &info_ext);
if (ret < 0) { if (ret) {
return ret; return ret;
} }
@ -335,7 +335,7 @@ virgl_get_resource_info_modifiers(uint32_t resource_id,
*modifiers = info_ext.modifiers; *modifiers = info_ext.modifiers;
#else #else
ret = virgl_renderer_resource_get_info(resource_id, info); ret = virgl_renderer_resource_get_info(resource_id, info);
if (ret < 0) { if (ret) {
return ret; return ret;
} }
@ -372,7 +372,7 @@ virgl_cmd_set_scanout(VuGpu *g,
uint64_t modifiers = 0; uint64_t modifiers = 0;
ret = virgl_get_resource_info_modifiers(ss.resource_id, &info, ret = virgl_get_resource_info_modifiers(ss.resource_id, &info,
&modifiers); &modifiers);
if (ret == -1) { if (ret) {
g_critical("%s: illegal resource specified %d\n", g_critical("%s: illegal resource specified %d\n",
__func__, ss.resource_id); __func__, ss.resource_id);
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;

View File

@ -148,9 +148,9 @@ Vring descriptor indices for packed virtqueues
A vring address description A vring address description
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+-------+-------+------+------------+------+-----------+-----+ +-------+-------+------------+------+-----------+-----+
| index | flags | size | descriptor | used | available | log | | index | flags | descriptor | used | available | log |
+-------+-------+------+------------+------+-----------+-----+ +-------+-------+------------+------+-----------+-----+
:index: a 32-bit vring index :index: a 32-bit vring index

View File

@ -1,8 +1,9 @@
During the graphical emulation, you can use special key combinations to During the graphical emulation, you can use special key combinations from
change modes. The default key mappings are shown below, but if you use the following table to change modes. By default the modifier is Ctrl-Alt
``-alt-grab`` then the modifier is Ctrl-Alt-Shift (instead of Ctrl-Alt) (used in the table below) which can be changed with ``-display`` suboption
and if you use ``-ctrl-grab`` then the modifier is the right Ctrl key ``mod=`` where appropriate. For example, ``-display sdl,
(instead of Ctrl-Alt): grab-mod=lshift-lctrl-lalt`` changes the modifier key to Ctrl-Alt-Shift,
while ``-display sdl,grab-mod=rctrl`` changes it to the right Ctrl key.
Ctrl-Alt-f Ctrl-Alt-f
Toggle full screen Toggle full screen
@ -28,7 +29,7 @@ Ctrl-Alt-n
*3* *3*
Serial port Serial port
Ctrl-Alt Ctrl-Alt-g
Toggle mouse and keyboard grab. Toggle mouse and keyboard grab.
In the virtual consoles, you can use Ctrl-Up, Ctrl-Down, Ctrl-PageUp and In the virtual consoles, you can use Ctrl-Up, Ctrl-Down, Ctrl-PageUp and

View File

@ -675,6 +675,8 @@ static void smmu_base_reset_hold(Object *obj)
{ {
SMMUState *s = ARM_SMMU(obj); SMMUState *s = ARM_SMMU(obj);
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->configs);
g_hash_table_remove_all(s->iotlb); g_hash_table_remove_all(s->iotlb);
} }

View File

@ -65,7 +65,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
iov_discard_undo(&req->inhdr_undo); iov_discard_undo(&req->inhdr_undo);
iov_discard_undo(&req->outhdr_undo); iov_discard_undo(&req->outhdr_undo);
virtqueue_push(req->vq, &req->elem, req->in_len); virtqueue_push(req->vq, &req->elem, req->in_len);
if (s->dataplane_started && !s->dataplane_disabled) { if (qemu_in_iothread()) {
virtio_blk_data_plane_notify(s->dataplane, req->vq); virtio_blk_data_plane_notify(s->dataplane, req->vq);
} else { } else {
virtio_notify(vdev, req->vq); virtio_notify(vdev, req->vq);

View File

@ -49,6 +49,7 @@ static void ct3_build_cdat(CDATObject *cdat, Error **errp)
g_autofree CDATTableHeader *cdat_header = NULL; g_autofree CDATTableHeader *cdat_header = NULL;
g_autofree CDATEntry *cdat_st = NULL; g_autofree CDATEntry *cdat_st = NULL;
uint8_t sum = 0; uint8_t sum = 0;
uint8_t *hdr_buf;
int ent, i; int ent, i;
/* Use default table if fopen == NULL */ /* Use default table if fopen == NULL */
@ -63,7 +64,7 @@ static void ct3_build_cdat(CDATObject *cdat, Error **errp)
cdat->built_buf_len = cdat->build_cdat_table(&cdat->built_buf, cdat->built_buf_len = cdat->build_cdat_table(&cdat->built_buf,
cdat->private); cdat->private);
if (!cdat->built_buf_len) { if (cdat->built_buf_len <= 0) {
/* Build later as not all data available yet */ /* Build later as not all data available yet */
cdat->to_update = true; cdat->to_update = true;
return; return;
@ -95,8 +96,12 @@ static void ct3_build_cdat(CDATObject *cdat, Error **errp)
/* For now, no runtime updates */ /* For now, no runtime updates */
cdat_header->sequence = 0; cdat_header->sequence = 0;
cdat_header->length += sizeof(CDATTableHeader); cdat_header->length += sizeof(CDATTableHeader);
sum += cdat_header->revision + cdat_header->sequence +
cdat_header->length; hdr_buf = (uint8_t *)cdat_header;
for (i = 0; i < sizeof(*cdat_header); i++) {
sum += hdr_buf[i];
}
/* Sum of all bytes including checksum must be 0 */ /* Sum of all bytes including checksum must be 0 */
cdat_header->checksum = ~sum + 1; cdat_header->checksum = ~sum + 1;

View File

@ -199,7 +199,7 @@ void cxl_component_register_block_init(Object *obj,
/* io registers controls link which we don't care about in QEMU */ /* io registers controls link which we don't care about in QEMU */
memory_region_init_io(&cregs->io, obj, NULL, cregs, ".io", memory_region_init_io(&cregs->io, obj, NULL, cregs, ".io",
CXL2_COMPONENT_IO_REGION_SIZE); CXL2_COMPONENT_IO_REGION_SIZE);
memory_region_init_io(&cregs->cache_mem, obj, &cache_mem_ops, cregs, memory_region_init_io(&cregs->cache_mem, obj, &cache_mem_ops, cxl_cstate,
".cache_mem", CXL2_COMPONENT_CM_REGION_SIZE); ".cache_mem", CXL2_COMPONENT_CM_REGION_SIZE);
memory_region_add_subregion(&cregs->component_registers, 0, &cregs->io); memory_region_add_subregion(&cregs->component_registers, 0, &cregs->io);

View File

@ -229,12 +229,9 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
static uint64_t mdev_reg_read(void *opaque, hwaddr offset, unsigned size) static uint64_t mdev_reg_read(void *opaque, hwaddr offset, unsigned size)
{ {
uint64_t retval = 0; CXLDeviceState *cxl_dstate = opaque;
retval = FIELD_DP64(retval, CXL_MEM_DEV_STS, MEDIA_STATUS, 1); return cxl_dstate->memdev_status;
retval = FIELD_DP64(retval, CXL_MEM_DEV_STS, MBOX_READY, 1);
return retval;
} }
static void ro_reg_write(void *opaque, hwaddr offset, uint64_t value, static void ro_reg_write(void *opaque, hwaddr offset, uint64_t value,
@ -371,7 +368,15 @@ static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
cxl_dstate->mbox_msi_n = msi_n; cxl_dstate->mbox_msi_n = msi_n;
} }
static void memdev_reg_init_common(CXLDeviceState *cxl_dstate) { } static void memdev_reg_init_common(CXLDeviceState *cxl_dstate)
{
uint64_t memdev_status_reg;
memdev_status_reg = FIELD_DP64(0, CXL_MEM_DEV_STS, MEDIA_STATUS, 1);
memdev_status_reg = FIELD_DP64(memdev_status_reg, CXL_MEM_DEV_STS,
MBOX_READY, 1);
cxl_dstate->memdev_status = memdev_status_reg;
}
void cxl_device_register_init_t3(CXLType3Dev *ct3d) void cxl_device_register_init_t3(CXLType3Dev *ct3d)
{ {

View File

@ -181,7 +181,7 @@ static void virgl_cmd_set_scanout(VirtIOGPU *g,
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
ret = virgl_renderer_resource_get_info(ss.resource_id, &info); ret = virgl_renderer_resource_get_info(ss.resource_id, &info);
#endif #endif
if (ret == -1) { if (ret) {
qemu_log_mask(LOG_GUEST_ERROR, qemu_log_mask(LOG_GUEST_ERROR,
"%s: illegal resource specified %d\n", "%s: illegal resource specified %d\n",
__func__, ss.resource_id); __func__, ss.resource_id);

View File

@ -7,6 +7,7 @@ config HPPA_B160L
select DINO select DINO
select LASI select LASI
select SERIAL select SERIAL
select SERIAL_PCI
select ISA_BUS select ISA_BUS
select I8259 select I8259
select IDE_CMD646 select IDE_CMD646
@ -16,3 +17,4 @@ config HPPA_B160L
select LASIPS2 select LASIPS2
select PARALLEL select PARALLEL
select ARTIST select ARTIST
select USB_OHCI_PCI

View File

@ -1415,7 +1415,7 @@ static void build_acpi0017(Aml *table)
aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0017"))); aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0017")));
method = aml_method("_STA", 0, AML_NOTSERIALIZED); method = aml_method("_STA", 0, AML_NOTSERIALIZED);
aml_append(method, aml_return(aml_int(0x01))); aml_append(method, aml_return(aml_int(0x0B)));
aml_append(dev, method); aml_append(dev, method);
build_cxl_dsm_method(dev); build_cxl_dsm_method(dev);

View File

@ -12,10 +12,6 @@ config IOAPIC
bool bool
select I8259 select I8259
config ARM_GIC
bool
select MSI_NONBROKEN
config OPENPIC config OPENPIC
bool bool
select MSI_NONBROKEN select MSI_NONBROKEN
@ -25,14 +21,18 @@ config APIC
select MSI_NONBROKEN select MSI_NONBROKEN
select I8259 select I8259
config ARM_GIC
bool
select ARM_GICV3_TCG if TCG
select ARM_GIC_KVM if KVM
select MSI_NONBROKEN
config ARM_GICV3_TCG config ARM_GICV3_TCG
bool bool
default y
depends on ARM_GIC && TCG depends on ARM_GIC && TCG
config ARM_GIC_KVM config ARM_GIC_KVM
bool bool
default y
depends on ARM_GIC && KVM depends on ARM_GIC && KVM
config XICS config XICS

View File

@ -421,7 +421,7 @@ static uint16_t tulip_mdi_default[] = {
/* MDI Registers 8 - 15 */ /* MDI Registers 8 - 15 */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* MDI Registers 16 - 31 */ /* MDI Registers 16 - 31 */
0x0003, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0x0000, 0x0001, 0x0000, 0x3b40, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
}; };
@ -429,7 +429,7 @@ static uint16_t tulip_mdi_default[] = {
static const uint16_t tulip_mdi_mask[] = { static const uint16_t tulip_mdi_mask[] = {
0x0000, 0xffff, 0xffff, 0xffff, 0xc01f, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xc01f, 0xffff, 0xffff, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0fff, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0fff, 0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff,
0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
}; };

View File

@ -7924,7 +7924,7 @@ static void nvme_init_state(NvmeCtrl *n)
n->aer_reqs = g_new0(NvmeRequest *, n->params.aerl + 1); n->aer_reqs = g_new0(NvmeRequest *, n->params.aerl + 1);
QTAILQ_INIT(&n->aer_queue); QTAILQ_INIT(&n->aer_queue);
list->numcntl = cpu_to_le16(max_vfs); list->numcntl = max_vfs;
for (i = 0; i < max_vfs; i++) { for (i = 0; i < max_vfs; i++) {
sctrl = &list->sec[i]; sctrl = &list->sec[i];
sctrl->pcid = cpu_to_le16(n->cntlid); sctrl->pcid = cpu_to_le16(n->cntlid);

View File

@ -340,6 +340,8 @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
break; break;
case DESIGNWARE_PCIE_ATU_VIEWPORT: case DESIGNWARE_PCIE_ATU_VIEWPORT:
val &= DESIGNWARE_PCIE_ATU_REGION_INBOUND |
(DESIGNWARE_PCIE_NUM_VIEWPORTS - 1);
root->atu_viewport = val; root->atu_viewport = val;
break; break;

View File

@ -132,7 +132,7 @@ static void build_rhct(GArray *table_data,
size_t len, aligned_len; size_t len, aligned_len;
uint32_t isa_offset, num_rhct_nodes; uint32_t isa_offset, num_rhct_nodes;
RISCVCPU *cpu; RISCVCPU *cpu;
char *isa; g_autofree char *isa = NULL;
AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id, AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id,
.oem_table_id = s->oem_table_id }; .oem_table_id = s->oem_table_id };

View File

@ -141,6 +141,7 @@ static void pl031_write(void * opaque, hwaddr offset,
g_autofree const char *qom_path = object_get_canonical_path(opaque); g_autofree const char *qom_path = object_get_canonical_path(opaque);
struct tm tm; struct tm tm;
s->lr = value;
s->tick_offset += value - pl031_get_count(s); s->tick_offset += value - pl031_get_count(s);
qemu_get_timedate(&tm, s->tick_offset); qemu_get_timedate(&tm, s->tick_offset);

View File

@ -1159,6 +1159,7 @@ again:
lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0); lsi_script_scsi_interrupt(s, LSI_SIST0_UDC, 0);
lsi_disconnect(s); lsi_disconnect(s);
trace_lsi_execute_script_stop(); trace_lsi_execute_script_stop();
reentrancy_level--;
return; return;
} }
insn = read_dword(s, s->dsp); insn = read_dword(s, s->dsp);

View File

@ -1149,6 +1149,7 @@ static void virtio_scsi_drained_begin(SCSIBus *bus)
static void virtio_scsi_drained_end(SCSIBus *bus) static void virtio_scsi_drained_end(SCSIBus *bus)
{ {
VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus); VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
VirtIODevice *vdev = VIRTIO_DEVICE(s); VirtIODevice *vdev = VIRTIO_DEVICE(s);
uint32_t total_queues = VIRTIO_SCSI_VQ_NUM_FIXED + uint32_t total_queues = VIRTIO_SCSI_VQ_NUM_FIXED +
s->parent_obj.conf.num_queues; s->parent_obj.conf.num_queues;
@ -1166,8 +1167,12 @@ static void virtio_scsi_drained_end(SCSIBus *bus)
for (uint32_t i = 0; i < total_queues; i++) { for (uint32_t i = 0; i < total_queues; i++) {
VirtQueue *vq = virtio_get_queue(vdev, i); VirtQueue *vq = virtio_get_queue(vdev, i);
if (vq == vs->event_vq) {
virtio_queue_aio_attach_host_notifier_no_poll(vq, s->ctx);
} else {
virtio_queue_aio_attach_host_notifier(vq, s->ctx); virtio_queue_aio_attach_host_notifier(vq, s->ctx);
} }
}
} }
static struct SCSIBusInfo virtio_scsi_scsi_info = { static struct SCSIBusInfo virtio_scsi_scsi_info = {

View File

@ -346,6 +346,11 @@ static const QemuOptDesc qemu_smbios_type4_opts[] = {
}; };
static const QemuOptDesc qemu_smbios_type8_opts[] = { static const QemuOptDesc qemu_smbios_type8_opts[] = {
{
.name = "type",
.type = QEMU_OPT_NUMBER,
.help = "SMBIOS element type",
},
{ {
.name = "internal_reference", .name = "internal_reference",
.type = QEMU_OPT_STRING, .type = QEMU_OPT_STRING,
@ -366,9 +371,15 @@ static const QemuOptDesc qemu_smbios_type8_opts[] = {
.type = QEMU_OPT_NUMBER, .type = QEMU_OPT_NUMBER,
.help = "port type", .help = "port type",
}, },
{ /* end of list */ }
}; };
static const QemuOptDesc qemu_smbios_type11_opts[] = { static const QemuOptDesc qemu_smbios_type11_opts[] = {
{
.name = "type",
.type = QEMU_OPT_NUMBER,
.help = "SMBIOS element type",
},
{ {
.name = "value", .name = "value",
.type = QEMU_OPT_STRING, .type = QEMU_OPT_STRING,
@ -379,6 +390,7 @@ static const QemuOptDesc qemu_smbios_type11_opts[] = {
.type = QEMU_OPT_STRING, .type = QEMU_OPT_STRING,
.help = "OEM string data from file", .help = "OEM string data from file",
}, },
{ /* end of list */ }
}; };
static const QemuOptDesc qemu_smbios_type17_opts[] = { static const QemuOptDesc qemu_smbios_type17_opts[] = {

View File

@ -273,13 +273,14 @@ static void usb_qdev_realize(DeviceState *qdev, Error **errp)
} }
if (dev->pcap_filename) { if (dev->pcap_filename) {
int fd = qemu_open_old(dev->pcap_filename, O_CREAT | O_WRONLY | O_TRUNC, 0666); int fd = qemu_open_old(dev->pcap_filename,
O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, 0666);
if (fd < 0) { if (fd < 0) {
error_setg(errp, "open %s failed", dev->pcap_filename); error_setg(errp, "open %s failed", dev->pcap_filename);
usb_qdev_unrealize(qdev); usb_qdev_unrealize(qdev);
return; return;
} }
dev->pcap = fdopen(fd, "w"); dev->pcap = fdopen(fd, "wb");
usb_pcap_init(dev->pcap); usb_pcap_init(dev->pcap);
} }
} }

View File

@ -824,9 +824,11 @@ static void vfio_msix_disable(VFIOPCIDevice *vdev)
} }
} }
if (vdev->nr_vectors) { /*
* Always clear MSI-X IRQ index. A PF device could have enabled
* MSI-X with no vectors. See vfio_msix_enable().
*/
vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX); vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX);
}
vfio_msi_disable_common(vdev); vfio_msi_disable_common(vdev);
vfio_intx_enable(vdev, &err); vfio_intx_enable(vdev, &err);

View File

@ -1264,6 +1264,8 @@ static void virtio_iommu_system_reset(void *opaque)
trace_virtio_iommu_system_reset(); trace_virtio_iommu_system_reset();
memset(s->iommu_pcibus_by_bus_num, 0, sizeof(s->iommu_pcibus_by_bus_num));
/* /*
* config.bypass is sticky across device reset, but should be restored on * config.bypass is sticky across device reset, but should be restored on
* system reset * system reset
@ -1302,8 +1304,6 @@ static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)
virtio_init(vdev, VIRTIO_ID_IOMMU, sizeof(struct virtio_iommu_config)); virtio_init(vdev, VIRTIO_ID_IOMMU, sizeof(struct virtio_iommu_config));
memset(s->iommu_pcibus_by_bus_num, 0, sizeof(s->iommu_pcibus_by_bus_num));
s->req_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, s->req_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE,
virtio_iommu_handle_command); virtio_iommu_handle_command);
s->event_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, NULL); s->event_vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE, NULL);

View File

@ -3556,6 +3556,17 @@ static void virtio_queue_host_notifier_aio_poll_end(EventNotifier *n)
void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx) void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx)
{ {
/*
* virtio_queue_aio_detach_host_notifier() can leave notifications disabled.
* Re-enable them. (And if detach has not been used before, notifications
* being enabled is still the default state while a notifier is attached;
* see virtio_queue_host_notifier_aio_poll_end(), which will always leave
* notifications enabled once the polling section is left.)
*/
if (!virtio_queue_get_notification(vq)) {
virtio_queue_set_notification(vq, 1);
}
aio_set_event_notifier(ctx, &vq->host_notifier, aio_set_event_notifier(ctx, &vq->host_notifier,
virtio_queue_host_notifier_read, virtio_queue_host_notifier_read,
virtio_queue_host_notifier_aio_poll, virtio_queue_host_notifier_aio_poll,
@ -3563,6 +3574,13 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx)
aio_set_event_notifier_poll(ctx, &vq->host_notifier, aio_set_event_notifier_poll(ctx, &vq->host_notifier,
virtio_queue_host_notifier_aio_poll_begin, virtio_queue_host_notifier_aio_poll_begin,
virtio_queue_host_notifier_aio_poll_end); virtio_queue_host_notifier_aio_poll_end);
/*
* We will have ignored notifications about new requests from the guest
* while no notifiers were attached, so "kick" the virt queue to process
* those requests now.
*/
event_notifier_set(&vq->host_notifier);
} }
/* /*
@ -3573,14 +3591,38 @@ void virtio_queue_aio_attach_host_notifier(VirtQueue *vq, AioContext *ctx)
*/ */
void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx) void virtio_queue_aio_attach_host_notifier_no_poll(VirtQueue *vq, AioContext *ctx)
{ {
/* See virtio_queue_aio_attach_host_notifier() */
if (!virtio_queue_get_notification(vq)) {
virtio_queue_set_notification(vq, 1);
}
aio_set_event_notifier(ctx, &vq->host_notifier, aio_set_event_notifier(ctx, &vq->host_notifier,
virtio_queue_host_notifier_read, virtio_queue_host_notifier_read,
NULL, NULL); NULL, NULL);
/*
* See virtio_queue_aio_attach_host_notifier().
* Note that this may be unnecessary for the type of virtqueues this
* function is used for. Still, it will not hurt to have a quick look into
* whether we can/should process any of the virtqueue elements.
*/
event_notifier_set(&vq->host_notifier);
} }
void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx) void virtio_queue_aio_detach_host_notifier(VirtQueue *vq, AioContext *ctx)
{ {
aio_set_event_notifier(ctx, &vq->host_notifier, NULL, NULL, NULL); aio_set_event_notifier(ctx, &vq->host_notifier, NULL, NULL, NULL);
/*
* aio_set_event_notifier_poll() does not guarantee whether io_poll_end()
* will run after io_poll_begin(), so by removing the notifier, we do not
* know whether virtio_queue_host_notifier_aio_poll_end() has run after a
* previous virtio_queue_host_notifier_aio_poll_begin(), i.e. whether
* notifications are enabled or disabled. It does not really matter anyway;
* we just removed the notifier, so we do not care about notifications until
* we potentially re-attach it. The attach_host_notifier functions will
* ensure that notifications are enabled again when they are needed.
*/
} }
void virtio_queue_host_notifier_read(EventNotifier *n) void virtio_queue_host_notifier_read(EventNotifier *n)

View File

@ -497,9 +497,14 @@ void aio_set_event_notifier(AioContext *ctx,
AioPollFn *io_poll, AioPollFn *io_poll,
EventNotifierHandler *io_poll_ready); EventNotifierHandler *io_poll_ready);
/* Set polling begin/end callbacks for an event notifier that has already been /*
* Set polling begin/end callbacks for an event notifier that has already been
* registered with aio_set_event_notifier. Do nothing if the event notifier is * registered with aio_set_event_notifier. Do nothing if the event notifier is
* not registered. * not registered.
*
* Note that if the io_poll_end() callback (or the entire notifier) is removed
* during polling, it will not be called, so an io_poll_begin() is not
* necessarily always followed by an io_poll_end().
*/ */
void aio_set_event_notifier_poll(AioContext *ctx, void aio_set_event_notifier_poll(AioContext *ctx,
EventNotifier *notifier, EventNotifier *notifier,

View File

@ -202,6 +202,9 @@ typedef struct cxl_device_state {
}; };
}; };
/* Stash the memory device status value */
uint64_t memdev_status;
struct { struct {
bool set; bool set;
uint64_t last_set; uint64_t last_set;
@ -353,8 +356,10 @@ static inline void __toggle_media(CXLDeviceState *cxl_dstate, int val)
{ {
uint64_t dev_status_reg; uint64_t dev_status_reg;
dev_status_reg = FIELD_DP64(0, CXL_MEM_DEV_STS, MEDIA_STATUS, val); dev_status_reg = cxl_dstate->memdev_status;
cxl_dstate->mbox_reg_state64[R_CXL_MEM_DEV_STS] = dev_status_reg; dev_status_reg = FIELD_DP64(dev_status_reg, CXL_MEM_DEV_STS, MEDIA_STATUS,
val);
cxl_dstate->memdev_status = dev_status_reg;
} }
#define cxl_dev_disable_media(cxlds) \ #define cxl_dev_disable_media(cxlds) \
do { __toggle_media((cxlds), 0x3); } while (0) do { __toggle_media((cxlds), 0x3); } while (0)

View File

@ -412,7 +412,7 @@ typedef struct TCGTemp {
unsigned int mem_coherent:1; unsigned int mem_coherent:1;
unsigned int mem_allocated:1; unsigned int mem_allocated:1;
unsigned int temp_allocated:1; unsigned int temp_allocated:1;
unsigned int temp_subindex:1; unsigned int temp_subindex:2;
int64_t val; int64_t val;
struct TCGTemp *mem_base; struct TCGTemp *mem_base;

View File

@ -173,21 +173,26 @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE; env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
if (cpu_isar_feature(aa64_mte, cpu)) { if (cpu_isar_feature(aa64_mte, cpu)) {
switch (arg2 & PR_MTE_TCF_MASK) {
case PR_MTE_TCF_NONE:
case PR_MTE_TCF_SYNC:
case PR_MTE_TCF_ASYNC:
break;
default:
return -EINVAL;
}
/* /*
* Write PR_MTE_TCF to SCTLR_EL1[TCF0]. * Write PR_MTE_TCF to SCTLR_EL1[TCF0].
* Note that the syscall values are consistent with hw. *
* The kernel has a per-cpu configuration for the sysadmin,
* /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
* which qemu does not implement.
*
* Because there is no performance difference between the modes, and
* because SYNC is most useful for debugging MTE errors, choose SYNC
* as the preferred mode. With this preference, and the way the API
* uses only two bits, there is no way for the program to select
* ASYMM mode.
*/ */
env->cp15.sctlr_el[1] = unsigned tcf = 0;
deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT); if (arg2 & PR_MTE_TCF_SYNC) {
tcf = 1;
} else if (arg2 & PR_MTE_TCF_ASYNC) {
tcf = 2;
}
env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
/* /*
* Write PR_MTE_TAG to GCR_EL1[Exclude]. * Write PR_MTE_TAG to GCR_EL1[Exclude].

Binary file not shown.

Binary file not shown.

View File

@ -63,7 +63,11 @@ vdso_syscall __kernel_clock_getres, __NR_clock_getres
* For now, elide the unwind info for __kernel_rt_sigreturn and rely on * For now, elide the unwind info for __kernel_rt_sigreturn and rely on
* the libgcc fallback routine as we have always done. This requires * the libgcc fallback routine as we have always done. This requires
* that the code sequence used be exact. * that the code sequence used be exact.
*
* Add a nop as a spacer to ensure that unwind does not pick up the
* unwind info from the preceding syscall.
*/ */
nop
__kernel_rt_sigreturn: __kernel_rt_sigreturn:
/* No BTI C insn here -- we arrive via RET. */ /* No BTI C insn here -- we arrive via RET. */
mov x8, #__NR_rt_sigreturn mov x8, #__NR_rt_sigreturn

View File

@ -762,7 +762,7 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
bool resume = qdict_get_try_bool(qdict, "resume", false); bool resume = qdict_get_try_bool(qdict, "resume", false);
const char *uri = qdict_get_str(qdict, "uri"); const char *uri = qdict_get_str(qdict, "uri");
Error *err = NULL; Error *err = NULL;
MigrationChannelList *caps = NULL; g_autoptr(MigrationChannelList) caps = NULL;
g_autoptr(MigrationChannel) channel = NULL; g_autoptr(MigrationChannel) channel = NULL;
if (inc) { if (inc) {
@ -787,8 +787,6 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
return; return;
} }
qapi_free_MigrationChannelList(caps);
if (!detach) { if (!detach) {
HMPMigrationStatus *status; HMPMigrationStatus *status;

View File

@ -128,11 +128,17 @@ static bool migration_needs_multiple_sockets(void)
return migrate_multifd() || migrate_postcopy_preempt(); return migrate_multifd() || migrate_postcopy_preempt();
} }
static bool transport_supports_multi_channels(SocketAddress *saddr) static bool transport_supports_multi_channels(MigrationAddress *addr)
{ {
if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) {
SocketAddress *saddr = &addr->u.socket;
return saddr->type == SOCKET_ADDRESS_TYPE_INET || return saddr->type == SOCKET_ADDRESS_TYPE_INET ||
saddr->type == SOCKET_ADDRESS_TYPE_UNIX || saddr->type == SOCKET_ADDRESS_TYPE_UNIX ||
saddr->type == SOCKET_ADDRESS_TYPE_VSOCK; saddr->type == SOCKET_ADDRESS_TYPE_VSOCK;
}
return false;
} }
static bool static bool
@ -140,8 +146,7 @@ migration_channels_and_transport_compatible(MigrationAddress *addr,
Error **errp) Error **errp)
{ {
if (migration_needs_multiple_sockets() && if (migration_needs_multiple_sockets() &&
(addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) && !transport_supports_multi_channels(addr)) {
!transport_supports_multi_channels(&addr->u.socket)) {
error_setg(errp, "Migration requires multi-channel URIs (e.g. tcp)"); error_setg(errp, "Migration requires multi-channel URIs (e.g. tcp)");
return false; return false;
} }
@ -650,6 +655,7 @@ static void process_incoming_migration_bh(void *opaque)
MIGRATION_STATUS_COMPLETED); MIGRATION_STATUS_COMPLETED);
qemu_bh_delete(mis->bh); qemu_bh_delete(mis->bh);
migration_incoming_state_destroy(); migration_incoming_state_destroy();
object_unref(OBJECT(migrate_get_current()));
} }
static void coroutine_fn static void coroutine_fn
@ -708,6 +714,7 @@ process_incoming_migration_co(void *opaque)
} }
mis->bh = qemu_bh_new(process_incoming_migration_bh, mis); mis->bh = qemu_bh_new(process_incoming_migration_bh, mis);
object_ref(OBJECT(migrate_get_current()));
qemu_bh_schedule(mis->bh); qemu_bh_schedule(mis->bh);
return; return;
fail: fail:

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1757,7 +1757,7 @@
# #
## ##
{ 'command': 'migrate', { 'command': 'migrate',
'data': {'uri': 'str', 'data': {'*uri': 'str',
'*channels': [ 'MigrationChannel' ], '*channels': [ 'MigrationChannel' ],
'*blk': { 'type': 'bool', 'features': [ 'deprecated' ] }, '*blk': { 'type': 'bool', 'features': [ 'deprecated' ] },
'*inc': { 'type': 'bool', 'features': [ 'deprecated' ] }, '*inc': { 'type': 'bool', 'features': [ 'deprecated' ] },

View File

@ -4118,7 +4118,8 @@ SRST
This option can be used several times to simulate up to 4 serial This option can be used several times to simulate up to 4 serial
ports. ports.
Use ``-serial none`` to disable all serial ports. You can use ``-serial none`` to suppress the creation of default
serial devices.
Available character devices are: Available character devices are:
@ -4140,10 +4141,17 @@ SRST
[Linux only] Pseudo TTY (a new PTY is automatically allocated) [Linux only] Pseudo TTY (a new PTY is automatically allocated)
``none`` ``none``
No device is allocated. No device is allocated. Note that for machine types which
emulate systems where a serial device is always present in
real hardware, this may be equivalent to the ``null`` option,
in that the serial device is still present but all output
is discarded. For boards where the number of serial ports is
truly variable, this suppresses the creation of the device.
``null`` ``null``
void device A guest will see the UART or serial device as present in the
machine, but all output is discarded, and there is no input.
Conceptually equivalent to redirecting the output to ``/dev/null``.
``chardev:id`` ``chardev:id``
Use a named character device defined with the ``-chardev`` Use a named character device defined with the ``-chardev``

@ -1 +1 @@
Subproject commit b8a3eec88cc74bbfe7fb389d026cc7d1d8a989c8 Subproject commit edc6681206c1a8791981a2f911d2fb8b3d2f5768

View File

@ -892,7 +892,7 @@ static void help(int exitcode)
printf("\nDuring emulation, the following keys are useful:\n" printf("\nDuring emulation, the following keys are useful:\n"
"ctrl-alt-f toggle full screen\n" "ctrl-alt-f toggle full screen\n"
"ctrl-alt-n switch to virtual console 'n'\n" "ctrl-alt-n switch to virtual console 'n'\n"
"ctrl-alt toggle mouse and keyboard grab\n" "ctrl-alt-g toggle mouse and keyboard grab\n"
"\n" "\n"
"When using -nographic, press 'ctrl-a h' to get some help.\n" "When using -nographic, press 'ctrl-a h' to get some help.\n"
"\n" "\n"
@ -1440,19 +1440,23 @@ static void qemu_create_default_devices(void)
static int serial_parse(const char *devname) static int serial_parse(const char *devname)
{ {
int index = num_serial_hds; int index = num_serial_hds;
char label[32];
if (strcmp(devname, "none") == 0)
return 0;
snprintf(label, sizeof(label), "serial%d", index);
serial_hds = g_renew(Chardev *, serial_hds, index + 1); serial_hds = g_renew(Chardev *, serial_hds, index + 1);
if (strcmp(devname, "none") == 0) {
/* Don't allocate a serial device for this index */
serial_hds[index] = NULL;
} else {
char label[32];
snprintf(label, sizeof(label), "serial%d", index);
serial_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL); serial_hds[index] = qemu_chr_new_mux_mon(label, devname, NULL);
if (!serial_hds[index]) { if (!serial_hds[index]) {
error_report("could not connect serial device" error_report("could not connect serial device"
" to character backend '%s'", devname); " to character backend '%s'", devname);
return -1; return -1;
} }
}
num_serial_hds++; num_serial_hds++;
return 0; return 0;
} }

View File

@ -1615,6 +1615,10 @@ void arm_cpu_post_init(Object *obj)
} }
} else if (cpu_isar_feature(aa32_vfp, cpu)) { } else if (cpu_isar_feature(aa32_vfp, cpu)) {
cpu->has_vfp = true; cpu->has_vfp = true;
if (tcg_enabled() || qtest_enabled()) {
qdev_property_add_static(DEVICE(obj),
&arm_cpu_has_vfp_property);
}
if (cpu_isar_feature(aa32_simd_r32, cpu)) { if (cpu_isar_feature(aa32_simd_r32, cpu)) {
cpu->has_vfp_d32 = true; cpu->has_vfp_d32 = true;
/* /*

View File

@ -1169,13 +1169,21 @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
bool enabled, prohibited = false, filtered; bool enabled, prohibited = false, filtered;
bool secure = arm_is_secure(env); bool secure = arm_is_secure(env);
int el = arm_current_el(env); int el = arm_current_el(env);
uint64_t mdcr_el2 = arm_mdcr_el2_eff(env); uint64_t mdcr_el2;
uint8_t hpmn = mdcr_el2 & MDCR_HPMN; uint8_t hpmn;
/*
* We might be called for M-profile cores where MDCR_EL2 doesn't
* exist and arm_mdcr_el2_eff() will assert, so this early-exit check
* must be before we read that value.
*/
if (!arm_feature(env, ARM_FEATURE_PMU)) { if (!arm_feature(env, ARM_FEATURE_PMU)) {
return false; return false;
} }
mdcr_el2 = arm_mdcr_el2_eff(env);
hpmn = mdcr_el2 & MDCR_HPMN;
if (!arm_feature(env, ARM_FEATURE_EL2) || if (!arm_feature(env, ARM_FEATURE_EL2) ||
(counter < hpmn || counter == 31)) { (counter < hpmn || counter == 31)) {
e = env->cp15.c9_pmcr & PMCRE; e = env->cp15.c9_pmcr & PMCRE;
@ -10823,6 +10831,24 @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
} }
if (env->exception.target_el == 2) { if (env->exception.target_el == 2) {
/* Debug exceptions are reported differently on AArch32 */
switch (syn_get_ec(env->exception.syndrome)) {
case EC_BREAKPOINT:
case EC_BREAKPOINT_SAME_EL:
case EC_AA32_BKPT:
case EC_VECTORCATCH:
env->exception.syndrome = syn_insn_abort(arm_current_el(env) == 2,
0, 0, 0x22);
break;
case EC_WATCHPOINT:
env->exception.syndrome = syn_set_ec(env->exception.syndrome,
EC_DATAABORT);
break;
case EC_WATCHPOINT_SAME_EL:
env->exception.syndrome = syn_set_ec(env->exception.syndrome,
EC_DATAABORT_SAME_EL);
break;
}
arm_cpu_do_interrupt_aarch32_hyp(cs); arm_cpu_do_interrupt_aarch32_hyp(cs);
return; return;
} }

View File

@ -1273,7 +1273,7 @@ FIELD(MTEDESC, TBI, 4, 2)
FIELD(MTEDESC, TCMA, 6, 2) FIELD(MTEDESC, TCMA, 6, 2)
FIELD(MTEDESC, WRITE, 8, 1) FIELD(MTEDESC, WRITE, 8, 1)
FIELD(MTEDESC, ALIGN, 9, 3) FIELD(MTEDESC, ALIGN, 9, 3)
FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */ FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr); bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra); uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);

View File

@ -25,6 +25,8 @@
#ifndef TARGET_ARM_SYNDROME_H #ifndef TARGET_ARM_SYNDROME_H
#define TARGET_ARM_SYNDROME_H #define TARGET_ARM_SYNDROME_H
#include "qemu/bitops.h"
/* Valid Syndrome Register EC field values */ /* Valid Syndrome Register EC field values */
enum arm_exception_class { enum arm_exception_class {
EC_UNCATEGORIZED = 0x00, EC_UNCATEGORIZED = 0x00,
@ -80,6 +82,7 @@ typedef enum {
SME_ET_InactiveZA, SME_ET_InactiveZA,
} SMEExceptionType; } SMEExceptionType;
#define ARM_EL_EC_LENGTH 6
#define ARM_EL_EC_SHIFT 26 #define ARM_EL_EC_SHIFT 26
#define ARM_EL_IL_SHIFT 25 #define ARM_EL_IL_SHIFT 25
#define ARM_EL_ISV_SHIFT 24 #define ARM_EL_ISV_SHIFT 24
@ -91,6 +94,11 @@ static inline uint32_t syn_get_ec(uint32_t syn)
return syn >> ARM_EL_EC_SHIFT; return syn >> ARM_EL_EC_SHIFT;
} }
static inline uint32_t syn_set_ec(uint32_t syn, uint32_t ec)
{
return deposit32(syn, ARM_EL_EC_SHIFT, ARM_EL_EC_LENGTH, ec);
}
/* /*
* Utility functions for constructing various kinds of syndrome value. * Utility functions for constructing various kinds of syndrome value.
* Note that in general we follow the AArch64 syndrome values; in a * Note that in general we follow the AArch64 syndrome values; in a

View File

@ -573,8 +573,8 @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
/* Perform gross MTE suppression early. */ /* Perform gross MTE suppression early. */
if (!tbi_check(desc, bit55) || if (!tbi_check(mtedesc, bit55) ||
tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
mtedesc = 0; mtedesc = 0;
} }
@ -750,8 +750,8 @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
/* Perform gross MTE suppression early. */ /* Perform gross MTE suppression early. */
if (!tbi_check(desc, bit55) || if (!tbi_check(mtedesc, bit55) ||
tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
mtedesc = 0; mtedesc = 0;
} }

View File

@ -5800,8 +5800,8 @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
/* Perform gross MTE suppression early. */ /* Perform gross MTE suppression early. */
if (!tbi_check(desc, bit55) || if (!tbi_check(mtedesc, bit55) ||
tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
mtedesc = 0; mtedesc = 0;
} }
@ -6156,8 +6156,8 @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
/* Perform gross MTE suppression early. */ /* Perform gross MTE suppression early. */
if (!tbi_check(desc, bit55) || if (!tbi_check(mtedesc, bit55) ||
tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
mtedesc = 0; mtedesc = 0;
} }
@ -6410,8 +6410,8 @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT); desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
/* Perform gross MTE suppression early. */ /* Perform gross MTE suppression early. */
if (!tbi_check(desc, bit55) || if (!tbi_check(mtedesc, bit55) ||
tcma_check(desc, bit55, allocation_tag_from_addr(addr))) { tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
mtedesc = 0; mtedesc = 0;
} }

View File

@ -28,6 +28,8 @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
bool sve_access_check(DisasContext *s); bool sve_access_check(DisasContext *s);
bool sme_enabled_check(DisasContext *s); bool sme_enabled_check(DisasContext *s);
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned); bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
uint32_t msz, bool is_write, uint32_t data);
/* This function corresponds to CheckStreamingSVEEnabled. */ /* This function corresponds to CheckStreamingSVEEnabled. */
static inline bool sme_sm_enabled_check(DisasContext *s) static inline bool sme_sm_enabled_check(DisasContext *s)

View File

@ -206,7 +206,7 @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
TCGv_ptr t_za, t_pg; TCGv_ptr t_za, t_pg;
TCGv_i64 addr; TCGv_i64 addr;
int svl, desc = 0; uint32_t desc;
bool be = s->be_data == MO_BE; bool be = s->be_data == MO_BE;
bool mte = s->mte_active[0]; bool mte = s->mte_active[0];
@ -224,18 +224,11 @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz); tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn)); tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
if (mte) { if (!mte) {
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
desc <<= SVE_MTEDESC_SHIFT;
} else {
addr = clean_data_tbi(s, addr); addr = clean_data_tbi(s, addr);
} }
svl = streaming_vec_reg_size(s);
desc = simd_desc(svl, svl, desc); desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr, fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
tcg_constant_i32(desc)); tcg_constant_i32(desc));

View File

@ -4437,33 +4437,47 @@ static const uint8_t dtype_esz[16] = {
3, 2, 1, 3 3, 2, 1, 3
}; };
uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
uint32_t msz, bool is_write, uint32_t data)
{
uint32_t sizem1;
uint32_t desc = 0;
/* Assert all of the data fits, with or without MTE enabled. */
assert(nregs >= 1 && nregs <= 4);
sizem1 = (nregs << msz) - 1;
assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
assert(data < 1u << SVE_MTEDESC_SHIFT);
if (s->mte_active[0]) {
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
desc <<= SVE_MTEDESC_SHIFT;
}
return simd_desc(vsz, vsz, desc | data);
}
static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr, static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
int dtype, uint32_t mte_n, bool is_write, int dtype, uint32_t nregs, bool is_write,
gen_helper_gvec_mem *fn) gen_helper_gvec_mem *fn)
{ {
unsigned vsz = vec_full_reg_size(s);
TCGv_ptr t_pg; TCGv_ptr t_pg;
int desc = 0; uint32_t desc;
if (!s->mte_active[0]) {
addr = clean_data_tbi(s, addr);
}
/* /*
* For e.g. LD4, there are not enough arguments to pass all 4 * For e.g. LD4, there are not enough arguments to pass all 4
* registers as pointers, so encode the regno into the data field. * registers as pointers, so encode the regno into the data field.
* For consistency, do this even for LD1. * For consistency, do this even for LD1.
*/ */
if (s->mte_active[0]) { desc = make_svemte_desc(s, vec_full_reg_size(s), nregs,
int msz = dtype_msz(dtype); dtype_msz(dtype), is_write, zt);
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
desc <<= SVE_MTEDESC_SHIFT;
} else {
addr = clean_data_tbi(s, addr);
}
desc = simd_desc(vsz, vsz, zt | desc);
t_pg = tcg_temp_new_ptr(); t_pg = tcg_temp_new_ptr();
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
@ -4600,7 +4614,7 @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
* accessible via the instruction encoding. * accessible via the instruction encoding.
*/ */
assert(fn != NULL); assert(fn != NULL);
do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn); do_mem_zpa(s, zt, pg, addr, dtype, nreg + 1, false, fn);
} }
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a) static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
@ -4847,8 +4861,13 @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr t_pg; TCGv_ptr t_pg;
int poff; int poff;
uint32_t desc;
/* Load the first quadword using the normal predicated load helpers. */ /* Load the first quadword using the normal predicated load helpers. */
if (!s->mte_active[0]) {
addr = clean_data_tbi(s, addr);
}
poff = pred_full_reg_offset(s, pg); poff = pred_full_reg_offset(s, pg);
if (vsz > 16) { if (vsz > 16) {
/* /*
@ -4872,7 +4891,8 @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
gen_helper_gvec_mem *fn gen_helper_gvec_mem *fn
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0]; = ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt))); desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
/* Replicate that first quadword. */ /* Replicate that first quadword. */
if (vsz > 16) { if (vsz > 16) {
@ -4915,6 +4935,7 @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
unsigned vsz_r32; unsigned vsz_r32;
TCGv_ptr t_pg; TCGv_ptr t_pg;
int poff, doff; int poff, doff;
uint32_t desc;
if (vsz < 32) { if (vsz < 32) {
/* /*
@ -4927,6 +4948,9 @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
} }
/* Load the first octaword using the normal predicated load helpers. */ /* Load the first octaword using the normal predicated load helpers. */
if (!s->mte_active[0]) {
addr = clean_data_tbi(s, addr);
}
poff = pred_full_reg_offset(s, pg); poff = pred_full_reg_offset(s, pg);
if (vsz > 32) { if (vsz > 32) {
@ -4951,7 +4975,8 @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
gen_helper_gvec_mem *fn gen_helper_gvec_mem *fn
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0]; = ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt))); desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
/* /*
* Replicate that first octaword. * Replicate that first octaword.
@ -5168,14 +5193,13 @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
if (nreg == 0) { if (nreg == 0) {
/* ST1 */ /* ST1 */
fn = fn_single[s->mte_active[0]][be][msz][esz]; fn = fn_single[s->mte_active[0]][be][msz][esz];
nreg = 1;
} else { } else {
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */ /* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
assert(msz == esz); assert(msz == esz);
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz]; fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
} }
assert(fn != NULL); assert(fn != NULL);
do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn); do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn);
} }
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a) static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
@ -5223,25 +5247,16 @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
int scale, TCGv_i64 scalar, int msz, bool is_write, int scale, TCGv_i64 scalar, int msz, bool is_write,
gen_helper_gvec_mem_scatter *fn) gen_helper_gvec_mem_scatter *fn)
{ {
unsigned vsz = vec_full_reg_size(s);
TCGv_ptr t_zm = tcg_temp_new_ptr(); TCGv_ptr t_zm = tcg_temp_new_ptr();
TCGv_ptr t_pg = tcg_temp_new_ptr(); TCGv_ptr t_pg = tcg_temp_new_ptr();
TCGv_ptr t_zt = tcg_temp_new_ptr(); TCGv_ptr t_zt = tcg_temp_new_ptr();
int desc = 0; uint32_t desc;
if (s->mte_active[0]) {
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
desc <<= SVE_MTEDESC_SHIFT;
}
desc = simd_desc(vsz, vsz, desc | scale);
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm)); tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm));
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt)); tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc)); fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
} }

View File

@ -6927,6 +6927,8 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu)
if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) {
env->features[FEAT_XSAVE_XCR0_LO] = 0; env->features[FEAT_XSAVE_XCR0_LO] = 0;
env->features[FEAT_XSAVE_XCR0_HI] = 0; env->features[FEAT_XSAVE_XCR0_HI] = 0;
env->features[FEAT_XSAVE_XSS_LO] = 0;
env->features[FEAT_XSAVE_XSS_HI] = 0;
return; return;
} }
@ -6945,9 +6947,9 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu)
} }
env->features[FEAT_XSAVE_XCR0_LO] = mask & CPUID_XSTATE_XCR0_MASK; env->features[FEAT_XSAVE_XCR0_LO] = mask & CPUID_XSTATE_XCR0_MASK;
env->features[FEAT_XSAVE_XCR0_HI] = mask >> 32; env->features[FEAT_XSAVE_XCR0_HI] = (mask & CPUID_XSTATE_XCR0_MASK) >> 32;
env->features[FEAT_XSAVE_XSS_LO] = mask & CPUID_XSTATE_XSS_MASK; env->features[FEAT_XSAVE_XSS_LO] = mask & CPUID_XSTATE_XSS_MASK;
env->features[FEAT_XSAVE_XSS_HI] = mask >> 32; env->features[FEAT_XSAVE_XSS_HI] = (mask & CPUID_XSTATE_XSS_MASK) >> 32;
} }
/***** Steps involved on loading and filtering CPUID data /***** Steps involved on loading and filtering CPUID data

View File

@ -2308,6 +2308,12 @@ static inline int cpu_mmu_index(CPUX86State *env, bool ifetch)
? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX; ? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX;
} }
static inline bool is_mmu_index_32(int mmu_index)
{
assert(mmu_index < MMU_PHYS_IDX);
return mmu_index & 1;
}
static inline int cpu_mmu_index_kernel(CPUX86State *env) static inline int cpu_mmu_index_kernel(CPUX86State *env)
{ {
return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX : return !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP_IDX :

View File

@ -1914,6 +1914,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
} }
case 0x1f: case 0x1f:
if (env->nr_dies < 2) { if (env->nr_dies < 2) {
cpuid_i--;
break; break;
} }
/* fallthrough */ /* fallthrough */
@ -1954,7 +1955,6 @@ int kvm_arch_init_vcpu(CPUState *cs)
c = &cpuid_data.entries[cpuid_i++]; c = &cpuid_data.entries[cpuid_i++];
} }
break; break;
case 0x7:
case 0x12: case 0x12:
for (j = 0; ; j++) { for (j = 0; ; j++) {
c->function = i; c->function = i;
@ -1974,6 +1974,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
c = &cpuid_data.entries[cpuid_i++]; c = &cpuid_data.entries[cpuid_i++];
} }
break; break;
case 0x7:
case 0x14: case 0x14:
case 0x1d: case 0x1d:
case 0x1e: { case 0x1e: {

View File

@ -134,7 +134,6 @@ static inline bool ptw_setl(const PTETranslate *in, uint32_t old, uint32_t set)
static bool mmu_translate(CPUX86State *env, const TranslateParams *in, static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
TranslateResult *out, TranslateFault *err) TranslateResult *out, TranslateFault *err)
{ {
const int32_t a20_mask = x86_get_a20_mask(env);
const target_ulong addr = in->addr; const target_ulong addr = in->addr;
const int pg_mode = in->pg_mode; const int pg_mode = in->pg_mode;
const bool is_user = (in->mmu_idx == MMU_USER_IDX); const bool is_user = (in->mmu_idx == MMU_USER_IDX);
@ -164,8 +163,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
/* /*
* Page table level 5 * Page table level 5
*/ */
pte_addr = ((in->cr3 & ~0xfff) + pte_addr = (in->cr3 & ~0xfff) + (((addr >> 48) & 0x1ff) << 3);
(((addr >> 48) & 0x1ff) << 3)) & a20_mask;
if (!ptw_translate(&pte_trans, pte_addr)) { if (!ptw_translate(&pte_trans, pte_addr)) {
return false; return false;
} }
@ -189,8 +187,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
/* /*
* Page table level 4 * Page table level 4
*/ */
pte_addr = ((pte & PG_ADDRESS_MASK) + pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 39) & 0x1ff) << 3);
(((addr >> 39) & 0x1ff) << 3)) & a20_mask;
if (!ptw_translate(&pte_trans, pte_addr)) { if (!ptw_translate(&pte_trans, pte_addr)) {
return false; return false;
} }
@ -210,8 +207,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
/* /*
* Page table level 3 * Page table level 3
*/ */
pte_addr = ((pte & PG_ADDRESS_MASK) + pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3);
(((addr >> 30) & 0x1ff) << 3)) & a20_mask;
if (!ptw_translate(&pte_trans, pte_addr)) { if (!ptw_translate(&pte_trans, pte_addr)) {
return false; return false;
} }
@ -238,7 +234,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
/* /*
* Page table level 3 * Page table level 3
*/ */
pte_addr = ((in->cr3 & ~0x1f) + ((addr >> 27) & 0x18)) & a20_mask; pte_addr = (in->cr3 & 0xffffffe0ULL) + ((addr >> 27) & 0x18);
if (!ptw_translate(&pte_trans, pte_addr)) { if (!ptw_translate(&pte_trans, pte_addr)) {
return false; return false;
} }
@ -260,8 +256,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
/* /*
* Page table level 2 * Page table level 2
*/ */
pte_addr = ((pte & PG_ADDRESS_MASK) + pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3);
(((addr >> 21) & 0x1ff) << 3)) & a20_mask;
if (!ptw_translate(&pte_trans, pte_addr)) { if (!ptw_translate(&pte_trans, pte_addr)) {
return false; return false;
} }
@ -287,8 +282,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
/* /*
* Page table level 1 * Page table level 1
*/ */
pte_addr = ((pte & PG_ADDRESS_MASK) + pte_addr = (pte & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3);
(((addr >> 12) & 0x1ff) << 3)) & a20_mask;
if (!ptw_translate(&pte_trans, pte_addr)) { if (!ptw_translate(&pte_trans, pte_addr)) {
return false; return false;
} }
@ -306,7 +300,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
/* /*
* Page table level 2 * Page table level 2
*/ */
pte_addr = ((in->cr3 & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask; pte_addr = (in->cr3 & 0xfffff000ULL) + ((addr >> 20) & 0xffc);
if (!ptw_translate(&pte_trans, pte_addr)) { if (!ptw_translate(&pte_trans, pte_addr)) {
return false; return false;
} }
@ -335,7 +329,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
/* /*
* Page table level 1 * Page table level 1
*/ */
pte_addr = ((pte & ~0xfffu) + ((addr >> 10) & 0xffc)) & a20_mask; pte_addr = (pte & ~0xfffu) + ((addr >> 10) & 0xffc);
if (!ptw_translate(&pte_trans, pte_addr)) { if (!ptw_translate(&pte_trans, pte_addr)) {
return false; return false;
} }
@ -422,10 +416,13 @@ do_check_protect_pse36:
} }
} }
/* align to page_size */ /* merge offset within page */
paddr = (pte & a20_mask & PG_ADDRESS_MASK & ~(page_size - 1)) paddr = (pte & PG_ADDRESS_MASK & ~(page_size - 1)) | (addr & (page_size - 1));
| (addr & (page_size - 1));
/*
* Note that NPT is walked (for both paging structures and final guest
* addresses) using the address with the A20 bit set.
*/
if (in->ptw_idx == MMU_NESTED_IDX) { if (in->ptw_idx == MMU_NESTED_IDX) {
CPUTLBEntryFull *full; CPUTLBEntryFull *full;
int flags, nested_page_size; int flags, nested_page_size;
@ -464,7 +461,7 @@ do_check_protect_pse36:
} }
} }
out->paddr = paddr; out->paddr = paddr & x86_get_a20_mask(env);
out->prot = prot; out->prot = prot;
out->page_size = page_size; out->page_size = page_size;
return true; return true;
@ -557,6 +554,10 @@ static bool get_physical_address(CPUX86State *env, vaddr addr,
break; break;
default: default:
if (is_mmu_index_32(mmu_idx)) {
addr = (uint32_t)addr;
}
if (likely(env->cr[0] & CR0_PG_MASK)) { if (likely(env->cr[0] & CR0_PG_MASK)) {
in.cr3 = env->cr[3]; in.cr3 = env->cr[3];
in.mmu_idx = mmu_idx; in.mmu_idx = mmu_idx;
@ -580,14 +581,8 @@ static bool get_physical_address(CPUX86State *env, vaddr addr,
break; break;
} }
/* Translation disabled. */ /* No translation needed. */
out->paddr = addr & x86_get_a20_mask(env); out->paddr = addr & x86_get_a20_mask(env);
#ifdef TARGET_X86_64
if (!(env->hflags & HF_LMA_MASK)) {
/* Without long mode we can only address 32bits in real mode */
out->paddr = (uint32_t)out->paddr;
}
#endif
out->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; out->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
out->page_size = TARGET_PAGE_SIZE; out->page_size = TARGET_PAGE_SIZE;
return true; return true;

View File

@ -201,6 +201,9 @@ void helper_wrmsr(CPUX86State *env)
tlb_flush(cs); tlb_flush(cs);
break; break;
case MSR_VM_HSAVE_PA: case MSR_VM_HSAVE_PA:
if (val & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
goto error;
}
env->vm_hsave = val; env->vm_hsave = val;
break; break;
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64

View File

@ -164,14 +164,19 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
uint64_t new_cr3; uint64_t new_cr3;
uint64_t new_cr4; uint64_t new_cr4;
cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0, GETPC());
if (aflag == 2) { if (aflag == 2) {
addr = env->regs[R_EAX]; addr = env->regs[R_EAX];
} else { } else {
addr = (uint32_t)env->regs[R_EAX]; addr = (uint32_t)env->regs[R_EAX];
} }
/* Exceptions are checked before the intercept. */
if (addr & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
}
cpu_svm_check_intercept_param(env, SVM_EXIT_VMRUN, 0, GETPC());
qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmrun! " TARGET_FMT_lx "\n", addr); qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmrun! " TARGET_FMT_lx "\n", addr);
env->vm_vmcb = addr; env->vm_vmcb = addr;
@ -463,14 +468,19 @@ void helper_vmload(CPUX86State *env, int aflag)
int mmu_idx = MMU_PHYS_IDX; int mmu_idx = MMU_PHYS_IDX;
target_ulong addr; target_ulong addr;
cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0, GETPC());
if (aflag == 2) { if (aflag == 2) {
addr = env->regs[R_EAX]; addr = env->regs[R_EAX];
} else { } else {
addr = (uint32_t)env->regs[R_EAX]; addr = (uint32_t)env->regs[R_EAX];
} }
/* Exceptions are checked before the intercept. */
if (addr & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
}
cpu_svm_check_intercept_param(env, SVM_EXIT_VMLOAD, 0, GETPC());
if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMLOAD, GETPC())) { if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMLOAD, GETPC())) {
mmu_idx = MMU_NESTED_IDX; mmu_idx = MMU_NESTED_IDX;
} }
@ -519,14 +529,19 @@ void helper_vmsave(CPUX86State *env, int aflag)
int mmu_idx = MMU_PHYS_IDX; int mmu_idx = MMU_PHYS_IDX;
target_ulong addr; target_ulong addr;
cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0, GETPC());
if (aflag == 2) { if (aflag == 2) {
addr = env->regs[R_EAX]; addr = env->regs[R_EAX];
} else { } else {
addr = (uint32_t)env->regs[R_EAX]; addr = (uint32_t)env->regs[R_EAX];
} }
/* Exceptions are checked before the intercept. */
if (addr & (0xfff | ((~0ULL) << env_archcpu(env)->phys_bits))) {
raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
}
cpu_svm_check_intercept_param(env, SVM_EXIT_VMSAVE, 0, GETPC());
if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMSAVE, GETPC())) { if (virtual_vm_load_save_enabled(env, SVM_EXIT_VMSAVE, GETPC())) {
mmu_idx = MMU_NESTED_IDX; mmu_idx = MMU_NESTED_IDX;
} }

View File

@ -1485,12 +1485,13 @@ static bool check_iopl(DisasContext *s)
/* if d == OR_TMP0, it means memory operand (address in A0) */ /* if d == OR_TMP0, it means memory operand (address in A0) */
static void gen_op(DisasContext *s1, int op, MemOp ot, int d) static void gen_op(DisasContext *s1, int op, MemOp ot, int d)
{ {
if (d != OR_TMP0) { /* Invalid lock prefix when destination is not memory or OP_CMPL. */
if (s1->prefix & PREFIX_LOCK) { if ((d != OR_TMP0 || op == OP_CMPL) && s1->prefix & PREFIX_LOCK) {
/* Lock prefix when destination is not memory. */
gen_illegal_opcode(s1); gen_illegal_opcode(s1);
return; return;
} }
if (d != OR_TMP0) {
gen_op_mov_v_reg(s1, ot, s1->T0, d); gen_op_mov_v_reg(s1, ot, s1->T0, d);
} else if (!(s1->prefix & PREFIX_LOCK)) { } else if (!(s1->prefix & PREFIX_LOCK)) {
gen_op_ld_v(s1, ot, s1->T0, s1->A0); gen_op_ld_v(s1, ot, s1->T0, s1->A0);

View File

@ -1312,6 +1312,10 @@ static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
{ {
CPUPPCState *env = &cpu->env; CPUPPCState *env = &cpu->env;
if (!(env->insns_flags2 & PPC2_ISA310)) {
return false;
}
if (!tcg_enabled()) { if (!tcg_enabled()) {
/* /*
* This does not load instructions and set the prefix bit correctly * This does not load instructions and set the prefix bit correctly
@ -1322,6 +1326,15 @@ static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
} }
switch (excp) { switch (excp) {
case POWERPC_EXCP_MCHECK:
if (!(env->error_code & PPC_BIT(42))) {
/*
* Fetch attempt caused a machine check, so attempting to fetch
* again would cause a recursive machine check.
*/
return false;
}
break;
case POWERPC_EXCP_HDSI: case POWERPC_EXCP_HDSI:
/* HDSI PRTABLE_FAULT has the originating access type in error_code */ /* HDSI PRTABLE_FAULT has the originating access type in error_code */
if ((env->spr[SPR_HDSISR] & DSISR_PRTABLE_FAULT) && if ((env->spr[SPR_HDSISR] & DSISR_PRTABLE_FAULT) &&
@ -1332,10 +1345,10 @@ static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
* instruction at NIP would cause recursive faults with the same * instruction at NIP would cause recursive faults with the same
* translation). * translation).
*/ */
break; return false;
} }
/* fall through */ break;
case POWERPC_EXCP_MCHECK:
case POWERPC_EXCP_DSI: case POWERPC_EXCP_DSI:
case POWERPC_EXCP_DSEG: case POWERPC_EXCP_DSEG:
case POWERPC_EXCP_ALIGN: case POWERPC_EXCP_ALIGN:
@ -1346,17 +1359,13 @@ static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
case POWERPC_EXCP_VPU: case POWERPC_EXCP_VPU:
case POWERPC_EXCP_VSXU: case POWERPC_EXCP_VSXU:
case POWERPC_EXCP_FU: case POWERPC_EXCP_FU:
case POWERPC_EXCP_HV_FU: { case POWERPC_EXCP_HV_FU:
uint32_t insn = ppc_ldl_code(env, env->nip);
if (is_prefix_insn(env, insn)) {
return true;
}
break; break;
}
default: default:
break;
}
return false; return false;
}
return is_prefix_insn(env, ppc_ldl_code(env, env->nip));
} }
#else #else
static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp) static bool is_prefix_insn_excp(PowerPCCPU *cpu, int excp)
@ -3224,6 +3233,7 @@ void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
switch (env->excp_model) { switch (env->excp_model) {
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
case POWERPC_EXCP_POWER8:
case POWERPC_EXCP_POWER9: case POWERPC_EXCP_POWER9:
case POWERPC_EXCP_POWER10: case POWERPC_EXCP_POWER10:
/* /*
@ -3245,6 +3255,10 @@ void ppc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
env->error_code |= PPC_BIT(42); env->error_code |= PPC_BIT(42);
} else { /* Fetch */ } else { /* Fetch */
/*
* is_prefix_insn_excp() tests !PPC_BIT(42) to avoid fetching
* the instruction, so that must always be clear for fetches.
*/
env->error_code = PPC_BIT(36) | PPC_BIT(44) | PPC_BIT(45); env->error_code = PPC_BIT(36) | PPC_BIT(44) | PPC_BIT(45);
} }
break; break;

View File

@ -2268,7 +2268,7 @@ static bool do_lstxv(DisasContext *ctx, int ra, TCGv displ,
static bool do_lstxv_D(DisasContext *ctx, arg_D *a, bool store, bool paired) static bool do_lstxv_D(DisasContext *ctx, arg_D *a, bool store, bool paired)
{ {
if (paired || a->rt >= 32) { if (paired || a->rt < 32) {
REQUIRE_VSX(ctx); REQUIRE_VSX(ctx);
} else { } else {
REQUIRE_VECTOR(ctx); REQUIRE_VECTOR(ctx);

View File

@ -1736,9 +1736,9 @@ static void tcg_out_goto_tb(TCGContext *s, int which)
* shifted immediate from pc. * shifted immediate from pc.
*/ */
int h = -i_disp; int h = -i_disp;
int l = h & 0xfff; int l = -(h & 0xfff);
h = encode_imm_nofail(h - l); h = encode_imm_nofail(h + l);
tcg_out_dat_imm(s, COND_AL, ARITH_SUB, TCG_REG_R0, TCG_REG_PC, h); tcg_out_dat_imm(s, COND_AL, ARITH_SUB, TCG_REG_R0, TCG_REG_PC, h);
tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, l); tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, l);
} }

View File

@ -2327,7 +2327,7 @@ static void tcg_target_init(TCGContext *s)
tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS; tcg_target_available_regs[TCG_TYPE_I32] = ALL_GENERAL_REGS;
tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS; tcg_target_available_regs[TCG_TYPE_I64] = ALL_GENERAL_REGS;
tcg_target_call_clobber_regs = ALL_GENERAL_REGS; tcg_target_call_clobber_regs = ALL_GENERAL_REGS | ALL_VECTOR_REGS;
tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0); tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0);
tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1); tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1);
tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2); tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2);

Binary file not shown.

View File

@ -90,6 +90,7 @@ RUN zypper update -y && \
pcre-devel-static \ pcre-devel-static \
pipewire-devel \ pipewire-devel \
pkgconfig \ pkgconfig \
python311 \
python311-base \ python311-base \
python311-pip \ python311-pip \
python311-setuptools \ python311-setuptools \

View File

@ -59,6 +59,10 @@ mappings:
CentOSStream8: CentOSStream8:
OpenSUSELeap15: OpenSUSELeap15:
python3-sqlite3:
CentOSStream8: python38
OpenSUSELeap15: python311
python3-tomli: python3-tomli:
# test using tomllib # test using tomllib
apk: apk:

View File

@ -97,6 +97,7 @@ packages:
- python3-pip - python3-pip
- python3-sphinx - python3-sphinx
- python3-sphinx-rtd-theme - python3-sphinx-rtd-theme
- python3-sqlite3
- python3-tomli - python3-tomli
- python3-venv - python3-venv
- rpm2cpio - rpm2cpio

View File

@ -83,12 +83,22 @@ echo
echo === Performing block-commit on active layer === echo === Performing block-commit on active layer ===
echo echo
capture_events="BLOCK_JOB_READY JOB_STATUS_CHANGE"
# Block commit on active layer, push the new overlay into base # Block commit on active layer, push the new overlay into base
_send_qemu_cmd $h "{ 'execute': 'block-commit', _send_qemu_cmd $h "{ 'execute': 'block-commit',
'arguments': { 'arguments': {
'device': 'virtio0' 'device': 'virtio0'
} }
}" "READY" }" "return"
_wait_event $h "JOB_STATUS_CHANGE"
_wait_event $h "JOB_STATUS_CHANGE"
_wait_event $h "JOB_STATUS_CHANGE"
_wait_event $h "BLOCK_JOB_READY"
capture_events=
_send_qemu_cmd $h "{ 'execute': 'block-job-complete', _send_qemu_cmd $h "{ 'execute': 'block-job-complete',
'arguments': { 'arguments': {

View File

@ -25,9 +25,9 @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off co
'device': 'virtio0' 'device': 'virtio0'
} }
} }
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "virtio0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "virtio0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "virtio0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "virtio0"}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "virtio0"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "virtio0"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "virtio0", "len": 0, "offset": 0, "speed": 0, "type": "commit"}}
{ 'execute': 'block-job-complete', { 'execute': 'block-job-complete',

View File

@ -184,6 +184,7 @@ if __name__ == '__main__':
sys.exit(str(e)) sys.exit(str(e))
if args.dry_run: if args.dry_run:
with env:
print('\n'.join([os.path.basename(t) for t in tests])) print('\n'.join([os.path.basename(t) for t in tests]))
else: else:
with TestRunner(env, tap=args.tap, with TestRunner(env, tap=args.tap,

View File

@ -126,7 +126,7 @@ class TestEnv(ContextManager['TestEnv']):
self.tmp_sock_dir = False self.tmp_sock_dir = False
Path(self.sock_dir).mkdir(parents=True, exist_ok=True) Path(self.sock_dir).mkdir(parents=True, exist_ok=True)
except KeyError: except KeyError:
self.sock_dir = tempfile.mkdtemp() self.sock_dir = tempfile.mkdtemp(prefix="qemu-iotests-")
self.tmp_sock_dir = True self.tmp_sock_dir = True
self.sample_img_dir = os.getenv('SAMPLE_IMG_DIR', self.sample_img_dir = os.getenv('SAMPLE_IMG_DIR',

View File

@ -333,7 +333,7 @@ if vnc.found()
endif endif
if dbus_display if dbus_display
qtests += {'dbus-display-test': [dbus_display1, gio]} qtests += {'dbus-display-test': [dbus_display1_dep, gio]}
endif endif
qtest_executables = {} qtest_executables = {}

View File

@ -326,6 +326,7 @@ static void test_socket_unix_abstract(void)
test_socket_unix_abstract_row(&matrix[i]); test_socket_unix_abstract_row(&matrix[i]);
} }
unlink(addr.u.q_unix.path);
g_free(addr.u.q_unix.path); g_free(addr.u.q_unix.path);
} }

View File

@ -102,7 +102,7 @@ $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \
$(if $(LOG_CONSOLE),--log-console) \ $(if $(LOG_CONSOLE),--log-console) \
--source-path $(SRC_PATH) \ --source-path $(SRC_PATH) \
--image "$@" \ --image "$@" \
--force \ $(if $(filter-out check-venv, $?), --force) \
--build-image $@, \ --build-image $@, \
" VM-IMAGE $*") " VM-IMAGE $*")

View File

@ -644,9 +644,9 @@ def main(vmcls, config=None):
vm = vmcls(args, config=config) vm = vmcls(args, config=config)
if args.build_image: if args.build_image:
if os.path.exists(args.image) and not args.force: if os.path.exists(args.image) and not args.force:
sys.stderr.writelines(["Image file exists: %s\n" % args.image, sys.stderr.writelines(["Image file exists, skipping build: %s\n" % args.image,
"Use --force option to overwrite\n"]) "Use --force option to overwrite\n"])
return 1 return 0
return vm.build_image(args.image) return vm.build_image(args.image)
if args.build_qemu: if args.build_qemu:
vm.add_source_dir(args.build_qemu) vm.add_source_dir(args.build_qemu)

View File

@ -22,8 +22,8 @@ class OpenBSDVM(basevm.BaseVM):
name = "openbsd" name = "openbsd"
arch = "x86_64" arch = "x86_64"
link = "https://cdn.openbsd.org/pub/OpenBSD/7.2/amd64/install72.iso" link = "https://cdn.openbsd.org/pub/OpenBSD/7.4/amd64/install74.iso"
csum = "0369ef40a3329efcb978c578c7fdc7bda71e502aecec930a74b44160928c91d3" csum = "a1001736ed9fe2307965b5fcdb426ae11f9b80d26eb21e404a705144a0a224a0"
size = "20G" size = "20G"
pkgs = [ pkgs = [
# tools # tools
@ -99,10 +99,10 @@ class OpenBSDVM(basevm.BaseVM):
self.console_wait_send("(I)nstall", "i\n") self.console_wait_send("(I)nstall", "i\n")
self.console_wait_send("Terminal type", "xterm\n") self.console_wait_send("Terminal type", "xterm\n")
self.console_wait_send("System hostname", "openbsd\n") self.console_wait_send("System hostname", "openbsd\n")
self.console_wait_send("Which network interface", "vio0\n") self.console_wait_send("Network interface to configure", "vio0\n")
self.console_wait_send("IPv4 address", "autoconf\n") self.console_wait_send("IPv4 address", "autoconf\n")
self.console_wait_send("IPv6 address", "none\n") self.console_wait_send("IPv6 address", "none\n")
self.console_wait_send("Which network interface", "done\n") self.console_wait_send("Network interface to configure", "done\n")
self.console_wait("Password for root account") self.console_wait("Password for root account")
self.console_send("%s\n" % self._config["root_pass"]) self.console_send("%s\n" % self._config["root_pass"])
self.console_wait("Password for root account") self.console_wait("Password for root account")
@ -124,6 +124,7 @@ class OpenBSDVM(basevm.BaseVM):
self.console_wait_send("Allow root ssh login", "yes\n") self.console_wait_send("Allow root ssh login", "yes\n")
self.console_wait_send("timezone", "UTC\n") self.console_wait_send("timezone", "UTC\n")
self.console_wait_send("root disk", "\n") self.console_wait_send("root disk", "\n")
self.console_wait_send("Encrypt the root disk with a passphrase", "no\n")
self.console_wait_send("(W)hole disk", "\n") self.console_wait_send("(W)hole disk", "\n")
self.console_wait_send("(A)uto layout", "c\n") self.console_wait_send("(A)uto layout", "c\n")

View File

@ -65,12 +65,24 @@ bool qemu_clipboard_check_serial(QemuClipboardInfo *info, bool client)
void qemu_clipboard_update(QemuClipboardInfo *info) void qemu_clipboard_update(QemuClipboardInfo *info)
{ {
uint32_t type;
QemuClipboardNotify notify = { QemuClipboardNotify notify = {
.type = QEMU_CLIPBOARD_UPDATE_INFO, .type = QEMU_CLIPBOARD_UPDATE_INFO,
.info = info, .info = info,
}; };
assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT); assert(info->selection < QEMU_CLIPBOARD_SELECTION__COUNT);
for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
/*
* If data is missing, the clipboard owner's 'request' callback needs to
* be set. Otherwise, there is no way to get the clipboard data and
* qemu_clipboard_request() cannot be called.
*/
if (info->types[type].available && !info->types[type].data) {
assert(info->owner && info->owner->request);
}
}
notifier_list_notify(&clipboard_notifiers, &notify); notifier_list_notify(&clipboard_notifiers, &notify);
if (cbinfo[info->selection] != info) { if (cbinfo[info->selection] != info) {
@ -132,6 +144,8 @@ void qemu_clipboard_request(QemuClipboardInfo *info,
!info->owner) !info->owner)
return; return;
assert(info->owner->request);
info->types[type].requested = true; info->types[type].requested = true;
info->owner->request(info, type); info->owner->request(info, type);
} }
@ -163,9 +177,15 @@ void qemu_clipboard_set_data(QemuClipboardPeer *peer,
} }
g_free(info->types[type].data); g_free(info->types[type].data);
info->types[type].data = g_memdup(data, size); if (size) {
info->types[type].data = g_memdup2(data, size);
info->types[type].size = size; info->types[type].size = size;
info->types[type].available = true; info->types[type].available = true;
} else {
info->types[type].data = NULL;
info->types[type].size = 0;
info->types[type].available = false;
}
if (update) { if (update) {
qemu_clipboard_update(info); qemu_clipboard_update(info);

View File

@ -1577,7 +1577,7 @@ void qemu_console_resize(QemuConsole *s, int width, int height)
assert(QEMU_IS_GRAPHIC_CONSOLE(s)); assert(QEMU_IS_GRAPHIC_CONSOLE(s));
if ((s->scanout.kind != SCANOUT_SURFACE || if ((s->scanout.kind != SCANOUT_SURFACE ||
(surface && surface->flags & QEMU_ALLOCATED_FLAG)) && (surface && !is_buffer_shared(surface) && !is_placeholder(surface))) &&
qemu_console_get_width(s, -1) == width && qemu_console_get_width(s, -1) == width &&
qemu_console_get_height(s, -1) == height) { qemu_console_get_height(s, -1) == height) {
return; return;

View File

@ -92,7 +92,7 @@ if dbus_display
'--c-namespace', 'QemuDBus', '--c-namespace', 'QemuDBus',
'--generate-c-code', '@BASENAME@']) '--generate-c-code', '@BASENAME@'])
dbus_display1_lib = static_library('dbus-display1', dbus_display1, dependencies: gio) dbus_display1_lib = static_library('dbus-display1', dbus_display1, dependencies: gio)
dbus_display1_dep = declare_dependency(link_with: dbus_display1_lib, include_directories: include_directories('.')) dbus_display1_dep = declare_dependency(link_with: dbus_display1_lib, sources: dbus_display1[0])
dbus_ss.add(when: [gio, dbus_display1_dep], dbus_ss.add(when: [gio, dbus_display1_dep],
if_true: [files( if_true: [files(
'dbus-chardev.c', 'dbus-chardev.c',

View File

@ -2445,6 +2445,11 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
} }
if (read_s32(data, 4) < 0) { if (read_s32(data, 4) < 0) {
if (!vnc_has_feature(vs, VNC_FEATURE_CLIPBOARD_EXT)) {
error_report("vnc: extended clipboard message while disabled");
vnc_client_error(vs);
break;
}
if (dlen < 4) { if (dlen < 4) {
error_report("vnc: malformed payload (header less than 4 bytes)" error_report("vnc: malformed payload (header less than 4 bytes)"
" in extended clipboard pseudo-encoding."); " in extended clipboard pseudo-encoding.");