diff options
-rw-r--r-- | hw/usb/hcd-xhci.c | 23 | ||||
-rw-r--r-- | tests/qtest/readconfig-test.c | 12 |
2 files changed, 25 insertions, 10 deletions
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 296cc6c8e6..3c48b58dde 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "qemu/timer.h" +#include "qemu/log.h" #include "qemu/module.h" #include "qemu/queue.h" #include "migration/vmstate.h" @@ -725,10 +726,14 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) bool control_td_set = 0; uint32_t link_cnt = 0; - while (1) { + do { TRBType type; - dma_memory_read(xhci->as, dequeue, &trb, TRB_SIZE, - MEMTXATTRS_UNSPECIFIED); + if (dma_memory_read(xhci->as, dequeue, &trb, TRB_SIZE, + MEMTXATTRS_UNSPECIFIED) != MEMTX_OK) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA memory access failed!\n", + __func__); + return -1; + } le64_to_cpus(&trb.parameter); le32_to_cpus(&trb.status); le32_to_cpus(&trb.control); @@ -762,7 +767,17 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) if (!control_td_set && !(trb.control & TRB_TR_CH)) { return length; } - } + + /* + * According to the xHCI spec, Transfer Ring segments should have + * a maximum size of 64 kB (see chapter "6 Data Structures") + */ + } while (length < TRB_LINK_LIMIT * 65536 / TRB_SIZE); + + qemu_log_mask(LOG_GUEST_ERROR, "%s: exceeded maximum tranfer ring size!\n", + __func__); + + return -1; } static void xhci_er_reset(XHCIState *xhci, int v) diff --git a/tests/qtest/readconfig-test.c b/tests/qtest/readconfig-test.c index 2e604d7c2d..c7a9b0c7dd 100644 --- a/tests/qtest/readconfig-test.c +++ b/tests/qtest/readconfig-test.c @@ -33,13 +33,12 @@ static QTestState *qtest_init_with_config(const char *cfgdata) g_assert_cmpint(cfgfd, >=, 0); ret = qemu_write_full(cfgfd, cfgdata, strlen(cfgdata)); + close(cfgfd); if (ret < 0) { unlink(cfgpath); } g_assert_cmpint(ret, ==, strlen(cfgdata)); - close(cfgfd); - args = g_strdup_printf("-nodefaults -machine none -readconfig %s", cfgpath); qts = qtest_init(args); @@ -79,7 +78,7 @@ static void test_x86_memdev(void) "size = \"200\""; qts = qtest_init_with_config(cfgdata); - /* Test valid command */ + /* Test valid command */ resp = qtest_qmp(qts, "{ 'execute': 'query-memdev' }"); test_x86_memdev_resp(qdict_get(resp, "return")); qobject_unref(resp); @@ -96,7 +95,7 @@ static void test_spice_resp(QObject *res) g_assert(res); v = qobject_input_visitor_new(res); - visit_type_SpiceInfo(v, "spcie", &spice, &error_abort); + visit_type_SpiceInfo(v, "spice", &spice, &error_abort); g_assert(spice); g_assert(spice->enabled); @@ -114,7 +113,7 @@ static void test_spice(void) "unix = \"on\"\n"; qts = qtest_init_with_config(cfgdata); - /* Test valid command */ + /* Test valid command */ resp = qtest_qmp(qts, "{ 'execute': 'query-spice' }"); test_spice_resp(qdict_get(resp, "return")); qobject_unref(resp); @@ -144,6 +143,7 @@ static void test_object_rng_resp(QObject *res) if (g_str_equal(obj->name, "rng0") && g_str_equal(obj->type, "child<rng-builtin>")) { seen_rng = true; + break; } tmp = tmp->next; @@ -164,7 +164,7 @@ static void test_object_rng(void) "id = \"rng0\"\n"; qts = qtest_init_with_config(cfgdata); - /* Test valid command */ + /* Test valid command */ resp = qtest_qmp(qts, "{ 'execute': 'qom-list'," " 'arguments': {'path': '/objects' }}"); |