Browse Source

Misc HW patches

- Remove versioned machines released in QEMU 3.1 and 4.0
 - Enable X.Org text rendering on ATI VGA model
 - Various memory leaks / overflows fixed
 - Build using -Wformat-overflow=2 CPPFLAG
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmmu7BAACgkQ4+MsLN6t
 wN4P2RAA2m5XpiwqjyUaaidGQTZi1qNqj3DOl1nOh3XpFCzD4BGUtbJp+06i59iL
 Q8yxFr7jtsNDiRdWC2ow8rWp3aQhqzvsn1hpNFWZoVHWOBsPnHpOmgFINlw3nZA2
 d/boV8aKE/VXhLY8plL3T4oy9rUSiwd7S4rubYjVIr2BVOQaiMKEZvLYUS4ErP5Q
 rhhgj08Z6NhB6fE+kxmi/R1+C8i8mYnCtK2vO9kXoyfdiwFNBpfmaZ6xJ0eSI/v9
 4GVkeEtTkBsvRjbo/S5OQIjUKYsB8y00UnaiO+VRPxVDHqks5eP2WtrZOjOKTs+C
 EaNkhqocMowGRt23JqM0XVaYktjzsXIYTGnRI33hmwL1qbyYK91wzxt5JqwYlpHo
 EGn6YqV4to/1QLSzPr25cETf089ZJ6gqoIPP/I8dwj4Ups+nDaAvRvOKAOTTnyez
 F8zZ+AYe6jhZKKN0iTwoaBUCFt1VgtJ6gSz/GChoALTrEcOGEzBxkfAbzTq9ir8/
 lmO62Rmdrzc8KZiclOyCQM1kOzNH4Jdzy3jEN9cyIQRhf+KVz1uQEqyR4Lb8xmHy
 S9Hts6CTP8yPXh/kL0xAlaY1IDRrkFwuTS52+XjwNyKTQFsOJX6VE2fJgA8ut7Jq
 gNc3sq0G1aCMRqB/1XHvawfSK1o6Olyk1P1i/FUAFzjIxGX0PMw=
 =zL9Q
 -----END PGP SIGNATURE-----

Merge tag 'hw-misc-20260309' of https://github.com/philmd/qemu into staging

Misc HW patches

- Remove versioned machines released in QEMU 3.1 and 4.0
- Enable X.Org text rendering on ATI VGA model
- Various memory leaks / overflows fixed
- Build using -Wformat-overflow=2 CPPFLAG

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmmu7BAACgkQ4+MsLN6t
# wN4P2RAA2m5XpiwqjyUaaidGQTZi1qNqj3DOl1nOh3XpFCzD4BGUtbJp+06i59iL
# Q8yxFr7jtsNDiRdWC2ow8rWp3aQhqzvsn1hpNFWZoVHWOBsPnHpOmgFINlw3nZA2
# d/boV8aKE/VXhLY8plL3T4oy9rUSiwd7S4rubYjVIr2BVOQaiMKEZvLYUS4ErP5Q
# rhhgj08Z6NhB6fE+kxmi/R1+C8i8mYnCtK2vO9kXoyfdiwFNBpfmaZ6xJ0eSI/v9
# 4GVkeEtTkBsvRjbo/S5OQIjUKYsB8y00UnaiO+VRPxVDHqks5eP2WtrZOjOKTs+C
# EaNkhqocMowGRt23JqM0XVaYktjzsXIYTGnRI33hmwL1qbyYK91wzxt5JqwYlpHo
# EGn6YqV4to/1QLSzPr25cETf089ZJ6gqoIPP/I8dwj4Ups+nDaAvRvOKAOTTnyez
# F8zZ+AYe6jhZKKN0iTwoaBUCFt1VgtJ6gSz/GChoALTrEcOGEzBxkfAbzTq9ir8/
# lmO62Rmdrzc8KZiclOyCQM1kOzNH4Jdzy3jEN9cyIQRhf+KVz1uQEqyR4Lb8xmHy
# S9Hts6CTP8yPXh/kL0xAlaY1IDRrkFwuTS52+XjwNyKTQFsOJX6VE2fJgA8ut7Jq
# gNc3sq0G1aCMRqB/1XHvawfSK1o6Olyk1P1i/FUAFzjIxGX0PMw=
# =zL9Q
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon Mar  9 15:49:36 2026 GMT
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD  6BB2 E3E3 2C2C DEAD C0DE

* tag 'hw-misc-20260309' of https://github.com/philmd/qemu: (49 commits)
  hw/misc/riscv_cpc: Free CPU array in instance_finalize
  hw/misc/sifive_e_aon: Don't leak timer
  hw/i3c/dw-i3c: Fix memory leaks in error logging paths
  ati-vga: Do not access pixel outside the screen
  ati-vga: Simplify hw cursor drawing
  ati-vga: Implement HOST_DATA flush to VRAM
  ati-vga: Implement HOST_DATA register writes
  ati-vga: Implement scissor rectangle clipping for 2D operations
  ati-vga: Remove ATIVGAState param from ati_2d_do_blt
  ati-vga: Split ati_2d_do_blt from ati_2d_blt
  ati-vga: Extract setup_2d_blt_ctx from ati_2d_blt
  ati-vga: Introduce ATI2DCtx struct for 2D blit context
  ati-vga: Use local variables for register values in ati_2d_blt
  ati-vga: Remove src and dst stride mutation in ati_2d_blt
  hw: Make qdev_get_printable_name() consistently return freeable string
  hw/qdev: Document qdev_get_dev_path()
  hw/timer/slavio_timer: Free resources allocated in instance_init
  hw/sparc/sun4m: Use qdev GPIOs rather than qemu_allocate_irqs()
  hw/sparc/sun4m: Don't set up dummy cpu interrupts
  hw/net/npcm_gmac: Catch accesses off the end of the register array
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
staging
Peter Maydell 3 weeks ago
parent
commit
31ee190665
  1. 24
      audio/coreaudio.m
  2. 32
      contrib/elf2dmp/main.c
  3. 8
      hw/acpi/piix4.c
  4. 55
      hw/audio/virtio-snd.c
  5. 29
      hw/core/machine.c
  6. 4
      hw/core/qdev.c
  7. 38
      hw/display/ati.c
  8. 441
      hw/display/ati_2d.c
  9. 9
      hw/display/ati_dbg.c
  10. 12
      hw/display/ati_int.h
  11. 13
      hw/display/ati_regs.h
  12. 7
      hw/i2c/pm_smbus.c
  13. 4
      hw/i2c/smbus_eeprom.c
  14. 10
      hw/i2c/smbus_ich9.c
  15. 11
      hw/i386/intel_iommu.c
  16. 2
      hw/i386/microvm.c
  17. 4
      hw/i386/nitro_enclave.c
  18. 34
      hw/i386/pc.c
  19. 36
      hw/i386/pc_piix.c
  20. 39
      hw/i386/pc_q35.c
  21. 6
      hw/i386/x86-common.c
  22. 6
      hw/i3c/dw-i3c.c
  23. 8
      hw/misc/riscv_cpc.c
  24. 16
      hw/misc/sifive_e_aon.c
  25. 14
      hw/net/npcm_gmac.c
  26. 3
      hw/pci-bridge/pcie_root_port.c
  27. 22
      hw/rtc/pl031.c
  28. 34
      hw/sparc/sun4m.c
  29. 9
      hw/timer/hpet.c
  30. 25
      hw/timer/slavio_timer.c
  31. 2
      hw/vfio/pci.c
  32. 5
      hw/virtio/virtio-balloon.c
  33. 12
      hw/virtio/virtio.c
  34. 4
      include/hw/audio/virtio-snd.h
  35. 7
      include/hw/core/boards.h
  36. 39
      include/hw/core/qdev.h
  37. 7
      include/hw/i2c/pm_smbus.h
  38. 1
      include/hw/i386/intel_iommu.h
  39. 2
      include/hw/i386/microvm.h
  40. 9
      include/hw/i386/pc.h
  41. 3
      include/hw/i386/x86.h
  42. 2
      include/hw/misc/sifive_e_aon.h
  43. 3
      include/hw/net/npcm_gmac.h
  44. 3
      include/hw/pci/pcie_port.h
  45. 1
      include/hw/rtc/pl031.h
  46. 1
      include/hw/virtio/virtio-balloon.h
  47. 1
      meson.build
  48. 17
      net/passt.c
  49. 9
      rust/hw/timer/hpet/src/device.rs
  50. 10
      target/i386/cpu.c
  51. 3
      target/i386/cpu.h
  52. 9
      tests/qtest/dbus-display-test.c
  53. 8
      tests/unit/test-qobject-input-visitor.c
  54. 7
      tests/unit/test-qobject-output-visitor.c
  55. 11
      ui/dbus-listener.c

24
audio/coreaudio.m

