Misc HW fixes

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmc7NwwACgkQ4+MsLN6t
 wN7zBA//VTiAcjB1KYovOiHQWdhtyE7JU+ZOCzULK2aDoKCP9wZM5yZVQgKbDFX/
 +bI2yjzTfZAWknxnqdShQMxvJE3PkD25mm8D2bP22/U9agKSrX4ll9pGt1NMIHUR
 Hy01gxoLYp0r/Vs0aDWVQGSU4v62hKjTNOFn30Gqg+Xu9W4glEPSwI5GicypxpWZ
 nNAl88whHZ6qouadNCSt0JghwWplw6ZkV3LU4dAUhhhRh+vkPoA3NiCCr4cNqNjJ
 yeGc6lLGf2M9GMpX3t2XEV6lXkBTdhUtdv0inZTzH8W2dYt/SL3n/nSKdddXU+fl
 F5cfUV8vhFTxeGOTodbwjv3GHxk4BAjKXhoHCPikkCC+tdzgCoAn+ie9Q0iSp28A
 kpXt099ByFpkCQ+4fu2+XjX6deC8mxKBKrqjNNEZDqhwuOuiG5Kw8lAzueQErmcZ
 djPm6HqnMQFvs4kAp3VMWiqMgkpjJqwB7dfffJfLcXr3+2WF8Ts181/y9LqnkGqn
 rlEjy57/dzbzTdt547j8GtKCbXmYOxUgd2a3k2sKCGBsCITtIpTjz2YsrafV84iD
 gij8M1IHvt41TNhikvWNKGxJ/5ZY2cx5G/QRbRFVYdFAR14xM45Q/XYuziQgt4if
 6/g7WibP9d8Sqb5Mlj4HLqpPghY0AZ+aaIAHVCDCVYsLpbw7Ixk=
 =zdCl
 -----END PGP SIGNATURE-----

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

Misc HW fixes

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmc7NwwACgkQ4+MsLN6t
# wN7zBA//VTiAcjB1KYovOiHQWdhtyE7JU+ZOCzULK2aDoKCP9wZM5yZVQgKbDFX/
# +bI2yjzTfZAWknxnqdShQMxvJE3PkD25mm8D2bP22/U9agKSrX4ll9pGt1NMIHUR
# Hy01gxoLYp0r/Vs0aDWVQGSU4v62hKjTNOFn30Gqg+Xu9W4glEPSwI5GicypxpWZ
# nNAl88whHZ6qouadNCSt0JghwWplw6ZkV3LU4dAUhhhRh+vkPoA3NiCCr4cNqNjJ
# yeGc6lLGf2M9GMpX3t2XEV6lXkBTdhUtdv0inZTzH8W2dYt/SL3n/nSKdddXU+fl
# F5cfUV8vhFTxeGOTodbwjv3GHxk4BAjKXhoHCPikkCC+tdzgCoAn+ie9Q0iSp28A
# kpXt099ByFpkCQ+4fu2+XjX6deC8mxKBKrqjNNEZDqhwuOuiG5Kw8lAzueQErmcZ
# djPm6HqnMQFvs4kAp3VMWiqMgkpjJqwB7dfffJfLcXr3+2WF8Ts181/y9LqnkGqn
# rlEjy57/dzbzTdt547j8GtKCbXmYOxUgd2a3k2sKCGBsCITtIpTjz2YsrafV84iD
# gij8M1IHvt41TNhikvWNKGxJ/5ZY2cx5G/QRbRFVYdFAR14xM45Q/XYuziQgt4if
# 6/g7WibP9d8Sqb5Mlj4HLqpPghY0AZ+aaIAHVCDCVYsLpbw7Ixk=
# =zdCl
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 18 Nov 2024 12:46:04 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-20241118' of https://github.com/philmd/qemu:
  hw/watchdog/cmsdk_apb_watchdog: Fix broken link
  net: mark struct ip_header as QEMU_PACKED
  hw/net/virtio-net.c: Don't assume IP length field is aligned
  hw/audio/hda: fix memory leak on audio setup
  Revert "hw/audio/hda: fix memory leak on audio setup"
  hw/misc/mos6522: Fix bad class definition of the MOS6522 device
  hw/sd/sdhci: Fix coding style
  tests/qtest/migration: Fix indentations
  usb-hub: Fix handling port power control messages
  MAINTAINERS: Update my email address for COLO
  hw/display: check frame buffer can hold blob
  hw/display: factor out the scanout blob to fb conversion
  hw/i386/elfboot: allocate "header" in heap
  hw/misc/nrf51_rng: Don't use BIT_MASK() when we mean BIT()
  vl: fix qemu_validate_options() indention

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2024-11-18 14:33:29 +00:00
commit 3f4ad55ea2
17 changed files with 188 additions and 142 deletions

