[PATCH v3] fuzz: map all BARs and enable PCI devices

Alexander Bulekov posted 1 patch 3 years, 4 months ago
Test checkpatch passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20201221181203.1853-1-alxndr@bu.edu
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Stefan Hajnoczi <stefanha@redhat.com>, Bandan Das <bsd@redhat.com>, Laurent Vivier <lvivier@redhat.com>, Thomas Huth <thuth@redhat.com>, Alexander Bulekov <alxndr@bu.edu>
tests/qtest/fuzz/generic_fuzz.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
[PATCH v3] fuzz: map all BARs and enable PCI devices
Posted by Alexander Bulekov 3 years, 4 months ago
Prior to this patch, the fuzzer found inputs to map PCI device BARs and
enable the device. While it is nice that the fuzzer can do this, it
added significant overhead, since the fuzzer needs to map all the
BARs (regenerating the memory topology), at the start of each input.
With this patch, we do this once, before fuzzing, mitigating some of
this overhead.

Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
---

v3: Plug the memory-leak pointed out by Thomas:
    https://gitlab.com/huth/qemu/-/jobs/920543745#L309

 tests/qtest/fuzz/generic_fuzz.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
index 07ad690683..be76d47d2d 100644
--- a/tests/qtest/fuzz/generic_fuzz.c
+++ b/tests/qtest/fuzz/generic_fuzz.c
@@ -16,6 +16,7 @@
 
 #include "hw/core/cpu.h"
 #include "tests/qtest/libqos/libqtest.h"
+#include "tests/qtest/libqos/pci-pc.h"
 #include "fuzz.h"
 #include "fork_fuzz.h"
 #include "exec/address-spaces.h"
@@ -762,10 +763,29 @@ static int locate_fuzz_objects(Object *child, void *opaque)
     return 0;
 }
 
+
+static void pci_enum(gpointer pcidev, gpointer bus)
+{
+    PCIDevice *dev = pcidev;
+    QPCIDevice *qdev;
+    int i;
+
+    qdev = qpci_device_find(bus, dev->devfn);
+    g_assert(qdev != NULL);
+    for (i = 0; i < 6; i++) {
+        if (dev->io_regions[i].size) {
+            qpci_iomap(qdev, i, NULL);
+        }
+    }
+    qpci_device_enable(qdev);
+    g_free(qdev);
+}
+
 static void generic_pre_fuzz(QTestState *s)
 {
     GHashTableIter iter;
     MemoryRegion *mr;
+    QPCIBus *pcibus;
     char **result;
 
     if (!getenv("QEMU_FUZZ_OBJECTS")) {
@@ -810,6 +830,10 @@ static void generic_pre_fuzz(QTestState *s)
         exit(1);
     }
 
+    pcibus = qpci_new_pc(s, NULL);
+    g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
+    qpci_free_pc(pcibus);
+
     counter_shm_init();
 }
 
-- 
2.29.2


