2 * QTest testcase for PV Panic PCI device
4 * Copyright (C) 2020 Oracle
7 * Mihai Carabas <mihai.carabas@oracle.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
14 #include "qemu/osdep.h"
16 #include "qapi/qmp/qdict.h"
17 #include "libqos/pci.h"
18 #include "libqos/pci-pc.h"
19 #include "hw/misc/pvpanic.h"
20 #include "hw/pci/pci_regs.h"
22 static void test_panic_nopause(void)
25 QDict
*response
, *data
;
31 qts
= qtest_init("-device pvpanic-pci,addr=04.0 -action panic=none");
32 pcibus
= qpci_new_pc(qts
, NULL
);
33 dev
= qpci_device_find(pcibus
, QPCI_DEVFN(0x4, 0x0));
34 qpci_device_enable(dev
);
35 bar
= qpci_iomap(dev
, 0, NULL
);
37 qpci_memread(dev
, bar
, 0, &val
, sizeof(val
));
38 g_assert_cmpuint(val
, ==, PVPANIC_EVENTS
);
41 qpci_memwrite(dev
, bar
, 0, &val
, sizeof(val
));
43 response
= qtest_qmp_eventwait_ref(qts
, "GUEST_PANICKED");
44 g_assert(qdict_haskey(response
, "data"));
45 data
= qdict_get_qdict(response
, "data");
46 g_assert(qdict_haskey(data
, "action"));
47 g_assert_cmpstr(qdict_get_str(data
, "action"), ==, "run");
48 qobject_unref(response
);
55 static void test_panic(void)
58 QDict
*response
, *data
;
64 qts
= qtest_init("-device pvpanic-pci,addr=04.0 -action panic=pause");
65 pcibus
= qpci_new_pc(qts
, NULL
);
66 dev
= qpci_device_find(pcibus
, QPCI_DEVFN(0x4, 0x0));
67 qpci_device_enable(dev
);
68 bar
= qpci_iomap(dev
, 0, NULL
);
70 qpci_memread(dev
, bar
, 0, &val
, sizeof(val
));
71 g_assert_cmpuint(val
, ==, PVPANIC_EVENTS
);
74 qpci_memwrite(dev
, bar
, 0, &val
, sizeof(val
));
76 response
= qtest_qmp_eventwait_ref(qts
, "GUEST_PANICKED");
77 g_assert(qdict_haskey(response
, "data"));
78 data
= qdict_get_qdict(response
, "data");
79 g_assert(qdict_haskey(data
, "action"));
80 g_assert_cmpstr(qdict_get_str(data
, "action"), ==, "pause");
81 qobject_unref(response
);
88 static void test_pvshutdown(void)
91 QDict
*response
, *data
;
97 qts
= qtest_init("-device pvpanic-pci,addr=04.0");
98 pcibus
= qpci_new_pc(qts
, NULL
);
99 dev
= qpci_device_find(pcibus
, QPCI_DEVFN(0x4, 0x0));
100 qpci_device_enable(dev
);
101 bar
= qpci_iomap(dev
, 0, NULL
);
103 qpci_memread(dev
, bar
, 0, &val
, sizeof(val
));
104 g_assert_cmpuint(val
, ==, PVPANIC_EVENTS
);
106 val
= PVPANIC_SHUTDOWN
;
107 qpci_memwrite(dev
, bar
, 0, &val
, sizeof(val
));
109 response
= qtest_qmp_eventwait_ref(qts
, "GUEST_PVSHUTDOWN");
110 qobject_unref(response
);
112 response
= qtest_qmp_eventwait_ref(qts
, "SHUTDOWN");
113 g_assert(qdict_haskey(response
, "data"));
114 data
= qdict_get_qdict(response
, "data");
115 g_assert(qdict_haskey(data
, "guest"));
116 g_assert(qdict_get_bool(data
, "guest"));
117 g_assert(qdict_haskey(data
, "reason"));
118 g_assert_cmpstr(qdict_get_str(data
, "reason"), ==, "guest-shutdown");
119 qobject_unref(response
);
122 qpci_free_pc(pcibus
);
126 int main(int argc
, char **argv
)
128 g_test_init(&argc
, &argv
, NULL
);
129 qtest_add_func("/pvpanic-pci/panic", test_panic
);
130 qtest_add_func("/pvpanic-pci/panic-nopause", test_panic_nopause
);
131 qtest_add_func("/pvpanic-pci/pvshutdown", test_pvshutdown
);