View File

@ -3559,7 +3559,7 @@ F: include/migration/failover.h
F: docs/COLO-FT.txt F: docs/COLO-FT.txt
COLO Proxy COLO Proxy
M: Zhang Chen <chen.zhang@intel.com> M: Zhang Chen <zhangckid@gmail.com>
M: Li Zhijian <lizhijian@fujitsu.com> M: Li Zhijian <lizhijian@fujitsu.com>
S: Supported S: Supported
F: docs/colo-proxy.txt F: docs/colo-proxy.txt

View File

@ -472,24 +472,6 @@ static void hda_audio_set_amp(HDAAudioStream *st)
} }
} }
static void hda_close_stream(HDAAudioState *a, HDAAudioStream *st)
{
if (st->node == NULL) {
return;
}
if (a->use_timer) {
timer_free(st->buft);
st->buft = NULL;
}
if (st->output) {
AUD_close_out(&a->card, st->voice.out);
st->voice.out = NULL;
} else {
AUD_close_in(&a->card, st->voice.in);
st->voice.in = NULL;
}
}
static void hda_audio_setup(HDAAudioStream *st) static void hda_audio_setup(HDAAudioStream *st)
{ {
bool use_timer = st->state->use_timer; bool use_timer = st->state->use_timer;
@ -502,12 +484,10 @@ static void hda_audio_setup(HDAAudioStream *st)
trace_hda_audio_format(st->node->name, st->as.nchannels, trace_hda_audio_format(st->node->name, st->as.nchannels,
fmt2name[st->as.fmt], st->as.freq); fmt2name[st->as.fmt], st->as.freq);
hda_close_stream(st->state, st);
if (st->output) { if (st->output) {
if (use_timer) { if (use_timer) {
cb = hda_audio_output_cb; cb = hda_audio_output_cb;
st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL, timer_del(st->buft);
hda_audio_output_timer, st);
} else { } else {
cb = hda_audio_compat_output_cb; cb = hda_audio_compat_output_cb;
} }
@ -516,8 +496,7 @@ static void hda_audio_setup(HDAAudioStream *st)
} else { } else {
if (use_timer) { if (use_timer) {
cb = hda_audio_input_cb; cb = hda_audio_input_cb;
st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL, timer_del(st->buft);
hda_audio_input_timer, st);
} else { } else {
cb = hda_audio_compat_input_cb; cb = hda_audio_compat_input_cb;
} }
@ -745,8 +724,12 @@ static void hda_audio_init(HDACodecDevice *hda,
st->gain_right = QEMU_HDA_AMP_STEPS; st->gain_right = QEMU_HDA_AMP_STEPS;
st->compat_bpos = sizeof(st->compat_buf); st->compat_bpos = sizeof(st->compat_buf);
st->output = true; st->output = true;
st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
hda_audio_output_timer, st);
} else { } else {
st->output = false; st->output = false;
st->buft = timer_new_ns(QEMU_CLOCK_VIRTUAL,
hda_audio_input_timer, st);
} }
st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 | st->format = AC_FMT_TYPE_PCM | AC_FMT_BITS_16 |
(1 << AC_FMT_CHAN_SHIFT); (1 << AC_FMT_CHAN_SHIFT);
@ -760,11 +743,21 @@ static void hda_audio_init(HDACodecDevice *hda,
static void hda_audio_exit(HDACodecDevice *hda) static void hda_audio_exit(HDACodecDevice *hda)
{ {
HDAAudioState *a = HDA_AUDIO(hda); HDAAudioState *a = HDA_AUDIO(hda);
HDAAudioStream *st;
int i; int i;
dprint(a, 1, "%s\n", __func__); dprint(a, 1, "%s\n", __func__);
for (i = 0; i < ARRAY_SIZE(a->st); i++) { for (i = 0; i < ARRAY_SIZE(a->st); i++) {
hda_close_stream(a, a->st + i); st = a->st + i;
if (st->node == NULL) {
continue;
}
timer_free(st->buft);
if (st->output) {
AUD_close_out(&a->card, st->voice.out);
} else {
AUD_close_in(&a->card, st->voice.in);
}
} }
AUD_remove_card(&a->card); AUD_remove_card(&a->card);
} }

View File

@ -805,7 +805,6 @@ static void virgl_cmd_set_scanout_blob(VirtIOGPU *g,
struct virtio_gpu_framebuffer fb = { 0 }; struct virtio_gpu_framebuffer fb = { 0 };
struct virtio_gpu_virgl_resource *res; struct virtio_gpu_virgl_resource *res;
struct virtio_gpu_set_scanout_blob ss; struct virtio_gpu_set_scanout_blob ss;
uint64_t fbend;
VIRTIO_GPU_FILL_CMD(ss); VIRTIO_GPU_FILL_CMD(ss);
virtio_gpu_scanout_blob_bswap(&ss); virtio_gpu_scanout_blob_bswap(&ss);
@ -852,26 +851,7 @@ static void virgl_cmd_set_scanout_blob(VirtIOGPU *g,
return; return;
} }
fb.format = virtio_gpu_get_pixman_format(ss.format); if (!virtio_gpu_scanout_blob_to_fb(&fb, &ss, res->base.blob_size)) {
if (!fb.format) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: pixel format not supported %d\n",
__func__, ss.format);
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
return;
}
fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
fb.width = ss.width;
fb.height = ss.height;
fb.stride = ss.strides[0];
fb.offset = ss.offsets[0] + ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
fbend = fb.offset;
fbend += fb.stride * (ss.r.height - 1);
fbend += fb.bytes_pp * ss.r.width;
if (fbend > res->base.blob_size) {
qemu_log_mask(LOG_GUEST_ERROR, "%s: fb end out of range\n",
__func__);
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
return; return;
} }

