Pull request

-----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAl7DkiAACgkQnKSrs4Gr
 c8h3lAf/encwoP2tfsFIMRmVfP2lu7lmbfcagv2CeuFU8DzFqrv1lJEoJTyWPq+X
 3mrlyhxBiUTt8+CiLLeOOiNHzq9P/7ApvREeBYZ+LV2vV12lZwas23pdmXV4YvAk
 OammorLzwoy6xFRoWUkElitMrcCrpwNNMe0DWGwvUPLAx4HUuXZ1Ilo1DKpB8YkR
 pI/x7h3/UG6jgxUIHao4P078jG+wANWxJBt8gPzm8vS9eC+nOLkkzvi6zfN8IqzD
 7RG9ieENJSz9lRQP/GGglW9aB83rmKsENGD0xrPWUNM6t9gvthJevAJUVBaoHUXr
 XKTsEUTYyR8nLasSNeAaT5nzHUa01w==
 =8IIS
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging

Pull request

# gpg: Signature made Tue 19 May 2020 09:00:32 BST
# gpg:                using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [full]
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>" [full]
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/block-pull-request:
  aio-posix: disable fdmon-io_uring when GSource is used
  aio-posix: don't duplicate fd handler deletion in fdmon_io_uring_destroy()
  tests/fuzz: Extract ioport_fuzz_qtest() method
  tests/fuzz: Extract pciconfig_fuzz_qos() method
  tests/fuzz: Remove unuseful/unused typedefs
  tests/fuzz: Add missing space in test description
  Makefile: List fuzz targets in 'make help'
  tests/fuzz/Makefile: Do not link code using unavailable devices

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-05-19 13:42:58 +01:00
commit f2465433b4
8 changed files with 69 additions and 24 deletions

View file

