- Fix "make check" problem that occurred with LANG=C and Python 3.5 / 3.6

- Get rid of some more dependencies on the global_qtest variable in the qtests
 - Some other small test clean-ups
 - Some copyright statement clarifications
 - Mark TARGET_FMT_lu as poisoned
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJc09qrAAoJEC7Z13T+cC21VmcP/jeQLEJUcAgTPGIkhsNrl6g+
 mXqnHd2QEJE+hzcbdgHs/d7XU3+BcPZVG22uoeWNK2S45JMk3gFrltZkx4HcOgW0
 UIjtiOu1bcTkSlU82/SaDFSvdvmP+CHcJrOMdwjZhK3UjjmMsR2VkKYd0ESnm7yP
 RFP7cSgEoMJyUPjieF0D8dg7XmSWdbhTI1XYyBOP2zPRoduFYT0eb+bE052SD7ve
 DussTGT6Ub0TpbGyKBtqtD9Ej0hkFAdSjNHeDr8Dzb7wHMTZD4J9m/8T04oOgtN0
 pUla6Ufx5aqr4H27DOF8XIrOz9945kisYJrJJFa9AOL5CM379upxnGdycVHN6MCE
 fuMXmtZ1mxuOJ9hutEk81whsDsXDuQwKA4YazJiSHhzJDzpztjn+Ng0fW5UGY2Wo
 dX8uaX04rTvmUWHuaZqPCwVjgVgzlTMYfVvh0+2NYDGsMQFQvMtlJW/RNLpT4dX1
 e5E5sKvQ3a8hrK6SiPZDftpnMEd+v/4BDSSQeVHbl03rFVsJH5CSoH/0f7lTDzOi
 LF53h8fiNt7u2/nIl7fVjn2haf9+JuWAdF1yyg4WFuvPncGcRNGVWJL+qj/dXxWJ
 kgQMDTGm00VYp00Pq+J5xTxVmOoZzEdO/hXKpwOHXOViw0M2CO871mRc57/CvHCY
 +0xtPH9bZdPj79GrigSA
 =LGlY
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2019-05-09' into staging

- Fix "make check" problem that occurred with LANG=C and Python 3.5 / 3.6
- Get rid of some more dependencies on the global_qtest variable in the qtests
- Some other small test clean-ups
- Some copyright statement clarifications
- Mark TARGET_FMT_lu as poisoned

# gpg: Signature made Thu 09 May 2019 08:45:47 BST
# gpg:                using RSA key 2ED9D774FE702DB5
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* remotes/huth-gitlab/tags/pull-request-2019-05-09:
  include/exec/poison: Mark TARGET_FMT_lu as poisoned, too
  target/sh4: Fix LGPL information in the file headers
  target/openrisc: Fix LGPL information in the file headers
  hw/i2c/smbus_ich9: Fix the confusing contributions-after-2012 statement
  tests: qpci_unplug_acpi_device_test() should not rely on global_qtest
  tests/drive_del-test: Use qtest_init() instead of qtest_start()
  tests/Makefile: Remove unused test-obj-y variable
  tests/tpm-tests: Use g_test_skip() to mark skipped tests
  tests/ide-test: Make test independent of global_qtest
  tests/test-hmp: Use qtest_init() instead of qtest_start()
  tests/qmp-cmd-test: Use qtest_init() instead of qtest_start()
  tests/megasas: Make test independent of global_qtest
  tests/tco: Make test independent of global_qtest
  tests: Force Python I/O encoding for check-qapi-schema

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-05-09 15:43:41 +01:00
commit 9d86d9eac9
37 changed files with 298 additions and 270 deletions

View File

@ -6,23 +6,18 @@
* VA Linux Systems Japan K.K.
* Copyright (C) 2012 Jason Baron <jbaron@redhat.com>
*
* This is based on acpi.c, but heavily rewritten.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2 as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>
*
* Contributions after 2012-01-13 are licensed under the terms of the
* GNU GPL, version 2 or (at your option) any later version.
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*/
#include "qemu/osdep.h"
#include "hw/hw.h"

View File