View File

@ -721,13 +721,47 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
&fb, res, &ss.r, &cmd->error); &fb, res, &ss.r, &cmd->error);
} }
bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_set_scanout_blob *ss,
uint64_t blob_size)
{
uint64_t fbend;
fb->format = virtio_gpu_get_pixman_format(ss->format);
if (!fb->format) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: host couldn't handle guest format %d\n",
__func__, ss->format);
return false;
}
fb->bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb->format), 8);
fb->width = ss->width;
fb->height = ss->height;
fb->stride = ss->strides[0];
fb->offset = ss->offsets[0] + ss->r.x * fb->bytes_pp + ss->r.y * fb->stride;
fbend = fb->offset;
fbend += (uint64_t) fb->stride * ss->r.height;
if (fbend > blob_size) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: fb end out of range\n",
__func__);
return false;
}
return true;
}
static void virtio_gpu_set_scanout_blob(VirtIOGPU *g, static void virtio_gpu_set_scanout_blob(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd) struct virtio_gpu_ctrl_command *cmd)
{ {
struct virtio_gpu_simple_resource *res; struct virtio_gpu_simple_resource *res;
struct virtio_gpu_framebuffer fb = { 0 }; struct virtio_gpu_framebuffer fb = { 0 };
struct virtio_gpu_set_scanout_blob ss; struct virtio_gpu_set_scanout_blob ss;
uint64_t fbend;
VIRTIO_GPU_FILL_CMD(ss); VIRTIO_GPU_FILL_CMD(ss);
virtio_gpu_scanout_blob_bswap(&ss); virtio_gpu_scanout_blob_bswap(&ss);
@ -753,28 +787,7 @@ static void virtio_gpu_set_scanout_blob(VirtIOGPU *g,
return; return;
} }
fb.format = virtio_gpu_get_pixman_format(ss.format); if (!virtio_gpu_scanout_blob_to_fb(&fb, &ss, res->blob_size)) {
if (!fb.format) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: host couldn't handle guest format %d\n",
__func__, ss.format);
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
return;
}
fb.bytes_pp = DIV_ROUND_UP(PIXMAN_FORMAT_BPP(fb.format), 8);
fb.width = ss.width;
fb.height = ss.height;
fb.stride = ss.strides[0];
fb.offset = ss.offsets[0] + ss.r.x * fb.bytes_pp + ss.r.y * fb.stride;
fbend = fb.offset;
fbend += fb.stride * (ss.r.height - 1);
fbend += fb.bytes_pp * ss.r.width;
if (fbend > res->blob_size) {
qemu_log_mask(LOG_GUEST_ERROR,
"%s: fb end out of range\n",
__func__);
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER; cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
return; return;
} }

View File