@ -1252,7 +1252,11 @@ endif
@$(if $(TARGET_DIRS), \
echo 'Architecture specific targets:'; \
$(foreach t, $(TARGET_DIRS), \
$(call print-help-run,$(t)/all,Build for $(t));) \
$(call print-help-run,$(t)/all,Build for $(t)); \
$(if $(CONFIG_FUZZ), \
$(if $(findstring softmmu,$(t)), \
$(call print-help-run,$(t)/fuzz,Build fuzzer for $(t)); \
))) \
echo '')
@$(if $(TOOLS), \
echo 'Tools targets:'; \

View file

@ -701,6 +701,9 @@ void aio_context_setup(AioContext *ctx);
*/
void aio_context_destroy(AioContext *ctx);
/* Used internally, do not call outside AioContext code */
void aio_context_use_g_source(AioContext *ctx);
/**
* aio_context_set_poll_params:
* @ctx: the aio context

View file

@ -7,9 +7,9 @@ fuzz-obj-y += tests/qtest/fuzz/fork_fuzz.o
fuzz-obj-y += tests/qtest/fuzz/qos_fuzz.o
# Targets
fuzz-obj-y += tests/qtest/fuzz/i440fx_fuzz.o
fuzz-obj-y += tests/qtest/fuzz/virtio_net_fuzz.o
fuzz-obj-y += tests/qtest/fuzz/virtio_scsi_fuzz.o
fuzz-obj-$(CONFIG_PCI_I440FX) += tests/qtest/fuzz/i440fx_fuzz.o
fuzz-obj-$(CONFIG_VIRTIO_NET) += tests/qtest/fuzz/virtio_net_fuzz.o
fuzz-obj-$(CONFIG_SCSI) += tests/qtest/fuzz/virtio_scsi_fuzz.o
FUZZ_CFLAGS += -I$(SRC_PATH)/tests -I$(SRC_PATH)/tests/qtest

View file

@ -39,18 +39,17 @@ enum action_id {
ACTION_MAX
};
static void i440fx_fuzz_qtest(QTestState *s,
static void ioport_fuzz_qtest(QTestState *s,
const unsigned char *Data, size_t Size) {
/*
* loop over the Data, breaking it up into actions. each action has an
* opcode, address offset and value
*/
typedef struct QTestFuzzAction {
struct {
uint8_t opcode;
uint8_t addr;
uint32_t value;
} QTestFuzzAction;
QTestFuzzAction a;
} a;
while (Size >= sizeof(a)) {
/* make a copy of the action so we can normalize the values in-place */
@ -85,25 +84,26 @@ static void i440fx_fuzz_qtest(QTestState *s,
flush_events(s);
}
static void i440fx_fuzz_qos(QTestState *s,
static void i440fx_fuzz_qtest(QTestState *s,
const unsigned char *Data,
size_t Size)
{
ioport_fuzz_qtest(s, Data, Size);
}
static void pciconfig_fuzz_qos(QTestState *s, QPCIBus *bus,
const unsigned char *Data, size_t Size) {
/*
* Same as i440fx_fuzz_qtest, but using QOS. devfn is incorporated into the
* Same as ioport_fuzz_qtest, but using QOS. devfn is incorporated into the
* value written over Port IO
*/
typedef struct QOSFuzzAction {
struct {
uint8_t opcode;
uint8_t offset;
int devfn;
uint32_t value;
} QOSFuzzAction;
} a;
static QPCIBus *bus;
if (!bus) {
bus = qpci_new_pc(s, fuzz_qos_alloc);
}
QOSFuzzAction a;
while (Size >= sizeof(a)) {
memcpy(&a, Data, sizeof(a));
switch (a.opcode % ACTION_MAX) {
@ -132,6 +132,19 @@ static void i440fx_fuzz_qos(QTestState *s,
flush_events(s);
}
static void i440fx_fuzz_qos(QTestState *s,
const unsigned char *Data,
size_t Size)
{
static QPCIBus *bus;
if (!bus) {
bus = qpci_new_pc(s, fuzz_qos_alloc);
}
pciconfig_fuzz_qos(s, bus, Data, Size);
}
static void i440fx_fuzz_qos_fork(QTestState *s,
const unsigned char *Data, size_t Size) {
if (fork() == 0) {
@ -159,7 +172,7 @@ static void register_pci_fuzz_targets(void)
/* Uses simple qtest commands and reboots to reset state */
fuzz_add_target(&(FuzzTarget){
.name = "i440fx-qtest-reboot-fuzz",
.description = "Fuzz the i440fx using raw qtest commands and"
.description = "Fuzz the i440fx using raw qtest commands and "
"rebooting after each run",
.get_init_cmdline = i440fx_argv,
.fuzz = i440fx_fuzz_qtest});
@ -167,7 +180,7 @@ static void register_pci_fuzz_targets(void)
/* Uses libqos and forks to prevent state leakage */
fuzz_add_qos_target(&(FuzzTarget){
.name = "i440fx-qos-fork-fuzz",
.description = "Fuzz the i440fx using raw qtest commands and"
.description = "Fuzz the i440fx using raw qtest commands and "
"rebooting after each run",
.pre_vm_init = &fork_init,
.fuzz = i440fx_fuzz_qos_fork,},
@ -182,7 +195,7 @@ static void register_pci_fuzz_targets(void)
*/
fuzz_add_qos_target(&(FuzzTarget){
.name = "i440fx-qos-noreset-fuzz",
.description = "Fuzz the i440fx using raw qtest commands and"
.description = "Fuzz the i440fx using raw qtest commands and "
"rebooting after each run",
.fuzz = i440fx_fuzz_qos,},
"i440FX-pcihost",

View file

@ -679,6 +679,19 @@ void aio_context_destroy(AioContext *ctx)
{
fdmon_io_uring_destroy(ctx);
fdmon_epoll_disable(ctx);
aio_free_deleted_handlers(ctx);
}
void aio_context_use_g_source(AioContext *ctx)
{
/*
* Disable io_uring when the glib main loop is used because it doesn't
* support mixed glib/aio_poll() usage. It relies on aio_poll() being
* called regularly so that changes to the monitored file descriptors are
* submitted, otherwise a list of pending fd handlers builds up.
*/
fdmon_io_uring_destroy(ctx);
aio_free_deleted_handlers(ctx);
}
void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,

View file

@ -414,6 +414,10 @@ void aio_context_destroy(AioContext *ctx)
{
}
void aio_context_use_g_source(AioContext *ctx)
{
}
void aio_context_set_poll_params(AioContext *ctx, int64_t max_ns,
int64_t grow, int64_t shrink, Error **errp)
{

View file

@ -362,6 +362,7 @@ static GSourceFuncs aio_source_funcs = {
GSource *aio_get_g_source(AioContext *ctx)
{
aio_context_use_g_source(ctx);
g_source_ref(&ctx->source);
return &ctx->source;
}

View file

@ -342,11 +342,18 @@ void fdmon_io_uring_destroy(AioContext *ctx)
io_uring_queue_exit(&ctx->fdmon_io_uring);
/* No need to submit these anymore, just free them. */
/* Move handlers due to be removed onto the deleted list */
while ((node = QSLIST_FIRST_RCU(&ctx->submit_list))) {
unsigned flags = atomic_fetch_and(&node->flags,
~(FDMON_IO_URING_PENDING |
FDMON_IO_URING_ADD |
FDMON_IO_URING_REMOVE));
if (flags & FDMON_IO_URING_REMOVE) {
QLIST_INSERT_HEAD_RCU(&ctx->deleted_aio_handlers, node, node_deleted);
}
QSLIST_REMOVE_HEAD_RCU(&ctx->submit_list, node_submitted);
QLIST_REMOVE(node, node);
g_free(node);
}
ctx->fdmon_ops = &fdmon_poll_ops;