mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'kraxel-20220927-pull-request' of https://gitlab.com/kraxel/qemu into staging
usb: make usbnet work with xhci. audio: add sndio backend. misc bugfixes for console, xhci, audio, ati-vga and virtio-gpu. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmMyse8ACgkQTLbY7tPo # cTiLrRAAltoyd++jsmhg2wXuJsfekfec3kOro7T+eSznDWfBRvm7VxJ+gswYBYga # HbEkHjII0yPbOP9WDMhhHx33g2nYdbhDLPKXHdK8MjHTTPxtYP7XmsWkEVpuuzTx # WqeYvGSmUri6QOUz7fd07IhiBT1aQvUQ/vWQ6OhyRVPy41bR8kIbGx3iV0JDxWvz # n3xUZALGLz3QAM0lXRzXPYT9JB/RqdbpMM35HNTpN9/xaZmgFWsyuQXSSm61pTtb # PS+lILDPjgZeYsfsZRyhZaSZrp2f6WOGm1ZdtSM0rvmRKezOzYnG8fm4fqZQLYSj # nrAqUs38sKaM71a3QbpXhDjbv4cpj0K3iSNLmlUq4pgvPiMgwPlgSwwCGlkNDaRo # IA1KON1pMH2A5vvtXEUt5RTkbXxHAAKPdpl5sS6kgbs7dgoKDqzaIPFQELam259Z # 9nbMBqz/d6gm2CFT5ogrY0q511IC5hWtsmbQZkOZeBd5SvhvyJ59DIabFDcw05fG # ixZVapewXYtzFUde2lb8X5qyneUVeGY5D2OJ2uUykHgR2Qz4d3CjXlhnRkLIkMcd # Uu6N1LTkjyuuB86BoTSZxk0iz94OvmyDiXpqwmRaCGcdnTOTj0dKrbRrtHdC2vCo # cBpUAIdyJvDJSm0X8ZWvvv1sMJCAJ7lofFf/P/jUKlacC2ipgXQ= # =QBLK # -----END PGP SIGNATURE----- # gpg: Signature made Tue 27 Sep 2022 04:18:55 EDT # gpg: using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * tag 'kraxel-20220927-pull-request' of https://gitlab.com/kraxel/qemu: (24 commits) virtio-gpu: update scanout if there is any area covered by the rect hw/display/ati_2d: Fix buffer overflow in ati_2d_blt (CVE-2021-3638) audio: remove abort() in audio_bug() Revert "audio: Log context for audio bug" audio: Add sndio backend usbnet: Report link-up via interrupt endpoint in CDC-ECM mode usbnet: Detect short packets as sent by the xHCI controller usbnet: Accept mandatory USB_CDC_SET_ETHERNET_PACKET_FILTER request usbnet: Add missing usb_wakeup() call in usbnet_receive() hcd-xhci: drop operation with secondary stream arrays enabled usb/msd: add usb_msd_fatal_error() and fix guest-triggerable assert usb/msd: move usb_msd_packet_complete() hcd-ohci: Drop ohci_service_iso_td() if ed->head & OHCI_DPTR_MASK is zero hw/usb/hcd-xhci: Check whether DMA accesses fail ui/console: fix three double frees in png_save() ui/vdagent: fix serial reset of guest agent ui/clipboard: reset the serial state on reset ui/vdagent: always reset the clipboard serial on caps ui/clipboard: fix serial priority ui: add some vdagent related traces ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
@@ -2438,6 +2438,7 @@ X: audio/jackaudio.c
|
||||
X: audio/ossaudio.c
|
||||
X: audio/paaudio.c
|
||||
X: audio/sdlaudio.c
|
||||
X: audio/sndioaudio.c
|
||||
X: audio/spiceaudio.c
|
||||
F: qapi/audio.json
|
||||
|
||||
@@ -2482,6 +2483,12 @@ R: Thomas Huth <huth@tuxfamily.org>
|
||||
S: Odd Fixes
|
||||
F: audio/sdlaudio.c
|
||||
|
||||
Sndio Audio backend
|
||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||
R: Alexandre Ratchov <alex@caoua.org>
|
||||
S: Odd Fixes
|
||||
F: audio/sndioaudio.c
|
||||
|
||||
Block layer core
|
||||
M: Kevin Wolf <kwolf@redhat.com>
|
||||
M: Hanna Reitz <hreitz@redhat.com>
|
||||
|
||||
+13
-12
@@ -138,7 +138,7 @@ static inline int audio_bits_to_index (int bits)
|
||||
default:
|
||||
audio_bug ("bits_to_index", 1);
|
||||
AUD_log (NULL, "invalid bits %d\n", bits);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size)
|
||||
AUD_log (NULL, "%s passed invalid arguments to audio_calloc\n",
|
||||
funcname);
|
||||
AUD_log (NULL, "nmemb=%d size=%zu (len=%zu)\n", nmemb, size, len);
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_malloc0 (len);
|
||||
@@ -543,7 +543,7 @@ static size_t audio_pcm_hw_get_live_in(HWVoiceIn *hw)
|
||||
size_t live = hw->total_samples_captured - audio_pcm_hw_find_min_in (hw);
|
||||
if (audio_bug(__func__, live > hw->conv_buf->size)) {
|
||||
dolog("live=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
return live;
|
||||
}
|
||||
@@ -581,7 +581,7 @@ static size_t audio_pcm_sw_read(SWVoiceIn *sw, void *buf, size_t size)
|
||||
}
|
||||
if (audio_bug(__func__, live > hw->conv_buf->size)) {
|
||||
dolog("live_in=%zu hw->conv_buf->size=%zu\n", live, hw->conv_buf->size);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
rpos = audio_ring_posb(hw->conv_buf->pos, live, hw->conv_buf->size);
|
||||
@@ -656,7 +656,7 @@ static size_t audio_pcm_hw_get_live_out (HWVoiceOut *hw, int *nb_live)
|
||||
|
||||
if (audio_bug(__func__, live > hw->mix_buf->size)) {
|
||||
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
return live;
|
||||
}
|
||||
@@ -706,7 +706,7 @@ static size_t audio_pcm_sw_write(SWVoiceOut *sw, void *buf, size_t size)
|
||||
live = sw->total_hw_samples_mixed;
|
||||
if (audio_bug(__func__, live > hwsamples)) {
|
||||
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hwsamples);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (live == hwsamples) {
|
||||
@@ -998,7 +998,7 @@ static size_t audio_get_avail (SWVoiceIn *sw)
|
||||
if (audio_bug(__func__, live > sw->hw->conv_buf->size)) {
|
||||
dolog("live=%zu sw->hw->conv_buf->size=%zu\n", live,
|
||||
sw->hw->conv_buf->size);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ldebug (
|
||||
@@ -1028,7 +1028,7 @@ static size_t audio_get_free(SWVoiceOut *sw)
|
||||
if (audio_bug(__func__, live > sw->hw->mix_buf->size)) {
|
||||
dolog("live=%zu sw->hw->mix_buf->size=%zu\n", live,
|
||||
sw->hw->mix_buf->size);
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
dead = sw->hw->mix_buf->size - live;
|
||||
@@ -1170,7 +1170,7 @@ static void audio_run_out (AudioState *s)
|
||||
|
||||
if (audio_bug(__func__, live > hw->mix_buf->size)) {
|
||||
dolog("live=%zu hw->mix_buf->size=%zu\n", live, hw->mix_buf->size);
|
||||
abort();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hw->pending_disable && !nb_live) {
|
||||
@@ -1203,7 +1203,7 @@ static void audio_run_out (AudioState *s)
|
||||
if (audio_bug(__func__, hw->mix_buf->pos >= hw->mix_buf->size)) {
|
||||
dolog("hw->mix_buf->pos=%zu hw->mix_buf->size=%zu played=%zu\n",
|
||||
hw->mix_buf->pos, hw->mix_buf->size, played);
|
||||
abort();
|
||||
hw->mix_buf->pos = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_OUT
|
||||
@@ -1223,7 +1223,7 @@ static void audio_run_out (AudioState *s)
|
||||
if (audio_bug(__func__, played > sw->total_hw_samples_mixed)) {
|
||||
dolog("played=%zu sw->total_hw_samples_mixed=%zu\n",
|
||||
played, sw->total_hw_samples_mixed);
|
||||
abort();
|
||||
played = sw->total_hw_samples_mixed;
|
||||
}
|
||||
|
||||
sw->total_hw_samples_mixed -= played;
|
||||
@@ -1346,7 +1346,7 @@ static void audio_run_capture (AudioState *s)
|
||||
if (audio_bug(__func__, captured > sw->total_hw_samples_mixed)) {
|
||||
dolog("captured=%zu sw->total_hw_samples_mixed=%zu\n",
|
||||
captured, sw->total_hw_samples_mixed);
|
||||
abort();
|
||||
captured = sw->total_hw_samples_mixed;
|
||||
}
|
||||
|
||||
sw->total_hw_samples_mixed -= captured;
|
||||
@@ -2030,6 +2030,7 @@ void audio_create_pdos(Audiodev *dev)
|
||||
CASE(OSS, oss, Oss);
|
||||
CASE(PA, pa, Pa);
|
||||
CASE(SDL, sdl, Sdl);
|
||||
CASE(SNDIO, sndio, );
|
||||
CASE(SPICE, spice, );
|
||||
CASE(WAV, wav, );
|
||||
|
||||
|
||||
+17
-12
@@ -59,13 +59,12 @@ static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
|
||||
if (audio_bug(__func__, !voice_size && max_voices)) {
|
||||
dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
|
||||
drv->name, max_voices);
|
||||
abort();
|
||||
glue (s->nb_hw_voices_, TYPE) = 0;
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, voice_size && !max_voices)) {
|
||||
dolog ("drv=`%s' voice_size=%d max_voices=0\n",
|
||||
drv->name, voice_size);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +81,6 @@ static void glue(audio_pcm_hw_alloc_resources_, TYPE)(HW *hw)
|
||||
size_t samples = hw->samples;
|
||||
if (audio_bug(__func__, samples == 0)) {
|
||||
dolog("Attempted to allocate empty buffer\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
HWBUF = g_malloc0(sizeof(STSampleBuffer) + sizeof(st_sample) * samples);
|
||||
@@ -254,12 +252,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
|
||||
|
||||
if (audio_bug(__func__, !drv)) {
|
||||
dolog ("No host audio driver\n");
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, !drv->pcm_ops)) {
|
||||
dolog ("Host audio driver without pcm_ops\n");
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hw = audio_calloc(__func__, 1, glue(drv->voice_size_, TYPE));
|
||||
@@ -277,13 +275,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
|
||||
QLIST_INIT (&hw->cap_head);
|
||||
#endif
|
||||
if (glue (hw->pcm_ops->init_, TYPE) (hw, as, s->drv_opaque)) {
|
||||
g_free(hw);
|
||||
return NULL;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, hw->samples <= 0)) {
|
||||
dolog("hw->samples=%zd\n", hw->samples);
|
||||
abort();
|
||||
goto err1;
|
||||
}
|
||||
|
||||
if (hw->info.is_float) {
|
||||
@@ -312,6 +309,12 @@ static HW *glue(audio_pcm_hw_add_new_, TYPE)(AudioState *s,
|
||||
audio_attach_capture (hw);
|
||||
#endif
|
||||
return hw;
|
||||
|
||||
err1:
|
||||
glue (hw->pcm_ops->fini_, TYPE) (hw);
|
||||
err0:
|
||||
g_free (hw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
|
||||
@@ -336,6 +339,8 @@ AudiodevPerDirectionOptions *glue(audio_get_pdo_, TYPE)(Audiodev *dev)
|
||||
return qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.TYPE);
|
||||
case AUDIODEV_DRIVER_SDL:
|
||||
return qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.TYPE);
|
||||
case AUDIODEV_DRIVER_SNDIO:
|
||||
return dev->u.sndio.TYPE;
|
||||
case AUDIODEV_DRIVER_SPICE:
|
||||
return dev->u.spice.TYPE;
|
||||
case AUDIODEV_DRIVER_WAV:
|
||||
@@ -432,7 +437,7 @@ void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
|
||||
if (sw) {
|
||||
if (audio_bug(__func__, !card)) {
|
||||
dolog ("card=%p\n", card);
|
||||
abort();
|
||||
return;
|
||||
}
|
||||
|
||||
glue (audio_close_, TYPE) (sw);
|
||||
@@ -454,7 +459,7 @@ SW *glue (AUD_open_, TYPE) (
|
||||
if (audio_bug(__func__, !card || !name || !callback_fn || !as)) {
|
||||
dolog ("card=%p name=%p callback_fn=%p as=%p\n",
|
||||
card, name, callback_fn, as);
|
||||
abort();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
s = card->state;
|
||||
@@ -465,12 +470,12 @@ SW *glue (AUD_open_, TYPE) (
|
||||
|
||||
if (audio_bug(__func__, audio_validate_settings(as))) {
|
||||
audio_print_settings (as);
|
||||
abort();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (audio_bug(__func__, !s->drv)) {
|
||||
dolog ("Can not open `%s' (no host audio driver)\n", name);
|
||||
abort();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (sw && audio_pcm_info_eq (&sw->info, as)) {
|
||||
|
||||
@@ -17,6 +17,7 @@ foreach m : [
|
||||
['pa', pulse, files('paaudio.c')],
|
||||
['sdl', sdl, files('sdlaudio.c')],
|
||||
['jack', jack, files('jackaudio.c')],
|
||||
['sndio', sndio, files('sndioaudio.c')],
|
||||
['spice', spice, files('spiceaudio.c')]
|
||||
]
|
||||
if m[1].found()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -287,8 +287,8 @@ select the fuzz target. Then, the qtest client is initialized. If the target
|
||||
requires qos, qgraph is set up and the QOM/LIBQOS modules are initialized.
|
||||
Then the QGraph is walked and the QEMU cmd_line is determined and saved.
|
||||
|
||||
After this, the ``vl.c:qemu_main`` is called to set up the guest. There are
|
||||
target-specific hooks that can be called before and after qemu_main, for
|
||||
After this, the ``vl.c:main`` is called to set up the guest. There are
|
||||
target-specific hooks that can be called before and after main, for
|
||||
additional setup(e.g. PCI setup, or VM snapshotting).
|
||||
|
||||
``LLVMFuzzerTestOneInput``: Uses qtest/qos functions to act based on the fuzz
|
||||
|
||||
+3
-3
@@ -84,7 +84,7 @@ void ati_2d_blt(ATIVGAState *s)
|
||||
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, s->regs.dst_x, s->regs.dst_y,
|
||||
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' : '^'));
|
||||
@@ -180,11 +180,11 @@ void ati_2d_blt(ATIVGAState *s)
|
||||
dst_stride /= sizeof(uint32_t);
|
||||
DPRINTF("pixman_fill(%p, %d, %d, %d, %d, %d, %d, %x)\n",
|
||||
dst_bits, dst_stride, bpp,
|
||||
s->regs.dst_x, s->regs.dst_y,
|
||||
dst_x, dst_y,
|
||||
s->regs.dst_width, s->regs.dst_height,
|
||||
filler);
|
||||
pixman_fill((uint32_t *)dst_bits, dst_stride, bpp,
|
||||
s->regs.dst_x, s->regs.dst_y,
|
||||
dst_x, dst_y,
|
||||
s->regs.dst_width, s->regs.dst_height,
|
||||
filler);
|
||||
if (dst_bits >= s->vga.vram_ptr + s->vga.vbe_start_addr &&
|
||||
|
||||
@@ -515,9 +515,10 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
|
||||
for (i = 0; i < g->parent_obj.conf.max_outputs; i++) {
|
||||
scanout = &g->parent_obj.scanout[i];
|
||||
if (scanout->resource_id == res->resource_id &&
|
||||
rf.r.x >= scanout->x && rf.r.y >= scanout->y &&
|
||||
rf.r.x + rf.r.width <= scanout->x + scanout->width &&
|
||||
rf.r.y + rf.r.height <= scanout->y + scanout->height &&
|
||||
rf.r.x < scanout->x + scanout->width &&
|
||||
rf.r.x + rf.r.width >= scanout->x &&
|
||||
rf.r.y < scanout->y + scanout->height &&
|
||||
rf.r.y + rf.r.height >= scanout->y &&
|
||||
console_has_gl(scanout->con)) {
|
||||
dpy_gl_update(scanout->con, 0, 0, scanout->width,
|
||||
scanout->height);
|
||||
|
||||
+31
-7
@@ -91,6 +91,8 @@ enum usbstring_idx {
|
||||
#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43
|
||||
#define USB_CDC_GET_ETHERNET_STATISTIC 0x44
|
||||
|
||||
#define USB_CDC_NETWORK_CONNECTION 0x00
|
||||
|
||||
#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
|
||||
#define STATUS_BYTECOUNT 16 /* 8 byte header + data */
|
||||
|
||||
@@ -640,6 +642,8 @@ struct USBNetState {
|
||||
uint16_t filter;
|
||||
uint32_t vendorid;
|
||||
|
||||
uint16_t connection;
|
||||
|
||||
unsigned int out_ptr;
|
||||
uint8_t out_buf[2048];
|
||||
|
||||
@@ -647,6 +651,7 @@ struct USBNetState {
|
||||
uint8_t in_buf[2048];
|
||||
|
||||
USBEndpoint *intr;
|
||||
USBEndpoint *bulk_in;
|
||||
|
||||
char usbstring_mac[13];
|
||||
NICState *nic;
|
||||
@@ -1121,6 +1126,12 @@ static void usb_net_handle_control(USBDevice *dev, USBPacket *p,
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ClassInterfaceOutRequest | USB_CDC_SET_ETHERNET_PACKET_FILTER:
|
||||
if (is_rndis(s)) {
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fail:
|
||||
fprintf(stderr, "usbnet: failed control transaction: "
|
||||
@@ -1133,18 +1144,28 @@ static void usb_net_handle_control(USBDevice *dev, USBPacket *p,
|
||||
|
||||
static void usb_net_handle_statusin(USBNetState *s, USBPacket *p)
|
||||
{
|
||||
le32 buf[2];
|
||||
le32 rbuf[2];
|
||||
uint16_t ebuf[4];
|
||||
|
||||
if (p->iov.size < 8) {
|
||||
p->status = USB_RET_STALL;
|
||||
return;
|
||||
}
|
||||
|
||||
buf[0] = cpu_to_le32(1);
|
||||
buf[1] = cpu_to_le32(0);
|
||||
usb_packet_copy(p, buf, 8);
|
||||
if (!s->rndis_resp.tqh_first) {
|
||||
p->status = USB_RET_NAK;
|
||||
if (is_rndis(s)) {
|
||||
rbuf[0] = cpu_to_le32(1);
|
||||
rbuf[1] = cpu_to_le32(0);
|
||||
usb_packet_copy(p, rbuf, 8);
|
||||
if (!s->rndis_resp.tqh_first) {
|
||||
p->status = USB_RET_NAK;
|
||||
}
|
||||
} else {
|
||||
ebuf[0] =
|
||||
cpu_to_be16(ClassInterfaceRequest | USB_CDC_NETWORK_CONNECTION);
|
||||
ebuf[1] = cpu_to_le16(s->connection);
|
||||
ebuf[2] = cpu_to_le16(1);
|
||||
ebuf[3] = cpu_to_le16(0);
|
||||
usb_packet_copy(p, ebuf, 8);
|
||||
}
|
||||
|
||||
#ifdef TRAFFIC_DEBUG
|
||||
@@ -1204,7 +1225,7 @@ static void usb_net_handle_dataout(USBNetState *s, USBPacket *p)
|
||||
s->out_ptr += sz;
|
||||
|
||||
if (!is_rndis(s)) {
|
||||
if (p->iov.size < 64) {
|
||||
if (p->iov.size % 64 || p->iov.size == 0) {
|
||||
qemu_send_packet(qemu_get_queue(s->nic), s->out_buf, s->out_ptr);
|
||||
s->out_ptr = 0;
|
||||
}
|
||||
@@ -1317,6 +1338,7 @@ static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t siz
|
||||
memcpy(in_buf, buf, size);
|
||||
s->in_len = total_size;
|
||||
s->in_ptr = 0;
|
||||
usb_wakeup(s->bulk_in, 0);
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -1358,7 +1380,9 @@ static void usb_net_realize(USBDevice *dev, Error **errp)
|
||||
s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */;
|
||||
s->filter = 0;
|
||||
s->vendorid = 0x1234;
|
||||
s->connection = 1; /* Connected */
|
||||
s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
|
||||
s->bulk_in = usb_ep_get(dev, USB_TOKEN_IN, 2);
|
||||
|
||||
qemu_macaddr_default_if_unset(&s->conf.macaddr);
|
||||
s->nic = qemu_new_nic(&net_usbnet_info, &s->conf,
|
||||
|
||||
+43
-13
@@ -177,6 +177,37 @@ static const USBDesc desc = {
|
||||
.str = desc_strings,
|
||||
};
|
||||
|
||||
static void usb_msd_packet_complete(MSDState *s)
|
||||
{
|
||||
USBPacket *p = s->packet;
|
||||
|
||||
/*
|
||||
* Set s->packet to NULL before calling usb_packet_complete
|
||||
* because another request may be issued before
|
||||
* usb_packet_complete returns.
|
||||
*/
|
||||
trace_usb_msd_packet_complete();
|
||||
s->packet = NULL;
|
||||
usb_packet_complete(&s->dev, p);
|
||||
}
|
||||
|
||||
static void usb_msd_fatal_error(MSDState *s)
|
||||
{
|
||||
trace_usb_msd_fatal_error();
|
||||
|
||||
if (s->packet) {
|
||||
s->packet->status = USB_RET_STALL;
|
||||
usb_msd_packet_complete(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Guest messed up up device state with illegal requests. Go
|
||||
* ignore any requests until the guests resets the device (and
|
||||
* brings it into a known state that way).
|
||||
*/
|
||||
s->needs_reset = true;
|
||||
}
|
||||
|
||||
static void usb_msd_copy_data(MSDState *s, USBPacket *p)
|
||||
{
|
||||
uint32_t len;
|
||||
@@ -208,24 +239,16 @@ static void usb_msd_send_status(MSDState *s, USBPacket *p)
|
||||
memset(&s->csw, 0, sizeof(s->csw));
|
||||
}
|
||||
|
||||
static void usb_msd_packet_complete(MSDState *s)
|
||||
{
|
||||
USBPacket *p = s->packet;
|
||||
|
||||
/* Set s->packet to NULL before calling usb_packet_complete
|
||||
because another request may be issued before
|
||||
usb_packet_complete returns. */
|
||||
trace_usb_msd_packet_complete();
|
||||
s->packet = NULL;
|
||||
usb_packet_complete(&s->dev, p);
|
||||
}
|
||||
|
||||
void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
|
||||
{
|
||||
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent);
|
||||
USBPacket *p = s->packet;
|
||||
|
||||
assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV));
|
||||
if ((s->mode == USB_MSDM_DATAOUT) != (req->cmd.mode == SCSI_XFER_TO_DEV)) {
|
||||
usb_msd_fatal_error(s);
|
||||
return;
|
||||
}
|
||||
|
||||
s->scsi_len = len;
|
||||
s->scsi_off = 0;
|
||||
if (p) {
|
||||
@@ -315,6 +338,8 @@ void usb_msd_handle_reset(USBDevice *dev)
|
||||
|
||||
memset(&s->csw, 0, sizeof(s->csw));
|
||||
s->mode = USB_MSDM_CBW;
|
||||
|
||||
s->needs_reset = false;
|
||||
}
|
||||
|
||||
static void usb_msd_handle_control(USBDevice *dev, USBPacket *p,
|
||||
@@ -380,6 +405,11 @@ static void usb_msd_handle_data(USBDevice *dev, USBPacket *p)
|
||||
SCSIDevice *scsi_dev;
|
||||
uint32_t len;
|
||||
|
||||
if (s->needs_reset) {
|
||||
p->status = USB_RET_STALL;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (p->pid) {
|
||||
case USB_TOKEN_OUT:
|
||||
if (devep != 2)
|
||||
|
||||
@@ -571,6 +571,11 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed)
|
||||
|
||||
addr = ed->head & OHCI_DPTR_MASK;
|
||||
|
||||
if (addr == 0) {
|
||||
ohci_die(ohci);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ohci_read_iso_td(ohci, addr, &iso_td)) {
|
||||
trace_usb_ohci_iso_td_read_failed(addr);
|
||||
ohci_die(ohci);
|
||||
@@ -859,6 +864,11 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
|
||||
int completion;
|
||||
|
||||
addr = ed->head & OHCI_DPTR_MASK;
|
||||
if (addr == 0) {
|
||||
ohci_die(ohci);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* See if this TD has already been submitted to the device. */
|
||||
completion = (addr == ohci->async_td);
|
||||
if (completion && !ohci->async_complete) {
|
||||
|
||||
+51
-17
@@ -463,6 +463,12 @@ static void xhci_mfwrap_timer(void *opaque)
|
||||
xhci_mfwrap_update(xhci);
|
||||
}
|
||||
|
||||
static void xhci_die(XHCIState *xhci)
|
||||
{
|
||||
xhci->usbsts |= USBSTS_HCE;
|
||||
DPRINTF("xhci: asserted controller error\n");
|
||||
}
|
||||
|
||||
static inline dma_addr_t xhci_addr64(uint32_t low, uint32_t high)
|
||||
{
|
||||
if (sizeof(dma_addr_t) == 4) {
|
||||
@@ -488,7 +494,14 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, dma_addr_t addr,
|
||||
|
||||
assert((len % sizeof(uint32_t)) == 0);
|
||||
|
||||
dma_memory_read(xhci->as, addr, buf, len, MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_read(xhci->as, addr, buf, len,
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
memset(buf, 0xff, len);
|
||||
xhci_die(xhci);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < (len / sizeof(uint32_t)); i++) {
|
||||
buf[i] = le32_to_cpu(buf[i]);
|
||||
@@ -496,7 +509,7 @@ static inline void xhci_dma_read_u32s(XHCIState *xhci, dma_addr_t addr,
|
||||
}
|
||||
|
||||
static inline void xhci_dma_write_u32s(XHCIState *xhci, dma_addr_t addr,
|
||||
uint32_t *buf, size_t len)
|
||||
const uint32_t *buf, size_t len)
|
||||
{
|
||||
int i;
|
||||
uint32_t tmp[5];
|
||||
@@ -508,7 +521,13 @@ static inline void xhci_dma_write_u32s(XHCIState *xhci, dma_addr_t addr,
|
||||
for (i = 0; i < n; i++) {
|
||||
tmp[i] = cpu_to_le32(buf[i]);
|
||||
}
|
||||
dma_memory_write(xhci->as, addr, tmp, len, MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_write(xhci->as, addr, tmp, len,
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
xhci_die(xhci);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport)
|
||||
@@ -593,12 +612,6 @@ static inline int xhci_running(XHCIState *xhci)
|
||||
return !(xhci->usbsts & USBSTS_HCH);
|
||||
}
|
||||
|
||||
static void xhci_die(XHCIState *xhci)
|
||||
{
|
||||
xhci->usbsts |= USBSTS_HCE;
|
||||
DPRINTF("xhci: asserted controller error\n");
|
||||
}
|
||||
|
||||
static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
|
||||
{
|
||||
XHCIInterrupter *intr = &xhci->intr[v];
|
||||
@@ -619,7 +632,12 @@ static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
|
||||
ev_trb.status, ev_trb.control);
|
||||
|
||||
addr = intr->er_start + TRB_SIZE*intr->er_ep_idx;
|
||||
dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE, MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_write(xhci->as, addr, &ev_trb, TRB_SIZE,
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
xhci_die(xhci);
|
||||
}
|
||||
|
||||
intr->er_ep_idx++;
|
||||
if (intr->er_ep_idx >= intr->er_size) {
|
||||
@@ -680,8 +698,12 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
|
||||
|
||||
while (1) {
|
||||
TRBType type;
|
||||
dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE,
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_read(xhci->as, ring->dequeue, trb, TRB_SIZE,
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
trb->addr = ring->dequeue;
|
||||
trb->ccs = ring->ccs;
|
||||
le64_to_cpus(&trb->parameter);
|
||||
@@ -798,8 +820,14 @@ static void xhci_er_reset(XHCIState *xhci, int v)
|
||||
xhci_die(xhci);
|
||||
return;
|
||||
}
|
||||
dma_memory_read(xhci->as, erstba, &seg, sizeof(seg),
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_read(xhci->as, erstba, &seg, sizeof(seg),
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n",
|
||||
__func__);
|
||||
xhci_die(xhci);
|
||||
return;
|
||||
}
|
||||
|
||||
le32_to_cpus(&seg.addr_low);
|
||||
le32_to_cpus(&seg.addr_high);
|
||||
le32_to_cpus(&seg.size);
|
||||
@@ -992,7 +1020,9 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx,
|
||||
}
|
||||
sctx = epctx->pstreams + streamid;
|
||||
} else {
|
||||
FIXME("secondary streams not implemented yet");
|
||||
fprintf(stderr, "xhci: FIXME: secondary streams not implemented yet");
|
||||
*cc_error = CC_INVALID_STREAM_TYPE_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sctx->sct == -1) {
|
||||
@@ -2415,8 +2445,12 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx)
|
||||
/* TODO: actually implement real values here */
|
||||
bw_ctx[0] = 0;
|
||||
memset(&bw_ctx[1], 80, xhci->numports); /* 80% */
|
||||
dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx),
|
||||
MEMTXATTRS_UNSPECIFIED);
|
||||
if (dma_memory_write(xhci->as, ctx, bw_ctx, sizeof(bw_ctx),
|
||||
MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory write failed!\n",
|
||||
__func__);
|
||||
return CC_TRB_ERROR;
|
||||
}
|
||||
|
||||
return CC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -263,6 +263,7 @@ usb_msd_packet_complete(void) ""
|
||||
usb_msd_cmd_submit(unsigned lun, unsigned tag, unsigned flags, unsigned len, unsigned data_len) "lun %u, tag 0x%x, flags 0x%08x, len %d, data-len %d"
|
||||
usb_msd_cmd_complete(unsigned status, unsigned tag) "status %d, tag 0x%x"
|
||||
usb_msd_cmd_cancel(unsigned tag) "tag 0x%x"
|
||||
usb_msd_fatal_error(void) ""
|
||||
|
||||
# dev-uas.c
|
||||
usb_uas_reset(int addr) "dev %d"
|
||||
|
||||
@@ -40,6 +40,7 @@ struct MSDState {
|
||||
bool removable;
|
||||
bool commandlog;
|
||||
SCSIDevice *scsi_dev;
|
||||
bool needs_reset;
|
||||
};
|
||||
|
||||
typedef struct MSDState MSDState;
|
||||
|
||||
+2
-1
@@ -5,6 +5,7 @@
|
||||
#ifndef QEMU_MAIN_H
|
||||
#define QEMU_MAIN_H
|
||||
|
||||
int qemu_main(int argc, char **argv, char **envp);
|
||||
int qemu_default_main(void);
|
||||
extern int (*qemu_main)(void);
|
||||
|
||||
#endif /* QEMU_MAIN_H */
|
||||
|
||||
@@ -284,23 +284,10 @@ bool qemu_in_main_thread(void);
|
||||
* Please refer to include/block/block-global-state.h for more
|
||||
* information about GS API.
|
||||
*/
|
||||
#ifdef CONFIG_COCOA
|
||||
/*
|
||||
* When using the Cocoa UI, addRemovableDevicesMenuItems() is called from
|
||||
* a thread different from the QEMU main thread and can not take the BQL,
|
||||
* triggering this assertions in the block layer (commit 0439c5a462).
|
||||
* As the Cocoa fix is not trivial, disable this assertion for the v7.0.0
|
||||
* release (when using Cocoa); we will restore it immediately after the
|
||||
* release.
|
||||
* This issue is tracked as https://gitlab.com/qemu-project/qemu/-/issues/926
|
||||
*/
|
||||
#define GLOBAL_STATE_CODE()
|
||||
#else
|
||||
#define GLOBAL_STATE_CODE() \
|
||||
do { \
|
||||
assert(qemu_in_main_thread()); \
|
||||
} while (0)
|
||||
#endif /* CONFIG_COCOA */
|
||||
|
||||
/*
|
||||
* Mark and check that the function is part of the I/O API.
|
||||
|
||||
@@ -102,7 +102,7 @@ void qemu_boot_set(const char *boot_order, Error **errp);
|
||||
|
||||
bool defaults_enabled(void);
|
||||
|
||||
void qemu_init(int argc, char **argv, char **envp);
|
||||
void qemu_init(int argc, char **argv);
|
||||
int qemu_main_loop(void);
|
||||
void qemu_cleanup(void);
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ void hmp_mouse_set(Monitor *mon, const QDict *qdict);
|
||||
/* keysym is a unicode code except for special keys (see QEMU_KEY_xxx
|
||||
constants) */
|
||||
#define QEMU_KEY_ESC1(c) ((c) | 0xe100)
|
||||
#define QEMU_KEY_TAB 0x0009
|
||||
#define QEMU_KEY_BACKSPACE 0x007f
|
||||
#define QEMU_KEY_UP QEMU_KEY_ESC1('A')
|
||||
#define QEMU_KEY_DOWN QEMU_KEY_ESC1('B')
|
||||
|
||||
+10
-9
@@ -589,12 +589,6 @@ endif
|
||||
|
||||
cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
|
||||
required: get_option('cocoa'))
|
||||
if cocoa.found() and get_option('sdl').enabled()
|
||||
error('Cocoa and SDL cannot be enabled at the same time')
|
||||
endif
|
||||
if cocoa.found() and get_option('gtk').enabled()
|
||||
error('Cocoa and GTK+ cannot be enabled at the same time')
|
||||
endif
|
||||
|
||||
vmnet = dependency('appleframeworks', modules: 'vmnet', required: get_option('vmnet'))
|
||||
if vmnet.found() and not cc.has_header_symbol('vmnet/vmnet.h',
|
||||
@@ -681,6 +675,11 @@ if not get_option('jack').auto() or have_system
|
||||
jack = dependency('jack', required: get_option('jack'),
|
||||
method: 'pkg-config', kwargs: static_kwargs)
|
||||
endif
|
||||
sndio = not_found
|
||||
if not get_option('sndio').auto() or have_system
|
||||
sndio = dependency('sndio', required: get_option('sndio'),
|
||||
method: 'pkg-config', kwargs: static_kwargs)
|
||||
endif
|
||||
|
||||
spice_protocol = not_found
|
||||
if not get_option('spice_protocol').auto() or have_system
|
||||
@@ -921,7 +920,7 @@ if not get_option('brlapi').auto() or have_system
|
||||
endif
|
||||
|
||||
sdl = not_found
|
||||
if not get_option('sdl').auto() or (have_system and not cocoa.found())
|
||||
if not get_option('sdl').auto() or have_system
|
||||
sdl = dependency('sdl2', required: get_option('sdl'), kwargs: static_kwargs)
|
||||
sdl_image = not_found
|
||||
endif
|
||||
@@ -1187,7 +1186,7 @@ endif
|
||||
gtk = not_found
|
||||
gtkx11 = not_found
|
||||
vte = not_found
|
||||
if not get_option('gtk').auto() or (have_system and not cocoa.found())
|
||||
if not get_option('gtk').auto() or have_system
|
||||
gtk = dependency('gtk+-3.0', version: '>=3.22.0',
|
||||
method: 'pkg-config',
|
||||
required: get_option('gtk'),
|
||||
@@ -1597,6 +1596,7 @@ if have_system
|
||||
'oss': oss.found(),
|
||||
'pa': pulse.found(),
|
||||
'sdl': sdl.found(),
|
||||
'sndio': sndio.found(),
|
||||
}
|
||||
foreach k, v: audio_drivers_available
|
||||
config_host_data.set('CONFIG_AUDIO_' + k.to_upper(), v)
|
||||
@@ -1604,7 +1604,7 @@ if have_system
|
||||
|
||||
# Default to native drivers first, OSS second, SDL third
|
||||
audio_drivers_priority = \
|
||||
[ 'pa', 'coreaudio', 'dsound', 'oss' ] + \
|
||||
[ 'pa', 'coreaudio', 'dsound', 'sndio', 'oss' ] + \
|
||||
(targetos == 'linux' ? [] : [ 'sdl' ])
|
||||
audio_drivers_default = []
|
||||
foreach k: audio_drivers_priority
|
||||
@@ -3928,6 +3928,7 @@ if vnc.found()
|
||||
endif
|
||||
if targetos not in ['darwin', 'haiku', 'windows']
|
||||
summary_info += {'OSS support': oss}
|
||||
summary_info += {'sndio support': sndio}
|
||||
elif targetos == 'darwin'
|
||||
summary_info += {'CoreAudio support': coreaudio}
|
||||
elif targetos == 'windows'
|
||||
|
||||
+3
-1
@@ -21,7 +21,7 @@ option('tls_priority', type : 'string', value : 'NORMAL',
|
||||
option('default_devices', type : 'boolean', value : true,
|
||||
description: 'Include a default selection of devices in emulators')
|
||||
option('audio_drv_list', type: 'array', value: ['default'],
|
||||
choices: ['alsa', 'coreaudio', 'default', 'dsound', 'jack', 'oss', 'pa', 'sdl'],
|
||||
choices: ['alsa', 'coreaudio', 'default', 'dsound', 'jack', 'oss', 'pa', 'sdl', 'sndio'],
|
||||
description: 'Set audio driver list')
|
||||
option('block_drv_rw_whitelist', type : 'string', value : '',
|
||||
description: 'set block driver read-write whitelist (by default affects only QEMU, not tools like qemu-img)')
|
||||
@@ -240,6 +240,8 @@ option('oss', type: 'feature', value: 'auto',
|
||||
description: 'OSS sound support')
|
||||
option('pa', type: 'feature', value: 'auto',
|
||||
description: 'PulseAudio sound support')
|
||||
option('sndio', type: 'feature', value: 'auto',
|
||||
description: 'sndio sound support')
|
||||
|
||||
option('vhost_kernel', type: 'feature', value: 'auto',
|
||||
description: 'vhost kernel backend support')
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user