@ -697,9 +697,11 @@ void x86_load_linux(X86MachineState *x86ms,
strlen(kernel_cmdline) + 1); strlen(kernel_cmdline) + 1);
fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
setup = g_memdup2(header, sizeof(header));
fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header)); fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header));
fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA,
header, sizeof(header)); setup, sizeof(header));
/* load initrd */ /* load initrd */
if (initrd_filename) { if (initrd_filename) {

View File

@ -107,25 +107,25 @@ static void rng_write(void *opaque, hwaddr offset,
break; break;
case NRF51_RNG_REG_SHORTS: case NRF51_RNG_REG_SHORTS:
s->shortcut_stop_on_valrdy = s->shortcut_stop_on_valrdy =
(value & BIT_MASK(NRF51_RNG_REG_SHORTS_VALRDY_STOP)) ? 1 : 0; (value & BIT(NRF51_RNG_REG_SHORTS_VALRDY_STOP)) ? 1 : 0;
break; break;
case NRF51_RNG_REG_INTEN: case NRF51_RNG_REG_INTEN:
s->interrupt_enabled = s->interrupt_enabled =
(value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) ? 1 : 0; (value & BIT(NRF51_RNG_REG_INTEN_VALRDY)) ? 1 : 0;
break; break;
case NRF51_RNG_REG_INTENSET: case NRF51_RNG_REG_INTENSET:
if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) { if (value & BIT(NRF51_RNG_REG_INTEN_VALRDY)) {
s->interrupt_enabled = 1; s->interrupt_enabled = 1;
} }
break; break;
case NRF51_RNG_REG_INTENCLR: case NRF51_RNG_REG_INTENCLR:
if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) { if (value & BIT(NRF51_RNG_REG_INTEN_VALRDY)) {
s->interrupt_enabled = 0; s->interrupt_enabled = 0;
} }
break; break;
case NRF51_RNG_REG_CONFIG: case NRF51_RNG_REG_CONFIG:
s->filter_enabled = s->filter_enabled =
(value & BIT_MASK(NRF51_RNG_REG_CONFIG_DECEN)) ? 1 : 0; (value & BIT(NRF51_RNG_REG_CONFIG_DECEN)) ? 1 : 0;
break; break;
default: default:

View File

@ -2049,6 +2049,21 @@ static ssize_t virtio_net_do_receive(NetClientState *nc, const uint8_t *buf,
return virtio_net_receive_rcu(nc, buf, size, false); return virtio_net_receive_rcu(nc, buf, size, false);
} }
/*
* Accessors to read and write the IP packet data length field. This
* is a potentially unaligned network-byte-order 16 bit unsigned integer
* pointed to by unit->ip_len.
*/
static uint16_t read_unit_ip_len(VirtioNetRscUnit *unit)
{
return lduw_be_p(unit->ip_plen);
}
static void write_unit_ip_len(VirtioNetRscUnit *unit, uint16_t l)
{
stw_be_p(unit->ip_plen, l);
}
static void virtio_net_rsc_extract_unit4(VirtioNetRscChain *chain, static void virtio_net_rsc_extract_unit4(VirtioNetRscChain *chain,
const uint8_t *buf, const uint8_t *buf,
VirtioNetRscUnit *unit) VirtioNetRscUnit *unit)
@ -2063,7 +2078,7 @@ static void virtio_net_rsc_extract_unit4(VirtioNetRscChain *chain,
unit->ip_plen = &ip->ip_len; unit->ip_plen = &ip->ip_len;
unit->tcp = (struct tcp_header *)(((uint8_t *)unit->ip) + ip_hdrlen); unit->tcp = (struct tcp_header *)(((uint8_t *)unit->ip) + ip_hdrlen);
unit->tcp_hdrlen = (htons(unit->tcp->th_offset_flags) & 0xF000) >> 10; unit->tcp_hdrlen = (htons(unit->tcp->th_offset_flags) & 0xF000) >> 10;
unit->payload = htons(*unit->ip_plen) - ip_hdrlen - unit->tcp_hdrlen; unit->payload = read_unit_ip_len(unit) - ip_hdrlen - unit->tcp_hdrlen;
} }
static void virtio_net_rsc_extract_unit6(VirtioNetRscChain *chain, static void virtio_net_rsc_extract_unit6(VirtioNetRscChain *chain,
@ -2082,7 +2097,7 @@ static void virtio_net_rsc_extract_unit6(VirtioNetRscChain *chain,
/* There is a difference between payload length in ipv4 and v6, /* There is a difference between payload length in ipv4 and v6,
ip header is excluded in ipv6 */ ip header is excluded in ipv6 */
unit->payload = htons(*unit->ip_plen) - unit->tcp_hdrlen; unit->payload = read_unit_ip_len(unit) - unit->tcp_hdrlen;
} }
static size_t virtio_net_rsc_drain_seg(VirtioNetRscChain *chain, static size_t virtio_net_rsc_drain_seg(VirtioNetRscChain *chain,
@ -2231,7 +2246,7 @@ static int32_t virtio_net_rsc_coalesce_data(VirtioNetRscChain *chain,
VirtioNetRscUnit *o_unit; VirtioNetRscUnit *o_unit;
o_unit = &seg->unit; o_unit = &seg->unit;
o_ip_len = htons(*o_unit->ip_plen); o_ip_len = read_unit_ip_len(o_unit);
nseq = htonl(n_unit->tcp->th_seq); nseq = htonl(n_unit->tcp->th_seq);
oseq = htonl(o_unit->tcp->th_seq); oseq = htonl(o_unit->tcp->th_seq);
@ -2267,7 +2282,7 @@ coalesce:
o_unit->payload += n_unit->payload; /* update new data len */ o_unit->payload += n_unit->payload; /* update new data len */
/* update field in ip header */ /* update field in ip header */
*o_unit->ip_plen = htons(o_ip_len + n_unit->payload); write_unit_ip_len(o_unit, o_ip_len + n_unit->payload);
/* Bring 'PUSH' big, the whql test guide says 'PUSH' can be coalesced /* Bring 'PUSH' big, the whql test guide says 'PUSH' can be coalesced
for windows guest, while this may change the behavior for linux for windows guest, while this may change the behavior for linux

View File

@ -289,9 +289,11 @@ static void sdhci_reset(SDHCIState *s)
timer_del(s->insert_timer); timer_del(s->insert_timer);
timer_del(s->transfer_timer); timer_del(s->transfer_timer);
/* Set all registers to 0. Capabilities/Version registers are not cleared /*
* Set all registers to 0. Capabilities/Version registers are not cleared
* and assumed to always preserve their value, given to them during * and assumed to always preserve their value, given to them during
* initialization */ * initialization
*/
memset(&s->sdmasysad, 0, (uintptr_t)&s->capareg - (uintptr_t)&s->sdmasysad); memset(&s->sdmasysad, 0, (uintptr_t)&s->capareg - (uintptr_t)&s->sdmasysad);
/* Reset other state based on current card insertion/readonly status */ /* Reset other state based on current card insertion/readonly status */
@ -305,7 +307,8 @@ static void sdhci_reset(SDHCIState *s)
static void sdhci_poweron_reset(DeviceState *dev) static void sdhci_poweron_reset(DeviceState *dev)
{ {
/* QOM (ie power-on) reset. This is identical to reset /*
* QOM (ie power-on) reset. This is identical to reset
* commanded via device register apart from handling of the * commanded via device register apart from handling of the
* 'pending insert on powerup' quirk. * 'pending insert on powerup' quirk.
*/ */
@ -445,8 +448,10 @@ static void sdhci_read_block_from_card(SDHCIState *s)
s->prnsts &= ~SDHC_DAT_LINE_ACTIVE; s->prnsts &= ~SDHC_DAT_LINE_ACTIVE;
} }
/* If stop at block gap request was set and it's not the last block of /*
* data - generate Block Event interrupt */ * If stop at block gap request was set and it's not the last block of
* data - generate Block Event interrupt
*/
if (s->stopped_state == sdhc_gap_read && (s->trnmod & SDHC_TRNS_MULTI) && if (s->stopped_state == sdhc_gap_read && (s->trnmod & SDHC_TRNS_MULTI) &&
s->blkcnt != 1) { s->blkcnt != 1) {
s->prnsts &= ~SDHC_DAT_LINE_ACTIVE; s->prnsts &= ~SDHC_DAT_LINE_ACTIVE;
@ -548,8 +553,10 @@ static void sdhci_write_block_to_card(SDHCIState *s)
sdhci_update_irq(s); sdhci_update_irq(s);
} }
/* Write @size bytes of @value data to host controller @s Buffer Data Port /*
* register */ * Write @size bytes of @value data to host controller @s Buffer Data Port
* register
*/
static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size) static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
{ {
unsigned i; unsigned i;
@ -594,9 +601,11 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
return; return;
} }
/* XXX: Some sd/mmc drivers (for example, u-boot-slp) do not account for /*
* XXX: Some sd/mmc drivers (for example, u-boot-slp) do not account for
* possible stop at page boundary if initial address is not page aligned, * possible stop at page boundary if initial address is not page aligned,
* allow them to work properly */ * allow them to work properly
*/
if ((s->sdmasysad % boundary_chk) == 0) { if ((s->sdmasysad % boundary_chk) == 0) {
page_aligned = true; page_aligned = true;
} }
@ -702,7 +711,8 @@ static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
dma_memory_read(s->dma_as, entry_addr, &adma2, sizeof(adma2), dma_memory_read(s->dma_as, entry_addr, &adma2, sizeof(adma2),
MEMTXATTRS_UNSPECIFIED); MEMTXATTRS_UNSPECIFIED);
adma2 = le64_to_cpu(adma2); adma2 = le64_to_cpu(adma2);
/* The spec does not specify endianness of descriptor table. /*
* The spec does not specify endianness of descriptor table.
* We currently assume that it is LE. * We currently assume that it is LE.
*/ */
dscr->addr = (hwaddr)extract64(adma2, 32, 32) & ~0x3ull; dscr->addr = (hwaddr)extract64(adma2, 32, 32) & ~0x3ull;
@ -977,8 +987,10 @@ static bool sdhci_can_issue_command(SDHCIState *s)
return true; return true;
} }
/* The Buffer Data Port register must be accessed in sequential and /*
* continuous manner */ * The Buffer Data Port register must be accessed in sequential and
* continuous manner
*/
static inline bool static inline bool
sdhci_buff_access_is_sequential(SDHCIState *s, unsigned byte_num) sdhci_buff_access_is_sequential(SDHCIState *s, unsigned byte_num)
{ {
@ -1206,8 +1218,10 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
MASKED_WRITE(s->argument, mask, value); MASKED_WRITE(s->argument, mask, value);
break; break;
case SDHC_TRNMOD: case SDHC_TRNMOD:
/* DMA can be enabled only if it is supported as indicated by /*
* capabilities register */ * DMA can be enabled only if it is supported as indicated by
* capabilities register
*/
if (!(s->capareg & R_SDHC_CAPAB_SDMA_MASK)) { if (!(s->capareg & R_SDHC_CAPAB_SDMA_MASK)) {
value &= ~SDHC_TRNS_DMA; value &= ~SDHC_TRNS_DMA;
} }
@ -1279,8 +1293,10 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
} else { } else {
s->norintsts &= ~SDHC_NIS_ERR; s->norintsts &= ~SDHC_NIS_ERR;
} }
/* Quirk for Raspberry Pi: pending card insert interrupt /*
* appears when first enabled after power on */ * Quirk for Raspberry Pi: pending card insert interrupt
* appears when first enabled after power on
*/
if ((s->norintstsen & SDHC_NISEN_INSERT) && s->pending_insert_state) { if ((s->norintstsen & SDHC_NISEN_INSERT) && s->pending_insert_state) {
assert(s->pending_insert_quirk); assert(s->pending_insert_quirk);
s->norintsts |= SDHC_NIS_INSERT; s->norintsts |= SDHC_NIS_INSERT;
@ -1396,8 +1412,10 @@ void sdhci_initfn(SDHCIState *s)
{ {
qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SDHCI_BUS, DEVICE(s), "sd-bus"); qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SDHCI_BUS, DEVICE(s), "sd-bus");
s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s); s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s); sdhci_raise_insertion_irq, s);
s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
sdhci_data_transfer, s);
s->io_ops = &sdhci_mmio_le_ops; s->io_ops = &sdhci_mmio_le_ops;
} }
@ -1445,11 +1463,13 @@ void sdhci_common_realize(SDHCIState *s, Error **errp)
void sdhci_common_unrealize(SDHCIState *s) void sdhci_common_unrealize(SDHCIState *s)
{ {
/* This function is expected to be called only once for each class: /*
* This function is expected to be called only once for each class:
* - SysBus: via DeviceClass->unrealize(), * - SysBus: via DeviceClass->unrealize(),
* - PCI: via PCIDeviceClass->exit(). * - PCI: via PCIDeviceClass->exit().
* However to avoid double-free and/or use-after-free we still nullify * However to avoid double-free and/or use-after-free we still nullify
* this variable (better safe than sorry!). */ * this variable (better safe than sorry!).
*/
g_free(s->fifo_buffer); g_free(s->fifo_buffer);
s->fifo_buffer = NULL; s->fifo_buffer = NULL;
} }