Re: [PATCH v3] fuzz: map all BARs and enable PCI devices
Posted by Philippe Mathieu-Daudé 3 years, 1 month ago
On 12/21/20 7:12 PM, Alexander Bulekov wrote:
> Prior to this patch, the fuzzer found inputs to map PCI device BARs and
> enable the device. While it is nice that the fuzzer can do this, it
> added significant overhead, since the fuzzer needs to map all the
> BARs (regenerating the memory topology), at the start of each input.
> With this patch, we do this once, before fuzzing, mitigating some of
> this overhead.
> 
> Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
> Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
> ---
> 
> v3: Plug the memory-leak pointed out by Thomas:
>     https://gitlab.com/huth/qemu/-/jobs/920543745#L309
> 
>  tests/qtest/fuzz/generic_fuzz.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
> index 07ad690683..be76d47d2d 100644
> --- a/tests/qtest/fuzz/generic_fuzz.c
> +++ b/tests/qtest/fuzz/generic_fuzz.c
> @@ -16,6 +16,7 @@
>  
>  #include "hw/core/cpu.h"
>  #include "tests/qtest/libqos/libqtest.h"
> +#include "tests/qtest/libqos/pci-pc.h"
>  #include "fuzz.h"
>  #include "fork_fuzz.h"
>  #include "exec/address-spaces.h"
> @@ -762,10 +763,29 @@ static int locate_fuzz_objects(Object *child, void *opaque)
>      return 0;
>  }
>  
> +
> +static void pci_enum(gpointer pcidev, gpointer bus)
> +{
> +    PCIDevice *dev = pcidev;
> +    QPCIDevice *qdev;
> +    int i;
> +
> +    qdev = qpci_device_find(bus, dev->devfn);
> +    g_assert(qdev != NULL);
> +    for (i = 0; i < 6; i++) {
> +        if (dev->io_regions[i].size) {
> +            qpci_iomap(qdev, i, NULL);
> +        }
> +    }
> +    qpci_device_enable(qdev);
> +    g_free(qdev);
> +}
> +
>  static void generic_pre_fuzz(QTestState *s)
>  {
>      GHashTableIter iter;
>      MemoryRegion *mr;
> +    QPCIBus *pcibus;
>      char **result;
>  
>      if (!getenv("QEMU_FUZZ_OBJECTS")) {
> @@ -810,6 +830,10 @@ static void generic_pre_fuzz(QTestState *s)
>          exit(1);
>      }
>  
> +    pcibus = qpci_new_pc(s, NULL);

FYI this patch restricted the "generic" fuzzer to the x86 arch.

> +    g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
> +    qpci_free_pc(pcibus);
> +
>      counter_shm_init();
>  }
>  
> 


Re: [PATCH v3] fuzz: map all BARs and enable PCI devices
Posted by Paolo Bonzini 3 years, 4 months ago
On 21/12/20 19:12, Alexander Bulekov wrote:
> Prior to this patch, the fuzzer found inputs to map PCI device BARs and
> enable the device. While it is nice that the fuzzer can do this, it
> added significant overhead, since the fuzzer needs to map all the
> BARs (regenerating the memory topology), at the start of each input.
> With this patch, we do this once, before fuzzing, mitigating some of
> this overhead.
> 
> Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
> Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
> ---
> 
> v3: Plug the memory-leak pointed out by Thomas:
>      https://gitlab.com/huth/qemu/-/jobs/920543745#L309
> 
>   tests/qtest/fuzz/generic_fuzz.c | 24 ++++++++++++++++++++++++
>   1 file changed, 24 insertions(+)
> 
> diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
> index 07ad690683..be76d47d2d 100644
> --- a/tests/qtest/fuzz/generic_fuzz.c
> +++ b/tests/qtest/fuzz/generic_fuzz.c
> @@ -16,6 +16,7 @@
>   
>   #include "hw/core/cpu.h"
>   #include "tests/qtest/libqos/libqtest.h"
> +#include "tests/qtest/libqos/pci-pc.h"
>   #include "fuzz.h"
>   #include "fork_fuzz.h"
>   #include "exec/address-spaces.h"
> @@ -762,10 +763,29 @@ static int locate_fuzz_objects(Object *child, void *opaque)
>       return 0;
>   }
>   
> +
> +static void pci_enum(gpointer pcidev, gpointer bus)
> +{
> +    PCIDevice *dev = pcidev;
> +    QPCIDevice *qdev;
> +    int i;
> +
> +    qdev = qpci_device_find(bus, dev->devfn);
> +    g_assert(qdev != NULL);
> +    for (i = 0; i < 6; i++) {
> +        if (dev->io_regions[i].size) {
> +            qpci_iomap(qdev, i, NULL);
> +        }
> +    }
> +    qpci_device_enable(qdev);
> +    g_free(qdev);
> +}
> +
>   static void generic_pre_fuzz(QTestState *s)
>   {
>       GHashTableIter iter;
>       MemoryRegion *mr;
> +    QPCIBus *pcibus;
>       char **result;
>   
>       if (!getenv("QEMU_FUZZ_OBJECTS")) {
> @@ -810,6 +830,10 @@ static void generic_pre_fuzz(QTestState *s)
>           exit(1);
>       }
>   
> +    pcibus = qpci_new_pc(s, NULL);
> +    g_ptr_array_foreach(fuzzable_pci_devices, pci_enum, pcibus);
> +    qpci_free_pc(pcibus);
> +
>       counter_shm_init();
>   }
>   
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>