@ -7,7 +7,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -7,7 +7,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -7,7 +7,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -44,6 +44,7 @@
#pragma GCC poison TARGET_LONG_BITS
#pragma GCC poison TARGET_FMT_lx
#pragma GCC poison TARGET_FMT_ld
#pragma GCC poison TARGET_FMT_lu
#pragma GCC poison TARGET_PAGE_SIZE
#pragma GCC poison TARGET_PAGE_MASK

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -7,7 +7,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -7,7 +7,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -7,7 +7,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -6,7 +6,7 @@
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -482,25 +482,6 @@ GENERATED_FILES += tests/test-qapi-types.h \
tests/test-qapi-events-sub-sub-module.h \
tests/test-qapi-introspect.h
test-obj-y = tests/check-qnum.o tests/check-qstring.o tests/check-qdict.o \
tests/check-qlist.o tests/check-qnull.o tests/check-qobject.o \
tests/check-qjson.o tests/check-qlit.o \
tests/check-block-qtest.o \
tests/test-coroutine.o tests/test-string-output-visitor.o \
tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \
tests/test-clone-visitor.o \
tests/test-qobject-input-visitor.o \
tests/test-qmp-cmds.o tests/test-visitor-serialization.o \
tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \
tests/test-opts-visitor.o tests/test-qmp-event.o \
tests/rcutorture.o tests/test-rcu-list.o \
tests/test-rcu-simpleq.o \
tests/test-rcu-tailq.o \
tests/test-qdist.o tests/test-shift128.o \
tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o \
tests/atomic_add-bench.o tests/atomic64-bench.o
$(test-obj-y): QEMU_INCLUDES += -Itests
QEMU_CFLAGS += -I$(SRC_PATH)/tests
@ -1103,7 +1084,7 @@ check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF)
.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
$(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
$(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \
$(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
PYTHONIOENCODING=utf-8 $(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
$^ >$*.test.out 2>$*.test.err; \
echo $$? >$*.test.exit, \
"TEST","$*.out")

View File

@ -16,32 +16,32 @@
#include "qapi/qmp/qdict.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
#define qmp_discard_response(q, ...) qobject_unref(qtest_qmp(q, __VA_ARGS__))
static void drive_add(void)
static void drive_add(QTestState *qts)
{
char *resp = hmp("drive_add 0 if=none,id=drive0");
char *resp = qtest_hmp(qts, "drive_add 0 if=none,id=drive0");
g_assert_cmpstr(resp, ==, "OK\r\n");
g_free(resp);
}
static void drive_del(void)
static void drive_del(QTestState *qts)
{
char *resp = hmp("drive_del drive0");
char *resp = qtest_hmp(qts, "drive_del drive0");
g_assert_cmpstr(resp, ==, "");
g_free(resp);
}
static void device_del(void)
static void device_del(QTestState *qts)
{
QDict *response;
/* Complication: ignore DEVICE_DELETED event */
qmp_discard_response("{'execute': 'device_del',"
qmp_discard_response(qts, "{'execute': 'device_del',"
" 'arguments': { 'id': 'dev0' } }");
response = qmp_receive();
response = qtest_qmp_receive(qts);
g_assert(response);
g_assert(qdict_haskey(response, "return"));
qobject_unref(response);
@ -49,18 +49,20 @@ static void device_del(void)
static void test_drive_without_dev(void)
{
QTestState *qts;
/* Start with an empty drive */
qtest_start("-drive if=none,id=drive0");
qts = qtest_init("-drive if=none,id=drive0");
/* Delete the drive */
drive_del();
drive_del(qts);
/* Ensure re-adding the drive works - there should be no duplicate ID error
* because the old drive must be gone.
*/
drive_add();
drive_add(qts);
qtest_end();
qtest_quit(qts);
}
/*
@ -85,54 +87,53 @@ static void test_after_failed_device_add(void)
{
char driver[32];
QDict *response;
QTestState *qts;
snprintf(driver, sizeof(driver), "virtio-blk-%s",
qvirtio_get_dev_type());
qtest_start("-drive if=none,id=drive0");
qts = qtest_init("-drive if=none,id=drive0");
/* Make device_add fail. If this leaks the virtio-blk device then a
* reference to drive0 will also be held (via qdev properties).
*/
response = qmp("{'execute': 'device_add',"
" 'arguments': {"
" 'driver': %s,"
" 'drive': 'drive0'"
"}}", driver);
response = qtest_qmp(qts, "{'execute': 'device_add',"
" 'arguments': {"
" 'driver': %s,"
" 'drive': 'drive0'"
"}}", driver);
g_assert(response);
qmp_assert_error_class(response, "GenericError");
/* Delete the drive */
drive_del();
drive_del(qts);
/* Try to re-add the drive. This fails with duplicate IDs if a leaked
* virtio-blk device exists that holds a reference to the old drive0.
*/
drive_add();
drive_add(qts);
qtest_end();
qtest_quit(qts);
}
static void test_drive_del_device_del(void)
{
char *args;
QTestState *qts;
/* Start with a drive used by a device that unplugs instantaneously */
args = g_strdup_printf("-drive if=none,id=drive0,file=null-co://,format=raw"
" -device virtio-scsi-%s"
" -device scsi-hd,drive=drive0,id=dev0",
qvirtio_get_dev_type());
qtest_start(args);
qts = qtest_initf("-drive if=none,id=drive0,file=null-co://,format=raw"
" -device virtio-scsi-%s"
" -device scsi-hd,drive=drive0,id=dev0",
qvirtio_get_dev_type());
/*
* Delete the drive, and then the device
* Doing it in this order takes notoriously tricky special paths
*/
drive_del();
device_del();
drive_del(qts);
device_del(qts);
qtest_end();
g_free(args);
qtest_quit(qts);
}
int main(int argc, char **argv)

View File

@ -231,8 +231,10 @@ static void test_e1000e_multiple_transfers(void *obj, void *data,
static void test_e1000e_hotplug(void *obj, void *data, QGuestAllocator * alloc)
{
QTestState *qts = global_qtest; /* TODO: get rid of global_qtest here */
qtest_qmp_device_add("e1000e", "e1000e_net", "{'addr': '0x06'}");
qpci_unplug_acpi_device_test("e1000e_net", 0x06);
qpci_unplug_acpi_device_test(qts, "e1000e_net", 0x06);
}
static void data_test_clear(void *sockets)

View File

@ -36,7 +36,7 @@
#include "hw/pci/pci_regs.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
#define qmp_discard_response(q, ...) qobject_unref(qtest_qmp(q, __VA_ARGS__))
#define TEST_IMAGE_SIZE 64 * 1024 * 1024
@ -125,38 +125,38 @@ static QGuestAllocator guest_malloc;
static char tmp_path[] = "/tmp/qtest.XXXXXX";
static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX";
static void ide_test_start(const char *cmdline_fmt, ...)
static QTestState *ide_test_start(const char *cmdline_fmt, ...)
{
QTestState *qts;
va_list ap;
char *cmdline;
va_start(ap, cmdline_fmt);
cmdline = g_strdup_vprintf(cmdline_fmt, ap);
qts = qtest_vinitf(cmdline_fmt, ap);
va_end(ap);
qtest_start(cmdline);
pc_alloc_init(&guest_malloc, global_qtest, 0);
pc_alloc_init(&guest_malloc, qts, 0);
g_free(cmdline);
return qts;
}
static void ide_test_quit(void)
static void ide_test_quit(QTestState *qts)
{
if (pcibus) {
qpci_free_pc(pcibus);
pcibus = NULL;
}
alloc_destroy(&guest_malloc);
qtest_end();
qtest_quit(qts);
}
static QPCIDevice *get_pci_device(QPCIBar *bmdma_bar, QPCIBar *ide_bar)
static QPCIDevice *get_pci_device(QTestState *qts, QPCIBar *bmdma_bar,
QPCIBar *ide_bar)
{
QPCIDevice *dev;
uint16_t vendor_id, device_id;
if (!pcibus) {
pcibus = qpci_new_pc(global_qtest, NULL);
pcibus = qpci_new_pc(qts, NULL);
}
/* Find PCI device and verify it's the right one */
@ -198,8 +198,8 @@ static uint64_t trim_range_le(uint64_t sector, uint16_t count)
return cpu_to_le64(((uint64_t)count << 48) + sector);
}
static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
PrdtEntry *prdt, int prdt_entries,
static int send_dma_request(QTestState *qts, int cmd, uint64_t sector,
int nb_sectors, PrdtEntry *prdt, int prdt_entries,
void(*post_exec)(QPCIDevice *dev, QPCIBar ide_bar,
uint64_t sector, int nb_sectors))
{
@ -211,7 +211,7 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
uint8_t status;
int flags;
dev = get_pci_device(&bmdma_bar, &ide_bar);
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
flags = cmd & ~0xff;
cmd &= 0xff;
@ -246,7 +246,7 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
/* Setup PRDT */
len = sizeof(*prdt) * prdt_entries;
guest_prdt = guest_alloc(&guest_malloc, len);
memwrite(guest_prdt, prdt, len);
qtest_memwrite(qts, guest_prdt, prdt, len);
qpci_io_writel(dev, bmdma_bar, bmreg_prdt, guest_prdt);
/* ATA DMA command */
@ -283,14 +283,15 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
status = qpci_io_readb(dev, bmdma_bar, bmreg_status);
} while ((status & (BM_STS_ACTIVE | BM_STS_INTR)) == BM_STS_ACTIVE);
g_assert_cmpint(get_irq(IDE_PRIMARY_IRQ), ==, !!(status & BM_STS_INTR));
g_assert_cmpint(qtest_get_irq(qts, IDE_PRIMARY_IRQ), ==,
!!(status & BM_STS_INTR));
/* Check IDE status code */
assert_bit_set(qpci_io_readb(dev, ide_bar, reg_status), DRDY);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), BSY | DRQ);
/* Reading the status register clears the IRQ */
g_assert(!get_irq(IDE_PRIMARY_IRQ));
g_assert(!qtest_get_irq(qts, IDE_PRIMARY_IRQ));
/* Stop DMA transfer if still active */
if (status & BM_STS_ACTIVE) {
@ -302,42 +303,61 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
return status;
}
static QTestState *test_bmdma_setup(void)
{
QTestState *qts;
qts = ide_test_start(
"-drive file=%s,if=ide,cache=writeback,format=raw "
"-global ide-hd.serial=%s -global ide-hd.ver=%s",
tmp_path, "testdisk", "version");
qtest_irq_intercept_in(qts, "ioapic");
return qts;
}
static void test_bmdma_teardown(QTestState *qts)
{
ide_test_quit(qts);
}
static void test_bmdma_simple_rw(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t status;
uint8_t *buf;
uint8_t *cmpbuf;
size_t len = 512;
uintptr_t guest_buf = guest_alloc(&guest_malloc, len);
uintptr_t guest_buf;
PrdtEntry prdt[1];
PrdtEntry prdt[] = {
{
.addr = cpu_to_le32(guest_buf),
.size = cpu_to_le32(len | PRDT_EOT),
},
};
qts = test_bmdma_setup();
dev = get_pci_device(&bmdma_bar, &ide_bar);
guest_buf = guest_alloc(&guest_malloc, len);
prdt[0].addr = cpu_to_le32(guest_buf);
prdt[0].size = cpu_to_le32(len | PRDT_EOT);
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
buf = g_malloc(len);
cmpbuf = g_malloc(len);
/* Write 0x55 pattern to sector 0 */
memset(buf, 0x55, len);
memwrite(guest_buf, buf, len);
qtest_memwrite(qts, guest_buf, buf, len);
status = send_dma_request(CMD_WRITE_DMA, 0, 1, prdt,
status = send_dma_request(qts, CMD_WRITE_DMA, 0, 1, prdt,
ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
/* Write 0xaa pattern to sector 1 */
memset(buf, 0xaa, len);
memwrite(guest_buf, buf, len);
qtest_memwrite(qts, guest_buf, buf, len);
status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt,
status = send_dma_request(qts, CMD_WRITE_DMA, 1, 1, prdt,
ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
@ -345,31 +365,35 @@ static void test_bmdma_simple_rw(void)
/* Read and verify 0x55 pattern in sector 0 */
memset(cmpbuf, 0x55, len);
status = send_dma_request(CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt), NULL);
status = send_dma_request(qts, CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt),
NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
memread(guest_buf, buf, len);
qtest_memread(qts, guest_buf, buf, len);
g_assert(memcmp(buf, cmpbuf, len) == 0);
/* Read and verify 0xaa pattern in sector 1 */
memset(cmpbuf, 0xaa, len);
status = send_dma_request(CMD_READ_DMA, 1, 1, prdt, ARRAY_SIZE(prdt), NULL);
status = send_dma_request(qts, CMD_READ_DMA, 1, 1, prdt, ARRAY_SIZE(prdt),
NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
memread(guest_buf, buf, len);
qtest_memread(qts, guest_buf, buf, len);
g_assert(memcmp(buf, cmpbuf, len) == 0);
free_pci_device(dev);
g_free(buf);
g_free(cmpbuf);
test_bmdma_teardown(qts);
}
static void test_bmdma_trim(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t status;
@ -380,16 +404,16 @@ static void test_bmdma_trim(void)
const uint64_t bad_range = trim_range_le(TEST_IMAGE_SIZE / 512 - 1, 2);
size_t len = 512;
uint8_t *buf;
uintptr_t guest_buf = guest_alloc(&guest_malloc, len);
uintptr_t guest_buf;
PrdtEntry prdt[1];
PrdtEntry prdt[] = {
{
.addr = cpu_to_le32(guest_buf),
.size = cpu_to_le32(len | PRDT_EOT),
},
};
qts = test_bmdma_setup();
dev = get_pci_device(&bmdma_bar, &ide_bar);
guest_buf = guest_alloc(&guest_malloc, len);
prdt[0].addr = cpu_to_le32(guest_buf),
prdt[0].size = cpu_to_le32(len | PRDT_EOT),
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
buf = g_malloc(len);
@ -397,9 +421,9 @@ static void test_bmdma_trim(void)
*((uint64_t *)buf) = trim_range[0];
*((uint64_t *)buf + 1) = trim_range[1];
memwrite(guest_buf, buf, 2 * sizeof(uint64_t));
qtest_memwrite(qts, guest_buf, buf, 2 * sizeof(uint64_t));
status = send_dma_request(CMD_DSM, 0, 1, prdt,
status = send_dma_request(qts, CMD_DSM, 0, 1, prdt,
ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
@ -408,9 +432,9 @@ static void test_bmdma_trim(void)
*((uint64_t *)buf) = trim_range[2];
*((uint64_t *)buf + 1) = bad_range;
memwrite(guest_buf, buf, 2 * sizeof(uint64_t));
qtest_memwrite(qts, guest_buf, buf, 2 * sizeof(uint64_t));
status = send_dma_request(CMD_DSM, 0, 1, prdt,
status = send_dma_request(qts, CMD_DSM, 0, 1, prdt,
ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_set(qpci_io_readb(dev, ide_bar, reg_status), ERR);
@ -418,10 +442,12 @@ static void test_bmdma_trim(void)
free_pci_device(dev);
g_free(buf);
test_bmdma_teardown(qts);
}
static void test_bmdma_short_prdt(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t status;
@ -433,24 +459,28 @@ static void test_bmdma_short_prdt(void)
},
};
dev = get_pci_device(&bmdma_bar, &ide_bar);
qts = test_bmdma_setup();
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
/* Normal request */
status = send_dma_request(CMD_READ_DMA, 0, 1,
status = send_dma_request(qts, CMD_READ_DMA, 0, 1,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
/* Abort the request before it completes */
status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
status = send_dma_request(qts, CMD_READ_DMA | CMDF_ABORT, 0, 1,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
free_pci_device(dev);
test_bmdma_teardown(qts);
}
static void test_bmdma_one_sector_short_prdt(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t status;
@ -463,24 +493,28 @@ static void test_bmdma_one_sector_short_prdt(void)
},
};
dev = get_pci_device(&bmdma_bar, &ide_bar);
qts = test_bmdma_setup();
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
/* Normal request */
status = send_dma_request(CMD_READ_DMA, 0, 2,
status = send_dma_request(qts, CMD_READ_DMA, 0, 2,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
/* Abort the request before it completes */
status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 2,
status = send_dma_request(qts, CMD_READ_DMA | CMDF_ABORT, 0, 2,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, 0);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
free_pci_device(dev);
test_bmdma_teardown(qts);
}
static void test_bmdma_long_prdt(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t status;
@ -492,29 +526,35 @@ static void test_bmdma_long_prdt(void)
},
};
dev = get_pci_device(&bmdma_bar, &ide_bar);
qts = test_bmdma_setup();
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
/* Normal request */
status = send_dma_request(CMD_READ_DMA, 0, 1,
status = send_dma_request(qts, CMD_READ_DMA, 0, 1,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
/* Abort the request before it completes */
status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
status = send_dma_request(qts, CMD_READ_DMA | CMDF_ABORT, 0, 1,
prdt, ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
free_pci_device(dev);
test_bmdma_teardown(qts);
}
static void test_bmdma_no_busmaster(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t status;
dev = get_pci_device(&bmdma_bar, &ide_bar);
qts = test_bmdma_setup();
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
/* No PRDT_EOT, each entry addr 0/size 64k, and in theory qemu shouldn't be
* able to access it anyway because the Bus Master bit in the PCI command
@ -522,7 +562,7 @@ static void test_bmdma_no_busmaster(void)
* good at confusing and occasionally crashing qemu. */
PrdtEntry prdt[4096] = { };
status = send_dma_request(CMD_READ_DMA | CMDF_NO_BM, 0, 512,
status = send_dma_request(qts, CMD_READ_DMA | CMDF_NO_BM, 0, 512,
prdt, ARRAY_SIZE(prdt), NULL);
/* Not entirely clear what the expected result is, but this is what we get
@ -530,20 +570,7 @@ static void test_bmdma_no_busmaster(void)
g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
free_pci_device(dev);
}
static void test_bmdma_setup(void)
{
ide_test_start(
"-drive file=%s,if=ide,cache=writeback,format=raw "
"-global ide-hd.serial=%s -global ide-hd.ver=%s",
tmp_path, "testdisk", "version");
qtest_irq_intercept_in(global_qtest, "ioapic");
}
static void test_bmdma_teardown(void)
{
ide_test_quit();
test_bmdma_teardown(qts);
}
static void string_cpu_to_be16(uint16_t *s, size_t bytes)
@ -559,6 +586,7 @@ static void string_cpu_to_be16(uint16_t *s, size_t bytes)
static void test_identify(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t data;
@ -566,12 +594,12 @@ static void test_identify(void)
int i;
int ret;
ide_test_start(
qts = ide_test_start(
"-drive file=%s,if=ide,cache=writeback,format=raw "
"-global ide-hd.serial=%s -global ide-hd.ver=%s",
tmp_path, "testdisk", "version");
dev = get_pci_device(&bmdma_bar, &ide_bar);
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
/* IDENTIFY command on device 0*/
qpci_io_writeb(dev, ide_bar, reg_device, 0);
@ -605,7 +633,7 @@ static void test_identify(void)
/* Write cache enabled bit */
assert_bit_set(buf[85], 0x20);
ide_test_quit();
ide_test_quit(qts);
free_pci_device(dev);
}
@ -613,7 +641,7 @@ static void test_identify(void)
* Write sector 1 with random data to make IDE storage dirty
* Needed for flush tests so that flushes actually go though the block layer
*/
static void make_dirty(uint8_t device)
static void make_dirty(QTestState *qts, uint8_t device)
{
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
@ -622,7 +650,7 @@ static void make_dirty(uint8_t device)
uintptr_t guest_buf;
void* buf;
dev = get_pci_device(&bmdma_bar, &ide_bar);
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
guest_buf = guest_alloc(&guest_malloc, len);
buf = g_malloc(len);
@ -630,7 +658,7 @@ static void make_dirty(uint8_t device)
g_assert(guest_buf);
g_assert(buf);
memwrite(guest_buf, buf, len);
qtest_memwrite(qts, guest_buf, buf, len);
PrdtEntry prdt[] = {
{
@ -639,7 +667,7 @@ static void make_dirty(uint8_t device)
},
};
status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt,
status = send_dma_request(qts, CMD_WRITE_DMA, 1, 1, prdt,
ARRAY_SIZE(prdt), NULL);
g_assert_cmphex(status, ==, BM_STS_INTR);
assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), DF | ERR);
@ -650,23 +678,24 @@ static void make_dirty(uint8_t device)
static void test_flush(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t data;
ide_test_start(
qts = ide_test_start(
"-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
tmp_path);
dev = get_pci_device(&bmdma_bar, &ide_bar);
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
qtest_irq_intercept_in(global_qtest, "ioapic");
qtest_irq_intercept_in(qts, "ioapic");
/* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
make_dirty(0);
make_dirty(qts, 0);
/* Delay the completion of the flush request until we explicitly do it */
g_free(hmp("qemu-io ide0-hd0 \"break flush_to_os A\""));
g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"break flush_to_os A\""));
/* FLUSH CACHE command on device 0*/
qpci_io_writeb(dev, ide_bar, reg_device, 0);
@ -678,7 +707,7 @@ static void test_flush(void)
assert_bit_clear(data, DF | ERR | DRQ);
/* Complete the command */
g_free(hmp("qemu-io ide0-hd0 \"resume A\""));
g_free(qtest_hmp(qts, "qemu-io ide0-hd0 \"resume A\""));
/* Check registers */
data = qpci_io_readb(dev, ide_bar, reg_device);
@ -691,29 +720,30 @@ static void test_flush(void)
assert_bit_set(data, DRDY);
assert_bit_clear(data, BSY | DF | ERR | DRQ);
ide_test_quit();
ide_test_quit(qts);
free_pci_device(dev);
}
static void test_retry_flush(const char *machine)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t data;
prepare_blkdebug_script(debug_path, "flush_to_disk");
ide_test_start(
qts = ide_test_start(
"-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw,"
"rerror=stop,werror=stop",
debug_path, tmp_path);
dev = get_pci_device(&bmdma_bar, &ide_bar);
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
qtest_irq_intercept_in(global_qtest, "ioapic");
qtest_irq_intercept_in(qts, "ioapic");
/* Dirty media so that CMD_FLUSH_CACHE will actually go to disk */
make_dirty(0);
make_dirty(qts, 0);
/* FLUSH CACHE command on device 0*/
qpci_io_writeb(dev, ide_bar, reg_device, 0);
@ -724,10 +754,10 @@ static void test_retry_flush(const char *machine)
assert_bit_set(data, BSY | DRDY);
assert_bit_clear(data, DF | ERR | DRQ);
qmp_eventwait("STOP");
qtest_qmp_eventwait(qts, "STOP");
/* Complete the command */
qmp_discard_response("{'execute':'cont' }");
qmp_discard_response(qts, "{'execute':'cont' }");
/* Check registers */
data = qpci_io_readb(dev, ide_bar, reg_device);
@ -740,18 +770,19 @@ static void test_retry_flush(const char *machine)
assert_bit_set(data, DRDY);
assert_bit_clear(data, BSY | DF | ERR | DRQ);
ide_test_quit();
ide_test_quit(qts);
free_pci_device(dev);
}
static void test_flush_nodev(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
ide_test_start("");
qts = ide_test_start("");
dev = get_pci_device(&bmdma_bar, &ide_bar);
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
/* FLUSH CACHE command on device 0*/
qpci_io_writeb(dev, ide_bar, reg_device, 0);
@ -760,16 +791,17 @@ static void test_flush_nodev(void)
/* Just testing that qemu doesn't crash... */
free_pci_device(dev);
ide_test_quit();
ide_test_quit(qts);
}
static void test_flush_empty_drive(void)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
ide_test_start("-device ide-cd,bus=ide.0");
dev = get_pci_device(&bmdma_bar, &ide_bar);
qts = ide_test_start("-device ide-cd,bus=ide.0");
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
/* FLUSH CACHE command on device 0 */
qpci_io_writeb(dev, ide_bar, reg_device, 0);
@ -778,7 +810,7 @@ static void test_flush_empty_drive(void)
/* Just testing that qemu doesn't crash... */
free_pci_device(dev);
ide_test_quit();
ide_test_quit(qts);
}
static void test_pci_retry_flush(void)
@ -823,21 +855,21 @@ static void send_scsi_cdb_read10(QPCIDevice *dev, QPCIBar ide_bar,
}
}
static void nsleep(int64_t nsecs)
static void nsleep(QTestState *qts, int64_t nsecs)
{
const struct timespec val = { .tv_nsec = nsecs };
nanosleep(&val, NULL);
clock_set(nsecs);
qtest_clock_set(qts, nsecs);
}
static uint8_t ide_wait_clear(uint8_t flag)
static uint8_t ide_wait_clear(QTestState *qts, uint8_t flag)
{
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
uint8_t data;
time_t st;
dev = get_pci_device(&bmdma_bar, &ide_bar);
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
/* Wait with a 5 second timeout */
time(&st);
@ -850,26 +882,26 @@ static uint8_t ide_wait_clear(uint8_t flag)
if (difftime(time(NULL), st) > 5.0) {
break;
}
nsleep(400);
nsleep(qts, 400);
}
g_assert_not_reached();
}
static void ide_wait_intr(int irq)
static void ide_wait_intr(QTestState *qts, int irq)
{
time_t st;
bool intr;
time(&st);
while (true) {
intr = get_irq(irq);
intr = qtest_get_irq(qts, irq);
if (intr) {
return;
}
if (difftime(time(NULL), st) > 5.0) {
break;
}
nsleep(400);
nsleep(qts, 400);
}
g_assert_not_reached();
@ -877,6 +909,7 @@ static void ide_wait_intr(int irq)
static void cdrom_pio_impl(int nblocks)
{
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
FILE *fh;
@ -897,10 +930,11 @@ static void cdrom_pio_impl(int nblocks)
g_assert_cmpint(ret, ==, patt_blocks);
fclose(fh);
ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
"-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
dev = get_pci_device(&bmdma_bar, &ide_bar);
qtest_irq_intercept_in(global_qtest, "ioapic");
qts = ide_test_start(
"-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
"-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
qtest_irq_intercept_in(qts, "ioapic");
/* PACKET command on device 0 */
qpci_io_writeb(dev, ide_bar, reg_device, 0);
@ -908,8 +942,8 @@ static void cdrom_pio_impl(int nblocks)
qpci_io_writeb(dev, ide_bar, reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0xFF));
qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET);
/* HP0: Check_Status_A State */
nsleep(400);
data = ide_wait_clear(BSY);
nsleep(qts, 400);
data = ide_wait_clear(qts, BSY);
/* HP1: Send_Packet State */
assert_bit_set(data, DRQ | DRDY);
assert_bit_clear(data, ERR | DF | BSY);
@ -930,10 +964,10 @@ static void cdrom_pio_impl(int nblocks)
size_t rem = (rxsize / 2) - offset;
/* HP3: INTRQ_Wait */
ide_wait_intr(IDE_PRIMARY_IRQ);
ide_wait_intr(qts, IDE_PRIMARY_IRQ);
/* HP2: Check_Status_B (and clear IRQ) */
data = ide_wait_clear(BSY);
data = ide_wait_clear(qts, BSY);
assert_bit_set(data, DRQ | DRDY);
assert_bit_clear(data, ERR | DF | BSY);
@ -945,17 +979,17 @@ static void cdrom_pio_impl(int nblocks)
}
/* Check for final completion IRQ */
ide_wait_intr(IDE_PRIMARY_IRQ);
ide_wait_intr(qts, IDE_PRIMARY_IRQ);
/* Sanity check final state */
data = ide_wait_clear(DRQ);
data = ide_wait_clear(qts, DRQ);
assert_bit_set(data, DRDY);
assert_bit_clear(data, DRQ | ERR | DF | BSY);
g_assert_cmpint(memcmp(pattern, rx, rxsize), ==, 0);
g_free(pattern);
g_free(rx);
test_bmdma_teardown();
test_bmdma_teardown(qts);
free_pci_device(dev);
}
@ -973,6 +1007,7 @@ static void test_cdrom_pio_large(void)
static void test_cdrom_dma(void)
{
QTestState *qts;
static const size_t len = ATAPI_BLOCK_SIZE;
size_t ret;
char *pattern = g_malloc(ATAPI_BLOCK_SIZE * 16);
@ -981,9 +1016,10 @@ static void test_cdrom_dma(void)
PrdtEntry prdt[1];
FILE *fh;
ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
"-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
qtest_irq_intercept_in(global_qtest, "ioapic");
qts = ide_test_start(
"-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
"-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
qtest_irq_intercept_in(qts, "ioapic");
guest_buf = guest_alloc(&guest_malloc, len);
prdt[0].addr = cpu_to_le32(guest_buf);
@ -995,15 +1031,15 @@ static void test_cdrom_dma(void)
g_assert_cmpint(ret, ==, 16);
fclose(fh);
send_dma_request(CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10);
send_dma_request(qts, CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10);
/* Read back data from guest memory into local qtest memory */
memread(guest_buf, rx, len);
qtest_memread(qts, guest_buf, rx, len);
g_assert_cmpint(memcmp(pattern, rx, len), ==, 0);
g_free(pattern);
g_free(rx);
test_bmdma_teardown();
test_bmdma_teardown(qts);
}
int main(int argc, char **argv)
@ -1028,7 +1064,6 @@ int main(int argc, char **argv)
qtest_add_func("/ide/identify", test_identify);
qtest_add_func("/ide/bmdma/setup", test_bmdma_setup);
qtest_add_func("/ide/bmdma/simple_rw", test_bmdma_simple_rw);
qtest_add_func("/ide/bmdma/trim", test_bmdma_trim);
qtest_add_func("/ide/bmdma/short_prdt", test_bmdma_short_prdt);
@ -1036,7 +1071,6 @@ int main(int argc, char **argv)
test_bmdma_one_sector_short_prdt);
qtest_add_func("/ide/bmdma/long_prdt", test_bmdma_long_prdt);
qtest_add_func("/ide/bmdma/no_busmaster", test_bmdma_no_busmaster);
qtest_add_func("/ide/bmdma/teardown", test_bmdma_teardown);
qtest_add_func("/ide/flush", test_flush);
qtest_add_func("/ide/flush/nodev", test_flush_nodev);

View File

@ -383,18 +383,21 @@ static void test_ivshmem_server(void)
static void test_ivshmem_hotplug(void)
{
QTestState *qts;
const char *arch = qtest_get_arch();
qtest_start("-object memory-backend-ram,size=1M,id=mb1");
qts = qtest_init("-object memory-backend-ram,size=1M,id=mb1");
global_qtest = qts; /* TODO: Get rid of global_qtest here */
qtest_qmp_device_add("ivshmem-plain", "iv1",
"{'addr': %s, 'memdev': 'mb1'}",
stringify(PCI_SLOT_HP));
if (strcmp(arch, "ppc64") != 0) {
qpci_unplug_acpi_device_test("iv1", PCI_SLOT_HP);
qpci_unplug_acpi_device_test(qts, "iv1", PCI_SLOT_HP);
}
qtest_end();
qtest_quit(qts);
global_qtest = NULL;
}
static void test_ivshmem_memdev(void)

View File

@ -176,19 +176,19 @@ void qpci_free_pc(QPCIBus *bus)
g_free(s);
}
void qpci_unplug_acpi_device_test(const char *id, uint8_t slot)
void qpci_unplug_acpi_device_test(QTestState *qts, const char *id, uint8_t slot)
{
QDict *response;
response = qmp("{'execute': 'device_del', 'arguments': {'id': %s}}",
id);
response = qtest_qmp(qts, "{'execute': 'device_del',"
" 'arguments': {'id': %s}}", id);
g_assert(response);
g_assert(!qdict_haskey(response, "error"));
qobject_unref(response);
outb(ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot);
qtest_outb(qts, ACPI_PCIHP_ADDR + PCI_EJ_BASE, 1 << slot);
qmp_eventwait("DEVICE_DELETED");
qtest_qmp_eventwait(qts, "DEVICE_DELETED");
}
static void qpci_pc_register_nodes(void)

View File

@ -123,7 +123,7 @@ QPCIBar qpci_iomap(QPCIDevice *dev, int barno, uint64_t *sizeptr);
void qpci_iounmap(QPCIDevice *dev, QPCIBar addr);
QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr);
void qpci_unplug_acpi_device_test(const char *id, uint8_t slot);
void qpci_unplug_acpi_device_test(QTestState *qs, const char *id, uint8_t slot);
void add_qpci_address(QOSGraphEdgeOptions *opts, QPCIAddress *addr);
#endif

View File

@ -66,7 +66,7 @@ static void megasas_pd_get_info_fuzz(void *obj, void *data, QGuestAllocator *all
context[7] = cpu_to_le32(0);
context_pa = guest_alloc(alloc, sizeof(context));
memwrite(context_pa, context, sizeof(context));
qtest_memwrite(dev->bus->qts, context_pa, context, sizeof(context));
qpci_io_writel(dev, bar, 0x40, context_pa);
}

View File

@ -61,10 +61,11 @@ static void test_query(const void *data)
int expected_error_class = query_error_class(cmd);
QDict *resp, *error;
const char *error_class;
QTestState *qts;
qtest_start(common_args);
qts = qtest_init(common_args);
resp = qmp("{ 'execute': %s }", cmd);
resp = qtest_qmp(qts, "{ 'execute': %s }", cmd);
error = qdict_get_qdict(resp, "error");
error_class = error ? qdict_get_str(error, "class") : NULL;
@ -78,7 +79,7 @@ static void test_query(const void *data)
}
qobject_unref(resp);
qtest_end();
qtest_quit(qts);
}
static bool query_is_blacklisted(const char *cmd)
@ -118,16 +119,18 @@ static void qmp_schema_init(QmpSchema *schema)
QDict *resp;
Visitor *qiv;
SchemaInfoList *tail;
QTestState *qts;
qtest_start(common_args);
resp = qmp("{ 'execute': 'query-qmp-schema' }");
qts = qtest_init(common_args);
resp = qtest_qmp(qts, "{ 'execute': 'query-qmp-schema' }");
qiv = qobject_input_visitor_new(qdict_get(resp, "return"));
visit_type_SchemaInfoList(qiv, NULL, &schema->list, &error_abort);
visit_free(qiv);
qobject_unref(resp);
qtest_end();
qtest_quit(qts);
schema->hash = g_hash_table_new(g_str_hash, g_str_equal);

View File

@ -45,13 +45,14 @@ typedef struct {
QPCIDevice *dev;
QPCIBar tco_io_bar;
QPCIBus *bus;
QTestState *qts;
} TestData;
static void test_end(TestData *d)
{
g_free(d->dev);
qpci_free_pc(d->bus);
qtest_end();
qtest_quit(d->qts);
}
static void test_init(TestData *d)
@ -61,7 +62,6 @@ static void test_init(TestData *d)
qs = qtest_initf("-machine q35 %s %s",
d->noreboot ? "" : "-global ICH9-LPC.noreboot=false",
!d->args ? "" : d->args);
global_qtest = qs;
qtest_irq_intercept_in(qs, "ioapic");
d->bus = qpci_new_pc(qs, NULL);
@ -78,6 +78,7 @@ static void test_init(TestData *d)
qpci_config_writel(d->dev, ICH9_LPC_RCBA, RCBA_BASE_ADDR | 0x1);
d->tco_io_bar = qpci_legacy_iomap(d->dev, PM_IO_BASE_ADDR + 0x60);
d->qts = qs;
}
static void stop_tco(const TestData *d)
@ -115,17 +116,17 @@ static void clear_tco_status(const TestData *d)
qpci_io_writew(d->dev, d->tco_io_bar, TCO2_STS, 0x0004);
}
static void reset_on_second_timeout(bool enable)
static void reset_on_second_timeout(const TestData *td, bool enable)
{
uint32_t val;
val = readl(RCBA_BASE_ADDR + ICH9_CC_GCS);
val = qtest_readl(td->qts, RCBA_BASE_ADDR + ICH9_CC_GCS);
if (enable) {
val &= ~ICH9_CC_GCS_NO_REBOOT;
} else {
val |= ICH9_CC_GCS_NO_REBOOT;
}
writel(RCBA_BASE_ADDR + ICH9_CC_GCS, val);
qtest_writel(td->qts, RCBA_BASE_ADDR + ICH9_CC_GCS, val);
}
static void test_tco_defaults(void)
@ -171,11 +172,11 @@ static void test_tco_timeout(void)
stop_tco(&d);
clear_tco_status(&d);
reset_on_second_timeout(false);
reset_on_second_timeout(&d, false);
set_tco_timeout(&d, ticks);
load_tco(&d);
start_tco(&d);
clock_step(ticks * TCO_TICK_NSEC);
qtest_clock_step(d.qts, ticks * TCO_TICK_NSEC);
/* test first timeout */
val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
@ -190,7 +191,7 @@ static void test_tco_timeout(void)
g_assert(ret == 0);
/* test second timeout */
clock_step(ticks * TCO_TICK_NSEC);
qtest_clock_step(d.qts, ticks * TCO_TICK_NSEC);
val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
ret = val & TCO_TIMEOUT ? 1 : 0;
g_assert(ret == 1);
@ -215,18 +216,18 @@ static void test_tco_max_timeout(void)
stop_tco(&d);
clear_tco_status(&d);
reset_on_second_timeout(false);
reset_on_second_timeout(&d, false);
set_tco_timeout(&d, ticks);
load_tco(&d);
start_tco(&d);
clock_step(((ticks & TCO_TMR_MASK) - 1) * TCO_TICK_NSEC);
qtest_clock_step(d.qts, ((ticks & TCO_TMR_MASK) - 1) * TCO_TICK_NSEC);
val = qpci_io_readw(d.dev, d.tco_io_bar, TCO_RLD);
g_assert_cmpint(val & TCO_RLD_MASK, ==, 1);
val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
ret = val & TCO_TIMEOUT ? 1 : 0;
g_assert(ret == 0);
clock_step(TCO_TICK_NSEC);
qtest_clock_step(d.qts, TCO_TICK_NSEC);
val = qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS);
ret = val & TCO_TIMEOUT ? 1 : 0;
g_assert(ret == 1);
@ -235,9 +236,9 @@ static void test_tco_max_timeout(void)
test_end(&d);
}
static QDict *get_watchdog_action(void)
static QDict *get_watchdog_action(const TestData *td)
{
QDict *ev = qmp_eventwait_ref("WATCHDOG");
QDict *ev = qtest_qmp_eventwait_ref(td->qts, "WATCHDOG");
QDict *data;
data = qdict_get_qdict(ev, "data");
@ -258,12 +259,12 @@ static void test_tco_second_timeout_pause(void)
stop_tco(&td);
clear_tco_status(&td);
reset_on_second_timeout(true);
reset_on_second_timeout(&td, true);
set_tco_timeout(&td, TCO_SECS_TO_TICKS(16));
load_tco(&td);
start_tco(&td);
clock_step(ticks * TCO_TICK_NSEC * 2);
ad = get_watchdog_action();
qtest_clock_step(td.qts, ticks * TCO_TICK_NSEC * 2);
ad = get_watchdog_action(&td);
g_assert(!strcmp(qdict_get_str(ad, "action"), "pause"));
qobject_unref(ad);
@ -283,12 +284,12 @@ static void test_tco_second_timeout_reset(void)
stop_tco(&td);
clear_tco_status(&td);
reset_on_second_timeout(true);
reset_on_second_timeout(&td, true);
set_tco_timeout(&td, TCO_SECS_TO_TICKS(16));
load_tco(&td);
start_tco(&td);
clock_step(ticks * TCO_TICK_NSEC * 2);
ad = get_watchdog_action();
qtest_clock_step(td.qts, ticks * TCO_TICK_NSEC * 2);
ad = get_watchdog_action(&td);
g_assert(!strcmp(qdict_get_str(ad, "action"), "reset"));
qobject_unref(ad);
@ -308,12 +309,12 @@ static void test_tco_second_timeout_shutdown(void)
stop_tco(&td);
clear_tco_status(&td);
reset_on_second_timeout(true);
reset_on_second_timeout(&td, true);
set_tco_timeout(&td, ticks);
load_tco(&td);
start_tco(&td);
clock_step(ticks * TCO_TICK_NSEC * 2);
ad = get_watchdog_action();
qtest_clock_step(td.qts, ticks * TCO_TICK_NSEC * 2);
ad = get_watchdog_action(&td);
g_assert(!strcmp(qdict_get_str(ad, "action"), "shutdown"));
qobject_unref(ad);
@ -333,12 +334,12 @@ static void test_tco_second_timeout_none(void)
stop_tco(&td);
clear_tco_status(&td);
reset_on_second_timeout(true);
reset_on_second_timeout(&td, true);
set_tco_timeout(&td, ticks);
load_tco(&td);
start_tco(&td);
clock_step(ticks * TCO_TICK_NSEC * 2);
ad = get_watchdog_action();
qtest_clock_step(td.qts, ticks * TCO_TICK_NSEC * 2);
ad = get_watchdog_action(&td);
g_assert(!strcmp(qdict_get_str(ad, "action"), "none"));
qobject_unref(ad);
@ -358,7 +359,7 @@ static void test_tco_ticks_counter(void)
stop_tco(&d);
clear_tco_status(&d);
reset_on_second_timeout(false);
reset_on_second_timeout(&d, false);
set_tco_timeout(&d, ticks);
load_tco(&d);
start_tco(&d);
@ -366,7 +367,7 @@ static void test_tco_ticks_counter(void)
do {
rld = qpci_io_readw(d.dev, d.tco_io_bar, TCO_RLD) & TCO_RLD_MASK;
g_assert_cmpint(rld, ==, ticks);
clock_step(TCO_TICK_NSEC);
qtest_clock_step(d.qts, TCO_TICK_NSEC);
ticks--;
} while (!(qpci_io_readw(d.dev, d.tco_io_bar, TCO1_STS) & TCO_TIMEOUT));
@ -405,11 +406,11 @@ static void test_tco1_status_bits(void)
stop_tco(&d);
clear_tco_status(&d);
reset_on_second_timeout(false);
reset_on_second_timeout(&d, false);
set_tco_timeout(&d, ticks);
load_tco(&d);
start_tco(&d);
clock_step(ticks * TCO_TICK_NSEC);
qtest_clock_step(d.qts, ticks * TCO_TICK_NSEC);
qpci_io_writeb(d.dev, d.tco_io_bar, TCO_DAT_IN, 0);
qpci_io_writeb(d.dev, d.tco_io_bar, TCO_DAT_OUT, 0);
@ -434,11 +435,11 @@ static void test_tco2_status_bits(void)
stop_tco(&d);
clear_tco_status(&d);
reset_on_second_timeout(true);
reset_on_second_timeout(&d, true);
set_tco_timeout(&d, ticks);
load_tco(&d);
start_tco(&d);
clock_step(ticks * TCO_TICK_NSEC * 2);
qtest_clock_step(d.qts, ticks * TCO_TICK_NSEC * 2);
val = qpci_io_readw(d.dev, d.tco_io_bar, TCO2_STS);
ret = val & (TCO_SECOND_TO_STS | TCO_BOOT_STS) ? 1 : 0;

View File

@ -73,13 +73,13 @@ static const char *hmp_cmds[] = {
};
/* Run through the list of pre-defined commands */
static void test_commands(void)
static void test_commands(QTestState *qts)
{
char *response;
int i;
for (i = 0; hmp_cmds[i] != NULL; i++) {
response = hmp("%s", hmp_cmds[i]);
response = qtest_hmp(qts, "%s", hmp_cmds[i]);
if (verbose) {
fprintf(stderr,
"\texecute HMP command: %s\n"
@ -92,11 +92,11 @@ static void test_commands(void)
}
/* Run through all info commands and call them blindly (without arguments) */
static void test_info_commands(void)
static void test_info_commands(QTestState *qts)
{
char *resp, *info, *info_buf, *endp;
info_buf = info = hmp("help info");
info_buf = info = qtest_hmp(qts, "help info");
while (*info) {
/* Extract the info command, ignore parameters and description */
@ -108,7 +108,7 @@ static void test_info_commands(void)
if (verbose) {
fprintf(stderr, "\t%s\n", info);
}
resp = hmp("%s", info);
resp = qtest_hmp(qts, "%s", info);
g_free(resp);
/* And move forward to the next line */
info = strchr(endp + 1, '\n');
@ -125,14 +125,15 @@ static void test_machine(gconstpointer data)
{
const char *machine = data;
char *args;
QTestState *qts;
args = g_strdup_printf("-S -M %s", machine);
qtest_start(args);
qts = qtest_init(args);
test_info_commands();
test_commands();
test_info_commands(qts);
test_commands(qts);
qtest_end();
qtest_quit(qts);
g_free(args);
g_free((void *)data);
}

View File

@ -22,7 +22,7 @@ static bool
tpm_test_swtpm_skip(void)
{
if (!tpm_util_swtpm_has_tpm2()) {
g_test_message("swtpm not in PATH or missing --tpm2 support");
g_test_skip("swtpm not in PATH or missing --tpm2 support");
return true;
}

View File

@ -679,6 +679,7 @@ static void pci_hotplug(void *obj, void *data, QGuestAllocator *t_alloc)
{
QVirtioPCIDevice *dev1 = obj;
QVirtioPCIDevice *dev;
QTestState *qts = dev1->pdev->bus->qts;
/* plug secondary disk */
qtest_qmp_device_add("virtio-blk-pci", "drv1",
@ -693,7 +694,7 @@ static void pci_hotplug(void *obj, void *data, QGuestAllocator *t_alloc)
qos_object_destroy((QOSGraphObject *)dev);
/* unplug secondary disk */
qpci_unplug_acpi_device_test("drv1", PCI_SLOT_HP);
qpci_unplug_acpi_device_test(qts, "drv1", PCI_SLOT_HP);
}
/*

View File

@ -162,13 +162,15 @@ static void stop_cont_test(void *obj, void *data, QGuestAllocator *t_alloc)
static void hotplug(void *obj, void *data, QGuestAllocator *t_alloc)
{
QVirtioPCIDevice *dev = obj;
QTestState *qts = dev->pdev->bus->qts;
const char *arch = qtest_get_arch();
qtest_qmp_device_add("virtio-net-pci", "net1",
"{'addr': %s}", stringify(PCI_SLOT_HP));
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP);
qpci_unplug_acpi_device_test(qts, "net1", PCI_SLOT_HP);
}
}

View File

@ -16,13 +16,16 @@
static void rng_hotplug(void *obj, void *data, QGuestAllocator *alloc)
{
QVirtioPCIDevice *dev = obj;
QTestState *qts = dev->pdev->bus->qts;
const char *arch = qtest_get_arch();
qtest_qmp_device_add("virtio-rng-pci", "rng1",
"{'addr': %s}", stringify(PCI_SLOT_HP));
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
qpci_unplug_acpi_device_test("rng1", PCI_SLOT_HP);
qpci_unplug_acpi_device_test(qts, "rng1", PCI_SLOT_HP);
}
}