View File

@ -479,6 +479,7 @@ static void usb_hub_handle_control(USBDevice *dev, USBPacket *p,
usb_hub_port_clear(port, PORT_STAT_SUSPEND); usb_hub_port_clear(port, PORT_STAT_SUSPEND);
port->wPortChange = 0; port->wPortChange = 0;
} }
break;
default: default:
goto fail; goto fail;
} }

View File

@ -12,8 +12,8 @@
/* /*
* This is a model of the "APB watchdog" which is part of the Cortex-M * This is a model of the "APB watchdog" which is part of the Cortex-M
* System Design Kit (CMSDK) and documented in the Cortex-M System * System Design Kit (CMSDK) and documented in the Cortex-M System
* Design Kit Technical Reference Manual (ARM DDI0479C): * Design Kit Technical Reference Manual (ARM DDI0479):
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit * https://developer.arm.com/documentation/ddi0479/
* *
* We also support the variant of this device found in the TI * We also support the variant of this device found in the TI
* Stellaris/Luminary boards and documented in: * Stellaris/Luminary boards and documented in:

View File

@ -154,7 +154,7 @@ struct MOS6522State {
OBJECT_DECLARE_TYPE(MOS6522State, MOS6522DeviceClass, MOS6522) OBJECT_DECLARE_TYPE(MOS6522State, MOS6522DeviceClass, MOS6522)
struct MOS6522DeviceClass { struct MOS6522DeviceClass {
DeviceClass parent_class; SysBusDeviceClass parent_class;
ResettablePhases parent_phases; ResettablePhases parent_phases;
void (*portB_write)(MOS6522State *dev); void (*portB_write)(MOS6522State *dev);

View File

@ -333,6 +333,21 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
struct virtio_gpu_scanout *s, struct virtio_gpu_scanout *s,
uint32_t resource_id); uint32_t resource_id);
/**
* virtio_gpu_scanout_blob_to_fb() - fill out fb based on scanout data
* fb: the frame-buffer descriptor to fill out
* ss: the scanout blob data
* blob_size: size of scanout blob data
*
* This will check we have enough space for the frame taking into
* account that stride.
*
* Returns true on success, otherwise logs guest error and returns false
*/
bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb,
struct virtio_gpu_set_scanout_blob *ss,
uint64_t blob_size);
/* virtio-gpu-udmabuf.c */ /* virtio-gpu-udmabuf.c */
bool virtio_gpu_have_udmabuf(void); bool virtio_gpu_have_udmabuf(void);
void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res); void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);