@ -272,7 +272,7 @@ static int coreaudio_buf_unlock(coreaudioVoiceOut *core, const char *fn_name)
#define COREAUDIO_WRAPPER_FUNC(name, ret_type, args_decl, args) \
static ret_type glue(coreaudio_, name)args_decl \
{ \
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw; \
coreaudioVoiceOut *core = (coreaudioVoiceOut *)hw; \
ret_type ret; \
\
if (coreaudio_buf_lock(core, "coreaudio_" #name)) { \
@ -310,16 +310,16 @@ static OSStatus audioDeviceIOProc(
UInt32 frameCount, pending_frames;
void *out = outOutputData->mBuffers[0].mData;
HWVoiceOut *hw = hwptr;
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hwptr;
coreaudioVoiceOut *core = hwptr;
size_t len;
if (coreaudio_buf_lock (core, "audioDeviceIOProc")) {
if (coreaudio_buf_lock(core, "audioDeviceIOProc")) {
inInputTime = 0;
return 0;
}
if (inDevice != core->outputDeviceID) {
coreaudio_buf_unlock (core, "audioDeviceIOProc(old device)");
coreaudio_buf_unlock(core, "audioDeviceIOProc(old device)");
return 0;
}
@ -329,7 +329,7 @@ static OSStatus audioDeviceIOProc(
/* if there are not enough samples, set signal and return */
if (pending_frames < frameCount) {
inInputTime = 0;
coreaudio_buf_unlock (core, "audioDeviceIOProc(empty)");
coreaudio_buf_unlock(core, "audioDeviceIOProc(empty)");
return 0;
}
@ -349,7 +349,7 @@ static OSStatus audioDeviceIOProc(
out += write_len;
}
coreaudio_buf_unlock (core, "audioDeviceIOProc");
coreaudio_buf_unlock(core, "audioDeviceIOProc");
return 0;
}
@ -394,11 +394,11 @@ static OSStatus init_out_device(coreaudioVoiceOut *core)
}
if (frameRange.mMinimum > core->frameSizeSetting) {
core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMinimum;
core->audioDevicePropertyBufferFrameSize = frameRange.mMinimum;
warn_report("coreaudio: Upsizing buffer frames to %f",
frameRange.mMinimum);
} else if (frameRange.mMaximum < core->frameSizeSetting) {
core->audioDevicePropertyBufferFrameSize = (UInt32) frameRange.mMaximum;
core->audioDevicePropertyBufferFrameSize = frameRange.mMaximum;
warn_report("coreaudio: Downsizing buffer frames to %f",
frameRange.mMaximum);
} else {
@ -563,7 +563,7 @@ static OSStatus handle_voice_change(
static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as)
{
OSStatus status;
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
coreaudioVoiceOut *core = (coreaudioVoiceOut *)hw;
int err;
Audiodev *dev = hw->s->dev;
AudiodevCoreaudioPerDirectionOptions *cpdo = dev->u.coreaudio.out;
@ -579,7 +579,7 @@ static int coreaudio_init_out(HWVoiceOut *hw, struct audsettings *as)
obt_as = *as;
as = &obt_as;
as->fmt = AUDIO_FORMAT_F32;
audio_pcm_init_info (&hw->info, as);
audio_pcm_init_info(&hw->info, as);
core->frameSizeSetting = audio_buffer_frames(
qapi_AudiodevCoreaudioPerDirectionOptions_base(cpdo), as, 11610);
@ -615,7 +615,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
{
OSStatus status;
int err;
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
coreaudioVoiceOut *core = (coreaudioVoiceOut *)hw;
status = AudioObjectRemovePropertyListener(kAudioObjectSystemObject,
&voice_addr,
@ -636,7 +636,7 @@ static void coreaudio_fini_out (HWVoiceOut *hw)
static void coreaudio_enable_out(HWVoiceOut *hw, bool enable)
{
coreaudioVoiceOut *core = (coreaudioVoiceOut *) hw;
coreaudioVoiceOut *core = (coreaudioVoiceOut *)hw;
core->enabled = enable;
update_device_playback_state(core);

32
contrib/elf2dmp/main.c

@ -494,18 +494,6 @@ static bool pe_check_pdb_name(uint64_t base, void *start_addr,
return !strcmp(pdb_name, PDB_NAME);
}
static void pe_get_pdb_symstore_hash(OMFSignatureRSDS *rsds, char *hash)
{
sprintf(hash, "%.08x%.04x%.04x%.02x%.02x", rsds->guid.a, rsds->guid.b,
rsds->guid.c, rsds->guid.d[0], rsds->guid.d[1]);
hash += 20;
for (unsigned int i = 0; i < 6; i++, hash += 2) {
sprintf(hash, "%.02x", rsds->guid.e[i]);
}
sprintf(hash, "%.01x", rsds->age);
}
int main(int argc, char *argv[])
{
int err = 1;
@ -517,9 +505,7 @@ int main(int argc, char *argv[])
uint64_t KernBase;
void *nt_start_addr = NULL;
WinDumpHeader64 header;
char pdb_hash[34];
char pdb_url[] = SYM_URL_BASE PDB_NAME
"/0123456789ABCDEF0123456789ABCDEFx/" PDB_NAME;
g_autofree char *pdb_url = NULL;
struct pdb_reader pdb;
uint64_t KdDebuggerDataBlock;
KDDEBUGGER_DATA64 *kdbg;
@ -583,9 +569,21 @@ int main(int argc, char *argv[])
printf("KernBase = 0x%016"PRIx64", signature is \'%.2s\'\n", KernBase,
(char *)nt_start_addr);
pe_get_pdb_symstore_hash(&rsds, pdb_hash);
pdb_url = g_strdup_printf("%s"
"%.08x%.04x%.04x"
"%.02x%.02x"
"%.02x%.02x"
"%.02x%.02x"
"%.02x%.02x%.01x"
"%s",
SYM_URL_BASE PDB_NAME "/",
rsds.guid.a, rsds.guid.b, rsds.guid.c,
rsds.guid.d[0], rsds.guid.d[1],
rsds.guid.e[0], rsds.guid.e[1],
rsds.guid.e[2], rsds.guid.e[3],
rsds.guid.e[4], rsds.guid.e[5], rsds.age,
"/" PDB_NAME);
sprintf(pdb_url, "%s%s/%s/%s", SYM_URL_BASE, PDB_NAME, pdb_hash, PDB_NAME);
printf("PDB URL is %s\n", pdb_url);
if (!download_url(PDB_NAME, pdb_url)) {

8
hw/acpi/piix4.c

@ -205,11 +205,6 @@ static const VMStateDescription vmstate_cpuhp_state = {
}
};
static bool piix4_vmstate_need_smbus(void *opaque, int version_id)
{
return pm_smbus_vmstate_needed();
}
/*
* This is a fudge to turn off the acpi_index field,
* whose test was always broken on piix4 with 6.2 and older machine types.
@ -238,8 +233,7 @@ static const VMStateDescription vmstate_acpi = {
VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),
VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState),
VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState),
VMSTATE_STRUCT_TEST(smb, PIIX4PMState, piix4_vmstate_need_smbus, 3,
pmsmb_vmstate, PMSMBus),
VMSTATE_STRUCT(smb, PIIX4PMState, 3, pmsmb_vmstate, PMSMBus),
VMSTATE_TIMER_PTR(ar.tmr.timer, PIIX4PMState),
VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState),
VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE),

55
hw/audio/virtio-snd.c

@ -130,7 +130,7 @@ static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound *s,
uint32_t stream_id)
{
return stream_id >= s->snd_conf.streams ? NULL :
s->pcm->streams[stream_id];
s->pcm.streams[stream_id];
}
/*
@ -143,7 +143,7 @@ static virtio_snd_pcm_set_params *virtio_snd_pcm_get_params(VirtIOSound *s,
uint32_t stream_id)
{
return stream_id >= s->snd_conf.streams ? NULL
: &s->pcm->pcm_params[stream_id];
: &s->pcm.pcm_params[stream_id];
}
/*
@ -260,7 +260,7 @@ uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
{
virtio_snd_pcm_set_params *st_params;
if (stream_id >= s->snd_conf.streams || s->pcm->pcm_params == NULL) {
if (stream_id >= s->snd_conf.streams || s->pcm.pcm_params == NULL) {
virtio_error(VIRTIO_DEVICE(s), "Streams have not been initialized.\n");
return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
}
@ -402,10 +402,10 @@ static void virtio_snd_pcm_close(VirtIOSoundPCMStream *stream)
if (stream) {
virtio_snd_pcm_flush(stream);
if (stream->info.direction == VIRTIO_SND_D_OUTPUT) {
audio_be_close_out(stream->pcm->snd->audio_be, stream->voice.out);
audio_be_close_out(stream->s->audio_be, stream->voice.out);
stream->voice.out = NULL;
} else if (stream->info.direction == VIRTIO_SND_D_INPUT) {
audio_be_close_in(stream->pcm->snd->audio_be, stream->voice.in);
audio_be_close_in(stream->s->audio_be, stream->voice.in);
stream->voice.in = NULL;
}
}
@ -424,8 +424,8 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
virtio_snd_pcm_set_params *params;
VirtIOSoundPCMStream *stream;
if (s->pcm->streams == NULL ||
s->pcm->pcm_params == NULL ||
if (s->pcm.streams == NULL ||
s->pcm.pcm_params == NULL ||
stream_id >= s->snd_conf.streams) {
return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
}
@ -440,7 +440,6 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
stream = g_new0(VirtIOSoundPCMStream, 1);
stream->active = false;
stream->id = stream_id;
stream->pcm = s->pcm;
stream->s = s;
stream->latency_bytes = 0;
qemu_mutex_init(&stream->queue_mutex);
@ -450,7 +449,7 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
* stream_id >= s->snd_conf.streams was checked before so this is
* in-bounds
*/
s->pcm->streams[stream_id] = stream;
s->pcm.streams[stream_id] = stream;
}
virtio_snd_get_qemu_audsettings(&as, params);
@ -884,11 +883,11 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
stream_id = le32_to_cpu(hdr.stream_id);
if (stream_id >= vsnd->snd_conf.streams
|| vsnd->pcm->streams[stream_id] == NULL) {
|| vsnd->pcm.streams[stream_id] == NULL) {
goto tx_err;
}
stream = vsnd->pcm->streams[stream_id];
stream = vsnd->pcm.streams[stream_id];
if (stream->info.direction != VIRTIO_SND_D_OUTPUT) {
goto tx_err;
}
@ -966,11 +965,11 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
stream_id = le32_to_cpu(hdr.stream_id);
if (stream_id >= vsnd->snd_conf.streams
|| !vsnd->pcm->streams[stream_id]) {
|| !vsnd->pcm.streams[stream_id]) {
goto rx_err;
}
stream = vsnd->pcm->streams[stream_id];
stream = vsnd->pcm.streams[stream_id];
if (stream == NULL || stream->info.direction != VIRTIO_SND_D_INPUT) {
goto rx_err;
}
@ -1064,11 +1063,9 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
vsnd->vmstate =
qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
vsnd->pcm = g_new0(VirtIOSoundPCM, 1);
vsnd->pcm->snd = vsnd;
vsnd->pcm->streams =
vsnd->pcm.streams =
g_new0(VirtIOSoundPCMStream *, vsnd->snd_conf.streams);
vsnd->pcm->pcm_params =
vsnd->pcm.pcm_params =
g_new0(virtio_snd_pcm_set_params, vsnd->snd_conf.streams);
virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
@ -1335,23 +1332,19 @@ static void virtio_snd_unrealize(DeviceState *dev)
qemu_del_vm_change_state_handler(vsnd->vmstate);
trace_virtio_snd_unrealize(vsnd);
if (vsnd->pcm) {
if (vsnd->pcm->streams) {
for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
stream = vsnd->pcm->streams[i];
if (stream) {
virtio_snd_process_cmdq(stream->s);
virtio_snd_pcm_close(stream);
qemu_mutex_destroy(&stream->queue_mutex);
g_free(stream);
}
if (vsnd->pcm.streams) {
for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
stream = vsnd->pcm.streams[i];
if (stream) {
virtio_snd_process_cmdq(stream->s);
virtio_snd_pcm_close(stream);
qemu_mutex_destroy(&stream->queue_mutex);
g_free(stream);
}
g_free(vsnd->pcm->streams);
}
g_free(vsnd->pcm->pcm_params);
g_free(vsnd->pcm);
vsnd->pcm = NULL;
g_free(vsnd->pcm.streams);
}
g_free(vsnd->pcm.pcm_params);
qemu_mutex_destroy(&vsnd->cmdq_mutex);
virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_CONTROL]);
virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_EVENT]);

29
hw/core/machine.c

@ -209,35 +209,6 @@ GlobalProperty hw_compat_4_1[] = {
};
const size_t hw_compat_4_1_len = G_N_ELEMENTS(hw_compat_4_1);
GlobalProperty hw_compat_4_0[] = {
{ "VGA", "edid", "false" },
{ "secondary-vga", "edid", "false" },
{ "bochs-display", "edid", "false" },
{ "virtio-vga", "edid", "false" },
{ "virtio-gpu-device", "edid", "false" },
{ "virtio-device", "use-started", "false" },
{ "virtio-balloon-device", "qemu-4-0-config-size", "true" },
{ "pl031", "migrate-tick-offset", "false" },
};
const size_t hw_compat_4_0_len = G_N_ELEMENTS(hw_compat_4_0);
GlobalProperty hw_compat_3_1[] = {
{ "pcie-root-port", "x-speed", "2_5" },
{ "pcie-root-port", "x-width", "1" },
{ "memory-backend-file", "x-use-canonical-path-for-ramblock-id", "true" },
{ "memory-backend-memfd", "x-use-canonical-path-for-ramblock-id", "true" },
{ "tpm-crb", "ppi", "false" },
{ "tpm-tis", "ppi", "false" },
{ "usb-kbd", "serial", "42" },
{ "usb-mouse", "serial", "42" },
{ "usb-tablet", "serial", "42" },
{ "virtio-blk-device", "discard", "false" },
{ "virtio-blk-device", "write-zeroes", "false" },
{ "virtio-balloon-device", "qemu-4-0-config-size", "false" },
{ "pcie-root-port-base", "disable-acs", "true" }, /* Added in 4.1 */
};
const size_t hw_compat_3_1_len = G_N_ELEMENTS(hw_compat_3_1);
MachineState *current_machine;
static char *machine_get_kernel(Object *obj, Error **errp)

4
hw/core/qdev.c

@ -420,7 +420,7 @@ const char *qdev_get_printable_name(DeviceState *vdev)
* names.
*/
if (vdev->id) {
return vdev->id;
return g_strdup(vdev->id);
}
/*
* Fall back to the canonical QOM device path (eg. ID for PCI
@ -437,7 +437,7 @@ const char *qdev_get_printable_name(DeviceState *vdev)
* Final fallback: if all else fails, return a placeholder string.
* This ensures the error message always contains a valid string.
*/
return "<unknown device>";
return g_strdup("<unknown device>");
}
void qdev_add_unplug_blocker(DeviceState *dev, Error *reason)

38
hw/display/ati.c

@ -198,7 +198,7 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
ATIVGAState *s = container_of(vga, ATIVGAState, vga);
uint32_t srcoff;
uint32_t *dp = (uint32_t *)d;
int i, j, h;
int i, j, h, idx = 0;
if (!(s->regs.crtc_gen_cntl & CRTC2_CUR_EN) ||
scr_y < vga->hw_cursor_y || scr_y >= vga->hw_cursor_y + 64 ||
@ -213,10 +213,13 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
uint32_t color;
uint8_t abits = vga_read_byte(vga, srcoff + i);
uint8_t xbits = vga_read_byte(vga, srcoff + i + 8);
for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1) {
for (j = 0; j < 8; j++, abits <<= 1, xbits <<= 1, idx++) {
if (vga->hw_cursor_x + idx >= h) {
return; /* end of screen, don't span to next line */
}
if (abits & BIT(7)) {
if (xbits & BIT(7)) {
color = dp[i * 8 + j] ^ 0xffffffff; /* complement */
color = dp[idx] ^ 0xffffffff; /* complement */
} else {
continue; /* transparent, no change */
}
@ -224,10 +227,7 @@ static void ati_cursor_draw_line(VGACommonState *vga, uint8_t *d, int scr_y)
color = (xbits & BIT(7) ? s->regs.cur_color1 :
s->regs.cur_color0) | 0xff000000;
}
if (vga->hw_cursor_x + i * 8 + j >= h) {
return; /* end of screen, don't span to next line */
}
dp[i * 8 + j] = color;
dp[idx] = color;
}
}
}
@ -1023,6 +1023,25 @@ static void ati_mm_write(void *opaque, hwaddr addr,
case SRC_SC_BOTTOM:
s->regs.src_sc_bottom = data & 0x3fff;
break;
case HOST_DATA0:
case HOST_DATA1:
case HOST_DATA2:
case HOST_DATA3:
case HOST_DATA4:
case HOST_DATA5:
case HOST_DATA6:
case HOST_DATA7:
case HOST_DATA_LAST:
if (!s->host_data.active) {
break;
}
s->host_data.acc[s->host_data.next++] = data;
if (addr == HOST_DATA_LAST) {
ati_host_data_finish(s);
} else if (s->host_data.next >= 4) {
ati_host_data_flush(s);
}
break;
default:
break;
}
@ -1128,6 +1147,11 @@ static void ati_vga_reset(DeviceState *dev)
/* reset vga */
vga_common_reset(&s->vga);
s->mode = VGA_MODE;
s->host_data.active = false;
s->host_data.next = 0;
s->host_data.row = 0;
s->host_data.col = 0;
}
static void ati_vga_exit(PCIDevice *dev)

441
hw/display/ati_2d.c

@ -13,6 +13,7 @@
#include "qemu/log.h"
#include "ui/pixel_ops.h"
#include "ui/console.h"
#include "ui/rect.h"
/*
* NOTE:
@ -24,7 +25,7 @@
* possible.
*/
static int ati_bpp_from_datatype(ATIVGAState *s)
static int ati_bpp_from_datatype(const ATIVGAState *s)
{
switch (s->regs.dp_datatype & 0xf) {
case 2:
@ -43,118 +44,182 @@ static int ati_bpp_from_datatype(ATIVGAState *s)
}
}
static void ati_set_dirty(ATIVGAState *s,
const uint8_t *dst_bits, unsigned dst_y)
typedef struct {
int bpp;
uint32_t rop3;
bool host_data_active;
bool left_to_right;
bool top_to_bottom;
uint32_t frgd_clr;
const uint8_t *palette;
const uint8_t *vram_end;
QemuRect scissor;
QemuRect dst;
int dst_stride;
uint8_t *dst_bits;
uint32_t dst_offset;
QemuRect src;
int src_stride;
const uint8_t *src_bits;
} ATI2DCtx;
static void ati_set_dirty(VGACommonState *vga, const ATI2DCtx *ctx)
{
VGACommonState *vga = &s->vga;
DisplaySurface *ds = qemu_console_surface(vga->con);
DPRINTF("%p %u ds: %p %d %d rop: %x\n", vga->vram_ptr, vga->vbe_start_addr,
surface_data(ds), surface_stride(ds), surface_bits_per_pixel(ds),
(s->regs.dp_mix & GMC_ROP3_MASK) >> 16);
if (dst_bits >= vga->vram_ptr + vga->vbe_start_addr &&
dst_bits < vga->vram_ptr + vga->vbe_start_addr +
vga->vbe_regs[VBE_DISPI_INDEX_YRES] * vga->vbe_line_offset) {
ctx->rop3 >> 16);
if (ctx->dst_bits >= vga->vram_ptr + vga->vbe_start_addr &&
ctx->dst_bits < vga->vram_ptr + vga->vbe_start_addr +
vga->vbe_regs[VBE_DISPI_INDEX_YRES] * vga->vbe_line_offset) {
memory_region_set_dirty(&vga->vram,
vga->vbe_start_addr + s->regs.dst_offset
+ dst_y * surface_stride(ds),
s->regs.dst_height * surface_stride(ds));
vga->vbe_start_addr + ctx->dst_offset +
ctx->dst.y * surface_stride(ds),
ctx->dst.height * surface_stride(ds));
}
}
void ati_2d_blt(ATIVGAState *s)
static void setup_2d_blt_ctx(const ATIVGAState *s, ATI2DCtx *ctx)
{
/* FIXME it is probably more complex than this and may need to be */
/* rewritten but for now as a start just to get some output: */
unsigned dst_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
s->regs.dst_x : s->regs.dst_x + 1 - s->regs.dst_width);
unsigned dst_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
s->regs.dst_y : s->regs.dst_y + 1 - s->regs.dst_height);
int bpp = ati_bpp_from_datatype(s);
if (!bpp) {
qemu_log_mask(LOG_GUEST_ERROR, "Invalid bpp\n");
return;
}
int dst_stride = s->regs.dst_pitch;
if (!dst_stride) {
qemu_log_mask(LOG_GUEST_ERROR, "Zero dest pitch\n");
return;
}
uint8_t *dst_bits = s->vga.vram_ptr + s->regs.dst_offset;
ctx->bpp = ati_bpp_from_datatype(s);
ctx->rop3 = s->regs.dp_mix & GMC_ROP3_MASK;
ctx->host_data_active = s->host_data.active;
ctx->left_to_right = s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT;
ctx->top_to_bottom = s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM;
ctx->frgd_clr = s->regs.dp_brush_frgd_clr;
ctx->palette = s->vga.palette;
ctx->dst_offset = s->regs.dst_offset;
ctx->vram_end = s->vga.vram_ptr + s->vga.vram_size;
ctx->scissor.width = s->regs.sc_right - s->regs.sc_left + 1;
ctx->scissor.height = s->regs.sc_bottom - s->regs.sc_top + 1;
ctx->scissor.x = s->regs.sc_left;
ctx->scissor.y = s->regs.sc_top;
ctx->dst.width = s->regs.dst_width;
ctx->dst.height = s->regs.dst_height;
ctx->dst.x = (ctx->left_to_right ?
s->regs.dst_x : s->regs.dst_x + 1 - ctx->dst.width);
ctx->dst.y = (ctx->top_to_bottom ?
s->regs.dst_y : s->regs.dst_y + 1 - ctx->dst.height);
ctx->dst_stride = s->regs.dst_pitch;
ctx->dst_bits = s->vga.vram_ptr + s->regs.dst_offset;
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
dst_bits += s->regs.crtc_offset & 0x07ffffff;
dst_stride *= bpp;
ctx->dst_bits += s->regs.crtc_offset & 0x07ffffff;
ctx->dst_stride *= ctx->bpp;
}
uint8_t *end = s->vga.vram_ptr + s->vga.vram_size;
if (dst_x > 0x3fff || dst_y > 0x3fff || dst_bits >= end
|| dst_bits + dst_x
+ (dst_y + s->regs.dst_height) * dst_stride >= end) {
qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
return;
ctx->src.x = (ctx->left_to_right ?
s->regs.src_x : s->regs.src_x + 1 - ctx->dst.width);
ctx->src.y = (ctx->top_to_bottom ?
s->regs.src_y : s->regs.src_y + 1 - ctx->dst.height);
ctx->src_stride = s->regs.src_pitch;
ctx->src_bits = s->vga.vram_ptr + s->regs.src_offset;
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
ctx->src_bits += s->regs.crtc_offset & 0x07ffffff;
ctx->src_stride *= ctx->bpp;
}
DPRINTF("%d %d %d, %d %d %d, (%d,%d) -> (%d,%d) %dx%d %c %c\n",
s->regs.src_offset, s->regs.dst_offset, s->regs.default_offset,
s->regs.src_pitch, s->regs.dst_pitch, s->regs.default_pitch,
s->regs.src_x, s->regs.src_y, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height,
(s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ? '>' : '<'),
(s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ? 'v' : '^'));
switch (s->regs.dp_mix & GMC_ROP3_MASK) {
ctx->src_stride, ctx->dst_stride, s->regs.default_pitch,
ctx->src.x, ctx->src.y, ctx->dst.x, ctx->dst.y,
ctx->dst.width, ctx->dst.height,
(ctx->left_to_right ? '>' : '<'),
(ctx->top_to_bottom ? 'v' : '^'));
}
static bool ati_2d_do_blt(ATI2DCtx *ctx, uint8_t use_pixman)
{
QemuRect vis_src, vis_dst;
if (!ctx->bpp) {
qemu_log_mask(LOG_GUEST_ERROR, "Invalid bpp\n");
return false;
}
if (!ctx->dst_stride) {
qemu_log_mask(LOG_GUEST_ERROR, "Zero dest pitch\n");
return false;
}
if (ctx->dst.x > 0x3fff || ctx->dst.y > 0x3fff ||
ctx->dst_bits >= ctx->vram_end || ctx->dst_bits + ctx->dst.x +
(ctx->dst.y + ctx->dst.height) * ctx->dst_stride >= ctx->vram_end) {
qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
return false;
}
qemu_rect_intersect(&ctx->dst, &ctx->scissor, &vis_dst);
if (!vis_dst.height || !vis_dst.width) {
/* Nothing is visible, completely clipped */
return false;
}
/*
* The src must be offset if clipping is applied to the dst.
* This is so that when the source is blit to a dst clipped
* on the top or left the src image is not shifted into the
* clipped region but actually clipped.
*/
vis_src.x = ctx->src.x + (vis_dst.x - ctx->dst.x);
vis_src.y = ctx->src.y + (vis_dst.y - ctx->dst.y);
vis_src.width = vis_dst.width;
vis_src.height = vis_dst.height;
DPRINTF("dst: (%d,%d) %dx%d -> vis_dst: (%d,%d) %dx%d\n",
ctx->dst.x, ctx->dst.y, ctx->dst.width, ctx->dst.height,
vis_dst.x, vis_dst.y, vis_dst.width, vis_dst.height);
DPRINTF("src: (%d,%d) %dx%d -> vis_src: (%d,%d) %dx%d\n",
ctx->src.x, ctx->src.y, ctx->dst.width, ctx->dst.height,
vis_src.x, vis_src.y, vis_src.width, vis_src.height);
switch (ctx->rop3) {
case ROP3_SRCCOPY:
{
bool fallback = false;
unsigned src_x = (s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT ?
s->regs.src_x : s->regs.src_x + 1 - s->regs.dst_width);
unsigned src_y = (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM ?
s->regs.src_y : s->regs.src_y + 1 - s->regs.dst_height);
int src_stride = s->regs.src_pitch;
if (!src_stride) {
if (!ctx->src_stride) {
qemu_log_mask(LOG_GUEST_ERROR, "Zero source pitch\n");
return;
}
uint8_t *src_bits = s->vga.vram_ptr + s->regs.src_offset;
if (s->dev_id == PCI_DEVICE_ID_ATI_RAGE128_PF) {
src_bits += s->regs.crtc_offset & 0x07ffffff;
src_stride *= bpp;
return false;
}
if (src_x > 0x3fff || src_y > 0x3fff || src_bits >= end
|| src_bits + src_x
+ (src_y + s->regs.dst_height) * src_stride >= end) {
if (!ctx->host_data_active &&
(vis_src.x > 0x3fff || vis_src.y > 0x3fff ||
ctx->src_bits >= ctx->vram_end || ctx->src_bits + vis_src.x +
(vis_src.y + vis_dst.height) * ctx->src_stride >= ctx->vram_end)) {
qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
return;
return false;
}
src_stride /= sizeof(uint32_t);
dst_stride /= sizeof(uint32_t);
DPRINTF("pixman_blt(%p, %p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n",
src_bits, dst_bits, src_stride, dst_stride, bpp, bpp,
src_x, src_y, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height);
DPRINTF("pixman_blt(%p, %p, %ld, %ld, %d, %d, %d, %d, %d, %d, %d, %d)\n",
ctx->src_bits, ctx->dst_bits,
ctx->src_stride / sizeof(uint32_t),
ctx->dst_stride / sizeof(uint32_t),
ctx->bpp, ctx->bpp, vis_src.x, vis_src.y, vis_dst.x, vis_dst.y,
vis_dst.width, vis_dst.height);
#ifdef CONFIG_PIXMAN
if ((s->use_pixman & BIT(1)) &&
s->regs.dp_cntl & DST_X_LEFT_TO_RIGHT &&
s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) {
fallback = !pixman_blt((uint32_t *)src_bits, (uint32_t *)dst_bits,
src_stride, dst_stride, bpp, bpp,
src_x, src_y, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height);
} else if (s->use_pixman & BIT(1)) {
int src_stride_words = ctx->src_stride / sizeof(uint32_t);
int dst_stride_words = ctx->dst_stride / sizeof(uint32_t);
if ((use_pixman & BIT(1)) &&
ctx->left_to_right && ctx->top_to_bottom) {
fallback = !pixman_blt((uint32_t *)ctx->src_bits,
(uint32_t *)ctx->dst_bits, src_stride_words,
dst_stride_words, ctx->bpp, ctx->bpp,
vis_src.x, vis_src.y, vis_dst.x, vis_dst.y,
vis_dst.width, vis_dst.height);
} else if (use_pixman & BIT(1)) {
/* FIXME: We only really need a temporary if src and dst overlap */
int llb = s->regs.dst_width * (bpp / 8);
int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t));
uint32_t *tmp = g_malloc(tmp_stride * sizeof(uint32_t) *
s->regs.dst_height);
fallback = !pixman_blt((uint32_t *)src_bits, tmp,
src_stride, tmp_stride, bpp, bpp,
src_x, src_y, 0, 0,
s->regs.dst_width, s->regs.dst_height);
int llb = vis_dst.width * (ctx->bpp / 8);
int tmp_stride_words = DIV_ROUND_UP(llb, sizeof(uint32_t));
uint32_t *tmp = g_malloc(tmp_stride_words * sizeof(uint32_t) *
vis_dst.height);
fallback = !pixman_blt((uint32_t *)ctx->src_bits, tmp,
src_stride_words, tmp_stride_words, ctx->bpp,
ctx->bpp, vis_src.x, vis_src.y, 0, 0,
vis_dst.width, vis_dst.height);
if (!fallback) {
fallback = !pixman_blt(tmp, (uint32_t *)dst_bits,
tmp_stride, dst_stride, bpp, bpp,
0, 0, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height);
fallback = !pixman_blt(tmp, (uint32_t *)ctx->dst_bits,
tmp_stride_words, dst_stride_words,
ctx->bpp, ctx->bpp, 0, 0,
vis_dst.x, vis_dst.y,
vis_dst.width, vis_dst.height);
}
g_free(tmp);
} else
@ -163,21 +228,21 @@ void ati_2d_blt(ATIVGAState *s)
fallback = true;
}
if (fallback) {
unsigned int y, i, j, bypp = bpp / 8;
unsigned int src_pitch = src_stride * sizeof(uint32_t);
unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
for (y = 0; y < s->regs.dst_height; y++) {
i = dst_x * bypp;
j = src_x * bypp;
if (s->regs.dp_cntl & DST_Y_TOP_TO_BOTTOM) {
i += (dst_y + y) * dst_pitch;
j += (src_y + y) * src_pitch;
unsigned int y, i, j, bypp = ctx->bpp / 8;
for (y = 0; y < vis_dst.height; y++) {
i = vis_dst.x * bypp;
j = vis_src.x * bypp;
if (ctx->top_to_bottom) {
i += (vis_dst.y + y) * ctx->dst_stride;
j += (vis_src.y + y) * ctx->src_stride;
} else {
i += (dst_y + s->regs.dst_height - 1 - y) * dst_pitch;
j += (src_y + s->regs.dst_height - 1 - y) * src_pitch;
i += (vis_dst.y + vis_dst.height - 1 - y)
* ctx->dst_stride;
j += (vis_src.y + vis_dst.height - 1 - y)
* ctx->src_stride;
}
memmove(&dst_bits[i], &src_bits[j], s->regs.dst_width * bypp);
memmove(&ctx->dst_bits[i], &ctx->src_bits[j],
vis_dst.width * bypp);
}
}
break;
@ -188,37 +253,39 @@ void ati_2d_blt(ATIVGAState *s)
{
uint32_t filler = 0;
switch (s->regs.dp_mix & GMC_ROP3_MASK) {
switch (ctx->rop3) {
case ROP3_PATCOPY:
filler = s->regs.dp_brush_frgd_clr;
filler = ctx->frgd_clr;
break;
case ROP3_BLACKNESS:
filler = 0xffUL << 24 | rgb_to_pixel32(s->vga.palette[0],
s->vga.palette[1], s->vga.palette[2]);
filler = 0xffUL << 24 | rgb_to_pixel32(ctx->palette[0],
ctx->palette[1],
ctx->palette[2]);
break;
case ROP3_WHITENESS:
filler = 0xffUL << 24 | rgb_to_pixel32(s->vga.palette[3],
s->vga.palette[4], s->vga.palette[5]);
filler = 0xffUL << 24 | rgb_to_pixel32(ctx->palette[3],
ctx->palette[4],
ctx->palette[5]);
break;
}
dst_stride /= sizeof(uint32_t);
DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
dst_bits, dst_stride, bpp, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height, filler);
DPRINTF("pixman_fill(%p, %ld, %d, %d, %d, %d, %d, %x)\n",
ctx->dst_bits, ctx->dst_stride / sizeof(uint32_t), ctx->bpp,
vis_dst.x, vis_dst.y, vis_dst.width, vis_dst.height, filler);
#ifdef CONFIG_PIXMAN
if (!(s->use_pixman & BIT(0)) ||
!pixman_fill((uint32_t *)dst_bits, dst_stride, bpp, dst_x, dst_y,
s->regs.dst_width, s->regs.dst_height, filler))
if (!(use_pixman & BIT(0)) ||
!pixman_fill((uint32_t *)ctx->dst_bits,
ctx->dst_stride / sizeof(uint32_t), ctx->bpp,
vis_dst.x, vis_dst.y, vis_dst.width, vis_dst.height,
filler))
#endif
{
/* fallback when pixman failed or we don't want to call it */
unsigned int x, y, i, bypp = bpp / 8;
unsigned int dst_pitch = dst_stride * sizeof(uint32_t);
for (y = 0; y < s->regs.dst_height; y++) {
i = dst_x * bypp + (dst_y + y) * dst_pitch;
for (x = 0; x < s->regs.dst_width; x++, i += bypp) {
stn_he_p(&dst_bits[i], bypp, filler);
unsigned int x, y, i, bypp = ctx->bpp / 8;
for (y = 0; y < vis_dst.height; y++) {
i = vis_dst.x * bypp + (vis_dst.y + y) * ctx->dst_stride;
for (x = 0; x < vis_dst.width; x++, i += bypp) {
stn_he_p(&ctx->dst_bits[i], bypp, filler);
}
}
}
@ -226,9 +293,143 @@ void ati_2d_blt(ATIVGAState *s)
}
default:
qemu_log_mask(LOG_UNIMP, "Unimplemented ati_2d blt op %x\n",
(s->regs.dp_mix & GMC_ROP3_MASK) >> 16);
ctx->rop3 >> 16);
return false;
}
return true;
}
void ati_2d_blt(ATIVGAState *s)
{
ATI2DCtx ctx;
uint32_t src_source = s->regs.dp_mix & DP_SRC_SOURCE;
/* Finish any active HOST_DATA blits before starting a new blit */
ati_host_data_finish(s);
if (src_source == DP_SRC_HOST || src_source == DP_SRC_HOST_BYTEALIGN) {
/* Begin a HOST_DATA blit */
s->host_data.active = true;
s->host_data.next = 0;
s->host_data.col = 0;
s->host_data.row = 0;
return;
}
setup_2d_blt_ctx(s, &ctx);
if (ati_2d_do_blt(&ctx, s->use_pixman)) {
ati_set_dirty(&s->vga, &ctx);
}
}
bool ati_host_data_flush(ATIVGAState *s)
{
ATI2DCtx ctx, chunk;
uint32_t fg = s->regs.dp_src_frgd_clr;
uint32_t bg = s->regs.dp_src_bkgd_clr;
unsigned bypp, pix_count, row, col, idx;
uint8_t pix_buf[ATI_HOST_DATA_ACC_BITS * sizeof(uint32_t)];
uint32_t byte_pix_order = s->regs.dp_datatype & DP_BYTE_PIX_ORDER;
uint32_t src_source = s->regs.dp_mix & DP_SRC_SOURCE;
uint32_t src_datatype = s->regs.dp_datatype & DP_SRC_DATATYPE;
if (!s->host_data.active) {
return false;
}
if (src_source != DP_SRC_HOST) {
qemu_log_mask(LOG_GUEST_ERROR,
"host_data_blt: unsupported src_source %x\n", src_source);
return false;
}
if (src_datatype != SRC_MONO_FRGD_BKGD && src_datatype != SRC_MONO_FRGD &&
src_datatype != SRC_COLOR) {
qemu_log_mask(LOG_GUEST_ERROR,
"host_data_blt: undefined src_datatype %x\n",
src_datatype);
return false;
}
setup_2d_blt_ctx(s, &ctx);
if (!ctx.left_to_right || !ctx.top_to_bottom) {
qemu_log_mask(LOG_UNIMP,
"host_data_blt: unsupported blit direction %c%c\n",
ctx.left_to_right ? '>' : '<',
ctx.top_to_bottom ? 'v' : '^');
return false;
}
bypp = ctx.bpp / 8;
ati_set_dirty(s, dst_bits, dst_y);
if (src_datatype == SRC_COLOR) {
pix_count = ATI_HOST_DATA_ACC_BITS / ctx.bpp;
memcpy(pix_buf, &s->host_data.acc[0], sizeof(s->host_data.acc));
} else {
pix_count = ATI_HOST_DATA_ACC_BITS;
/* Expand monochrome bits to color pixels */
idx = 0;
for (int word = 0; word < 4; word++) {
for (int byte = 0; byte < 4; byte++) {
uint8_t byte_val = s->host_data.acc[word] >> (byte * 8);
for (int i = 0; i < 8; i++) {
bool is_fg = byte_val & BIT(byte_pix_order ? i : 7 - i);
uint32_t color = is_fg ? fg : bg;
stn_he_p(&pix_buf[idx], bypp, color);
idx += bypp;
}
}
}
}
/* Copy and then modify blit ctx for use in a chunked blit */
chunk = ctx;
chunk.src_bits = pix_buf;
chunk.src.y = 0;
chunk.src_stride = ATI_HOST_DATA_ACC_BITS * bypp;
/* Blit one scanline chunk at a time */
row = s->host_data.row;
col = s->host_data.col;
idx = 0;
DPRINTF("blt %dpx @ row: %d, col: %d\n", pix_count, row, col);
while (idx < pix_count && row < ctx.dst.height) {
unsigned pix_in_scanline = MIN(pix_count - idx,
ctx.dst.width - col);
chunk.src.x = idx;
/* Build a rect for this scanline chunk */
chunk.dst.x = ctx.dst.x + col;
chunk.dst.y = ctx.dst.y + row;
chunk.dst.width = pix_in_scanline;
chunk.dst.height = 1;
DPRINTF("blt %dpx span @ row: %d, col: %d to dst (%d,%d)\n",
pix_in_scanline, row, col, chunk.dst.x, chunk.dst.y);
if (ati_2d_do_blt(&chunk, s->use_pixman)) {
ati_set_dirty(&s->vga, &chunk);
}
idx += pix_in_scanline;
col += pix_in_scanline;
if (col >= ctx.dst.width) {
col = 0;
row += 1;
}
}
/* Track state of the overall blit for use by the next flush */
s->host_data.next = 0;
s->host_data.row = row;
s->host_data.col = col;
if (s->host_data.row >= ctx.dst.height) {
s->host_data.active = false;
}
return s->host_data.active;
}
void ati_host_data_finish(ATIVGAState *s)
{
if (ati_host_data_flush(s)) {
qemu_log_mask(LOG_GUEST_ERROR,
"HOST_DATA blit ended before all data was written\n");
}
s->host_data.active = false;
}

9
hw/display/ati_dbg.c

@ -252,6 +252,15 @@ static struct ati_regdesc ati_reg_names[] = {
{"MC_SRC1_CNTL", 0x19D8},
{"TEX_CNTL", 0x1800},
{"RAGE128_MPP_TB_CONFIG", 0x01c0},
{"HOST_DATA0", 0x17c0},
{"HOST_DATA1", 0x17c4},
{"HOST_DATA2", 0x17c8},
{"HOST_DATA3", 0x17cc},
{"HOST_DATA4", 0x17d0},
{"HOST_DATA5", 0x17d4},
{"HOST_DATA6", 0x17d8},
{"HOST_DATA7", 0x17dc},
{"HOST_DATA_LAST", 0x17e0},
{NULL, -1}
};

12
hw/display/ati_int.h

@ -33,6 +33,7 @@
#define ATI_RAGE128_LINEAR_APER_SIZE (64 * MiB)
#define ATI_R100_LINEAR_APER_SIZE (128 * MiB)
#define ATI_HOST_DATA_ACC_BITS 128
#define TYPE_ATI_VGA "ati-vga"
OBJECT_DECLARE_SIMPLE_TYPE(ATIVGAState, ATI_VGA)
@ -96,6 +97,14 @@ typedef struct ATIVGARegs {
uint32_t default_tile;
} ATIVGARegs;
typedef struct ATIHostDataState {
bool active;
uint32_t row;
uint32_t col;
uint32_t next;
uint32_t acc[4];
} ATIHostDataState;
struct ATIVGAState {
PCIDevice dev;
VGACommonState vga;
@ -114,10 +123,13 @@ struct ATIVGAState {
MemoryRegion io;
MemoryRegion mm;
ATIVGARegs regs;
ATIHostDataState host_data;
};
const char *ati_reg_name(int num);
void ati_2d_blt(ATIVGAState *s);
bool ati_host_data_flush(ATIVGAState *s);
void ati_host_data_finish(ATIVGAState *s);
#endif /* ATI_INT_H */

13
hw/display/ati_regs.h

@ -252,6 +252,15 @@
#define DP_T12_CNTL 0x178c
#define DST_BRES_T1_LNTH 0x1790
#define DST_BRES_T2_LNTH 0x1794
#define HOST_DATA0 0x17c0
#define HOST_DATA1 0x17c4
#define HOST_DATA2 0x17c8
#define HOST_DATA3 0x17cc
#define HOST_DATA4 0x17d0
#define HOST_DATA5 0x17d4
#define HOST_DATA6 0x17d8
#define HOST_DATA7 0x17dc
#define HOST_DATA_LAST 0x17e0
#define SCALE_SRC_HEIGHT_WIDTH 0x1994
#define SCALE_OFFSET_0 0x1998
#define SCALE_PITCH 0x199c
@ -388,7 +397,11 @@
#define DST_32BPP 0x00000006
#define DP_DST_DATATYPE 0x0000000f
#define DP_BRUSH_DATATYPE 0x00000f00
#define SRC_MONO_FRGD_BKGD 0x00000000
#define SRC_MONO_FRGD 0x00010000
#define SRC_COLOR 0x00030000
#define DP_SRC_DATATYPE 0x00030000
#define DP_BYTE_PIX_ORDER 0x40000000
#define BRUSH_SOLIDCOLOR 0x00000d00

7
hw/i2c/pm_smbus.c

@ -443,13 +443,6 @@ static const MemoryRegionOps pm_smbus_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
bool pm_smbus_vmstate_needed(void)
{
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
return !mc->smbus_no_migration_support;
}
const VMStateDescription pmsmb_vmstate = {
.name = "pmsmb",
.version_id = 1,

4
hw/i2c/smbus_eeprom.c

@ -88,11 +88,9 @@ static int eeprom_write_data(SMBusDevice *dev, uint8_t *buf, uint8_t len)
static bool smbus_eeprom_vmstate_needed(void *opaque)
{
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
SMBusEEPROMDevice *eeprom = opaque;
return (eeprom->accessed || smbus_vmstate_needed(&eeprom->smbusdev)) &&
!mc->smbus_no_migration_support;
return eeprom->accessed || smbus_vmstate_needed(&eeprom->smbusdev);
}
static const VMStateDescription vmstate_smbus_eeprom = {

10
hw/i2c/smbus_ich9.c

@ -41,20 +41,14 @@ struct ICH9SMBState {
PMSMBus smb;
};
static bool ich9_vmstate_need_smbus(void *opaque, int version_id)
{
return pm_smbus_vmstate_needed();
}
static const VMStateDescription vmstate_ich9_smbus = {
.name = "ich9_smb",
.version_id = 1,
.minimum_version_id = 1,
.fields = (const VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, ICH9SMBState),
VMSTATE_BOOL_TEST(irq_enabled, ICH9SMBState, ich9_vmstate_need_smbus),
VMSTATE_STRUCT_TEST(smb, ICH9SMBState, ich9_vmstate_need_smbus, 1,
pmsmb_vmstate, PMSMBus),
VMSTATE_BOOL(irq_enabled, ICH9SMBState),
VMSTATE_STRUCT(smb, ICH9SMBState, 1, pmsmb_vmstate, PMSMBus),
VMSTATE_END_OF_LIST()
}
};

11
hw/i386/intel_iommu.c

@ -4205,7 +4205,6 @@ static const Property vtd_properties[] = {
DEFINE_PROP_BOOL("snoop-control", IntelIOMMUState, snoop_control, false),
DEFINE_PROP_BOOL("x-pasid-mode", IntelIOMMUState, pasid, false),
DEFINE_PROP_BOOL("svm", IntelIOMMUState, svm, false),
DEFINE_PROP_BOOL("dma-drain", IntelIOMMUState, dma_drain, true),
DEFINE_PROP_BOOL("stale-tm", IntelIOMMUState, stale_tm, false),
DEFINE_PROP_BOOL("fs1gp", IntelIOMMUState, fs1gp, true),
};
@ -5000,11 +4999,8 @@ static void vtd_cap_init(IntelIOMMUState *s)
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_ECAP_PT |
VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SSLPS |
VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SSLPS | VTD_CAP_DRAIN |
VTD_CAP_ESRTPS | VTD_CAP_MGAW(s->aw_bits);
if (s->dma_drain) {
s->cap |= VTD_CAP_DRAIN;
}
if (x86_iommu->dma_translation) {
if (s->aw_bits >= VTD_HOST_AW_39BIT) {
s->cap |= VTD_CAP_SAGAW_39bit;
@ -5582,11 +5578,6 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp)
return false;
}
if (s->scalable_mode && !s->dma_drain) {
error_setg(errp, "Need to set dma_drain for scalable mode");
return false;
}
if (s->pasid && !s->scalable_mode) {
error_setg(errp, "Need to set scalable mode for PASID");
return false;

2
hw/i386/microvm.c

@ -330,7 +330,7 @@ static void microvm_memory_init(MicrovmMachineState *mms)
rom_set_fw(fw_cfg);
if (machine->kernel_filename != NULL) {
mmc->x86_load_linux(x86ms, fw_cfg, 0, true);
mmc->x86_load_linux(x86ms, fw_cfg, 0);
}
if (mms->option_roms) {

4
hw/i386/nitro_enclave.c

@ -164,7 +164,7 @@ static void nitro_enclave_machine_initfn(Object *obj)
}
static void x86_load_eif(X86MachineState *x86ms, FWCfgState *fw_cfg,
int acpi_data_size, bool pvh_enabled)
int acpi_data_size)
{
Error *err = NULL;
char *eif_kernel, *eif_initrd, *eif_cmdline;
@ -199,7 +199,7 @@ static void x86_load_eif(X86MachineState *x86ms, FWCfgState *fw_cfg,
machine->kernel_cmdline = eif_cmdline;
}
x86_load_linux(x86ms, fw_cfg, 0, true);
x86_load_linux(x86ms, fw_cfg, 0);
unlink(machine->kernel_filename);
unlink(machine->initrd_filename);

34
hw/i386/pc.c

@ -177,34 +177,6 @@ const size_t pc_compat_4_2_len = G_N_ELEMENTS(pc_compat_4_2);
GlobalProperty pc_compat_4_1[] = {};
const size_t pc_compat_4_1_len = G_N_ELEMENTS(pc_compat_4_1);
GlobalProperty pc_compat_4_0[] = {};
const size_t pc_compat_4_0_len = G_N_ELEMENTS(pc_compat_4_0);
GlobalProperty pc_compat_3_1[] = {
{ "intel-iommu", "dma-drain", "off" },
{ "Opteron_G3" "-" TYPE_X86_CPU, "rdtscp", "off" },
{ "Opteron_G4" "-" TYPE_X86_CPU, "rdtscp", "off" },
{ "Opteron_G4" "-" TYPE_X86_CPU, "npt", "off" },
{ "Opteron_G4" "-" TYPE_X86_CPU, "nrip-save", "off" },
{ "Opteron_G5" "-" TYPE_X86_CPU, "rdtscp", "off" },
{ "Opteron_G5" "-" TYPE_X86_CPU, "npt", "off" },
{ "Opteron_G5" "-" TYPE_X86_CPU, "nrip-save", "off" },
{ "EPYC" "-" TYPE_X86_CPU, "npt", "off" },
{ "EPYC" "-" TYPE_X86_CPU, "nrip-save", "off" },
{ "EPYC-IBPB" "-" TYPE_X86_CPU, "npt", "off" },
{ "EPYC-IBPB" "-" TYPE_X86_CPU, "nrip-save", "off" },
{ "Skylake-Client" "-" TYPE_X86_CPU, "mpx", "on" },
{ "Skylake-Client-IBRS" "-" TYPE_X86_CPU, "mpx", "on" },
{ "Skylake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
{ "Skylake-Server-IBRS" "-" TYPE_X86_CPU, "mpx", "on" },
{ "Cascadelake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
{ "Icelake-Client" "-" TYPE_X86_CPU, "mpx", "on" },
{ "Icelake-Server" "-" TYPE_X86_CPU, "mpx", "on" },
{ "Cascadelake-Server" "-" TYPE_X86_CPU, "stepping", "5" },
{ TYPE_X86_CPU, "x-intel-pt-auto-level", "off" },
};
const size_t pc_compat_3_1_len = G_N_ELEMENTS(pc_compat_3_1);
/*
* @PC_FW_DATA:
* Size of the chunk of memory at the top of RAM for the BIOS ACPI tables
@ -588,7 +560,6 @@ void xen_load_linux(PCMachineState *pcms)
{
int i;
FWCfgState *fw_cfg;
PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms);
X86MachineState *x86ms = X86_MACHINE(pcms);
assert(MACHINE(pcms)->kernel_filename != NULL);
@ -598,7 +569,7 @@ void xen_load_linux(PCMachineState *pcms)
fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, x86ms->boot_cpus);
rom_set_fw(fw_cfg);
x86_load_linux(x86ms, fw_cfg, PC_FW_DATA, pcmc->pvh_enabled);
x86_load_linux(x86ms, fw_cfg, PC_FW_DATA);
for (i = 0; i < nb_option_roms; i++) {
assert(!strcmp(option_rom[i].name, "linuxboot_dma.bin") ||
!strcmp(option_rom[i].name, "pvh.bin") ||
@ -932,7 +903,7 @@ void pc_memory_init(PCMachineState *pcms,
}
if (linux_boot) {
x86_load_linux(x86ms, fw_cfg, PC_FW_DATA, pcmc->pvh_enabled);
x86_load_linux(x86ms, fw_cfg, PC_FW_DATA);
}
for (i = 0; i < nb_option_roms; i++) {
@ -1673,7 +1644,6 @@ static void pc_machine_class_init(ObjectClass *oc, const void *data)
pcmc->has_reserved_memory = true;
pcmc->enforce_amd_1tb_hole = true;
pcmc->isa_bios_alias = true;
pcmc->pvh_enabled = true;
pcmc->kvmclock_create_always = true;
x86mc->apic_xrupt_override = true;
assert(!mc->get_hotplug_handler);

36
hw/i386/pc_piix.c

@ -644,30 +644,6 @@ static void pc_i440fx_machine_4_1_options(MachineClass *m)
DEFINE_I440FX_MACHINE(4, 1);
static void pc_i440fx_machine_4_0_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_i440fx_machine_4_1_options(m);
pcmc->default_cpu_version = CPU_VERSION_LEGACY;
compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len);
compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len);
}
DEFINE_I440FX_MACHINE(4, 0);
static void pc_i440fx_machine_3_1_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_i440fx_machine_4_0_options(m);
m->smbus_no_migration_support = true;
pcmc->pvh_enabled = false;
compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len);
compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len);
}
DEFINE_I440FX_MACHINE(3, 1);
#ifdef CONFIG_XEN
static void xenfv_machine_4_2_options(MachineClass *m)
{
@ -679,16 +655,4 @@ static void xenfv_machine_4_2_options(MachineClass *m)
DEFINE_PC_MACHINE(xenfv_4_2, "xenfv-4.2", pc_xen_hvm_init,
xenfv_machine_4_2_options);
static void xenfv_machine_3_1_options(MachineClass *m)
{
pc_i440fx_machine_3_1_options(m);
m->desc = "Xen Fully-virtualized PC";
m->alias = "xenfv";
m->max_cpus = HVM_MAX_VCPUS;
m->default_machine_opts = "accel=xen,suppress-vmdesc=on";
}
DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
xenfv_machine_3_1_options);
#endif

39
hw/i386/pc_q35.c

@ -575,42 +575,3 @@ static void pc_q35_machine_4_1_options(MachineClass *m)
}
DEFINE_Q35_MACHINE(4, 1);
static void pc_q35_machine_4_0_1_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_q35_machine_4_1_options(m);
pcmc->default_cpu_version = CPU_VERSION_LEGACY;
/*
* This is the default machine for the 4.0-stable branch. It is basically
* a 4.0 that doesn't use split irqchip by default. It MUST hence apply the
* 4.0 compat props.
*/
compat_props_add(m->compat_props, hw_compat_4_0, hw_compat_4_0_len);
compat_props_add(m->compat_props, pc_compat_4_0, pc_compat_4_0_len);
}
DEFINE_Q35_MACHINE_BUGFIX(4, 0, 1);
static void pc_q35_machine_4_0_options(MachineClass *m)
{
pc_q35_machine_4_0_1_options(m);
m->default_kernel_irqchip_split = true;
/* Compat props are applied by the 4.0.1 machine */
}
DEFINE_Q35_MACHINE(4, 0);
static void pc_q35_machine_3_1_options(MachineClass *m)
{
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
pc_q35_machine_4_0_options(m);
m->default_kernel_irqchip_split = false;
m->smbus_no_migration_support = true;
pcmc->pvh_enabled = false;
compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len);
compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len);
}
DEFINE_Q35_MACHINE(3, 1);

6
hw/i386/x86-common.c

@ -642,8 +642,7 @@ static bool load_elfboot(const char *kernel_filename,
void x86_load_linux(X86MachineState *x86ms,
FWCfgState *fw_cfg,
int acpi_data_size,
bool pvh_enabled)
int acpi_data_size)
{
uint16_t protocol;
int setup_size, kernel_size, cmdline_size;
@ -704,8 +703,7 @@ void x86_load_linux(X86MachineState *x86ms,
* saving the PVH entry point used by the x86/HVM direct boot ABI.
* If load_elfboot() is successful, populate the fw_cfg info.
*/
if (pvh_enabled &&
load_elfboot(kernel_filename, kernel_size,
if (load_elfboot(kernel_filename, kernel_size,
header, pvh_start_addr, fw_cfg)) {
fclose(f);

6
hw/i3c/dw-i3c.c

@ -490,8 +490,9 @@ static int dw_i3c_recv_data(DWI3C *s, bool is_i2c, uint8_t *data,
/* I3C devices can NACK if the controller sends an unsupported CCC. */
ret = i3c_recv(s->bus, data, num_to_read, num_read);
if (ret) {
g_autofree char *path = object_get_canonical_path(OBJECT(s));
qemu_log_mask(LOG_GUEST_ERROR, "%s: NACKed receiving byte\n",
object_get_canonical_path(OBJECT(s)));
path);
ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_ST_STATUS,
DW_I3C_TRANSFER_STATE_HALT);
ARRAY_FIELD_DP32(s->regs, PRESENT_STATE, CM_TFR_STATUS,
@ -1107,8 +1108,9 @@ static void dw_i3c_resp_queue_push(DWI3C *s, uint8_t err, uint8_t tid,
static void dw_i3c_push_tx(DWI3C *s, uint32_t val)
{
if (fifo32_is_full(&s->tx_queue)) {
g_autofree char *path = object_get_canonical_path(OBJECT(s));
qemu_log_mask(LOG_GUEST_ERROR, "%s: Tried to push to TX FIFO when "
"full\n", object_get_canonical_path(OBJECT(s)));
"full\n", path);
return;
}

8
hw/misc/riscv_cpc.c

@ -185,6 +185,13 @@ static void riscv_cpc_init(Object *obj)
}
}
static void riscv_cpc_finalize(Object *obj)
{
RISCVCPCState *s = RISCV_CPC(obj);
g_free(s->cpus);
}
static void riscv_cpc_realize(DeviceState *dev, Error **errp)
{
RISCVCPCState *s = RISCV_CPC(dev);
@ -254,6 +261,7 @@ static const TypeInfo riscv_cpc_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(RISCVCPCState),
.instance_init = riscv_cpc_init,
.instance_finalize = riscv_cpc_finalize,
.class_init = riscv_cpc_class_init,
};

16
hw/misc/sifive_e_aon.c

@ -94,9 +94,9 @@ static void sifive_e_aon_wdt_update_state(SiFiveEAONState *r)
next += muldiv64((r->wdogcmp0 - wdogs) <<
FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, SCALE),
NANOSECONDS_PER_SECOND, r->wdogclk_freq);
timer_mod(r->wdog_timer, next);
timer_mod(&r->wdog_timer, next);
} else {
timer_mod(r->wdog_timer, INT64_MAX);
timer_mod(&r->wdog_timer, INT64_MAX);
}
}
@ -283,12 +283,19 @@ static void sifive_e_aon_init(Object *obj)
sysbus_init_mmio(sbd, &r->mmio);
/* watchdog timer */
r->wdog_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
sifive_e_aon_wdt_expired_cb, r);
timer_init_ns(&r->wdog_timer, QEMU_CLOCK_VIRTUAL,
sifive_e_aon_wdt_expired_cb, r);
r->wdogclk_freq = SIFIVE_E_LFCLK_DEFAULT_FREQ;
sysbus_init_irq(sbd, &r->wdog_irq);
}
static void sifive_e_aon_finalize(Object *obj)
{
SiFiveEAONState *r = SIFIVE_E_AON(obj);
timer_del(&r->wdog_timer);
}
static const Property sifive_e_aon_properties[] = {
DEFINE_PROP_UINT64("wdogclk-frequency", SiFiveEAONState, wdogclk_freq,
SIFIVE_E_LFCLK_DEFAULT_FREQ),
@ -307,6 +314,7 @@ static const TypeInfo sifive_e_aon_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SiFiveEAONState),
.instance_init = sifive_e_aon_init,
.instance_finalize = sifive_e_aon_finalize,
.class_init = sifive_e_aon_class_init,
};

14
hw/net/npcm_gmac.c

@ -700,6 +700,13 @@ static uint64_t npcm_gmac_read(void *opaque, hwaddr offset, unsigned size)
NPCMGMACState *gmac = opaque;
uint32_t v = 0;
if (offset >= NPCM_GMAC_REG_SIZE) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid register offset: 0x%04" HWADDR_PRIx"\n",
DEVICE(gmac)->canonical_path, offset);
return v;
}
switch (offset) {
/* Write only registers */
case A_NPCM_DMA_XMT_POLL_DEMAND:
@ -724,6 +731,13 @@ static void npcm_gmac_write(void *opaque, hwaddr offset,
trace_npcm_gmac_reg_write(DEVICE(gmac)->canonical_path, offset, v);
if (offset >= NPCM_GMAC_REG_SIZE) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: invalid register offset: 0x%04" HWADDR_PRIx"\n",
DEVICE(gmac)->canonical_path, offset);
return;
}
switch (offset) {
/* Read only registers */
case A_NPCM_GMAC_VERSION:

3
hw/pci-bridge/pcie_root_port.c

@ -117,7 +117,7 @@ static void rp_realize(PCIDevice *d, Error **errp)
pcie_aer_root_init(d);
rp_aer_vector_update(d);
if (rpc->acs_offset && !s->disable_acs) {
if (rpc->acs_offset) {
pcie_acs_init(d, rpc->acs_offset);
}
return;
@ -151,7 +151,6 @@ static void rp_exit(PCIDevice *d)
static const Property rp_props[] = {
DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present,
QEMU_PCIE_SLTCAP_PCP_BITNR, true),
DEFINE_PROP_BOOL("disable-acs", PCIESlot, disable_acs, false),
};
static void rp_instance_post_init(Object *obj)

22
hw/rtc/pl031.c

@ -278,18 +278,10 @@ static int pl031_tick_offset_post_load(void *opaque, int version_id)
return 0;
}
static bool pl031_tick_offset_needed(void *opaque)
{
PL031State *s = opaque;
return s->migrate_tick_offset;
}
static const VMStateDescription vmstate_pl031_tick_offset = {
.name = "pl031/tick-offset",
.version_id = 1,
.minimum_version_id = 1,
.needed = pl031_tick_offset_needed,
.post_load = pl031_tick_offset_post_load,
.fields = (const VMStateField[]) {
VMSTATE_UINT32(tick_offset, PL031State),
@ -319,25 +311,11 @@ static const VMStateDescription vmstate_pl031 = {
}
};
static const Property pl031_properties[] = {
/*
* True to correctly migrate the tick offset of the RTC. False to
* obtain backward migration compatibility with older QEMU versions,
* at the expense of the guest RTC going backwards compared with the
* host RTC when the VM is saved/restored if using -rtc host.
* (Even if set to 'true' older QEMU can migrate forward to newer QEMU;
* 'false' also permits newer QEMU to migrate to older QEMU.)
*/
DEFINE_PROP_BOOL("migrate-tick-offset",
PL031State, migrate_tick_offset, true),
};
static void pl031_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->vmsd = &vmstate_pl031;
device_class_set_props(dc, pl031_properties);
}
static const TypeInfo pl031_info = {

34
hw/sparc/sun4m.c

@ -196,10 +196,6 @@ static void cpu_set_irq(void *opaque, int irq, int level)
}
}
static void dummy_cpu_set_irq(void *opaque, int irq, int level)
{
}
static void sun4m_cpu_reset(void *opaque)
{
SPARCCPU *cpu = opaque;
@ -344,7 +340,8 @@ static void *sparc32_dma_init(hwaddr dma_base,
static DeviceState *slavio_intctl_init(hwaddr addr,
hwaddr addrg,
qemu_irq **parent_irq)
unsigned int smp_cpus,
DeviceState **cpus)
{
DeviceState *dev;
SysBusDevice *s;
@ -355,9 +352,10 @@ static DeviceState *slavio_intctl_init(hwaddr addr,
s = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(s, &error_fatal);
for (i = 0; i < MAX_CPUS; i++) {
for (i = 0; i < smp_cpus; i++) {
for (j = 0; j < MAX_PILS; j++) {
sysbus_connect_irq(s, i * MAX_PILS + j, parent_irq[i][j]);
sysbus_connect_irq(s, i * MAX_PILS + j,
qdev_get_gpio_in_named(cpus[i], "pil", j));
}
}
sysbus_mmio_map(s, 0, addrg);
@ -788,22 +786,25 @@ static const TypeInfo ram_info = {
.class_init = ram_class_init,
};
static void cpu_devinit(const char *cpu_type, unsigned int id,
uint64_t prom_addr, qemu_irq **cpu_irqs)
static DeviceState *cpu_devinit(const char *cpu_type, unsigned int id,
uint64_t prom_addr)
{
SPARCCPU *cpu;
CPUSPARCState *env;
DeviceState *cpudev;
cpu = SPARC_CPU(object_new(cpu_type));
env = &cpu->env;
cpudev = DEVICE(cpu);
qemu_register_reset(sun4m_cpu_reset, cpu);
object_property_set_bool(OBJECT(cpu), "start-powered-off", id != 0,
&error_abort);
qdev_realize_and_unref(DEVICE(cpu), NULL, &error_fatal);
qdev_init_gpio_in_named(cpudev, cpu_set_irq, "pil", MAX_PILS);
qdev_realize_and_unref(cpudev, NULL, &error_fatal);
cpu_sparc_set_id(env, id);
*cpu_irqs = qemu_allocate_irqs(cpu_set_irq, cpu, MAX_PILS);
env->prom_addr = prom_addr;
return cpudev;
}
static void dummy_fdc_tc(void *opaque, int irq, int level)
@ -816,13 +817,14 @@ static void sun4m_hw_init(MachineState *machine)
DeviceState *slavio_intctl;
unsigned int i;
Nvram *nvram;
qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
qemu_irq slavio_irq[32], slavio_cpu_irq[MAX_CPUS];
qemu_irq fdc_tc;
unsigned long kernel_size;
uint32_t initrd_size;
DriveInfo *fd[MAX_FD];
FWCfgState *fw_cfg;
DeviceState *dev, *ms_kb_orgate, *serial_orgate;
DeviceState *cpus[MAX_CPUS];
SysBusDevice *s;
unsigned int smp_cpus = machine->smp.cpus;
unsigned int max_cpus = machine->smp.max_cpus;
@ -838,12 +840,9 @@ static void sun4m_hw_init(MachineState *machine)
/* init CPUs */
for(i = 0; i < smp_cpus; i++) {
cpu_devinit(machine->cpu_type, i, hwdef->slavio_base, &cpu_irqs[i]);
cpus[i] = cpu_devinit(machine->cpu_type, i, hwdef->slavio_base);
}
for (i = smp_cpus; i < MAX_CPUS; i++)
cpu_irqs[i] = qemu_allocate_irqs(dummy_cpu_set_irq, NULL, MAX_PILS);
/* Create and map RAM frontend */
dev = qdev_new("memory");
object_property_set_link(OBJECT(dev), "memdev", OBJECT(ram_memdev), &error_fatal);
@ -860,7 +859,8 @@ static void sun4m_hw_init(MachineState *machine)
slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
hwdef->intctl_base + 0x10000ULL,
cpu_irqs);
smp_cpus,
cpus);
for (i = 0; i < 32; i++) {
slavio_irq[i] = qdev_get_gpio_in(slavio_intctl, i);

9
hw/timer/hpet.c

@ -75,7 +75,6 @@ struct HPETState {
QemuMutex lock;
MemoryRegion iomem;
uint64_t hpet_offset;
bool hpet_offset_saved;
QemuSeqLock state_version;
qemu_irq irqs[HPET_NUM_IRQ_ROUTES];
uint32_t flags;
@ -272,11 +271,6 @@ static int hpet_post_load(void *opaque, int version_id)
t->cmp64 = hpet_calculate_cmp64(t, s->hpet_counter, t->cmp);
t->last = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - NANOSECONDS_PER_SECOND;
}
/* Recalculate the offset between the main counter and guest time */
if (!s->hpet_offset_saved) {
s->hpet_offset = ticks_to_ns(s->hpet_counter)
- qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
}
return 0;
}
@ -285,7 +279,7 @@ static bool hpet_offset_needed(void *opaque)
{
HPETState *s = opaque;
return hpet_enabled(s) && s->hpet_offset_saved;
return hpet_enabled(s);
}
static bool hpet_rtc_irq_level_needed(void *opaque)
@ -766,7 +760,6 @@ static const Property hpet_device_properties[] = {
DEFINE_PROP_UINT8("timers", HPETState, num_timers, HPET_MIN_TIMERS),
DEFINE_PROP_BIT("msi", HPETState, flags, HPET_MSI_SUPPORT, false),
DEFINE_PROP_UINT32(HPET_INTCAP, HPETState, intcap, 0),
DEFINE_PROP_BOOL("hpet-offset-saved", HPETState, hpet_offset_saved, true),
};
static void hpet_device_class_init(ObjectClass *klass, const void *data)

25
hw/timer/slavio_timer.c

@ -62,20 +62,21 @@ typedef struct CPUTimerState {
#define TYPE_SLAVIO_TIMER "slavio_timer"
OBJECT_DECLARE_SIMPLE_TYPE(SLAVIO_TIMERState, SLAVIO_TIMER)
typedef struct TimerContext {
MemoryRegion iomem;
SLAVIO_TIMERState *s;
unsigned int timer_index; /* 0 for system, 1 ... MAX_CPUS for CPU timers */
} TimerContext;
struct SLAVIO_TIMERState {
SysBusDevice parent_obj;
uint32_t num_cpus;
uint32_t cputimer_mode;
CPUTimerState cputimer[MAX_CPUS + 1];
TimerContext timer_context[MAX_CPUS + 1];
};
typedef struct TimerContext {
MemoryRegion iomem;
SLAVIO_TIMERState *s;
unsigned int timer_index; /* 0 for system, 1 ... MAX_CPUS for CPU timers */
} TimerContext;
#define SYS_TIMER_SIZE 0x14
#define CPU_TIMER_SIZE 0x10
@ -400,7 +401,7 @@ static void slavio_timer_init(Object *obj)
uint64_t size;
char timer_name[20];
tc = g_new0(TimerContext, 1);
tc = &s->timer_context[i];
tc->s = s;
tc->timer_index = i;
@ -420,6 +421,15 @@ static void slavio_timer_init(Object *obj)
}
}
static void slavio_timer_finalize(Object *obj)
{
SLAVIO_TIMERState *s = SLAVIO_TIMER(obj);
for (int i = 0; i <= MAX_CPUS; i++) {
ptimer_free(s->cputimer[i].timer);
}
}
static const Property slavio_timer_properties[] = {
DEFINE_PROP_UINT32("num_cpus", SLAVIO_TIMERState, num_cpus, 0),
};
@ -438,6 +448,7 @@ static const TypeInfo slavio_timer_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SLAVIO_TIMERState),
.instance_init = slavio_timer_init,
.instance_finalize = slavio_timer_finalize,
.class_init = slavio_timer_class_init,
};

2
hw/vfio/pci.c

@ -2739,7 +2739,7 @@ void vfio_pci_post_reset(VFIOPCIDevice *vdev)
bool vfio_pci_host_match(PCIHostDeviceAddress *addr, const char *name)
{
char tmp[13];
char tmp[36];
sprintf(tmp, "%04x:%02x:%02x.%1x", addr->domain,
addr->bus, addr->slot, addr->function);

5
hw/virtio/virtio-balloon.c

@ -708,9 +708,6 @@ static size_t virtio_balloon_config_size(VirtIOBalloon *s)
{
uint64_t features = s->host_features;
if (s->qemu_4_0_config_size) {
return sizeof(struct virtio_balloon_config);
}
if (virtio_has_feature(features, VIRTIO_BALLOON_F_PAGE_POISON)) {
return sizeof(struct virtio_balloon_config);
}
@ -1054,8 +1051,6 @@ static const Property virtio_balloon_properties[] = {
* is disabled, resulting in QEMU 3.1 migration incompatibility. This
* property retains this quirk for QEMU 4.1 machine types.
*/
DEFINE_PROP_BOOL("qemu-4-0-config-size", VirtIOBalloon,
qemu_4_0_config_size, false),
DEFINE_PROP_LINK("iothread", VirtIOBalloon, iothread, TYPE_IOTHREAD,
IOThread *),
};

12
hw/virtio/virtio.c

@ -281,10 +281,12 @@ void virtio_init_region_cache(VirtIODevice *vdev, int n)
len = address_space_cache_init(&new->desc, vdev->dma_as,
addr, size, packed);
if (len < size) {
g_autofree const char *devname = qdev_get_printable_name(DEVICE(vdev));
virtio_error(vdev,
"Failed to map descriptor ring for device %s: "
"invalid guest physical address or corrupted queue setup",
qdev_get_printable_name(DEVICE(vdev)));
devname);
goto err_desc;
}
@ -292,10 +294,12 @@ void virtio_init_region_cache(VirtIODevice *vdev, int n)
len = address_space_cache_init(&new->used, vdev->dma_as,
vq->vring.used, size, true);
if (len < size) {
g_autofree const char *devname = qdev_get_printable_name(DEVICE(vdev));
virtio_error(vdev,
"Failed to map used ring for device %s: "
"possible guest misconfiguration or insufficient memory",
qdev_get_printable_name(DEVICE(vdev)));
devname);
goto err_used;
}
@ -303,10 +307,12 @@ void virtio_init_region_cache(VirtIODevice *vdev, int n)
len = address_space_cache_init(&new->avail, vdev->dma_as,
vq->vring.avail, size, false);
if (len < size) {
g_autofree const char *devname = qdev_get_printable_name(DEVICE(vdev));
virtio_error(vdev,
"Failed to map avalaible ring for device %s: "
"possible queue misconfiguration or overlapping memory region",
qdev_get_printable_name(DEVICE(vdev)));
devname);
goto err_avail;
}