View File

@ -102,7 +102,7 @@ typedef struct VirtioNetRscStat {
/* Rsc unit general info used to checking if can coalescing */ /* Rsc unit general info used to checking if can coalescing */
typedef struct VirtioNetRscUnit { typedef struct VirtioNetRscUnit {
void *ip; /* ip header */ void *ip; /* ip header */
uint16_t *ip_plen; /* data len pointer in ip header field */ void *ip_plen; /* pointer to unaligned uint16_t data len in ip header */
struct tcp_header *tcp; /* tcp header */ struct tcp_header *tcp; /* tcp header */
uint16_t tcp_hdrlen; /* tcp header len */ uint16_t tcp_hdrlen; /* tcp header len */
uint16_t payload; /* pure payload without virtio/eth/ip/tcp */ uint16_t payload; /* pure payload without virtio/eth/ip/tcp */

View File

@ -56,7 +56,7 @@ struct ip_header {
uint8_t ip_p; /* protocol */ uint8_t ip_p; /* protocol */
uint16_t ip_sum; /* checksum */ uint16_t ip_sum; /* checksum */
uint32_t ip_src, ip_dst; /* source and destination address */ uint32_t ip_src, ip_dst; /* source and destination address */
}; } QEMU_PACKED;
typedef struct tcp_header { typedef struct tcp_header {
uint16_t th_sport; /* source port */ uint16_t th_sport; /* source port */

View File

@ -113,8 +113,8 @@ static bool ufd_version_check(void)
} }
uffd_feature_thread_id = api_struct.features & UFFD_FEATURE_THREAD_ID; uffd_feature_thread_id = api_struct.features & UFFD_FEATURE_THREAD_ID;
ioctl_mask = 1ULL << _UFFDIO_REGISTER | ioctl_mask = (1ULL << _UFFDIO_REGISTER |
1ULL << _UFFDIO_UNREGISTER; 1ULL << _UFFDIO_UNREGISTER);
if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) { if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) {
g_test_message("Skipping test: Missing userfault feature"); g_test_message("Skipping test: Missing userfault feature");
return false; return false;
@ -1384,8 +1384,10 @@ static void test_postcopy_preempt_tls_psk(void)
static void wait_for_postcopy_status(QTestState *one, const char *status) static void wait_for_postcopy_status(QTestState *one, const char *status)
{ {
wait_for_migration_status(one, status, wait_for_migration_status(one, status,
(const char * []) { "failed", "active", (const char * []) {
"completed", NULL }); "failed", "active",
"completed", NULL
});
} }
static void postcopy_recover_fail(QTestState *from, QTestState *to, static void postcopy_recover_fail(QTestState *from, QTestState *to,
@ -2575,14 +2577,16 @@ static void test_migrate_fd_finish_hook(QTestState *from,
/* Test closing fds */ /* Test closing fds */
/* We assume, that QEMU removes named fd from its list, /* We assume, that QEMU removes named fd from its list,
* so this should fail */ * so this should fail */
rsp = qtest_qmp(from, "{ 'execute': 'closefd'," rsp = qtest_qmp(from,
"{ 'execute': 'closefd',"
" 'arguments': { 'fdname': 'fd-mig' }}"); " 'arguments': { 'fdname': 'fd-mig' }}");
g_assert_true(qdict_haskey(rsp, "error")); g_assert_true(qdict_haskey(rsp, "error"));
error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc"); error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found"); g_assert_cmpstr(error_desc, ==, "File descriptor named 'fd-mig' not found");
qobject_unref(rsp); qobject_unref(rsp);
rsp = qtest_qmp(to, "{ 'execute': 'closefd'," rsp = qtest_qmp(to,
"{ 'execute': 'closefd',"
" 'arguments': { 'fdname': 'fd-mig' }}"); " 'arguments': { 'fdname': 'fd-mig' }}");
g_assert_true(qdict_haskey(rsp, "error")); g_assert_true(qdict_haskey(rsp, "error"));
error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc"); error_desc = qdict_get_str(qdict_get_qdict(rsp, "error"), "desc");
@ -2741,11 +2745,11 @@ static void test_validate_uri_channels_both_set(void)
}, },
.listen_uri = "defer", .listen_uri = "defer",
.connect_uri = "tcp:127.0.0.1:0", .connect_uri = "tcp:127.0.0.1:0",
.connect_channels = "[ { 'channel-type': 'main'," .connect_channels = ("[ { ""'channel-type': 'main',"
" 'addr': { 'transport': 'socket'," " 'addr': { 'transport': 'socket',"
" 'type': 'inet'," " 'type': 'inet',"
" 'host': '127.0.0.1'," " 'host': '127.0.0.1',"
" 'port': '0' } } ]", " 'port': '0' } } ]"),
}; };
do_test_validate_uri_channel(&args); do_test_validate_uri_channel(&args);
@ -3032,11 +3036,11 @@ static void test_multifd_tcp_channels_none(void)
.listen_uri = "defer", .listen_uri = "defer",
.start_hook = test_migrate_precopy_tcp_multifd_start, .start_hook = test_migrate_precopy_tcp_multifd_start,
.live = true, .live = true,
.connect_channels = "[ { 'channel-type': 'main'," .connect_channels = ("[ { 'channel-type': 'main',"
" 'addr': { 'transport': 'socket'," " 'addr': { 'transport': 'socket',"
" 'type': 'inet'," " 'type': 'inet',"
" 'host': '127.0.0.1'," " 'host': '127.0.0.1',"
" 'port': '0' } } ]", " 'port': '0' } } ]"),
}; };
test_precopy_common(&args); test_precopy_common(&args);
} }
@ -3668,7 +3672,8 @@ static void test_migrate_dirty_limit(void)
throttle_us_per_full = 0; throttle_us_per_full = 0;
while (throttle_us_per_full == 0) { while (throttle_us_per_full == 0) {
throttle_us_per_full = throttle_us_per_full =
read_migrate_property_int(from, "dirty-limit-throttle-time-per-round"); read_migrate_property_int(from,
"dirty-limit-throttle-time-per-round");
usleep(100); usleep(100);
g_assert_false(src_state.stop_seen); g_assert_false(src_state.stop_seen);
} }
@ -3680,7 +3685,8 @@ static void test_migrate_dirty_limit(void)
/* Check if dirty limit throttle switched off, set timeout 1ms */ /* Check if dirty limit throttle switched off, set timeout 1ms */
do { do {
throttle_us_per_full = throttle_us_per_full =
read_migrate_property_int(from, "dirty-limit-throttle-time-per-round"); read_migrate_property_int(from,
"dirty-limit-throttle-time-per-round");
usleep(100); usleep(100);
g_assert_false(src_state.stop_seen); g_assert_false(src_state.stop_seen);
} while (throttle_us_per_full != 0 && --max_try_count); } while (throttle_us_per_full != 0 && --max_try_count);
@ -3709,7 +3715,8 @@ static void test_migrate_dirty_limit(void)
throttle_us_per_full = 0; throttle_us_per_full = 0;
while (throttle_us_per_full == 0) { while (throttle_us_per_full == 0) {
throttle_us_per_full = throttle_us_per_full =
read_migrate_property_int(from, "dirty-limit-throttle-time-per-round"); read_migrate_property_int(from,
"dirty-limit-throttle-time-per-round");
usleep(100); usleep(100);
g_assert_false(src_state.stop_seen); g_assert_false(src_state.stop_seen);
} }