4
include/hw/audio/virtio-snd.h

@ -122,7 +122,6 @@ struct VirtIOSoundPCMBuffer {
};
struct VirtIOSoundPCM {
VirtIOSound *snd;
/*
* PCM parameters are a separate field instead of a VirtIOSoundPCMStream
* field, because the operation of PCM control requests is first
@ -135,7 +134,6 @@ struct VirtIOSoundPCM {
};
struct VirtIOSoundPCMStream {
VirtIOSoundPCM *pcm;
virtio_snd_pcm_info info;
virtio_snd_pcm_set_params params;
uint32_t id;
@ -216,7 +214,7 @@ struct VirtIOSound {
VirtQueue *queues[VIRTIO_SND_VQ_MAX];
uint64_t features;
VirtIOSoundPCM *pcm;
VirtIOSoundPCM pcm;
AudioBackend *audio_be;
VMChangeStateEntry *vmstate;
virtio_snd_config snd_conf;

7
include/hw/core/boards.h

@ -314,7 +314,6 @@ struct MachineClass {
bool auto_enable_numa_with_memhp;
bool auto_enable_numa_with_memdev;
bool ignore_boot_device_suffixes;
bool smbus_no_migration_support;
bool nvdimm_supported;
bool numa_mem_supported;
bool auto_enable_numa;
@ -865,10 +864,4 @@ extern const size_t hw_compat_4_2_len;
extern GlobalProperty hw_compat_4_1[];
extern const size_t hw_compat_4_1_len;
extern GlobalProperty hw_compat_4_0[];
extern const size_t hw_compat_4_0_len;
extern GlobalProperty hw_compat_3_1[];
extern const size_t hw_compat_3_1_len;
#endif

39
include/hw/core/qdev.h

@ -324,6 +324,10 @@ struct BusClass {
/* FIXME first arg should be BusState */
void (*print_dev)(Monitor *mon, DeviceState *dev, int indent);
/*
* Return a newly allocated string containing the path of the
* device on this bus.
*/
char *(*get_dev_path)(DeviceState *dev);
/*
@ -1060,7 +1064,42 @@ bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp);
extern bool qdev_hot_removed;
/**
* qdev_get_dev_path(): Return the path of a device on its bus
* @dev: device to get the path of
*
* Returns: A newly allocated string containing the dev path of
* @dev. The caller must free this with g_free().
* The format of the string depends on the bus; for instance a
* PCI device's path will be in the format::
*
* Domain:00:Slot.Function:Slot.Function....:Slot.Function
*
* and a SCSI device's path will be::
*
* channel:ID:LUN
*
* (possibly prefixed by the path of the SCSI controller).
*
* If @dev is NULL or not on a bus, returns NULL.
*/
char *qdev_get_dev_path(DeviceState *dev);
/**
* qdev_get_printable_name: Return human readable name for device
* @dev: Device to get name of
*
* Returns: A newly allocated string containing some human
* readable name for the device, suitable for printing in
* user-facing error messages. The function will never return NULL,
* so the name can be used without further checking or fallbacks.
*
* If the device has an explicitly set ID (e.g. by the user on the
* command line via "-device thisdev,id=myid") this is preferred.
* Otherwise we try the canonical QOM device path (which will be
* the PCI ID for PCI devices, for example). If all else fails
* we will return the placeholder "<unknown device">.
*/
const char *qdev_get_printable_name(DeviceState *dev);
void qbus_set_hotplug_handler(BusState *bus, Object *handler);

7
include/hw/i2c/pm_smbus.h

@ -44,13 +44,6 @@ typedef struct PMSMBus {
void pm_smbus_init(DeviceState *parent, PMSMBus *smb, bool force_aux_blk);
/*
* For backwards compatibility on migration, older versions don't have
* working migration for pm_smbus, this lets us ignore the migrations
* for older machine versions.
*/
bool pm_smbus_vmstate_needed(void);
extern const VMStateDescription pmsmb_vmstate;
#endif /* PM_SMBUS_H */

1
include/hw/i386/intel_iommu.h

@ -314,7 +314,6 @@ struct IntelIOMMUState {
bool intr_eime; /* Extended interrupt mode enabled */
OnOffAuto intr_eim; /* Toggle for EIM cabability */
uint8_t aw_bits; /* Host/IOVA address width (in bits) */
bool dma_drain; /* Whether DMA r/w draining enabled */
bool pasid; /* Whether to support PASID */
bool fs1gp; /* First Stage 1-GByte Page Support */

2
include/hw/i386/microvm.h

@ -79,7 +79,7 @@ struct MicrovmMachineClass {
HotplugHandler *(*orig_hotplug_handler)(MachineState *machine,
DeviceState *dev);
void (*x86_load_linux)(X86MachineState *x86ms, FWCfgState *fw_cfg,
int acpi_data_size, bool pvh_enabled);
int acpi_data_size);
};
struct MicrovmMachineState {

9
include/hw/i386/pc.h

@ -110,9 +110,6 @@ struct PCMachineClass {
bool enforce_amd_1tb_hole;
bool isa_bios_alias;
/* use PVH to load kernels that support this feature */
bool pvh_enabled;
/* create kvmclock device even when KVM PV features are not exposed */
bool kvmclock_create_always;
@ -271,12 +268,6 @@ extern const size_t pc_compat_4_2_len;
extern GlobalProperty pc_compat_4_1[];
extern const size_t pc_compat_4_1_len;
extern GlobalProperty pc_compat_4_0[];
extern const size_t pc_compat_4_0_len;
extern GlobalProperty pc_compat_3_1[];
extern const size_t pc_compat_3_1_len;
#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
static void pc_machine_##suffix##_class_init(ObjectClass *oc, \
const void *data) \

3
include/hw/i386/x86.h

@ -129,8 +129,7 @@ void x86_bios_rom_reload(X86MachineState *x86ms);
void x86_load_linux(X86MachineState *x86ms,
FWCfgState *fw_cfg,
int acpi_data_size,
bool pvh_enabled);
int acpi_data_size);
bool x86_machine_is_smm_enabled(const X86MachineState *x86ms);
bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms);

2
include/hw/misc/sifive_e_aon.h

@ -46,7 +46,7 @@ struct SiFiveEAONState {
MemoryRegion mmio;
/*< watchdog timer >*/
QEMUTimer *wdog_timer;
QEMUTimer wdog_timer;
qemu_irq wdog_irq;
uint64_t wdog_restart_time;
uint64_t wdogclk_freq;

3
include/hw/net/npcm_gmac.h

@ -24,7 +24,8 @@
#include "hw/core/sysbus.h"
#include "net/net.h"
#define NPCM_GMAC_NR_REGS (0x1060 / sizeof(uint32_t))
#define NPCM_GMAC_REG_SIZE 0x1060
#define NPCM_GMAC_NR_REGS (NPCM_GMAC_REG_SIZE / sizeof(uint32_t))
#define NPCM_GMAC_MAX_PHYS 32
#define NPCM_GMAC_MAX_PHY_REGS 32

3
include/hw/pci/pcie_port.h

@ -60,9 +60,6 @@ struct PCIESlot {
PCIExpLinkWidth width;
bool flitmode;
/* Disable ACS (really for a pcie_root_port) */
bool disable_acs;
/* Indicates whether any type of hot-plug is allowed on the slot */
bool hotplug;

1
include/hw/rtc/pl031.h

@ -36,7 +36,6 @@ struct PL031State {
uint32_t tick_offset_vmstate;
uint32_t tick_offset;
bool tick_offset_migrated;
bool migrate_tick_offset;
uint32_t mr;
uint32_t lr;

1
include/hw/virtio/virtio-balloon.h

@ -70,7 +70,6 @@ struct VirtIOBalloon {
int64_t stats_poll_interval;
uint32_t host_features;
bool qemu_4_0_config_size;
uint32_t poison_val;
/* State of the resettable container */

1
meson.build

@ -694,6 +694,7 @@ warn_flags = [
'-Wempty-body',
'-Wendif-labels',
'-Wexpansion-to-defined',
'-Wformat-overflow=2',
'-Wformat-security',
'-Wformat-y2k',
'-Wignored-qualifiers',

17
net/passt.c

@ -102,7 +102,9 @@ static void net_passt_cleanup(NetClientState *nc)
}
#endif
kill(s->pid, SIGTERM);
if (s->pid > 0) {
kill(s->pid, SIGTERM);
}
if (g_remove(s->pidfile) != 0) {
warn_report("Failed to remove passt pidfile %s: %s",
s->pidfile, strerror(errno));
@ -268,8 +270,17 @@ static int net_passt_start_daemon(NetPasstState *s, int sock, Error **errp)
return -1;
}
if (g_subprocess_get_if_exited(daemon) &&
g_subprocess_get_exit_status(daemon)) {
if (g_subprocess_get_if_exited(daemon)) {
gint status = g_subprocess_get_exit_status(daemon);
if (status) {
error_setg(errp, "Passt exited with code %d", status);
return -1;
}
}
if (g_subprocess_get_if_signaled(daemon)) {
error_setg(errp, "Passt killed with signal %d",
g_subprocess_get_term_sig(daemon));
return -1;
}

9
rust/hw/timer/hpet/src/device.rs

@ -627,8 +627,6 @@ pub struct HPETState {
flags: u32,
hpet_offset_migration: BqlCell<u64>,
#[property(rename = "hpet-offset-saved", default = true)]
hpet_offset_saved: bool,
irqs: [InterruptSource; HPET_NUM_IRQ_ROUTES],
rtc_irq_level: BqlCell<u32>,
@ -947,11 +945,6 @@ impl HPETState {
tn_regs.last = CLOCK_VIRTUAL.get_ns() - NANOSECONDS_PER_SECOND;
}
// Recalculate the offset between the main counter and guest time
if !self.hpet_offset_saved {
self.hpet_offset_migration
.set(ticks_to_ns(regs.counter) - CLOCK_VIRTUAL.get_ns());
}
regs.hpet_offset = self.hpet_offset_migration.get();
Ok(())
@ -962,7 +955,7 @@ impl HPETState {
}
fn is_offset_needed(&self) -> bool {
self.regs.borrow().is_hpet_enabled() && self.hpet_offset_saved
self.regs.borrow().is_hpet_enabled()
}
fn validate_num_timers(&self, _version_id: u8) -> bool {

10
target/i386/cpu.c

@ -9565,13 +9565,7 @@ void x86_cpu_expand_features(X86CPU *cpu, Error **errp)
/* Intel Processor Trace requires CPUID[0x14] */
if ((env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_INTEL_PT)) {
if (cpu->intel_pt_auto_level) {
x86_cpu_adjust_level(cpu, &cpu->env.cpuid_min_level, 0x14);
} else if (cpu->env.cpuid_min_level < 0x14) {
mark_unavailable_features(cpu, FEAT_7_0_EBX,
CPUID_7_0_EBX_INTEL_PT,
"Intel PT need CPUID leaf 0x14, please set by \"-cpu ...,intel-pt=on,min-level=0x14\"");
}
x86_cpu_adjust_level(cpu, &cpu->env.cpuid_min_level, 0x14);
}
/*
@ -10589,8 +10583,6 @@ static const Property x86_cpu_properties[] = {
* to the specific Windows version being used."
*/
DEFINE_PROP_INT32("x-hv-max-vps", X86CPU, hv_max_vps, -1),
DEFINE_PROP_BOOL("x-intel-pt-auto-level", X86CPU, intel_pt_auto_level,
true),
DEFINE_PROP_BOOL("x-l1-cache-per-thread", X86CPU, l1_cache_per_core, true),
DEFINE_PROP_BOOL("x-force-cpuid-0x1f", X86CPU, force_cpuid_0x1f, false),

3
target/i386/cpu.h

@ -2457,9 +2457,6 @@ struct ArchCPU {
/* Only advertise TOPOEXT features that AMD defines */
bool amd_topoext_features_only;
/* Enable auto level-increase for Intel Processor Trace leave */
bool intel_pt_auto_level;
/* if true fill the top bits of the MTRR_PHYSMASKn variable range */
bool fill_mtrr_mask;

9
tests/qtest/dbus-display-test.c

@ -76,6 +76,7 @@ test_dbus_display_vm(void)
qemu_dbus_display1_vm_get_name(QEMU_DBUS_DISPLAY1_VM(vm)),
==,
"dbus-test");
g_clear_object(&conn);
qtest_quit(qts);
}
@ -97,6 +98,8 @@ static gboolean listener_handle_scanout(
GVariant *arg_data,
TestDBusConsoleRegister *test)
{
qemu_dbus_display1_listener_complete_scanout(object, invocation);
if (!test->with_map) {
g_main_loop_quit(test->loop);
}
@ -131,6 +134,9 @@ static gboolean listener_handle_scanout_map(
g_assert_no_errno(addr == MAP_FAILED ? -1 : 0);
g_assert_no_errno(munmap(addr, len));
qemu_dbus_display1_listener_unix_map_complete_scanout_map(object, invocation,
NULL);
g_main_loop_quit(test->loop);
close(fd);
@ -287,6 +293,7 @@ test_dbus_display_console(const void* data)
g_clear_object(&test.server);
g_clear_object(&test.listener_conn);
g_clear_object(&conn);
qtest_quit(qts);
}
@ -322,6 +329,7 @@ test_dbus_display_keyboard(void)
&err);
if (g_error_matches(err, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) {
g_test_skip("The VM doesn't have a console!");
g_clear_object(&conn);
qtest_quit(qts);
return;
}
@ -348,6 +356,7 @@ test_dbus_display_keyboard(void)
g_assert_cmpint(qemu_dbus_display1_keyboard_get_modifiers(
QEMU_DBUS_DISPLAY1_KEYBOARD(keyboard)), ==, 0);
g_clear_object(&conn);
qtest_quit(qts);
}

8
tests/unit/test-qobject-input-visitor.c

@ -500,7 +500,7 @@ static void test_visitor_in_list_struct(TestInputVisitorData *data,
g_string_append_printf(json, "'number': [");
sep = "";
for (i = 0; i < 32; i++) {
g_string_append_printf(json, "%s%f", sep, (double)i / 3);
g_string_append_printf(json, "%s%f", sep, (double)i / FLT_RADIX);
sep = ", ";
}
g_string_append_printf(json, "], ");
@ -583,11 +583,7 @@ static void test_visitor_in_list_struct(TestInputVisitorData *data,
i = 0;
for (num_list = arrs->number; num_list; num_list = num_list->next) {
char expected[32], actual[32];
sprintf(expected, "%.6f", (double)i / 3);
sprintf(actual, "%.6f", num_list->value);
g_assert_cmpstr(expected, ==, actual);
g_assert_cmpfloat(num_list->value, ==, (double)i / FLT_RADIX);
i++;
}

7
tests/unit/test-qobject-output-visitor.c

@ -538,7 +538,7 @@ static void test_visitor_out_list_struct(TestOutputVisitorData *data,
}
for (i = 31; i >= 0; i--) {
QAPI_LIST_PREPEND(arrs->number, (double)i / 3);
QAPI_LIST_PREPEND(arrs->number, (double)i / FLT_RADIX);
}
for (i = 31; i >= 0; i--) {
@ -571,12 +571,9 @@ static void test_visitor_out_list_struct(TestOutputVisitorData *data,
i = 0;
QLIST_FOREACH_ENTRY(qlist, e) {
QNum *qvalue = qobject_to(QNum, qlist_entry_obj(e));
char expected[32], actual[32];
g_assert(qvalue);
sprintf(expected, "%.6f", (double)i / 3);
sprintf(actual, "%.6f", qnum_get_double(qvalue));
g_assert_cmpstr(actual, ==, expected);
g_assert_cmpfloat(qnum_get_double(qvalue), ==, (double)i / FLT_RADIX);
i++;
}

11
ui/dbus-listener.c

@ -815,8 +815,7 @@ static void ddl_scanout(DBusDisplayListener *ddl)
qemu_dbus_display1_listener_call_scanout(
ddl->proxy, surface_width(ddl->ds), surface_height(ddl->ds),
surface_stride(ddl->ds), surface_format(ddl->ds), v_data,
G_DBUS_CALL_FLAGS_NONE, DBUS_DEFAULT_TIMEOUT, NULL, NULL,
g_object_ref(ddl));
G_DBUS_CALL_FLAGS_NONE, DBUS_DEFAULT_TIMEOUT, NULL, NULL, NULL);
}
static void dbus_gfx_update(DisplayChangeListener *dcl,
@ -961,19 +960,19 @@ dbus_display_listener_dispose(GObject *object)
g_clear_object(&ddl->conn);
g_clear_pointer(&ddl->bus_name, g_free);
g_clear_object(&ddl->proxy);
#ifdef WIN32
g_clear_object(&ddl->map_proxy);
#ifdef WIN32
g_clear_object(&ddl->d3d11_proxy);
g_clear_pointer(&ddl->peer_process, CloseHandle);
#ifdef CONFIG_PIXMAN
pixman_region32_fini(&ddl->gl_damage);
#endif
#ifdef CONFIG_OPENGL
egl_fb_destroy(&ddl->fb);
#endif
#else /* !WIN32 */
g_clear_object(&ddl->scanout_dmabuf_v2_proxy);
#endif
#ifdef CONFIG_PIXMAN
pixman_region32_fini(&ddl->gl_damage);
#endif
G_OBJECT_CLASS(dbus_display_listener_parent_class)->dispose(object);
}

Loading…
Cancel
Save