Re: [PATCH v9 06/16] vpci/header: implement guest BAR register handlers

2023-08-31 Thread Stewart Hildebrand
On 8/29/23 19:19, Volodymyr Babchuk wrote:
> diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
> index e58bbdf68d..e96d7b2b37 100644
> --- a/xen/drivers/vpci/header.c
> +++ b/xen/drivers/vpci/header.c
> @@ -477,6 +477,72 @@ static void cf_check bar_write(
>  pci_conf_write32(pdev->sbdf, reg, val);
>  }
> 
> +static void cf_check guest_bar_write(const struct pci_dev *pdev,
> + unsigned int reg, uint32_t val, void 
> *data)
> +{
> +struct vpci_bar *bar = data;
> +bool hi = false;
> +uint64_t guest_addr = bar->guest_addr;
> +
> +if ( bar->type == VPCI_BAR_MEM64_HI )
> +{
> +ASSERT(reg > PCI_BASE_ADDRESS_0);
> +bar--;
> +hi = true;
> +}
> +else
> +{
> +val &= PCI_BASE_ADDRESS_MEM_MASK;
> +}
> +
> +guest_addr &= ~(0xull << (hi ? 32 : 0));

Uppercase ULL on the constant to avoid a MISRA violation



Re: [PATCH v9 10/16] vpci/header: emulate PCI_COMMAND register for guests

2023-08-31 Thread Stewart Hildebrand
On 8/29/23 19:19, Volodymyr Babchuk wrote:
> diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
> index 1e82217200..e351db4620 100644
> --- a/xen/drivers/vpci/header.c
> +++ b/xen/drivers/vpci/header.c
> @@ -523,6 +546,14 @@ static void cf_check cmd_write(
>  pci_conf_write16(pdev->sbdf, reg, cmd);
>  }
> 
> +static uint32_t guest_cmd_read(const struct pci_dev *pdev, unsigned int reg,

As this function is called indirectly, it needs a cf_check attribute

> +   void *data)
> +{
> +const struct vpci_header *header = data;
> +
> +return header->guest_cmd;
> +}
> +
>  static void cf_check bar_write(
>  const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
>  {



[PATCH v5 5/5] xen/vpci: header: filter PCI capabilities

2023-08-31 Thread Stewart Hildebrand
Currently, Xen vPCI only supports virtualizing the MSI and MSI-X capabilities.
Hide all other PCI capabilities (including extended capabilities) from domUs for
now, even though there may be certain devices/drivers that depend on being able
to discover certain capabilities.

We parse the physical PCI capabilities linked list and add vPCI register
handlers for the next elements, inserting our own next value, thus presenting a
modified linked list to the domU.

Introduce helper functions vpci_hw_read8 and vpci_read_val. The vpci_read_val
helper function returns a fixed value, which may be used for RAZ registers, or
registers whose value doesn't change.

Introduce pci_find_next_cap_ttl() helper while adapting the logic from
pci_find_next_cap() to suit our needs, and implement the existing
pci_find_next_cap() in terms of the new helper.

Signed-off-by: Stewart Hildebrand 
Reviewed-by: Jan Beulich 
---
v4->v5:
* use more appropriate types, continued
* get rid of unnecessary hook function
* add Jan's R-b

v3->v4:
* move mask_cap_list setting to this patch
* leave pci_find_next_cap signature alone
* use more appropriate types

v2->v3:
* get rid of > 0 in loop condition
* implement pci_find_next_cap in terms of new pci_find_next_cap_ttl function so
  that hypothetical future callers wouldn't be required to pass 
* change NULL to (void *)0 for RAZ value passed to vpci_read_val
* change type of ttl to unsigned int
* remember to mask off the low 2 bits of next in the initial loop iteration
* change return type of pci_find_next_cap and pci_find_next_cap_ttl
* avoid wrapping the PCI_STATUS_CAP_LIST condition by using ! instead of == 0

v1->v2:
* change type of ttl to int
* use switch statement instead of if/else
* adapt existing pci_find_next_cap helper instead of rolling our own
* pass ttl as in/out
* "pass through" the lower 2 bits of the next pointer
* squash helper functions into this patch to avoid transient dead code situation
* extended capabilities RAZ/WI
---
 xen/drivers/pci/pci.c | 26 +-
 xen/drivers/vpci/header.c | 76 +++
 xen/drivers/vpci/vpci.c   | 12 +++
 xen/include/xen/pci.h |  3 ++
 xen/include/xen/vpci.h|  5 +++
 5 files changed, 113 insertions(+), 9 deletions(-)

diff --git a/xen/drivers/pci/pci.c b/xen/drivers/pci/pci.c
index 3569ccb24e9e..8799d60c2156 100644
--- a/xen/drivers/pci/pci.c
+++ b/xen/drivers/pci/pci.c
@@ -39,31 +39,39 @@ unsigned int pci_find_cap_offset(pci_sbdf_t sbdf, unsigned 
int cap)
 return 0;
 }
 
-unsigned int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos,
-   unsigned int cap)
+unsigned int pci_find_next_cap_ttl(pci_sbdf_t sbdf, unsigned int pos,
+   bool (*is_match)(unsigned int),
+   unsigned int cap, unsigned int *ttl)
 {
-u8 id;
-int ttl = 48;
+unsigned int id;
 
-while ( ttl-- )
+while ( (*ttl)-- )
 {
 pos = pci_conf_read8(sbdf, pos);
 if ( pos < 0x40 )
 break;
 
-pos &= ~3;
-id = pci_conf_read8(sbdf, pos + PCI_CAP_LIST_ID);
+id = pci_conf_read8(sbdf, (pos & ~3) + PCI_CAP_LIST_ID);
 
 if ( id == 0xff )
 break;
-if ( id == cap )
+if ( (is_match && is_match(id)) || (!is_match && id == cap) )
 return pos;
 
-pos += PCI_CAP_LIST_NEXT;
+pos = (pos & ~3) + PCI_CAP_LIST_NEXT;
 }
+
 return 0;
 }
 
+unsigned int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos,
+   unsigned int cap)
+{
+unsigned int ttl = 48;
+
+return pci_find_next_cap_ttl(sbdf, pos, NULL, cap, ) & ~3;
+}
+
 /**
  * pci_find_ext_capability - Find an extended capability
  * @sbdf: PCI device to query
diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index 791791e6c9b6..f7d02a7f7bfa 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -525,6 +525,18 @@ static void cf_check rom_write(
 rom->addr = val & PCI_ROM_ADDRESS_MASK;
 }
 
+static bool cf_check vpci_cap_supported(unsigned int id)
+{
+switch ( id )
+{
+case PCI_CAP_ID_MSI:
+case PCI_CAP_ID_MSIX:
+return true;
+default:
+return false;
+}
+}
+
 static int cf_check init_bars(struct pci_dev *pdev)
 {
 uint16_t cmd;
@@ -562,6 +574,70 @@ static int cf_check init_bars(struct pci_dev *pdev)
 if ( rc )
 return rc;
 
+if ( !is_hardware_domain(pdev->domain) )
+{
+if ( !(pci_conf_read16(pdev->sbdf, PCI_STATUS) & PCI_STATUS_CAP_LIST) )
+{
+/* RAZ/WI */
+rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
+   PCI_CAPABILITY_LIST, 1, (void *)0);
+if ( rc )
+return rc;
+}
+else
+{
+/* Only expose capabilities to the guest that vPCI can handle. */
+unsigned int next, ttl = 

[XEN][PATCH v11 15/20] arm/asm/setup.h: Update struct map_range_data to add rangeset.

2023-08-31 Thread Vikram Garhwal
Add rangesets for IRQs and IOMEMs. This was done to accommodate dynamic overlay
node addition/removal operations. With overlay operations, new IRQs and IOMEMs
are added in dt_host and routed. While removing overlay nodes, nodes are removed
from dt_host and their IRQs and IOMEMs routing is also removed. Storing IRQs and
IOMEMs in the rangeset will avoid re-parsing the device tree nodes to get the
IOMEM and IRQ ranges for overlay remove ops.

Dynamic overlay node add/remove will be introduced in follow-up patches.

Signed-off-by: Vikram Garhwal 

---
Changes from v10:
Replace paddr_to_pfn(PAGE_ALIGN()) with paddr_to_pfn_aligned().
Change data type of irq.
fix function change for handle_device().
Remove unnecessary change .d = d in mr_data.
---
---
 xen/arch/arm/device.c| 43 +---
 xen/arch/arm/domain_build.c  |  4 +--
 xen/arch/arm/include/asm/setup.h |  9 ---
 3 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
index 327e4d24fb..1f631d3274 100644
--- a/xen/arch/arm/device.c
+++ b/xen/arch/arm/device.c
@@ -165,6 +165,15 @@ int map_range_to_domain(const struct dt_device_node *dev,
 dt_dprintk("  - MMIO: %010"PRIx64" - %010"PRIx64" P2MType=%x\n",
addr, addr + len, mr_data->p2mt);
 
+if ( mr_data->iomem_ranges )
+{
+res = rangeset_add_range(mr_data->iomem_ranges,
+ paddr_to_pfn(addr),
+ paddr_to_pfn_aligned(addr + len - 1));
+if ( res )
+return res;
+}
+
 return 0;
 }
 
@@ -178,10 +187,11 @@ int map_range_to_domain(const struct dt_device_node *dev,
  */
 int map_device_irqs_to_domain(struct domain *d,
   struct dt_device_node *dev,
-  bool need_mapping)
+  bool need_mapping,
+  struct rangeset *irq_ranges)
 {
 unsigned int i, nirq;
-int res;
+int res, irq;
 struct dt_raw_irq rirq;
 
 nirq = dt_number_of_irq(dev);
@@ -208,17 +218,24 @@ int map_device_irqs_to_domain(struct domain *d,
 continue;
 }
 
-res = platform_get_irq(dev, i);
-if ( res < 0 )
+irq = platform_get_irq(dev, i);
+if ( irq < 0 )
 {
 printk(XENLOG_ERR "Unable to get irq %u for %s\n",
i, dt_node_full_name(dev));
-return res;
+return irq;
 }
 
-res = map_irq_to_domain(d, res, need_mapping, dt_node_name(dev));
+res = map_irq_to_domain(d, irq, need_mapping, dt_node_name(dev));
 if ( res )
 return res;
+
+if ( irq_ranges )
+{
+res = rangeset_add_singleton(irq_ranges, irq);
+if ( res )
+return res;
+}
 }
 
 return 0;
@@ -249,6 +266,11 @@ static int map_dt_irq_to_domain(const struct 
dt_device_node *dev,
 }
 
 res = map_irq_to_domain(d, irq, !mr_data->skip_mapping, dt_node_name(dev));
+if ( res )
+return res;
+
+if ( mr_data->irq_ranges )
+res = rangeset_add_singleton(mr_data->irq_ranges, irq);
 
 return res;
 }
@@ -289,7 +311,8 @@ static int map_device_children(const struct dt_device_node 
*dev,
  *  - Assign the device to the guest if it's protected by an IOMMU
  *  - Map the IRQs and iomem regions to DOM0
  */
-int handle_device(struct domain *d, struct dt_device_node *dev, p2m_type_t 
p2mt)
+int handle_device(struct domain *d, struct dt_device_node *dev, p2m_type_t 
p2mt,
+  struct rangeset *iomem_ranges, struct rangeset *irq_ranges)
 {
 unsigned int naddr;
 unsigned int i;
@@ -308,7 +331,9 @@ int handle_device(struct domain *d, struct dt_device_node 
*dev, p2m_type_t p2mt)
 .p2mt = p2mt,
 .skip_mapping = !own_device ||
 (is_pci_passthrough_enabled() &&
-(device_get_class(dev) == DEVICE_PCI_HOSTBRIDGE))
+(device_get_class(dev) == DEVICE_PCI_HOSTBRIDGE)),
+.iomem_ranges = iomem_ranges,
+.irq_ranges = irq_ranges
 };
 
 naddr = dt_number_of_address(dev);
@@ -342,7 +367,7 @@ int handle_device(struct domain *d, struct dt_device_node 
*dev, p2m_type_t p2mt)
 }
 }
 
-res = map_device_irqs_to_domain(d, dev, own_device);
+res = map_device_irqs_to_domain(d, dev, own_device, irq_ranges);
 if ( res < 0 )
 return res;
 
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index ff4fc30769..29dcbb8a2e 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -2402,7 +2402,7 @@ static int __init handle_node(struct domain *d, struct 
kernel_info *kinfo,
"WARNING: Path %s is reserved, skip the node as we may re-use 
the path.\n",
path);
 
-res = handle_device(d, node, p2mt);
+res = 

[XEN][PATCH v11 18/20] tools/libs/ctrl: Implement new xc interfaces for dt overlay

2023-08-31 Thread Vikram Garhwal
xc_dt_overlay() sends the device tree binary overlay, size of .dtbo and overlay
operation type i.e. add or remove to xen.

Signed-off-by: Vikram Garhwal 
Reviewed-by: Anthony PERARD 
---
 tools/include/xenctrl.h |  5 
 tools/libs/ctrl/Makefile.common |  1 +
 tools/libs/ctrl/xc_dt_overlay.c | 50 +
 3 files changed, 56 insertions(+)
 create mode 100644 tools/libs/ctrl/xc_dt_overlay.c

diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h
index 12dca13b69..2ef8b4e054 100644
--- a/tools/include/xenctrl.h
+++ b/tools/include/xenctrl.h
@@ -2653,6 +2653,11 @@ int xc_livepatch_replace(xc_interface *xch, char *name, 
uint32_t timeout, uint32
 int xc_domain_cacheflush(xc_interface *xch, uint32_t domid,
  xen_pfn_t start_pfn, xen_pfn_t nr_pfns);
 
+#if defined(__arm__) || defined(__aarch64__)
+int xc_dt_overlay(xc_interface *xch, void *overlay_fdt,
+  uint32_t overlay_fdt_size, uint8_t overlay_op);
+#endif
+
 /* Compat shims */
 #include "xenctrl_compat.h"
 
diff --git a/tools/libs/ctrl/Makefile.common b/tools/libs/ctrl/Makefile.common
index 0a09c28fd3..247afbe5f9 100644
--- a/tools/libs/ctrl/Makefile.common
+++ b/tools/libs/ctrl/Makefile.common
@@ -24,6 +24,7 @@ OBJS-y   += xc_hcall_buf.o
 OBJS-y   += xc_foreign_memory.o
 OBJS-y   += xc_kexec.o
 OBJS-y   += xc_resource.o
+OBJS-$(CONFIG_ARM)  += xc_dt_overlay.o
 OBJS-$(CONFIG_X86) += xc_psr.o
 OBJS-$(CONFIG_X86) += xc_pagetab.o
 OBJS-$(CONFIG_Linux) += xc_linux.o
diff --git a/tools/libs/ctrl/xc_dt_overlay.c b/tools/libs/ctrl/xc_dt_overlay.c
new file mode 100644
index 00..c2224c4d15
--- /dev/null
+++ b/tools/libs/ctrl/xc_dt_overlay.c
@@ -0,0 +1,50 @@
+/*
+ *
+ * Device Tree Overlay functions.
+ * Copyright (C) 2021 Xilinx Inc.
+ * Author Vikram Garhwal 
+ *
+ * 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;
+ * version 2.1 of the License.
+ *
+ * This library 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 .
+ */
+
+#include "xc_private.h"
+
+int xc_dt_overlay(xc_interface *xch, void *overlay_fdt,
+  uint32_t overlay_fdt_size, uint8_t overlay_op)
+{
+int err;
+struct xen_sysctl sysctl = {
+.cmd = XEN_SYSCTL_dt_overlay,
+.u.dt_overlay = {
+.overlay_op = overlay_op,
+.overlay_fdt_size = overlay_fdt_size,
+}
+};
+
+DECLARE_HYPERCALL_BOUNCE(overlay_fdt, overlay_fdt_size,
+ XC_HYPERCALL_BUFFER_BOUNCE_IN);
+
+if ( (err = xc_hypercall_bounce_pre(xch, overlay_fdt)) )
+goto err;
+
+set_xen_guest_handle(sysctl.u.dt_overlay.overlay_fdt, overlay_fdt);
+
+if ( (err = do_sysctl(xch, )) != 0 )
+PERROR("%s failed", __func__);
+
+err:
+xc_hypercall_bounce_post(xch, overlay_fdt);
+
+return err;
+}
-- 
2.17.1




[XEN][PATCH v11 13/20] asm/smp.h: Fix circular dependency for device_tree.h and rwlock.h

2023-08-31 Thread Vikram Garhwal
Dynamic programming ops will modify the dt_host and there might be other
function which are browsing the dt_host at the same time. To avoid the race
conditions, we will need to add a rwlock to protect access to the dt_host.
However, adding rwlock in device_tree.h causes following circular dependency:
device_tree.h->rwlock.h->smp.h->asm/smp.h->device_tree.h

To fix this, removed the "#include  and forward declared
"struct dt_device_node".

Signed-off-by: Vikram Garhwal 
Reviewed-by: Henry Wang 
Reviewed-by: Michal Orzel 
Acked-by: Julien Grall 
---
Changes from v7:
Move struct dt_device_node declaration just above arch_cpu_init().
---
---
 xen/arch/arm/include/asm/smp.h | 4 +++-
 xen/arch/arm/smpboot.c | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/include/asm/smp.h b/xen/arch/arm/include/asm/smp.h
index a37ca55bff..4fabdf5310 100644
--- a/xen/arch/arm/include/asm/smp.h
+++ b/xen/arch/arm/include/asm/smp.h
@@ -3,7 +3,6 @@
 
 #ifndef __ASSEMBLY__
 #include 
-#include 
 #include 
 #endif
 
@@ -23,6 +22,9 @@ DECLARE_PER_CPU(cpumask_var_t, cpu_core_mask);
 extern void noreturn stop_cpu(void);
 
 extern int arch_smp_init(void);
+
+struct dt_device_node;
+
 extern int arch_cpu_init(int cpu, struct dt_device_node *dn);
 extern int arch_cpu_up(int cpu);
 extern void arch_cpu_up_finish(void);
diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c
index e107b86b7b..eeb76cd551 100644
--- a/xen/arch/arm/smpboot.c
+++ b/xen/arch/arm/smpboot.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.17.1




[XEN][PATCH v11 19/20] tools/libs/light: Implement new libxl functions for device tree overlay ops

2023-08-31 Thread Vikram Garhwal
Signed-off-by: Vikram Garhwal 
Reviewed-by: Anthony PERARD 
---
 tools/include/libxl.h   | 11 +
 tools/libs/light/Makefile   |  3 ++
 tools/libs/light/libxl_dt_overlay.c | 71 +
 3 files changed, 85 insertions(+)
 create mode 100644 tools/libs/light/libxl_dt_overlay.c

diff --git a/tools/include/libxl.h b/tools/include/libxl.h
index 82b764ff57..abc5fd52da 100644
--- a/tools/include/libxl.h
+++ b/tools/include/libxl.h
@@ -259,6 +259,12 @@
  */
 #define LIBXL_HAVE_DEVICETREE_PASSTHROUGH 1
 
+#if defined(__arm__) || defined(__aarch64__)
+/**
+ * This means Device Tree Overlay is supported.
+ */
+#define LIBXL_HAVE_DT_OVERLAY 1
+#endif
 /*
  * libxl_domain_build_info has device_model_user to specify the user to
  * run the device model with. See docs/misc/qemu-deprivilege.txt.
@@ -2498,6 +2504,11 @@ libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, 
uint32_t domid,
 int *num);
 void libxl_device_pci_list_free(libxl_device_pci* list, int num);
 
+#if defined(__arm__) || defined(__aarch64__)
+int libxl_dt_overlay(libxl_ctx *ctx, void *overlay,
+ uint32_t overlay_size, uint8_t overlay_op);
+#endif
+
 /*
  * Turns the current process into a backend device service daemon
  * for a driver domain.
diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile
index 5d7ff94b05..ba4c1b7933 100644
--- a/tools/libs/light/Makefile
+++ b/tools/libs/light/Makefile
@@ -112,6 +112,9 @@ OBJS-y += _libxl_types.o
 OBJS-y += libxl_flask.o
 OBJS-y += _libxl_types_internal.o
 
+# Device tree overlay is enabled only for ARM architecture.
+OBJS-$(CONFIG_ARM) += libxl_dt_overlay.o
+
 ifeq ($(CONFIG_LIBNL),y)
 CFLAGS_LIBXL += $(LIBNL3_CFLAGS)
 endif
diff --git a/tools/libs/light/libxl_dt_overlay.c 
b/tools/libs/light/libxl_dt_overlay.c
new file mode 100644
index 00..a6c709a6dc
--- /dev/null
+++ b/tools/libs/light/libxl_dt_overlay.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 Xilinx Inc.
+ * Author Vikram Garhwal 
+ *
+ * This program 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; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * 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.
+ */
+
+#include "libxl_osdeps.h" /* must come before any other headers */
+#include "libxl_internal.h"
+#include 
+#include 
+
+static int check_overlay_fdt(libxl__gc *gc, void *fdt, size_t size)
+{
+int r;
+
+if (fdt_magic(fdt) != FDT_MAGIC) {
+LOG(ERROR, "Overlay FDT is not a valid Flat Device Tree");
+return ERROR_FAIL;
+}
+
+r = fdt_check_header(fdt);
+if (r) {
+LOG(ERROR, "Failed to check the overlay FDT (%d)", r);
+return ERROR_FAIL;
+}
+
+if (fdt_totalsize(fdt) > size) {
+LOG(ERROR, "Overlay FDT totalsize is too big");
+return ERROR_FAIL;
+}
+
+return 0;
+}
+
+int libxl_dt_overlay(libxl_ctx *ctx, void *overlay_dt, uint32_t 
overlay_dt_size,
+ uint8_t overlay_op)
+{
+int rc;
+int r;
+GC_INIT(ctx);
+
+if (check_overlay_fdt(gc, overlay_dt, overlay_dt_size)) {
+LOG(ERROR, "Overlay DTB check failed");
+rc = ERROR_FAIL;
+goto out;
+} else {
+LOG(DEBUG, "Overlay DTB check passed");
+rc = 0;
+}
+
+r = xc_dt_overlay(ctx->xch, overlay_dt, overlay_dt_size, overlay_op);
+
+if (r) {
+LOG(ERROR, "%s: Adding/Removing overlay dtb failed.", __func__);
+rc = ERROR_FAIL;
+}
+
+out:
+GC_FREE;
+return rc;
+}
+
-- 
2.17.1




[XEN][PATCH v11 11/20] xen/iommu: Introduce iommu_remove_dt_device()

2023-08-31 Thread Vikram Garhwal
Remove master device from the IOMMU. This will be helpful when removing the
overlay nodes using dynamic programming during run time.

Signed-off-by: Vikram Garhwal 

---
Changes from v10:
Add comment regarding return values of iommu_remove_dt_device().
Add ASSERT to check if is_protected is removed or not.
Changes from v7:
Add check if IOMMU is enabled.
Fix indentation of fail.
---
---
 xen/drivers/passthrough/device_tree.c | 43 +++
 xen/include/xen/iommu.h   | 10 +++
 2 files changed, 53 insertions(+)

diff --git a/xen/drivers/passthrough/device_tree.c 
b/xen/drivers/passthrough/device_tree.c
index 687c61e7da..80f6efc606 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -127,6 +127,49 @@ int iommu_release_dt_devices(struct domain *d)
 return 0;
 }
 
+int iommu_remove_dt_device(struct dt_device_node *np)
+{
+const struct iommu_ops *ops = iommu_get_ops();
+struct device *dev = dt_to_dev(np);
+int rc;
+
+if ( !iommu_enabled )
+return 1;
+
+if ( !ops )
+return -EOPNOTSUPP;
+
+spin_lock(_lock);
+
+if ( iommu_dt_device_is_assigned_locked(np) )
+{
+rc = -EBUSY;
+goto fail;
+}
+
+if ( !ops->remove_device )
+{
+rc = -EOPNOTSUPP;
+goto fail;
+}
+
+/*
+ * De-register the device from the IOMMU driver.
+ * The driver is responsible for removing is_protected flag.
+ */
+rc = ops->remove_device(0, dev);
+
+if ( !rc )
+{
+ASSERT(!dt_device_is_protected(np));
+iommu_fwspec_free(dev);
+}
+
+ fail:
+spin_unlock(_lock);
+return rc;
+}
+
 int iommu_add_dt_device(struct dt_device_node *np)
 {
 const struct iommu_ops *ops = iommu_get_ops();
diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
index a18b68e247..84bd77395e 100644
--- a/xen/include/xen/iommu.h
+++ b/xen/include/xen/iommu.h
@@ -235,6 +235,16 @@ int iommu_add_dt_device(struct dt_device_node *np);
 int iommu_do_dt_domctl(struct xen_domctl *domctl, struct domain *d,
XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl);
 
+/*
+ * Helper to remove master device from the IOMMU.
+ *
+ * Return values:
+ *  0 : device is de-registerd from IOMMU.
+ * <0 : error while removing the device from IOMMU.
+ * >0 : IOMMU is not enabled/present or device is not connected to it.
+ */
+int iommu_remove_dt_device(struct dt_device_node *np);
+
 #endif /* HAS_DEVICE_TREE */
 
 struct page_info;
-- 
2.17.1




[XEN][PATCH v11 10/20] xen/iommu: protect iommu_add_dt_device() with dtdevs_lock

2023-08-31 Thread Vikram Garhwal
Protect iommu_add_dt_device() with dtdevs_lock to prevent concurrent access
to add/remove/assign/deassign.
With addition of dynamic programming feature(follow-up patches in this series),
this function can be concurrently accessed by dynamic node add/remove using
device tree overlays.

Signed-off-by: Vikram Garhwal 
Reviewed-by: Luca Fancellu 
Reviewed-by: Michal Orzel 

---
Changes from v7:
Update commit message and fix indent.
---
---
 xen/drivers/passthrough/device_tree.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/xen/drivers/passthrough/device_tree.c 
b/xen/drivers/passthrough/device_tree.c
index a7d86a20a0..687c61e7da 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -147,6 +147,8 @@ int iommu_add_dt_device(struct dt_device_node *np)
 if ( dev_iommu_fwspec_get(dev) )
 return 0;
 
+spin_lock(_lock);
+
 /*
  * According to the Documentation/devicetree/bindings/iommu/iommu.txt
  * from Linux.
@@ -159,7 +161,10 @@ int iommu_add_dt_device(struct dt_device_node *np)
  * these callback implemented.
  */
 if ( !ops->add_device || !ops->dt_xlate )
-return -EINVAL;
+{
+rc = -EINVAL;
+goto fail;
+}
 
 if ( !dt_device_is_available(iommu_spec.np) )
 break;
@@ -190,6 +195,8 @@ int iommu_add_dt_device(struct dt_device_node *np)
 if ( rc < 0 )
 iommu_fwspec_free(dev);
 
+ fail:
+spin_unlock(_lock);
 return rc;
 }
 
-- 
2.17.1




[XEN][PATCH v11 16/20] xen/arm: Implement device tree node removal functionalities

2023-08-31 Thread Vikram Garhwal
Introduce sysctl XEN_SYSCTL_dt_overlay to remove device-tree nodes added using
device tree overlay.

xl dt-overlay remove file.dtbo:
Removes all the nodes in a given dtbo.
First, removes IRQ permissions and MMIO accesses. Next, it finds the nodes
in dt_host and delete the device node entries from dt_host.

The nodes get removed only if it is not used by any of dom0 or domio.

Also, added overlay_track struct to keep the track of added node through device
tree overlay. overlay_track has dt_host_new which is unflattened form of updated
fdt and name of overlay nodes. When a node is removed, we also free the memory
used by overlay_track for the particular overlay node.

Nested overlay removal is supported in sequential manner only i.e. if
overlay_child nests under overlay_parent, it is assumed that user first removes
overlay_child and then removes overlay_parent.
Also, this is an experimental feature so it is expected from user to make sure
correct device tree overlays are used when adding nodes and making sure devices
are not being used by other domain before removing them from Xen tree.
Partially added/removed i.e. failures while removing the overlay may cause other
failures and might need a system reboot.

Signed-off-by: Vikram Garhwal 

---
Changes from v10:
Add iommu_remove_dt_device if device has IOMMU added.
Changes from v9:
Remove iommu and IRQ routing as this will not be done while adding the 
nodes.
Changes from v8:
Remove IRQs and IOMMU entries using rangesets instead of parsing each node.
Changes from v7:
Add dt-overlay.c in MAINTAINERS.
Add comments for dt_overlay_remove_node.
Rename handle_remove_irq_iommu() to remove_resources().
Add comment regarding false mapping flag for reason behind not removing the
mapping..
Remove irq_access_premitted() check.
Add error handling for remove_all_descendant_nodes
Change read_lock with write_lock.
Remove check_overlay_fdt() call from handle_remove_overlay_nodes().
Re-organize dt_sysctl and reutnr -EOPNOSTSUPP for error cases. Also, renamed
this function to dt_overlay_sysctl.
Remove unnecessary header includes in dt-overlay.h
Correct indentation and make func   tion inputs const wherever possible.
Make overlay_fdt const_void inside xen_sysctl_dt_overlay{}.
Add comment regarding why we not removing IRQ and MMIO mappings.
Move overlay_node_count() out of this patch as it's not being used here
anymore.
Changes from v6:
Add explicit padding for xen_system_dt_overlay{}
Update license.
Rearrange xfree in dt_sysctl()
Update overlay_track struct comment with relevant message.
Fix missing xen/errno.h for builds without CONFIG_OVERLAY_DTB cases.
Fix header formatting.
---
---
 MAINTAINERS  |   1 +
 xen/arch/arm/sysctl.c|  16 +-
 xen/common/Makefile  |   1 +
 xen/common/dt-overlay.c  | 406 +++
 xen/include/public/sysctl.h  |  24 +++
 xen/include/xen/dt-overlay.h |  63 ++
 6 files changed, 510 insertions(+), 1 deletion(-)
 create mode 100644 xen/common/dt-overlay.c
 create mode 100644 xen/include/xen/dt-overlay.h

diff --git a/MAINTAINERS b/MAINTAINERS
index bf71ac144c..d320233538 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -301,6 +301,7 @@ M:  Julien Grall 
 S: Supported
 F: xen/common/libfdt/
 F: xen/common/device_tree.c
+F: xen/common/dt-overlay.c
 F: xen/include/xen/libfdt/
 F: xen/include/xen/device_tree.h
 F: xen/drivers/passthrough/device_tree.c
diff --git a/xen/arch/arm/sysctl.c b/xen/arch/arm/sysctl.c
index e9a0661146..5cda0dc674 100644
--- a/xen/arch/arm/sysctl.c
+++ b/xen/arch/arm/sysctl.c
@@ -9,6 +9,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,7 +26,20 @@ void arch_do_physinfo(struct xen_sysctl_physinfo *pi)
 long arch_do_sysctl(struct xen_sysctl *sysctl,
 XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
 {
-return -ENOSYS;
+long ret;
+
+switch ( sysctl->cmd )
+{
+case XEN_SYSCTL_dt_overlay:
+ret = dt_overlay_sysctl(>u.dt_overlay);
+break;
+
+default:
+ret = -ENOSYS;
+break;
+}
+
+return ret;
 }
 
 /*
diff --git a/xen/common/Makefile b/xen/common/Makefile
index 46049eac35..e7e96b1087 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_DEBUG_TRACE) += debugtrace.o
 obj-$(CONFIG_HAS_DEVICE_TREE) += device_tree.o
 obj-$(CONFIG_IOREQ_SERVER) += dm.o
 obj-y += domain.o
+obj-$(CONFIG_OVERLAY_DTB) += dt-overlay.o
 obj-y += event_2l.o
 obj-y += event_channel.o
 obj-y += event_fifo.o
diff --git a/xen/common/dt-overlay.c b/xen/common/dt-overlay.c
new file mode 100644
index 00..7b7224c29a
--- /dev/null
+++ b/xen/common/dt-overlay.c
@@ -0,0 +1,406 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * xen/common/dt-overlay.c
+ *
+ * Device tree overlay support in Xen.
+ *
+ * Copyright 

[XEN][PATCH v11 14/20] common/device_tree: Add rwlock for dt_host

2023-08-31 Thread Vikram Garhwal
Dynamic programming ops will modify the dt_host and there might be other
functions which are browsing the dt_host at the same time. To avoid the race
conditions, adding rwlock for browsing the dt_host during runtime. dt_host
writer will be added in the follow-up patch for device tree overlay
functionalities.

Reason behind adding rwlock instead of spinlock:
For now, dynamic programming is the sole modifier of dt_host in Xen during
run time. All other access functions like iommu_release_dt_device() are
just reading the dt_host during run-time. So, there is a need to protect
others from browsing the dt_host while dynamic programming is modifying
it. rwlock is better suitable for this task as spinlock won't be able to
differentiate between read and write access.

Signed-off-by: Vikram Garhwal 
Reviewed-by: Michal Orzel 
---
Changes from v10:
Add ASSERT for iommu_assign_dt_device() and iommu_add_dt_device().
Changes from v9:
Update commit message and fix indentation.
Add ASSERT() for iommu_deassign_dt_device() and iommu_remove_dt_device().
Fix code styles.
Remove rwlock_init in unflatten_device_tree() and do DEFINE_RWLOCK in
device-tree.c
Changes from v7:
Keep one lock for dt_host instead of lock for each node under dt_host.
---
---
 xen/common/device_tree.c  |  1 +
 xen/drivers/passthrough/device_tree.c | 28 +--
 xen/include/xen/device_tree.h |  7 +++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index f38f51ec0b..b1c2952951 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -31,6 +31,7 @@ dt_irq_xlate_func dt_irq_xlate;
 struct dt_device_node *dt_host;
 /* Interrupt controller node*/
 const struct dt_device_node *dt_interrupt_controller;
+DEFINE_RWLOCK(dt_host_lock);
 
 /**
  * struct dt_alias_prop - Alias property in 'aliases' node
diff --git a/xen/drivers/passthrough/device_tree.c 
b/xen/drivers/passthrough/device_tree.c
index 80f6efc606..1f9cfccf95 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -31,6 +31,8 @@ int iommu_assign_dt_device(struct domain *d, struct 
dt_device_node *dev)
 int rc = -EBUSY;
 struct domain_iommu *hd = dom_iommu(d);
 
+ASSERT(system_state <= SYS_STATE_active || rw_is_locked(_host_lock));
+
 if ( !is_iommu_enabled(d) )
 return -EINVAL;
 
@@ -62,6 +64,8 @@ int iommu_deassign_dt_device(struct domain *d, struct 
dt_device_node *dev)
 const struct domain_iommu *hd = dom_iommu(d);
 int rc;
 
+ASSERT(rw_is_locked(_host_lock));
+
 if ( !is_iommu_enabled(d) )
 return -EINVAL;
 
@@ -113,6 +117,8 @@ int iommu_release_dt_devices(struct domain *d)
 if ( !is_iommu_enabled(d) )
 return 0;
 
+read_lock(_host_lock);
+
 list_for_each_entry_safe(dev, _dev, >dt_devices, domain_list)
 {
 rc = iommu_deassign_dt_device(d, dev);
@@ -120,10 +126,14 @@ int iommu_release_dt_devices(struct domain *d)
 {
 dprintk(XENLOG_ERR, "Failed to deassign %s in domain %u\n",
 dt_node_full_name(dev), d->domain_id);
+read_unlock(_host_lock);
+
 return rc;
 }
 }
 
+read_unlock(_host_lock);
+
 return 0;
 }
 
@@ -133,6 +143,8 @@ int iommu_remove_dt_device(struct dt_device_node *np)
 struct device *dev = dt_to_dev(np);
 int rc;
 
+ASSERT(rw_is_locked(_host_lock));
+
 if ( !iommu_enabled )
 return 1;
 
@@ -177,6 +189,8 @@ int iommu_add_dt_device(struct dt_device_node *np)
 struct device *dev = dt_to_dev(np);
 int rc = 1, index = 0;
 
+ASSERT(system_state <= SYS_STATE_active || rw_is_locked(_host_lock));
+
 if ( !iommu_enabled )
 return 1;
 
@@ -249,6 +263,8 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct 
domain *d,
 int ret;
 struct dt_device_node *dev;
 
+read_lock(_host_lock);
+
 switch ( domctl->cmd )
 {
 case XEN_DOMCTL_assign_device:
@@ -289,7 +305,10 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct 
domain *d,
 }
 
 if ( d == dom_io )
-return -EINVAL;
+{
+ret = -EINVAL;
+break;
+}
 
 ret = iommu_add_dt_device(dev);
 if ( ret < 0 )
@@ -327,7 +346,10 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct 
domain *d,
 break;
 
 if ( d == dom_io )
-return -EINVAL;
+{
+ret = -EINVAL;
+break;
+}
 
 ret = iommu_deassign_dt_device(d, dev);
 
@@ -342,5 +364,7 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct 
domain *d,
 break;
 }
 
+read_unlock(_host_lock);
+
 return ret;
 }
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index 44d315c8ba..a262bba2ed 100644
--- a/xen/include/xen/device_tree.h
+++ 

[XEN][PATCH v11 17/20] xen/arm: Implement device tree node addition functionalities

2023-08-31 Thread Vikram Garhwal
Update sysctl XEN_SYSCTL_dt_overlay to enable support for dtbo nodes addition
using device tree overlay.

xl dt-overlay add file.dtbo:
Each time overlay nodes are added using .dtbo, a new fdt(memcpy of
device_tree_flattened) is created and updated with overlay nodes. This
updated fdt is further unflattened to a dt_host_new. Next, it checks if any
of the overlay nodes already exists in the dt_host. If overlay nodes doesn't
exist then find the overlay nodes in dt_host_new, find the overlay node's
parent in dt_host and add the nodes as child under their parent in the
dt_host. The node is attached as the last node under target parent.

Finally, add IRQs, add device to IOMMUs, set permissions and map MMIO for 
the
overlay node.

When a node is added using overlay, a new entry is allocated in the
overlay_track to keep the track of memory allocation due to addition of overlay
node. This is helpful for freeing the memory allocated when a device tree node
is removed.

The main purpose of this to address first part of dynamic programming i.e.
making xen aware of new device tree node which means updating the dt_host with
overlay node information. Here we are adding/removing node from dt_host, and
checking/setting IOMMU and IRQ permission but never mapping them to any domain.
Right now, mapping/Un-mapping will happen only when a new domU is
created/destroyed using "xl create".

Signed-off-by: Vikram Garhwal 

---
Changes from v10:
Change int to unsigned int for accessing node_nums.
Re-organize free_nodes_full_path().
Change order of calling xfree for err cases.
Changes from v9:
Remove add_resources() and use handle_device().
Changes from v8:
Add rangeset to keep IRQs and IOMEM information.
Changes from v7:
Move overlay_node_count() in this patch.
Fix indent with goto statements.
Rename handle_add_irq_iommu() to add_resources().
Changes from v6:
Fix comment style and add comment regarding false flag in irq mapping.
Move malloc for nodes_full_path to handle_add_overlay_nodes.
Move node_num define to start of overlay_get_nodes_info().
Remove "domain *d" from handle_add_irq_iommu().
Fix error handling for handle_add_irq_iommu().
Split handle_add_overlay_nodes to two functions.
Create a separate function for freeing nodes_full_path.
Fix xfree for dt_sysctl.
---
---
 xen/common/dt-overlay.c | 495 
 1 file changed, 495 insertions(+)

diff --git a/xen/common/dt-overlay.c b/xen/common/dt-overlay.c
index 7b7224c29a..d748ea3df0 100644
--- a/xen/common/dt-overlay.c
+++ b/xen/common/dt-overlay.c
@@ -34,6 +34,25 @@ find_last_descendants_node(const struct dt_device_node 
*device_node)
 return child_node;
 }
 
+/*
+ * Returns next node to the input node. If node has children then return
+ * last descendant's next node.
+*/
+static struct dt_device_node *
+dt_find_next_node(struct dt_device_node *dt, const struct dt_device_node *node)
+{
+struct dt_device_node *np;
+
+dt_for_each_device_node(dt, np)
+if ( np == node )
+break;
+
+if ( np->child )
+np = find_last_descendants_node(np);
+
+return np->allnext;
+}
+
 static int dt_overlay_remove_node(struct dt_device_node *device_node)
 {
 struct dt_device_node *np;
@@ -111,6 +130,78 @@ static int dt_overlay_remove_node(struct dt_device_node 
*device_node)
 return 0;
 }
 
+static int dt_overlay_add_node(struct dt_device_node *device_node,
+   const char *parent_node_path)
+{
+struct dt_device_node *parent_node;
+struct dt_device_node *next_node;
+
+parent_node = dt_find_node_by_path(parent_node_path);
+
+if ( parent_node == NULL )
+{
+dt_dprintk("Parent node %s not found. Overlay node will not be 
added\n",
+   parent_node_path);
+return -EINVAL;
+}
+
+/* If parent has no child. */
+if ( parent_node->child == NULL )
+{
+next_node = parent_node->allnext;
+device_node->parent = parent_node;
+parent_node->allnext = device_node;
+parent_node->child = device_node;
+}
+else
+{
+struct dt_device_node *np;
+/*
+ * If parent has at least one child node.
+ * Iterate to the last child node of parent.
+ */
+for ( np = parent_node->child; np->sibling != NULL; np = np->sibling );
+
+/* Iterate over all child nodes of np node. */
+if ( np->child )
+{
+struct dt_device_node *np_last_descendant;
+
+np_last_descendant = find_last_descendants_node(np);
+
+next_node = np_last_descendant->allnext;
+np_last_descendant->allnext = device_node;
+}
+else
+{
+next_node = np->allnext;
+np->allnext = device_node;
+}
+
+device_node->parent = parent_node;
+np->sibling = device_node;
+

[XEN][PATCH v11 20/20] tools/xl: Add new xl command overlay for device tree overlay support

2023-08-31 Thread Vikram Garhwal
Signed-off-by: Vikram Garhwal 
Reviewed-by: Anthony PERARD 
---
 tools/xl/xl.h   |  1 +
 tools/xl/xl_cmdtable.c  |  6 +
 tools/xl/xl_vmcontrol.c | 52 +
 3 files changed, 59 insertions(+)

diff --git a/tools/xl/xl.h b/tools/xl/xl.h
index 72538d6a81..a923daccd3 100644
--- a/tools/xl/xl.h
+++ b/tools/xl/xl.h
@@ -138,6 +138,7 @@ int main_shutdown(int argc, char **argv);
 int main_reboot(int argc, char **argv);
 int main_list(int argc, char **argv);
 int main_vm_list(int argc, char **argv);
+int main_dt_overlay(int argc, char **argv);
 int main_create(int argc, char **argv);
 int main_config_update(int argc, char **argv);
 int main_button_press(int argc, char **argv);
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 67604e9536..2463521156 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -631,6 +631,12 @@ const struct cmd_spec cmd_table[] = {
   "Issue a qemu monitor command to the device model of a domain",
   " ",
 },
+{ "dt-overlay",
+  _dt_overlay, 0, 1,
+  "Add/Remove a device tree overlay",
+  "add/remove <.dtbo>"
+  "-h print this help\n"
+},
 };
 
 const int cmdtable_len = ARRAY_SIZE(cmd_table);
diff --git a/tools/xl/xl_vmcontrol.c b/tools/xl/xl_vmcontrol.c
index 03971927e9..cea5b4a88e 100644
--- a/tools/xl/xl_vmcontrol.c
+++ b/tools/xl/xl_vmcontrol.c
@@ -1265,6 +1265,58 @@ int main_create(int argc, char **argv)
 return 0;
 }
 
+int main_dt_overlay(int argc, char **argv)
+{
+const char *overlay_ops = NULL;
+const char *overlay_config_file = NULL;
+void *overlay_dtb = NULL;
+int rc;
+uint8_t op;
+int overlay_dtb_size = 0;
+const int overlay_add_op = 1;
+const int overlay_remove_op = 2;
+
+if (argc < 2) {
+help("dt_overlay");
+return EXIT_FAILURE;
+}
+
+overlay_ops = argv[1];
+overlay_config_file = argv[2];
+
+if (strcmp(overlay_ops, "add") == 0)
+op = overlay_add_op;
+else if (strcmp(overlay_ops, "remove") == 0)
+op = overlay_remove_op;
+else {
+fprintf(stderr, "Invalid dt overlay operation\n");
+return EXIT_FAILURE;
+}
+
+if (overlay_config_file) {
+rc = libxl_read_file_contents(ctx, overlay_config_file,
+  _dtb, _dtb_size);
+
+if (rc) {
+fprintf(stderr, "failed to read the overlay device tree file %s\n",
+overlay_config_file);
+free(overlay_dtb);
+return ERROR_FAIL;
+}
+} else {
+fprintf(stderr, "overlay dtbo file not provided\n");
+return ERROR_FAIL;
+}
+
+rc = libxl_dt_overlay(ctx, overlay_dtb, overlay_dtb_size, op);
+
+free(overlay_dtb);
+
+if (rc)
+return EXIT_FAILURE;
+
+return rc;
+}
 /*
  * Local variables:
  * mode: C
-- 
2.17.1




[XEN][PATCH v11 06/20] libfdt: Keep fdt functions after init for CONFIG_OVERLAY_DTB.

2023-08-31 Thread Vikram Garhwal
This is done to access fdt library function which are required for adding device
tree overlay nodes for dynamic programming of nodes.

Signed-off-by: Vikram Garhwal 
Acked-by: Julien Grall 
---
 xen/common/libfdt/Makefile | 4 
 1 file changed, 4 insertions(+)

diff --git a/xen/common/libfdt/Makefile b/xen/common/libfdt/Makefile
index 75aaefa2e3..d50487aa6e 100644
--- a/xen/common/libfdt/Makefile
+++ b/xen/common/libfdt/Makefile
@@ -1,7 +1,11 @@
 include $(src)/Makefile.libfdt
 
 SECTIONS := text data $(SPECIAL_DATA_SECTIONS)
+
+# For CONFIG_OVERLAY_DTB, libfdt functionalities will be needed during runtime.
+ifneq ($(CONFIG_OVERLAY_DTB),y)
 OBJCOPYFLAGS := $(foreach s,$(SECTIONS),--rename-section .$(s)=.init.$(s))
+endif
 
 obj-y += libfdt.o
 nocov-y += libfdt.o
-- 
2.17.1




[XEN][PATCH v11 09/20] xen/iommu: Move spin_lock from iommu_dt_device_is_assigned to caller

2023-08-31 Thread Vikram Garhwal
Rename iommu_dt_device_is_assigned() to iommu_dt_device_is_assigned_locked().

Moving spin_lock to caller was done to prevent the concurrent access to
iommu_dt_device_is_assigned while doing add/remove/assign/deassign. Follow-up
patches in this series introduces node add/remove feature.

Signed-off-by: Vikram Garhwal 
Reviewed-by: Michal Orzel 
---
Changes from v10:
Move spin_lock before iommu_dt_device_is_assigned_locked() call.
Rebase the patch with latest Xen.
Changes from v9:
Make iommu_dt_device_is_assigned_locked() static and delete header.
Move dtdevs_lock before iommu_dt_device_is_assigned_locked().
Changes from v7:
Update commit message.
Add ASSERT().
---
---
 xen/drivers/passthrough/device_tree.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/xen/drivers/passthrough/device_tree.c 
b/xen/drivers/passthrough/device_tree.c
index 3c0322c797..a7d86a20a0 100644
--- a/xen/drivers/passthrough/device_tree.c
+++ b/xen/drivers/passthrough/device_tree.c
@@ -83,16 +83,16 @@ fail:
 return rc;
 }
 
-static bool iommu_dt_device_is_assigned(const struct dt_device_node *dev)
+static bool iommu_dt_device_is_assigned_locked(const struct dt_device_node 
*dev)
 {
 bool assigned = false;
 
+ASSERT(spin_is_locked(_lock));
+
 if ( !dt_device_is_protected(dev) )
 return 0;
 
-spin_lock(_lock);
 assigned = !list_empty(>domain_list);
-spin_unlock(_lock);
 
 return assigned;
 }
@@ -225,12 +225,16 @@ int iommu_do_dt_domctl(struct xen_domctl *domctl, struct 
domain *d,
 
 if ( domctl->cmd == XEN_DOMCTL_test_assign_device )
 {
-if ( iommu_dt_device_is_assigned(dev) )
+spin_lock(_lock);
+
+if ( iommu_dt_device_is_assigned_locked(dev) )
 {
 printk(XENLOG_G_ERR "%s already assigned.\n",
dt_node_full_name(dev));
 ret = -EINVAL;
 }
+
+spin_unlock(_lock);
 break;
 }
 
-- 
2.17.1




[PATCH v5 4/5] xen/vpci: header: status register handler

2023-08-31 Thread Stewart Hildebrand
Introduce a handler for the PCI status register, with ability to mask the
capabilities bit. The status register contains reserved bits, read-only bits,
and write-1-to-clear bits, so introduce bitmasks to handle these in vPCI. If a
bit in the bitmask is set, then the special meaning applies:

  res_mask: read as zero, write ignore
  ro_mask: read normal, write ignore
  rw1c_mask: read normal, write 1 to clear

The mask_cap_list flag will be set in a follow-on patch.

Signed-off-by: Stewart Hildebrand 
---
v4->v5:
* add support for res_mask
* add support for ro_mask (squash ro_mask patch)
* add constants for reserved, read-only, and rw1c masks

v3->v4:
* move mask_cap_list setting to the capabilities patch
* single pci_conf_read16 in status_read
* align mask_cap_list bitfield in struct vpci_header
* change to rw1c bit mask instead of treating whole register as rw1c
* drop subsystem prefix on renamed add_register function

v2->v3:
* new patch
---
 xen/drivers/vpci/header.c  | 18 +++
 xen/drivers/vpci/vpci.c| 46 +++---
 xen/include/xen/pci_regs.h |  8 +++
 xen/include/xen/vpci.h | 10 +
 4 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/xen/drivers/vpci/header.c b/xen/drivers/vpci/header.c
index 767c1ba718d7..791791e6c9b6 100644
--- a/xen/drivers/vpci/header.c
+++ b/xen/drivers/vpci/header.c
@@ -413,6 +413,18 @@ static void cf_check cmd_write(
 pci_conf_write16(pdev->sbdf, reg, cmd);
 }
 
+static uint32_t cf_check status_read(const struct pci_dev *pdev,
+ unsigned int reg, void *data)
+{
+struct vpci_header *header = data;
+uint32_t status = pci_conf_read16(pdev->sbdf, reg);
+
+if ( header->mask_cap_list )
+status &= ~PCI_STATUS_CAP_LIST;
+
+return status;
+}
+
 static void cf_check bar_write(
 const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
 {
@@ -544,6 +556,12 @@ static int cf_check init_bars(struct pci_dev *pdev)
 if ( rc )
 return rc;
 
+rc = vpci_add_register_mask(pdev->vpci, status_read, vpci_hw_write16,
+PCI_STATUS, 2, header, 
PCI_STATUS_RESERVED_MASK,
+PCI_STATUS_RO_MASK, PCI_STATUS_RW1C_MASK);
+if ( rc )
+return rc;
+
 if ( pdev->ignore_bars )
 return 0;
 
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index 3bec9a4153da..6e6ad4b80a0d 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -29,6 +29,9 @@ struct vpci_register {
 unsigned int offset;
 void *private;
 struct list_head node;
+uint32_t res_mask;
+uint32_t ro_mask;
+uint32_t rw1c_mask;
 };
 
 #ifdef __XEN__
@@ -145,9 +148,16 @@ uint32_t cf_check vpci_hw_read32(
 return pci_conf_read32(pdev->sbdf, reg);
 }
 
-int vpci_add_register(struct vpci *vpci, vpci_read_t *read_handler,
-  vpci_write_t *write_handler, unsigned int offset,
-  unsigned int size, void *data)
+void cf_check vpci_hw_write16(
+const struct pci_dev *pdev, unsigned int reg, uint32_t val, void *data)
+{
+pci_conf_write16(pdev->sbdf, reg, val);
+}
+
+static int add_register(struct vpci *vpci, vpci_read_t *read_handler,
+vpci_write_t *write_handler, unsigned int offset,
+unsigned int size, void *data, uint32_t res_mask,
+uint32_t ro_mask, uint32_t rw1c_mask)
 {
 struct list_head *prev;
 struct vpci_register *r;
@@ -167,6 +177,9 @@ int vpci_add_register(struct vpci *vpci, vpci_read_t 
*read_handler,
 r->size = size;
 r->offset = offset;
 r->private = data;
+r->res_mask = res_mask & (0xU >> (32 - 8 * size));
+r->ro_mask = ro_mask & (0xU >> (32 - 8 * size));
+r->rw1c_mask = rw1c_mask & (0xU >> (32 - 8 * size));
 
 spin_lock(>lock);
 
@@ -193,6 +206,23 @@ int vpci_add_register(struct vpci *vpci, vpci_read_t 
*read_handler,
 return 0;
 }
 
+int vpci_add_register(struct vpci *vpci, vpci_read_t *read_handler,
+  vpci_write_t *write_handler, unsigned int offset,
+  unsigned int size, void *data)
+{
+return add_register(vpci, read_handler, write_handler, offset, size, data,
+0, 0, 0);
+}
+
+int vpci_add_register_mask(struct vpci *vpci, vpci_read_t *read_handler,
+   vpci_write_t *write_handler, unsigned int offset,
+   unsigned int size, void *data, uint32_t res_mask,
+   uint32_t ro_mask, uint32_t rw1c_mask)
+{
+return add_register(vpci, read_handler, write_handler, offset, size, data,
+res_mask, ro_mask, rw1c_mask);
+}
+
 int vpci_remove_register(struct vpci *vpci, unsigned int offset,
  unsigned int size)
 {
@@ -376,6 +406,7 @@ uint32_t vpci_read(pci_sbdf_t sbdf, unsigned int reg, 

[XEN][PATCH v11 08/20] xen/device-tree: Add dt_find_node_by_path_from() to find nodes in device tree

2023-08-31 Thread Vikram Garhwal
Add dt_find_node_by_path_from() to find a matching node with path for a
dt_device_node.

Reason behind this function:
Each time overlay nodes are added using .dtbo, a new fdt (memcpy of
device_tree_flattened) is created and updated with overlay nodes. This
updated fdt is further unflattened to a dt_host_new. Next, we need to find
the overlay nodes in dt_host_new, find the overlay node's parent in dt_host
and add the nodes as child under their parent in the dt_host. Thus we need
this function to search for node in different unflattened device trees.

Also, make dt_find_node_by_path() static inline.

Signed-off-by: Vikram Garhwal 
Reviewed-by: Michal Orzel 
Acked-by: Stefano Stabellini 

---
Changes from v10:
Fix commit message with right function name.
Changes from v9:
Fix indentation issues.

Changes from v7:
Rename device_tree_find_node_by_path() to dt_find_node_by_path_from().
Fix indentation.
---
---
 xen/common/device_tree.c  |  5 +++--
 xen/include/xen/device_tree.h | 17 +++--
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index b8ef1c7ae2..f38f51ec0b 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -358,11 +358,12 @@ struct dt_device_node *dt_find_node_by_type(struct 
dt_device_node *from,
 return np;
 }
 
-struct dt_device_node *dt_find_node_by_path(const char *path)
+struct dt_device_node *dt_find_node_by_path_from(struct dt_device_node *from,
+ const char *path)
 {
 struct dt_device_node *np;
 
-dt_for_each_device_node(dt_host, np)
+dt_for_each_device_node(from, np)
 if ( np->full_name && (dt_node_cmp(np->full_name, path) == 0) )
 break;
 
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index a518310a62..44d315c8ba 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -570,13 +570,26 @@ struct dt_device_node *dt_find_node_by_type(struct 
dt_device_node *from,
 struct dt_device_node *dt_find_node_by_alias(const char *alias);
 
 /**
- * dt_find_node_by_path - Find a node matching a full DT path
+ * dt_find_node_by_path_from - Generic function to find a node matching the
+ * full DT path for any given unflatten device tree
+ * @from: The device tree node to start searching from
  * @path: The full path to match
  *
  * Returns a node pointer.
  */
-struct dt_device_node *dt_find_node_by_path(const char *path);
+struct dt_device_node *dt_find_node_by_path_from(struct dt_device_node *from,
+ const char *path);
 
+/**
+ * dt_find_node_by_path - Find a node matching a full DT path in dt_host
+ * @path: The full path to match
+ *
+ * Returns a node pointer.
+ */
+static inline struct dt_device_node *dt_find_node_by_path(const char *path)
+{
+return dt_find_node_by_path_from(dt_host, path);
+}
 
 /**
  * dt_find_node_by_gpath - Same as dt_find_node_by_path but retrieve the
-- 
2.17.1




[XEN][PATCH v11 12/20] xen/smmu: Add remove_device callback for smmu_iommu ops

2023-08-31 Thread Vikram Garhwal
Add remove_device callback for removing the device entry from smmu-master using
following steps:
1. Find if SMMU master exists for the device node.
2. Check if device is currently in use.
3. Remove the SMMU master.

Signed-off-by: Vikram Garhwal 

---
 Changes from v9:
Remove iommu_dt_device_is_assigned_locked().
Add comment regarding caller holding the locks to protect concurrent access.
 Changes from v7:
Added comments on arm_smmu_dt_remove_device_generic().
---
---
 xen/drivers/passthrough/arm/smmu.c | 60 ++
 1 file changed, 60 insertions(+)

diff --git a/xen/drivers/passthrough/arm/smmu.c 
b/xen/drivers/passthrough/arm/smmu.c
index c37fa9af13..71799064f8 100644
--- a/xen/drivers/passthrough/arm/smmu.c
+++ b/xen/drivers/passthrough/arm/smmu.c
@@ -815,6 +815,19 @@ static int insert_smmu_master(struct arm_smmu_device *smmu,
return 0;
 }
 
+static int remove_smmu_master(struct arm_smmu_device *smmu,
+ struct arm_smmu_master *master)
+{
+   if (!smmu->masters.rb_node) {
+   ASSERT_UNREACHABLE();
+   return -ENOENT;
+   }
+
+   rb_erase(>node, >masters);
+
+   return 0;
+}
+
 static int arm_smmu_dt_add_device_legacy(struct arm_smmu_device *smmu,
 struct device *dev,
 struct iommu_fwspec *fwspec)
@@ -852,6 +865,32 @@ static int arm_smmu_dt_add_device_legacy(struct 
arm_smmu_device *smmu,
return insert_smmu_master(smmu, master);
 }
 
+static int arm_smmu_dt_remove_device_legacy(struct arm_smmu_device *smmu,
+struct device *dev)
+{
+   struct arm_smmu_master *master;
+   struct device_node *dev_node = dev_get_dev_node(dev);
+   int ret;
+
+   master = find_smmu_master(smmu, dev_node);
+   if (master == NULL) {
+   dev_err(dev,
+   "No registrations found for master device %s\n",
+   dev_node->name);
+   return -EINVAL;
+   }
+
+   ret = remove_smmu_master(smmu, master);
+   if (ret)
+   return ret;
+
+   /* Protected by dt_host_lock and dtdevs_lock as caller holds these 
locks. */
+   dev_node->is_protected = false;
+
+   kfree(master);
+   return 0;
+}
+
 static int register_smmu_master(struct arm_smmu_device *smmu,
struct device *dev,
struct of_phandle_args *masterspec)
@@ -875,6 +914,26 @@ static int register_smmu_master(struct arm_smmu_device 
*smmu,
 fwspec);
 }
 
+/*
+ * The driver which supports generic IOMMU DT bindings must have this
+ * callback implemented.
+ */
+static int arm_smmu_dt_remove_device_generic(u8 devfn, struct device *dev)
+{
+   struct arm_smmu_device *smmu;
+   struct iommu_fwspec *fwspec;
+
+   fwspec = dev_iommu_fwspec_get(dev);
+   if (fwspec == NULL)
+   return -ENXIO;
+
+   smmu = find_smmu(fwspec->iommu_dev);
+   if (smmu == NULL)
+   return -ENXIO;
+
+   return arm_smmu_dt_remove_device_legacy(smmu, dev);
+}
+
 static int arm_smmu_dt_add_device_generic(u8 devfn, struct device *dev)
 {
struct arm_smmu_device *smmu;
@@ -2859,6 +2918,7 @@ static const struct iommu_ops arm_smmu_iommu_ops = {
 .init = arm_smmu_iommu_domain_init,
 .hwdom_init = arch_iommu_hwdom_init,
 .add_device = arm_smmu_dt_add_device_generic,
+.remove_device = arm_smmu_dt_remove_device_generic,
 .teardown = arm_smmu_iommu_domain_teardown,
 .iotlb_flush = arm_smmu_iotlb_flush,
 .assign_device = arm_smmu_assign_dev,
-- 
2.17.1




[XEN][PATCH v11 07/20] libfdt: overlay: change overlay_get_target()

2023-08-31 Thread Vikram Garhwal
Rename overlay_get_target() to fdt_overlay_target_offset() and remove static
function type.

This is done to get the target path for the overlay nodes which is very useful
in many cases. For example, Xen hypervisor needs it when applying overlays
because Xen needs to do further processing of the overlay nodes, e.g. mapping of
resources(IRQs and IOMMUs) to other VMs, creation of SMMU pagetables, etc.

Signed-off-by: Vikram Garhwal 
Message-Id: <1637204036-382159-2-git-send-email-fnu.vik...@xilinx.com>
Signed-off-by: David Gibson 
Origin: git://git.kernel.org/pub/scm/utils/dtc/dtc.git 45f3d1a095dd

Signed-off-by: Vikram Garhwal 
Reviewed-by: Michal Orzel 
Reviewed-by: Henry Wang 
Acked-by: Juline Grall 
---
 xen/common/libfdt/fdt_overlay.c | 29 +++--
 xen/common/libfdt/version.lds   |  1 +
 xen/include/xen/libfdt/libfdt.h | 18 ++
 3 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/xen/common/libfdt/fdt_overlay.c b/xen/common/libfdt/fdt_overlay.c
index 7b95e2b639..acf0c4c2a6 100644
--- a/xen/common/libfdt/fdt_overlay.c
+++ b/xen/common/libfdt/fdt_overlay.c
@@ -41,37 +41,22 @@ static uint32_t overlay_get_target_phandle(const void 
*fdto, int fragment)
return fdt32_to_cpu(*val);
 }
 
-/**
- * overlay_get_target - retrieves the offset of a fragment's target
- * @fdt: Base device tree blob
- * @fdto: Device tree overlay blob
- * @fragment: node offset of the fragment in the overlay
- * @pathp: pointer which receives the path of the target (or NULL)
- *
- * overlay_get_target() retrieves the target offset in the base
- * device tree of a fragment, no matter how the actual targeting is
- * done (through a phandle or a path)
- *
- * returns:
- *  the targeted node offset in the base device tree
- *  Negative error code on error
- */
-static int overlay_get_target(const void *fdt, const void *fdto,
- int fragment, char const **pathp)
+int fdt_overlay_target_offset(const void *fdt, const void *fdto,
+ int fragment_offset, char const **pathp)
 {
uint32_t phandle;
const char *path = NULL;
int path_len = 0, ret;
 
/* Try first to do a phandle based lookup */
-   phandle = overlay_get_target_phandle(fdto, fragment);
+   phandle = overlay_get_target_phandle(fdto, fragment_offset);
if (phandle == (uint32_t)-1)
return -FDT_ERR_BADPHANDLE;
 
/* no phandle, try path */
if (!phandle) {
/* And then a path based lookup */
-   path = fdt_getprop(fdto, fragment, "target-path", _len);
+   path = fdt_getprop(fdto, fragment_offset, "target-path", 
_len);
if (path)
ret = fdt_path_offset(fdt, path);
else
@@ -638,7 +623,7 @@ static int overlay_merge(void *fdt, void *fdto)
if (overlay < 0)
return overlay;
 
-   target = overlay_get_target(fdt, fdto, fragment, NULL);
+   target = fdt_overlay_target_offset(fdt, fdto, fragment, NULL);
if (target < 0)
return target;
 
@@ -781,7 +766,7 @@ static int overlay_symbol_update(void *fdt, void *fdto)
return -FDT_ERR_BADOVERLAY;
 
/* get the target of the fragment */
-   ret = overlay_get_target(fdt, fdto, fragment, _path);
+   ret = fdt_overlay_target_offset(fdt, fdto, fragment, 
_path);
if (ret < 0)
return ret;
target = ret;
@@ -803,7 +788,7 @@ static int overlay_symbol_update(void *fdt, void *fdto)
 
if (!target_path) {
/* again in case setprop_placeholder changed it */
-   ret = overlay_get_target(fdt, fdto, fragment, 
_path);
+   ret = fdt_overlay_target_offset(fdt, fdto, fragment, 
_path);
if (ret < 0)
return ret;
target = ret;
diff --git a/xen/common/libfdt/version.lds b/xen/common/libfdt/version.lds
index 7ab85f1d9d..cbce5d4a8b 100644
--- a/xen/common/libfdt/version.lds
+++ b/xen/common/libfdt/version.lds
@@ -77,6 +77,7 @@ LIBFDT_1.2 {
fdt_appendprop_addrrange;
fdt_setprop_inplace_namelen_partial;
fdt_create_with_flags;
+   fdt_overlay_target_offset;
local:
*;
 };
diff --git a/xen/include/xen/libfdt/libfdt.h b/xen/include/xen/libfdt/libfdt.h
index c71689e2be..fabddbee8c 100644
--- a/xen/include/xen/libfdt/libfdt.h
+++ b/xen/include/xen/libfdt/libfdt.h
@@ -2109,6 +2109,24 @@ int fdt_del_node(void *fdt, int nodeoffset);
  */
 int fdt_overlay_apply(void *fdt, void *fdto);
 
+/**
+ * fdt_overlay_target_offset - retrieves the offset of a fragment's target
+ * @fdt: Base device tree blob
+ * @fdto: Device tree overlay blob
+ * 

[PATCH v5 3/5] xen/pci: update PCI_STATUS_* constants

2023-08-31 Thread Stewart Hildebrand
Interrupt status introduced in PCI 2.3
Immediate readiness introduced in PCIe 4.0

Signed-off-by: Stewart Hildebrand 
---
v4->v5:
* new patch
---
 xen/include/xen/pci_regs.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/xen/include/xen/pci_regs.h b/xen/include/xen/pci_regs.h
index a90aff1712ba..84b18736a85d 100644
--- a/xen/include/xen/pci_regs.h
+++ b/xen/include/xen/pci_regs.h
@@ -50,6 +50,8 @@
 #define  PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
 
 #define PCI_STATUS 0x06/* 16 bits */
+#define  PCI_STATUS_IMM_READY  0x01/* Immediate Readiness */
+#define  PCI_STATUS_INTERRUPT  0x08/* Interrupt status */
 #define  PCI_STATUS_CAP_LIST   0x10/* Support Capability List */
 #define  PCI_STATUS_66MHZ  0x20/* Support 66 Mhz PCI 2.1 bus */
 #define  PCI_STATUS_UDF0x40/* Support User Definable 
Features [obsolete] */
-- 
2.42.0




[XEN][PATCH v11 03/20] xen/arm/device: Remove __init from function type

2023-08-31 Thread Vikram Garhwal
Remove __init from following function to access during runtime:
1. map_irq_to_domain()
2. handle_device_interrupts()
3. map_range_to_domain()
4. unflatten_dt_node()
5. handle_device()
6. map_device_children()
7. map_dt_irq_to_domain()
Move map_irq_to_domain() prototype from domain_build.h to setup.h.

Above changes will create an error on build as non-init function are still
in domain_build.c file. So, to avoid build fails, following changes are done:
1. Move map_irq_to_domain(), handle_device_interrupts(), map_range_to_domain(),
handle_device(), map_device_children() and map_dt_irq_to_domain()
to device.c. After removing __init type,  these functions are not specific
to domain building, so moving them out of domain_build.c to device.c.
2. Remove static type from handle_device_interrupts().

Also, renamed handle_device_interrupts() to map_device_irqs_to_domain().

Overall, these changes are done to support the dynamic programming of a nodes
where an overlay node will be added to fdt and unflattened node will be added to
dt_host. Furthermore, IRQ and mmio mapping will be done for the added node.

Signed-off-by: Vikram Garhwal 
Reviewed-by: Michal Orzel 

---
Changes from v10:
Remove unnecessary rangeset variables  from handle_device() declaration.
Rename handle_device_interrupts() to map_device_irqs_to_domain().
Fix code styles.

Changes from v9:
Move handle_device(), map_device_children() and map_dt_irq_to_domain() out
of domain_build.c
---
---
 xen/arch/arm/device.c   | 294 +++
 xen/arch/arm/domain_build.c | 295 +---
 xen/arch/arm/include/asm/domain_build.h |   2 -
 xen/arch/arm/include/asm/setup.h|   9 +
 xen/common/device_tree.c|  12 +-
 5 files changed, 310 insertions(+), 302 deletions(-)

diff --git a/xen/arch/arm/device.c b/xen/arch/arm/device.c
index ca8539dee5..327e4d24fb 100644
--- a/xen/arch/arm/device.c
+++ b/xen/arch/arm/device.c
@@ -9,8 +9,10 @@
  */
 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
 
 extern const struct device_desc _sdevice[], _edevice[];
@@ -75,6 +77,298 @@ enum device_class device_get_class(const struct 
dt_device_node *dev)
 return DEVICE_UNKNOWN;
 }
 
+int map_irq_to_domain(struct domain *d, unsigned int irq,
+  bool need_mapping, const char *devname)
+{
+int res;
+
+res = irq_permit_access(d, irq);
+if ( res )
+{
+printk(XENLOG_ERR "Unable to permit to %pd access to IRQ %u\n", d, 
irq);
+return res;
+}
+
+if ( need_mapping )
+{
+/*
+ * Checking the return of vgic_reserve_virq is not
+ * necessary. It should not fail except when we try to map
+ * the IRQ twice. This can legitimately happen if the IRQ is shared
+ */
+vgic_reserve_virq(d, irq);
+
+res = route_irq_to_guest(d, irq, irq, devname);
+if ( res < 0 )
+{
+printk(XENLOG_ERR "Unable to map IRQ%u to %pd\n", irq, d);
+return res;
+}
+}
+
+dt_dprintk("  - IRQ: %u\n", irq);
+return 0;
+}
+
+int map_range_to_domain(const struct dt_device_node *dev,
+uint64_t addr, uint64_t len, void *data)
+{
+struct map_range_data *mr_data = data;
+struct domain *d = mr_data->d;
+int res;
+
+if ( (addr != (paddr_t)addr) || (((paddr_t)~0 - addr) < len) )
+{
+printk(XENLOG_ERR "%s: [0x%"PRIx64", 0x%"PRIx64"] exceeds the maximum 
allowed PA width (%u bits)",
+   dt_node_full_name(dev), addr, (addr + len), PADDR_BITS);
+return -ERANGE;
+}
+
+/*
+ * reserved-memory regions are RAM carved out for a special purpose.
+ * They are not MMIO and therefore a domain should not be able to
+ * manage them via the IOMEM interface.
+ */
+if ( strncasecmp(dt_node_full_name(dev), "/reserved-memory/",
+ strlen("/reserved-memory/")) != 0 )
+{
+res = iomem_permit_access(d, paddr_to_pfn(addr),
+paddr_to_pfn(PAGE_ALIGN(addr + len - 1)));
+if ( res )
+{
+printk(XENLOG_ERR "Unable to permit to dom%d access to"
+" 0x%"PRIx64" - 0x%"PRIx64"\n",
+d->domain_id,
+addr & PAGE_MASK, PAGE_ALIGN(addr + len) - 1);
+return res;
+}
+}
+
+if ( !mr_data->skip_mapping )
+{
+res = map_regions_p2mt(d,
+   gaddr_to_gfn(addr),
+   PFN_UP(len),
+   maddr_to_mfn(addr),
+   mr_data->p2mt);
+
+if ( res < 0 )
+{
+printk(XENLOG_ERR "Unable to map 0x%"PRIx64
+   " - 0x%"PRIx64" in domain %d\n",
+   addr & PAGE_MASK, PAGE_ALIGN(addr + len) - 1,
+   d->domain_id);
+

[XEN][PATCH v11 05/20] xen/arm: Add CONFIG_OVERLAY_DTB

2023-08-31 Thread Vikram Garhwal
Introduce a config option where the user can enable support for adding/removing
device tree nodes using a device tree binary overlay.

Update SUPPORT.md and CHANGELOG.md to state the Device Tree Overlays support for
Arm.

Signed-off-by: Vikram Garhwal 
Acked-by: Henry Wang 
Reviewed-by: Michal Orzel 

---
Changes from v9:
Fix style.
Changes from v7:
Add this feature as "experimental support" in CHANGELOG.md
---
---
 CHANGELOG.md | 2 ++
 SUPPORT.md   | 6 ++
 xen/arch/arm/Kconfig | 5 +
 3 files changed, 13 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2516526589..24636b8eaf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,6 +27,8 @@ The format is based on [Keep a 
Changelog](https://keepachangelog.com/en/1.0.0/)
  - On Arm, add suport for Firmware Framework for Arm A-profile (FF-A) Mediator
(Tech Preview)
  - Add Intel Hardware P-States (HWP) cpufreq driver.
+ - On Arm, experimental support for dynamic addition/removal of Xen device tree
+   nodes using a device tree overlay binary (.dtbo).
 
 ### Removed
  - On x86, the "pku" command line option has been removed.  It has never
diff --git a/SUPPORT.md b/SUPPORT.md
index 6ce0ec29b0..3461f5cf2f 100644
--- a/SUPPORT.md
+++ b/SUPPORT.md
@@ -855,6 +855,12 @@ xen/arch/arm/tee/ffa.c for limitations.
 
 Status: Supported
 
+### Device Tree Overlays
+
+Add/Remove device tree nodes using a device tree overlay binary (.dtbo).
+
+Status, ARM: Experimental
+
 ### ARM: Guest ACPI support
 
 Status: Supported
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index 57bd1d01d7..650aca99ac 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -92,6 +92,11 @@ config HAS_ITS
 bool "GICv3 ITS MSI controller support (UNSUPPORTED)" if UNSUPPORTED
 depends on GICV3 && !NEW_VGIC && !ARM_32
 
+config OVERLAY_DTB
+   bool "DTB overlay support (UNSUPPORTED)" if UNSUPPORTED
+   help
+ Dynamic addition/removal of Xen device tree nodes using a dtbo.
+
 config HVM
 def_bool y
 
-- 
2.17.1




[XEN][PATCH v11 02/20] common/device_tree.c: unflatten_device_tree() propagate errors

2023-08-31 Thread Vikram Garhwal
This will be useful in dynamic node programming when new dt nodes are unflattend
during runtime. Invalid device tree node related errors should be propagated
back to the caller.

Signed-off-by: Vikram Garhwal 
Reviewed-by: Michal Orzel 
Acked-by: Stefano Stabellini 

---
Changes from v9:
Replace __be64 with void.
Changes from v7:
Free allocated memory in case of errors when calling unflatten_dt_node.
---
---
 xen/common/device_tree.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index 7c6b41c3b4..b6d9f018c6 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -2110,6 +2110,9 @@ static int __init __unflatten_device_tree(const void *fdt,
 /* First pass, scan for size */
 start = ((unsigned long)fdt) + fdt_off_dt_struct(fdt);
 size = unflatten_dt_node(fdt, 0, , NULL, NULL, 0);
+if ( !size )
+return -EINVAL;
+
 size = (size | 3) + 1;
 
 dt_dprintk("  size is %#lx allocating...\n", size);
@@ -2127,11 +2130,21 @@ static int __init __unflatten_device_tree(const void 
*fdt,
 start = ((unsigned long)fdt) + fdt_off_dt_struct(fdt);
 unflatten_dt_node(fdt, mem, , NULL, , 0);
 if ( be32_to_cpup((__be32 *)start) != FDT_END )
-printk(XENLOG_WARNING "Weird tag at end of tree: %08x\n",
+{
+printk(XENLOG_ERR "Weird tag at end of tree: %08x\n",
   *((u32 *)start));
+xfree((void *)mem);
+return -EINVAL;
+}
+
 if ( be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeefU )
-printk(XENLOG_WARNING "End of tree marker overwritten: %08x\n",
+{
+printk(XENLOG_ERR "End of tree marker overwritten: %08x\n",
   be32_to_cpu(((__be32 *)mem)[size / 4]));
+xfree((void *)mem);
+return -EINVAL;
+}
+
 *allnextp = NULL;
 
 dt_dprintk(" <- unflatten_device_tree()\n");
-- 
2.17.1




[XEN][PATCH v11 04/20] common/device_tree: Export __unflatten_device_tree()

2023-08-31 Thread Vikram Garhwal
Following changes are done to __unflatten_device_tree():
1. __unflatten_device_tree() is renamed to unflatten_device_tree().
2. Remove __init and static function type.

The changes are done to make this function useable for dynamic node programming
where new device tree overlay nodes are added to fdt and further unflattend to
update xen device tree during runtime.

Signed-off-by: Vikram Garhwal 
Acked-by: Julien Grall 

---
Changes from v7:
Update the commit with why unflatten_device_tree() is changed.
Move function documentation to device_tree.h
---
---
 xen/common/device_tree.c  | 19 +++
 xen/include/xen/device_tree.h | 14 ++
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index fccf98f94e..b8ef1c7ae2 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -2082,20 +2082,7 @@ static unsigned long unflatten_dt_node(const void *fdt,
 return mem;
 }
 
-/**
- * __unflatten_device_tree - create tree of device_nodes from flat blob
- *
- * unflattens a device-tree, creating the
- * tree of struct device_node. It also fills the "name" and "type"
- * pointers of the nodes so the normal device-tree walking functions
- * can be used.
- * @fdt: The fdt to expand
- * @mynodes: The device_node tree created by the call
- *
- * Returns 0 on success and a negative number on error
- */
-static int __init __unflatten_device_tree(const void *fdt,
-  struct dt_device_node **mynodes)
+int unflatten_device_tree(const void *fdt, struct dt_device_node **mynodes)
 {
 unsigned long start, mem, size;
 struct dt_device_node **allnextp = mynodes;
@@ -2234,10 +2221,10 @@ dt_find_interrupt_controller(const struct 
dt_device_match *matches)
 
 void __init dt_unflatten_host_device_tree(void)
 {
-int error = __unflatten_device_tree(device_tree_flattened, _host);
+int error = unflatten_device_tree(device_tree_flattened, _host);
 
 if ( error )
-panic("__unflatten_device_tree failed with error %d\n", error);
+panic("unflatten_device_tree failed with error %d\n", error);
 
 dt_alias_scan();
 }
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index 1d79e23b28..a518310a62 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -178,6 +178,20 @@ int device_tree_for_each_node(const void *fdt, int node,
  */
 void dt_unflatten_host_device_tree(void);
 
+/**
+ * unflatten_device_tree - create tree of device_nodes from flat blob
+ *
+ * unflattens a device-tree, creating the
+ * tree of struct device_node. It also fills the "name" and "type"
+ * pointers of the nodes so the normal device-tree walking functions
+ * can be used.
+ * @fdt: The fdt to expand
+ * @mynodes: The device_node tree created by the call
+ *
+ * Returns 0 on success and a negative number on error
+ */
+int unflatten_device_tree(const void *fdt, struct dt_device_node **mynodes);
+
 /**
  * IRQ translation callback
  * TODO: For the moment we assume that we only have ONE
-- 
2.17.1




[XEN][PATCH v11 01/20] common/device_tree: handle memory allocation failure in __unflatten_device_tree()

2023-08-31 Thread Vikram Garhwal
Change __unflatten_device_tree() return type to integer so it can propagate
memory allocation failure. Add panic() in dt_unflatten_host_device_tree() for
memory allocation failure during boot.

Fixes: fb97eb614acf ("xen/arm: Create a hierarchical device tree")
Signed-off-by: Vikram Garhwal 
Reviewed-by: Henry Wang 
Reviewed-by: Michal Orzel 
Acked-by: Julien Grall 

---
Changes from v9:
Update comment regarding return value of unflatten_device_tree().
---
---
 xen/common/device_tree.c | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index 0522fdf976..7c6b41c3b4 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -2091,9 +2091,11 @@ static unsigned long __init unflatten_dt_node(const void 
*fdt,
  * can be used.
  * @fdt: The fdt to expand
  * @mynodes: The device_node tree created by the call
+ *
+ * Returns 0 on success and a negative number on error
  */
-static void __init __unflatten_device_tree(const void *fdt,
-   struct dt_device_node **mynodes)
+static int __init __unflatten_device_tree(const void *fdt,
+  struct dt_device_node **mynodes)
 {
 unsigned long start, mem, size;
 struct dt_device_node **allnextp = mynodes;
@@ -2114,6 +2116,8 @@ static void __init __unflatten_device_tree(const void 
*fdt,
 
 /* Allocate memory for the expanded device tree */
 mem = (unsigned long)_xmalloc (size + 4, __alignof__(struct 
dt_device_node));
+if ( !mem )
+return -ENOMEM;
 
 ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeefU);
 
@@ -2131,6 +2135,8 @@ static void __init __unflatten_device_tree(const void 
*fdt,
 *allnextp = NULL;
 
 dt_dprintk(" <- unflatten_device_tree()\n");
+
+return 0;
 }
 
 static void dt_alias_add(struct dt_alias_prop *ap,
@@ -2215,7 +2221,11 @@ dt_find_interrupt_controller(const struct 
dt_device_match *matches)
 
 void __init dt_unflatten_host_device_tree(void)
 {
-__unflatten_device_tree(device_tree_flattened, _host);
+int error = __unflatten_device_tree(device_tree_flattened, _host);
+
+if ( error )
+panic("__unflatten_device_tree failed with error %d\n", error);
+
 dt_alias_scan();
 }
 
-- 
2.17.1




[XEN][PATCH v11 00/20] dynamic node programming using overlay dtbo

2023-08-31 Thread Vikram Garhwal
Hi,
This patch series is for introducing dynamic programming i.e. add/remove the
devices during run time. Using "xl dt_overlay" a device can be added/removed
with dtbo.

For adding a node using dynamic programming:
1. flatten device tree overlay node will be added to a fdt
2. Updated fdt will be unflattened to a new dt_host_new
3. Extract the newly added node information from dt_host_new
4. Add the added node under correct parent in original dt_host.
3. Map/Permit interrupt and iomem region as required.

For removing a node:
1. Find the node with given path.
2. Check if the node is used by any of domus. Removes the node only when
it's not used by any domain.
3. Removes IRQ permissions and MMIO access.
5. Find the node in dt_host and delete the device node entry from dt_host.
6. Free the overlay_tracker entry which means free dt_host_new also(created
in adding node step).

The main purpose of this series to address first part of the dynamic programming
i.e. making Xen aware of new device tree node which means updating the dt_host
with overlay node information. Here we are adding/removing node from dt_host,
and checking/set IOMMU and IRQ permission but never mapping them to any domain.
Right now, mapping/Un-mapping will happen only when a new domU is
created/destroyed using "xl create".

To map IOREQ and IOMMU during runtime, there will be another small series after
this one where we will do the actual IOMMU and IRQ mapping to a running domain
and will call unmap_mmio_regions() to remove the mapping.

Example of overlay node:
/dts-v1/;

/ {

fragment@0 {
target-path = "/axi";

__overlay__ {

ethernet@ff0e {
compatible = "cdns,zynqmp-gem", "cdns,gem";
status = "okay";
interrupt-parent = <0x4>;
interrupts = <0x0 0x3f 0x4>;
reg = <0x0 0xff0e 0x0 0x1000>;
clock-names = "pclk", "hclk", "tx_clk", 
"rx_clk", "tsu_clk";
#address-cells = <0x1>;
#size-cells = <0x0>;
#stream-id-cells = <0x1>;
iommus = <0xe 0x877>;
power-domains = <0xc 0x20>;
clocks = <0x3 0x1f 0x3 0x6b 0x3 0x30 0x3 0x34 
0x3 0x2c>;
phy-handle = <0xf>;
pinctrl-names = "default";
pinctrl-0 = <0x10>;
phy-mode = "rgmii-id";
xlnx,ptp-enet-clock = <0x0>;
local-mac-address = [00 0a 35 00 22 01];
xen,passthrough = <1>;
ethernet-phy@c {
reg = <0xc>;
ti,rx-internal-delay = <0x8>;
ti,tx-internal-delay = <0xa>;
ti,fifo-depth = <0x1>;
ti,dp83867-rxctrl-strap-quirk;
interrupt-parent = <0x4>;
interrupts = <0x0 0x4f 0x4>;
xen,passthrough = <1>;
phandle = <0x2>;
};
};
};
};

Change Log:
 v5 -> v6:
Add separate patch for memory allocation failure in 
__unflatten_device_tree().
Move __unflatten_device_tree() function type changes to single patch.
Add error propagation for failures in unflatten_dt_node.
Change CONFIG_OVERLAY_DTB status to "ARM: Tech Preview".
xen/smmu: Add remove_device callback for smmu_iommu ops:
Added check to see if device is currently used.
common/device_tree: Add rwlock for dt_host:
Addressed feedback from Henry to rearrange code.
xen/arm: Implement device tree node removal functionalities:
Changed file name to dash format.
Addressed Michal's comments.
Rectified formatting related errors pointed by Michal.

 v4 -> v5:
Split patch 01/16 to two patches. One with function type changes and another
with changes inside unflatten_device_tree().
Change dt_overlay xl command to dt-overlay.
Protect overlay functionality with CONFIG(arm).
Fix rwlock issues.
Move include "device_tree.h" to c file where arch_cpu_init() is called and
forward declare dt_device_node. This was done to avoid circular deps b/w
device_tree.h and rwlock.h
Address Michal's comment on coding style.

 v3 -> v4:
Add support for adding node's children.
Add rwlock to dt_host functions.
Corrected fdt size issue when applying overlay into it.

[PATCH v5 2/5] x86/msi: rearrange read_pci_mem_bar slightly

2023-08-31 Thread Stewart Hildebrand
Use pdev->sbdf instead of the PCI_SBDF macro in calls to pci_* functions
where appropriate. Move NULL check earlier.

Suggested-by: Jan Beulich 
Signed-off-by: Stewart Hildebrand 
Reviewed-by: Jan Beulich 
---
v4->v5:
* add Jan's R-b

v3->v4:
* new patch

Suggested-by tag added based on conversation at [1]

[1] https://lists.xenproject.org/archives/html/xen-devel/2023-08/msg01886.html
---
 xen/arch/x86/msi.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 8d4fd43b10a6..a78367d7cf5d 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -674,19 +674,19 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 
func, u8 bir, int vf)
 {
 struct pci_dev *pdev = pci_get_pdev(NULL,
 PCI_SBDF(seg, bus, slot, func));
-unsigned int pos = pci_find_ext_capability(PCI_SBDF(seg, bus, slot,
-func),
-   PCI_EXT_CAP_ID_SRIOV);
-uint16_t ctrl = pci_conf_read16(PCI_SBDF(seg, bus, slot, func),
-pos + PCI_SRIOV_CTRL);
-uint16_t num_vf = pci_conf_read16(PCI_SBDF(seg, bus, slot, func),
-  pos + PCI_SRIOV_NUM_VF);
-uint16_t offset = pci_conf_read16(PCI_SBDF(seg, bus, slot, func),
-  pos + PCI_SRIOV_VF_OFFSET);
-uint16_t stride = pci_conf_read16(PCI_SBDF(seg, bus, slot, func),
-  pos + PCI_SRIOV_VF_STRIDE);
-
-if ( !pdev || !pos ||
+unsigned int pos;
+uint16_t ctrl, num_vf, offset, stride;
+
+if ( !pdev )
+return 0;
+
+pos = pci_find_ext_capability(pdev->sbdf, PCI_EXT_CAP_ID_SRIOV);
+ctrl = pci_conf_read16(pdev->sbdf, pos + PCI_SRIOV_CTRL);
+num_vf = pci_conf_read16(pdev->sbdf, pos + PCI_SRIOV_NUM_VF);
+offset = pci_conf_read16(pdev->sbdf, pos + PCI_SRIOV_VF_OFFSET);
+stride = pci_conf_read16(pdev->sbdf, pos + PCI_SRIOV_VF_STRIDE);
+
+if ( !pos ||
  !(ctrl & PCI_SRIOV_CTRL_VFE) ||
  !(ctrl & PCI_SRIOV_CTRL_MSE) ||
  !num_vf || !offset || (num_vf > 1 && !stride) ||
-- 
2.42.0




[PATCH v5 1/5] xen/pci: convert pci_find_*cap* to pci_sbdf_t

2023-08-31 Thread Stewart Hildebrand
Convert pci_find_*cap* functions and call sites to pci_sbdf_t, and remove some
now unused local variables. Also change to more appropriate types on lines that
are already being modified as a result of the pci_sbdf_t conversion.

Signed-off-by: Stewart Hildebrand 
Reviewed-by: Jan Beulich 
---
I built with EXTRA_CFLAGS_XEN_CORE="-Wunused-but-set-variable" (and
unfortunately -Wno-error=unused-but-set-variable too) to identify locations of
unneeded local variables as a result of the change to pci_sbdf_t.

v4->v5:
* add Jan's R-b

v3->v4:
* use more appropriate types on lines that are being modified anyway
* remove "no functional change" from commit description

v2->v3:
* new patch
---
 xen/arch/x86/msi.c | 40 ++
 xen/drivers/char/ehci-dbgp.c   |  3 +-
 xen/drivers/passthrough/amd/iommu_detect.c |  2 +-
 xen/drivers/passthrough/ats.c  |  4 +--
 xen/drivers/passthrough/ats.h  |  6 ++--
 xen/drivers/passthrough/msi.c  |  6 ++--
 xen/drivers/passthrough/pci.c  | 21 +---
 xen/drivers/passthrough/vtd/quirks.c   | 10 ++
 xen/drivers/passthrough/vtd/x86/ats.c  |  3 +-
 xen/drivers/pci/pci.c  | 32 +
 xen/drivers/vpci/msi.c |  4 +--
 xen/drivers/vpci/msix.c|  4 +--
 xen/include/xen/pci.h  | 11 +++---
 13 files changed, 58 insertions(+), 88 deletions(-)

diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 41b82f3e87cb..8d4fd43b10a6 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -283,7 +283,7 @@ static void msi_set_enable(struct pci_dev *dev, int enable)
 u8 slot = PCI_SLOT(dev->devfn);
 u8 func = PCI_FUNC(dev->devfn);
 
-pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
+pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSI);
 if ( pos )
 __msi_set_enable(seg, bus, slot, func, pos, enable);
 }
@@ -291,12 +291,9 @@ static void msi_set_enable(struct pci_dev *dev, int enable)
 static void msix_set_enable(struct pci_dev *dev, int enable)
 {
 int pos;
-u16 control, seg = dev->seg;
-u8 bus = dev->bus;
-u8 slot = PCI_SLOT(dev->devfn);
-u8 func = PCI_FUNC(dev->devfn);
+uint16_t control;
 
-pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSIX);
+pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX);
 if ( pos )
 {
 control = pci_conf_read16(dev->sbdf, msix_control_reg(pos));
@@ -603,13 +600,10 @@ static int msi_capability_init(struct pci_dev *dev,
 struct msi_desc *entry;
 int pos;
 unsigned int i, mpos;
-u16 control, seg = dev->seg;
-u8 bus = dev->bus;
-u8 slot = PCI_SLOT(dev->devfn);
-u8 func = PCI_FUNC(dev->devfn);
+uint16_t control;
 
 ASSERT(pcidevs_locked());
-pos = pci_find_cap_offset(seg, bus, slot, func, PCI_CAP_ID_MSI);
+pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSI);
 if ( !pos )
 return -ENODEV;
 control = pci_conf_read16(dev->sbdf, msi_control_reg(pos));
@@ -680,8 +674,8 @@ static u64 read_pci_mem_bar(u16 seg, u8 bus, u8 slot, u8 
func, u8 bir, int vf)
 {
 struct pci_dev *pdev = pci_get_pdev(NULL,
 PCI_SBDF(seg, bus, slot, func));
-unsigned int pos = pci_find_ext_capability(seg, bus,
-   PCI_DEVFN(slot, func),
+unsigned int pos = pci_find_ext_capability(PCI_SBDF(seg, bus, slot,
+func),
PCI_EXT_CAP_ID_SRIOV);
 uint16_t ctrl = pci_conf_read16(PCI_SBDF(seg, bus, slot, func),
 pos + PCI_SRIOV_CTRL);
@@ -772,8 +766,7 @@ static int msix_capability_init(struct pci_dev *dev,
 u8 slot = PCI_SLOT(dev->devfn);
 u8 func = PCI_FUNC(dev->devfn);
 bool maskall = msix->host_maskall, zap_on_error = false;
-unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
-   PCI_CAP_ID_MSIX);
+unsigned int pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX);
 
 if ( !pos )
 return -ENODEV;
@@ -1097,12 +1090,7 @@ static void _pci_cleanup_msix(struct arch_msix *msix)
 static void __pci_disable_msix(struct msi_desc *entry)
 {
 struct pci_dev *dev = entry->dev;
-u16 seg = dev->seg;
-u8 bus = dev->bus;
-u8 slot = PCI_SLOT(dev->devfn);
-u8 func = PCI_FUNC(dev->devfn);
-unsigned int pos = pci_find_cap_offset(seg, bus, slot, func,
-   PCI_CAP_ID_MSIX);
+unsigned int pos = pci_find_cap_offset(dev->sbdf, PCI_CAP_ID_MSIX);
 u16 control = pci_conf_read16(dev->sbdf,
   msix_control_reg(entry->msi_attrib.pos));
 bool maskall = dev->msix->host_maskall;
@@ -1206,8 +1194,7 @@ void 

[PATCH v5 0/5] vPCI capabilities filtering

2023-08-31 Thread Stewart Hildebrand
This small series enables vPCI to filter which PCI capabilities we expose to a
domU. This series adds vPCI register handlers within
xen/drivers/vpci/header.c:init_bars(), along with some supporting functions.

Note there are minor rebase conflicts with the in-progress vPCI series [1].
These conflicts fall into the category of functions and code being added
adjacent to one another, so are easily resolved. I did not identify any
dependency on the vPCI locking work, and the two series deal with different
aspects of emulating the PCI header.

Future work may involve adding handlers for more registers in the vPCI header,
such as VID/DID, etc. Future work may also involve exposing additional
capabilities to the guest for broader device/driver support.

v4->v5:
* drop ("x86/msi: remove some unused-but-set-variables") as it has been
  committed
* add ("xen/pci: update PCI_STATUS_* constants")
* squash ro_mask patch

v3->v4:
* drop "xen/pci: address a violation of MISRA C:2012 Rule 8.3" as it has been
  committed
* re-order status register handler and capabilities filtering patches
* split an unrelated change from ("xen/pci: convert pci_find_*cap* to 
pci_sbdf_t")
  into its own patch
* add new patch ("x86/msi: rearrange read_pci_mem_bar slightly") based on
  feedback
* add new RFC patch ("xen/vpci: support ro mask")

v2->v3:
* drop RFC "xen/vpci: header: avoid cast for value passed to vpci_read_val"
* minor misra C violation fixup in preparatory patch
* switch to pci_sbdf_t in preparatory patch
* introduce status handler

v1->v2:
* squash helper functions into the patch where they are used to avoid transient
  dead code situation
* add new RFC patch, possibly throwaway, to get an idea of what it would look
  like to get rid of the (void *)(uintptr_t) cast by introducing a new memory
  allocation

[1] https://lists.xenproject.org/archives/html/xen-devel/2023-07/msg01281.html

Stewart Hildebrand (5):
  xen/pci: convert pci_find_*cap* to pci_sbdf_t
  x86/msi: rearrange read_pci_mem_bar slightly
  xen/pci: update PCI_STATUS_* constants
  xen/vpci: header: status register handler
  xen/vpci: header: filter PCI capabilities

 xen/arch/x86/msi.c | 62 +-
 xen/drivers/char/ehci-dbgp.c   |  3 +-
 xen/drivers/passthrough/amd/iommu_detect.c |  2 +-
 xen/drivers/passthrough/ats.c  |  4 +-
 xen/drivers/passthrough/ats.h  |  6 +-
 xen/drivers/passthrough/msi.c  |  6 +-
 xen/drivers/passthrough/pci.c  | 21 ++---
 xen/drivers/passthrough/vtd/quirks.c   | 10 +--
 xen/drivers/passthrough/vtd/x86/ats.c  |  3 +-
 xen/drivers/pci/pci.c  | 52 +++-
 xen/drivers/vpci/header.c  | 94 ++
 xen/drivers/vpci/msi.c |  4 +-
 xen/drivers/vpci/msix.c|  4 +-
 xen/drivers/vpci/vpci.c| 58 +++--
 xen/include/xen/pci.h  | 14 ++--
 xen/include/xen/pci_regs.h | 10 +++
 xen/include/xen/vpci.h | 15 
 17 files changed, 255 insertions(+), 113 deletions(-)


base-commit: 6621932264e3e86df3913db4249ecd3eb100b13f
-- 
2.42.0




Re: [PATCH v4 6/6] xen/vpci: header: filter PCI capabilities

2023-08-31 Thread Stewart Hildebrand
On 8/31/23 08:11, Jan Beulich wrote:
> On 28.08.2023 19:56, Stewart Hildebrand wrote:
>> Currently, Xen vPCI only supports virtualizing the MSI and MSI-X 
>> capabilities.
>> Hide all other PCI capabilities (including extended capabilities) from domUs 
>> for
>> now, even though there may be certain devices/drivers that depend on being 
>> able
>> to discover certain capabilities.
>>
>> We parse the physical PCI capabilities linked list and add vPCI register
>> handlers for the next elements, inserting our own next value, thus 
>> presenting a
>> modified linked list to the domU.
>>
>> Introduce helper functions vpci_hw_read8 and vpci_read_val. The vpci_read_val
>> helper function returns a fixed value, which may be used for RAZ registers, 
>> or
>> registers whose value doesn't change.
>>
>> Introduce pci_find_next_cap_ttl() helper while adapting the logic from
>> pci_find_next_cap() to suit our needs, and implement the existing
>> pci_find_next_cap() in terms of the new helper.
>>
>> Signed-off-by: Stewart Hildebrand 
> 
> Reviewed-by: Jan Beulich > 
> Nevertheless a couple of remarks:
> 
>> --- a/xen/drivers/pci/pci.c
>> +++ b/xen/drivers/pci/pci.c
>> @@ -39,31 +39,44 @@ unsigned int pci_find_cap_offset(pci_sbdf_t sbdf, 
>> unsigned int cap)
>>  return 0;
>>  }
>>
>> -unsigned int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos,
>> -   unsigned int cap)
>> +unsigned int pci_find_next_cap_ttl(pci_sbdf_t sbdf, unsigned int pos,
>> +   bool (*is_match)(unsigned int, unsigned 
>> int),
>> +   unsigned int userdata, unsigned int *ttl)
>>  {
>> -u8 id;
>> -int ttl = 48;
>> +unsigned int id;
>>
>> -while ( ttl-- )
>> +while ( (*ttl)-- )
>>  {
>>  pos = pci_conf_read8(sbdf, pos);
>>  if ( pos < 0x40 )
>>  break;
>>
>> -pos &= ~3;
>> -id = pci_conf_read8(sbdf, pos + PCI_CAP_LIST_ID);
>> +id = pci_conf_read8(sbdf, (pos & ~3) + PCI_CAP_LIST_ID);
>>
>>  if ( id == 0xff )
>>  break;
>> -if ( id == cap )
>> +if ( is_match(id, userdata) )
>>  return pos;
>>
>> -pos += PCI_CAP_LIST_NEXT;
>> +pos = (pos & ~3) + PCI_CAP_LIST_NEXT;
>>  }
>> +
>>  return 0;
>>  }
>>
>> +static bool cf_check is_cap_match(unsigned int id1, unsigned int id2)
>> +{
>> +return id1 == id2;
>> +}
> 
> Personally I would have preferred to get away without yet another hook
> function here, by ...
> 
>> +unsigned int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos,
>> +   unsigned int cap)
>> +{
>> +unsigned int ttl = 48;
>> +
>> +return pci_find_next_cap_ttl(sbdf, pos, is_cap_match, cap, ) & ~3;
> 
> ... passing NULL here and then suitably handling the case in that
> common helper.

Thinking in terms of reducing the amount of dead code, I'll change it

>> @@ -561,6 +573,71 @@ static int cf_check init_bars(struct pci_dev *pdev)
>>  if ( rc )
>>  return rc;
>>
>> +if ( !is_hardware_domain(pdev->domain) )
>> +{
>> +if ( !(pci_conf_read16(pdev->sbdf, PCI_STATUS) & 
>> PCI_STATUS_CAP_LIST) )
>> +{
>> +/* RAZ/WI */
>> +rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
>> +   PCI_CAPABILITY_LIST, 1, (void *)0);
>> +if ( rc )
>> +return rc;
>> +}
>> +else
>> +{
>> +/* Only expose capabilities to the guest that vPCI can handle. 
>> */
>> +uint8_t next;
> 
> If this was "unsigned long", ...
> 
>> +unsigned int ttl = 48;
>> +
>> +next = pci_find_next_cap_ttl(pdev->sbdf, PCI_CAPABILITY_LIST,
>> + vpci_cap_supported, 0, );
>> +
>> +rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
>> +   PCI_CAPABILITY_LIST, 1,
>> +   (void *)(uintptr_t)next);
> 
> ... you'd avoid the need for the double cast here and again below. Yet
> then I realize that Misra would take offence at us doing so ...

As ugly as that double cast is, I think I prefer the next and pos declarations 
have consistent types (which I had intended to be unsigned int to match the 
prior patches, not uint8_t). As well as not making the MISRA situation any 
worse. The casts, after all, make it excruciatingly obvious what we're doing 
here, I hope.

Stew



[xen-unstable test] 182581: regressions - FAIL

2023-08-31 Thread osstest service owner
flight 182581 xen-unstable real [real]
flight 182587 xen-unstable real-retest [real]
http://logs.test-lab.xenproject.org/osstest/logs/182581/
http://logs.test-lab.xenproject.org/osstest/logs/182587/

Regressions :-(

Tests which did not succeed and are blocking,
including tests which could not be run:
 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 7 xen-install fail REGR. vs. 
182571

Tests which did not succeed, but are not blocking:
 test-amd64-i386-xl-qemuu-win7-amd64 19 guest-stop fail like 182571
 test-armhf-armhf-libvirt 16 saverestore-support-checkfail  like 182571
 test-amd64-amd64-qemuu-nested-amd 20 debian-hvm-install/l1/l2 fail like 182571
 test-amd64-amd64-xl-qemuu-ws16-amd64 19 guest-stopfail like 182571
 test-armhf-armhf-libvirt-qcow2 15 saverestore-support-check   fail like 182571
 test-amd64-amd64-xl-qemut-win7-amd64 19 guest-stopfail like 182571
 test-amd64-i386-xl-qemut-ws16-amd64 19 guest-stop fail like 182571
 test-amd64-i386-xl-qemut-win7-amd64 19 guest-stop fail like 182571
 test-amd64-amd64-xl-qemut-ws16-amd64 19 guest-stopfail like 182571
 test-armhf-armhf-libvirt-raw 15 saverestore-support-checkfail  like 182571
 test-amd64-i386-xl-qemuu-ws16-amd64 19 guest-stop fail like 182571
 test-amd64-amd64-xl-qemuu-win7-amd64 19 guest-stopfail like 182571
 test-amd64-amd64-libvirt 15 migrate-support-checkfail   never pass
 test-amd64-i386-xl-pvshim14 guest-start  fail   never pass
 test-amd64-i386-libvirt-xsm  15 migrate-support-checkfail   never pass
 test-amd64-amd64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl  16 saverestore-support-checkfail   never pass
 test-amd64-i386-libvirt  15 migrate-support-checkfail   never pass
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-armhf-armhf-xl-credit2  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl  16 saverestore-support-checkfail   never pass
 test-amd64-i386-libvirt-raw  14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 15 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-vhd 14 migrate-support-checkfail   never pass
 test-armhf-armhf-libvirt 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-vhd  14 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-vhd  15 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt-qcow2 14 migrate-support-checkfail never pass
 test-armhf-armhf-xl-vhd  14 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-vhd  15 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-rtds 15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-rtds 16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-arndale  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-arndale  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-multivcpu 15 migrate-support-checkfail  never pass
 test-armhf-armhf-xl-multivcpu 16 saverestore-support-checkfail  never pass
 test-armhf-armhf-libvirt-raw 14 migrate-support-checkfail   never pass

version targeted for testing:
 xen  6621932264e3e86df3913db4249ecd3eb100b13f
baseline version:
 xen  e5522c71beaa83f2f5d2118724ace9f90c22e583

Last test of basis   182571  2023-08-30 17:08:53 Z1 days
Testing same since   182581  2023-08-31 08:22:39 Z0 days

Re: [XEN][PATCH v10 11/20] xen/iommu: Introduce iommu_remove_dt_device()

2023-08-31 Thread Vikram Garhwal
On Thu, Aug 31, 2023 at 09:32:48AM +0200, Michal Orzel wrote:
> 
> 
> On 31/08/2023 09:23, Michal Orzel wrote:
> > 
> > 
> > On 30/08/2023 19:48, Vikram Garhwal wrote:
> >> Hi Michal,
> >> On Tue, Aug 29, 2023 at 10:23:30AM +0200, Michal Orzel wrote:
> >>>
> >>>
> >>> On 25/08/2023 10:02, Vikram Garhwal wrote:
>  Remove master device from the IOMMU. This will be helpful when removing 
>  the
>  overlay nodes using dynamic programming during run time.
> 
>  Signed-off-by: Vikram Garhwal 
>  Acked-by: Jan Beulich 
> >>>
> >>> You don't seem to handle Julien remarks for this patch made in v9.
> >>> I will forward them here to avoid answering to old version, but for the 
> >>> future, do not carry the exact same patch
> >>> if you haven't yet addressed someone's remarks.
> >> This got skipped as I cannot find direct email from Julien. The only email 
> >> reply
> >> on this patch is can find is from: xen-devel-boun...@lists.xenproject.org 
> >> and
> >> this got messed up with other larger set of email xen-devel sends.
> >>
> >> Did you get direct email?
> >>>
> 
>  ---
>  Changes from v7:
>  Add check if IOMMU is enabled.
>  Fix indentation of fail.
>  ---
>  ---
>   xen/drivers/passthrough/device_tree.c | 44 +++
>   xen/include/xen/iommu.h   |  1 +
>   2 files changed, 45 insertions(+)
> 
>  diff --git a/xen/drivers/passthrough/device_tree.c 
>  b/xen/drivers/passthrough/device_tree.c
>  index 1202eac625..3fad65fb69 100644
>  --- a/xen/drivers/passthrough/device_tree.c
>  +++ b/xen/drivers/passthrough/device_tree.c
>  @@ -128,6 +128,50 @@ int iommu_release_dt_devices(struct domain *d)
>   return 0;
>   }
> 
>  +int iommu_remove_dt_device(struct dt_device_node *np)
>  +{
>  +const struct iommu_ops *ops = iommu_get_ops();
>  +struct device *dev = dt_to_dev(np);
>  +int rc;
>  +
>  +if ( !iommu_enabled )
>  +return 1;
> >>> J:
> >>> The caller doesn't seem to check if the error code is > 0. So can we
> >>> instead return a -ERRNO?
> >> Will change the check in caller. I want to keep this as it as so it looks
> >> similar to iommu_add_dt_device().
> >>>
> >>> If you want to continue to return a value > 0 then I think it should be
> >>> documented in a comment like we did for iommu_add_dt_device().
> >>>
> >> Will add comment before iommu_remove_dt_device().
>  +
>  +if ( !ops )
>  +return -EOPNOTSUPP;
>  +
>  +spin_lock(_lock);
>  +
>  +if ( iommu_dt_device_is_assigned_locked(np) )
>  +{
>  +rc = -EBUSY;
>  +goto fail;
>  +}
>  +
>  +/*
>  + * The driver which supports generic IOMMU DT bindings must have 
>  this
>  + * callback implemented.
>  + */
> >>> J:
> >>> I have questioned this message in v7 and I still question it. I guess
> >>> you copied the comment on top of add_device(), this was add there
> >>> because we have a different way to add legacy device.
> >>>
> >>> But here there are no such requirement. In fact, you are not adding the
> >>> the callback to all the IOMMU drivers... Yet all of them support the
> >>> generic IOMMU DT bindings.
> >> Will change this.
> >>>
>  +if ( !ops->remove_device )
>  +{
>  +rc = -EOPNOTSUPP;
>  +goto fail;
>  +}
>  +
>  +/*
>  + * Remove master device from the IOMMU if latter is present and 
>  available.
> >>> J:
> >>> I read this as this will not return an error if the device is protected.
> >>> However, AFAICT, the implement in the SMMU driver provided in this
> >>> series will return an error. So I would suggest to replace this sentence
> >>> with:
> >>>
> >>> de-register the device from the IOMMU driver.
> >> Will change the comment.
> >>>
>  + * The driver is responsible for removing is_protected flag.
> >>> J:
> >>> Can you add an assert in the 'if ( !rc )' block to confirm that
> >>> is_protected was effectively removed. Something like:
> >>>
> >>> ASSERT(!dt_device_is_protected(dev));
> >> Is ASSERT really required here. remove callback can return before setting 
> >> is_protected as false.
> > I think Julien wanted to add extra check to make sure driver behaves as 
> > expected.
> > That said, his suggestion is incorrect since the callback can return before 
> > clearing the flag.
> > So, if ASSERT is required, this should be:
> > ASSERT(rc || !dt_device_is_protected(dev));
> > so that we check for is_protected being false only on callback returning 
> > success (i.e. 0).
> I wrote this based on iommu_add_dt_device(), which does:
> if ( !rc )
> rc = ops->add_device(0, dev);
> 
> but looking at iommu_remove_dt_device(), where you have:
> rc = ops->remove_device(0, dev);
> if ( !rc )
> iommu_fwspec_free(dev);
> 
> you 

[qemu-mainline test] 182584: regressions - FAIL

2023-08-31 Thread osstest service owner
flight 182584 qemu-mainline real [real]
http://logs.test-lab.xenproject.org/osstest/logs/182584/

Regressions :-(

Tests which did not succeed and are blocking,
including tests which could not be run:
 build-arm64-pvops 6 kernel-build fail REGR. vs. 182570

Tests which did not succeed, but are not blocking:
 test-arm64-arm64-libvirt-raw  1 build-check(1)   blocked  n/a
 test-arm64-arm64-libvirt-xsm  1 build-check(1)   blocked  n/a
 test-arm64-arm64-xl   1 build-check(1)   blocked  n/a
 test-arm64-arm64-xl-credit1   1 build-check(1)   blocked  n/a
 test-arm64-arm64-xl-credit2   1 build-check(1)   blocked  n/a
 test-arm64-arm64-xl-thunderx  1 build-check(1)   blocked  n/a
 test-arm64-arm64-xl-vhd   1 build-check(1)   blocked  n/a
 test-arm64-arm64-xl-xsm   1 build-check(1)   blocked  n/a
 test-armhf-armhf-libvirt 16 saverestore-support-checkfail  like 182570
 test-amd64-amd64-xl-qemuu-win7-amd64 19 guest-stopfail like 182570
 test-armhf-armhf-libvirt-qcow2 15 saverestore-support-check   fail like 182570
 test-armhf-armhf-libvirt-raw 15 saverestore-support-checkfail  like 182570
 test-amd64-i386-xl-qemuu-ws16-amd64 19 guest-stop fail like 182570
 test-amd64-amd64-xl-qemuu-ws16-amd64 19 guest-stopfail like 182570
 test-amd64-amd64-qemuu-nested-amd 20 debian-hvm-install/l1/l2 fail like 182570
 test-amd64-i386-xl-qemuu-win7-amd64 19 guest-stop fail like 182570
 test-amd64-i386-xl-pvshim14 guest-start  fail   never pass
 test-amd64-amd64-libvirt 15 migrate-support-checkfail   never pass
 test-amd64-amd64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-amd64-i386-libvirt-xsm  15 migrate-support-checkfail   never pass
 test-amd64-i386-libvirt  15 migrate-support-checkfail   never pass
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-armhf-armhf-xl-multivcpu 15 migrate-support-checkfail  never pass
 test-armhf-armhf-xl-multivcpu 16 saverestore-support-checkfail  never pass
 test-armhf-armhf-xl  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-libvirt 15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-rtds 15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-rtds 16 saverestore-support-checkfail   never pass
 test-amd64-i386-libvirt-raw  14 migrate-support-checkfail   never pass
 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-armhf-armhf-xl-arndale  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-arndale  16 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-vhd 14 migrate-support-checkfail   never pass
 test-armhf-armhf-libvirt-qcow2 14 migrate-support-checkfail never pass
 test-armhf-armhf-libvirt-raw 14 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-vhd  14 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-vhd  15 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  16 saverestore-support-checkfail   never pass

version targeted for testing:
 qemuu17780edd81d27fcfdb7a802efc870a99788bd2fc
baseline version:
 qemuu156618d9ea67f2f2e31d9dedd97f2dcccbe6808c

Last test of basis   182570  2023-08-30 16:37:20 Z1 days
Testing same since   182584  2023-08-31 16:38:53 Z0 days1 attempts


People who touched revisions under test:
  Alex Bennée 
  Daniel P. Berrangé 
  Ilya Leoshkevich 
  Jean-Christophe Dubois 
  Markus Armbruster 
  Matheus Branco Borella 
  Oleksandr Tyshchenko 
  Peter Maydell 
  Richard Henderson 
  Stefan Hajnoczi 
  Stefano Stabellini 
  Thomas Huth 
  Vikram Garhwal 
  Warner Losh 

jobs:
 build-amd64-xsm  pass
 build-arm64-xsm  pass
 build-i386-xsm   pass
 build-amd64  pass
 build-arm64  pass
 build-armhf  pass
 build-i386   pass
 build-amd64-libvirt  pass
 build-arm64-libvirt

Re: [PATCH v2 5/8] xen/ppc: Define minimal stub headers required for full build

2023-08-31 Thread Shawn Anastasio
On 8/30/23 5:49 AM, Jan Beulich wrote:
> On 23.08.2023 22:07, Shawn Anastasio wrote:
>> --- /dev/null
>> +++ b/xen/arch/ppc/include/asm/altp2m.h
>> @@ -0,0 +1,25 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +#ifndef __ASM_PPC_ALTP2M_H__
>> +#define __ASM_PPC_ALTP2M_H__
>> +
>> +#include 
>> +
>> +struct domain;
>> +struct vcpu;
>> +
>> +/* Alternate p2m on/off per domain */
>> +static inline bool altp2m_active(const struct domain *d)
>> +{
>> +/* Not implemented on PPC. */
>> +return false;
>> +}
>> +
>> +/* Alternate p2m VCPU */
>> +static inline uint16_t altp2m_vcpu_idx(const struct vcpu *v)
>> +{
>> +/* Not implemented on PPC, should not be reached. */
>> +BUG_ON("unimplemented");
> 
> I would have thought this construct is meant to flag places that need
> work in the course of bringing up Xen on PPC. This isn't one of those,
> I think. Perhaps ASSERT_UNREACHABLE() is slightly better here than
> Arm's BUG()?
>

Yes, good point. I did an indiscriminate regex to replace all BUG()
calls introduced by my earlier patch with this new construct, but as you
point out it erroneously included functions that are meant to be
unreachable.

I'll go with ASSERT_UNREACHABLE() here.

>> --- /dev/null
>> +++ b/xen/arch/ppc/include/asm/current.h
>> @@ -0,0 +1,42 @@
>> +#ifndef __ASM_PPC_CURRENT_H__
>> +#define __ASM_PPC_CURRENT_H__
>> +
>> +#include 
>> +
>> +#ifndef __ASSEMBLY__
>> +
>> +struct vcpu;
>> +
>> +/* Which VCPU is "current" on this PCPU. */
>> +DECLARE_PER_CPU(struct vcpu *, curr_vcpu);
>> +
>> +#define current(this_cpu(curr_vcpu))
>> +#define set_current(vcpu)  do { current = (vcpu); } while (0)
>> +#define get_cpu_current(cpu)  (per_cpu(curr_vcpu, cpu))
>> +
>> +/* Per-VCPU state that lives at the top of the stack */
>> +struct cpu_info {
>> +struct cpu_user_regs guest_cpu_user_regs;
>> +unsigned long elr;
>> +uint32_t flags;
> 
> May I suggest that you pick one of fixed-width types or basic C types
> for consistent use here?
>

Sure. I'll go with C types here.

>> +};
>> +
>> +static inline struct cpu_info *get_cpu_info(void)
>> +{
>> +#ifdef __clang__
>> +unsigned long sp;
>> +
>> +asm ("mr %0, 1" : "=r" (sp));
> 
> Nit: Style.
> 

Will fix.

>> --- /dev/null
>> +++ b/xen/arch/ppc/include/asm/device.h
>> @@ -0,0 +1,53 @@
>> +#ifndef __ASM_PPC_DEVICE_H__
>> +#define __ASM_PPC_DEVICE_H__
>> +
>> +enum device_type
>> +{
>> +DEV_DT,
>> +DEV_PCI,
>> +};
>> +
>> +struct device {
>> +enum device_type type;
>> +#ifdef CONFIG_HAS_DEVICE_TREE
>> +struct dt_device_node *of_node; /* Used by drivers imported from Linux 
>> */
>> +#endif
>> +};
>> +
>> +enum device_class
>> +{
>> +DEVICE_SERIAL,
>> +DEVICE_IOMMU,
>> +DEVICE_GIC,
>> +DEVICE_PCI_HOSTBRIDGE,
>> +/* Use for error */
>> +DEVICE_UNKNOWN,
>> +};
>> +
>> +struct device_desc {
>> +/* Device name */
>> +const char *name;
>> +/* Device class */
>> +enum device_class class;
>> +/* List of devices supported by this driver */
>> +const struct dt_device_match *dt_match;
>> +/*
>> + * Device initialization.
>> + *
>> + * -EAGAIN is used to indicate that device probing is deferred.
>> + */
>> +int (*init)(struct dt_device_node *dev, const void *data);
>> +};
>> +
>> +typedef struct device device_t;
>> +
>> +#define DT_DEVICE_START(_name, _namestr, _class)\
>> +static const struct device_desc __dev_desc_##_name __used   \
>> +__section(".dev.info") = {  \
>> +.name = _namestr,   \
>> +.class = _class,\
>> +
>> +#define DT_DEVICE_END   \
>> +};
>> +
>> +#endif /* __ASM_PPC_DEVICE_H__ */
> 
> Do you really need everything you put in here?
>

The device_type enumerations and struct device are required.

Some definition of device_t is required, as well as some definition of
DT_DEVICE_{START,END}. I could of course stub them out (e.g. with empty
structs) but I didn't really see a point when the definitions from ARM
seem largely applicable.

That said, the DEVICE_GIC enumeration definitely doesn't belong, so I'll
remove it.

>> --- /dev/null
>> +++ b/xen/arch/ppc/include/asm/div64.h
>> @@ -0,0 +1,14 @@
>> +#ifndef __ASM_PPC_DIV64_H__
>> +#define __ASM_PPC_DIV64_H__
>> +
>> +#include 
>> +
>> +#define do_div(n,base) ({   \
>> +uint32_t __base = (base);   \
>> +uint32_t __rem; \
>> +__rem = ((uint64_t)(n)) % __base;   \
>> +(n) = ((uint64_t)(n)) / __base; \
>> +__rem;  \
>> +})
> 
> I understand you're merely copying this from elsewhere, but it would be
> really nice if style could be corrected for such new instances (no
> leading underscores, blank after comma, and ideally also no excess

[ovmf test] 182586: all pass - PUSHED

2023-08-31 Thread osstest service owner
flight 182586 ovmf real [real]
http://logs.test-lab.xenproject.org/osstest/logs/182586/

Perfect :-)
All tests in this flight passed as required
version targeted for testing:
 ovmf beafabdae49c873adecdb7511dbebe9d4ff5c8f0
baseline version:
 ovmf 4c8144dd665619731b6c3c19f4f1ae664b69fa4b

Last test of basis   182582  2023-08-31 13:42:21 Z0 days
Testing same since   182586  2023-08-31 19:42:36 Z0 days1 attempts


People who touched revisions under test:
  Nate DeSimone 

jobs:
 build-amd64-xsm  pass
 build-i386-xsm   pass
 build-amd64  pass
 build-i386   pass
 build-amd64-libvirt  pass
 build-i386-libvirt   pass
 build-amd64-pvopspass
 build-i386-pvops pass
 test-amd64-amd64-xl-qemuu-ovmf-amd64 pass
 test-amd64-i386-xl-qemuu-ovmf-amd64  pass



sg-report-flight on osstest.test-lab.xenproject.org
logs: /home/logs/logs
images: /home/logs/images

Logs, config files, etc. are available at
http://logs.test-lab.xenproject.org/osstest/logs

Explanation of these reports, and of osstest in general, is at
http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master
http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master

Test harness code can be found at
http://xenbits.xen.org/gitweb?p=osstest.git;a=summary


Pushing revision :

To xenbits.xen.org:/home/xen/git/osstest/ovmf.git
   4c8144dd66..beafabdae4  beafabdae49c873adecdb7511dbebe9d4ff5c8f0 -> 
xen-tested-master



Re: [PATCH v4 4/6] xen/vpci: header: status register handler

2023-08-31 Thread Stewart Hildebrand
On 8/30/23 10:05, Jan Beulich wrote:
> On 28.08.2023 19:56, Stewart Hildebrand wrote:
>> --- a/xen/drivers/vpci/header.c
>> +++ b/xen/drivers/vpci/header.c
>> @@ -413,6 +413,18 @@ static void cf_check cmd_write(
>>  pci_conf_write16(pdev->sbdf, reg, cmd);
>>  }
>>
>> +static uint32_t cf_check status_read(const struct pci_dev *pdev,
>> + unsigned int reg, void *data)
>> +{
>> +struct vpci_header *header = data;
>> +uint32_t status = pci_conf_read16(pdev->sbdf, reg);
>> +
>> +if ( header->mask_cap_list )
>> +status &= ~PCI_STATUS_CAP_LIST;
>> +
>> +return status;
>> +}
> 
> Imo we also cannot validly pass through any of the reserved bits. Doing so
> is an option only once we know what purpose they might gain.

OK. I think in the long term, having a res_mask in struct vpci_register for the 
reserved bits will be more flexible.

> (In this
> context I notice our set of PCI_STATUS_* constants isn't quite up-to-date.)

I'll add these 2 new constants in the next version of the series (in a separate 
patch):
#define  PCI_STATUS_IMM_READY  0x01/* Immediate Readiness */

#define  PCI_STATUS_INTERRUPT  0x08/* Interrupt status */

>> @@ -544,6 +556,11 @@ static int cf_check init_bars(struct pci_dev *pdev)
>>  if ( rc )
>>  return rc;
>>
>> +rc = vpci_add_rw1c_register(pdev->vpci, status_read, vpci_hw_write16,
>> +PCI_STATUS, 2, header, 0xF900);
> 
> Rather than a literal number, imo this wants to be an OR of the respective
> PCI_STATUS_* constants (which, if you like, could of course be consolidated
> into a new PCI_STATUS_RW1C_MASK, to help readability).

OK.

>> @@ -167,6 +174,7 @@ int vpci_add_register(struct vpci *vpci, vpci_read_t 
>> *read_handler,
>>  r->size = size;
>>  r->offset = offset;
>>  r->private = data;
>> +r->rw1c_mask = rw1c_mask;
> 
> To avoid surprises with ...
> 
>> @@ -424,6 +443,7 @@ static void vpci_write_helper(const struct pci_dev *pdev,
>>  uint32_t val;
>>
>>  val = r->read(pdev, r->offset, r->private);
>> +val &= ~r->rw1c_mask;
>>  data = merge_result(val, data, size, offset);
> 
> ... the user of this field, should you either assert that no bits beyond
> the field size are set, or simply mask to the respective number of bits?

Good point, I'll mask it (in add_register()).

Stew



Re: [PATCH v9 12/16] vpci: add initial support for virtual PCI bus topology

2023-08-31 Thread Volodymyr Babchuk


Hi Jan,

Jan Beulich  writes:

> On 30.08.2023 01:19, Volodymyr Babchuk wrote:
>> From: Oleksandr Andrushchenko 
>> 
>> Assign SBDF to the PCI devices being passed through with bus 0.
>> The resulting topology is where PCIe devices reside on the bus 0 of the
>> root complex itself (embedded endpoints).
>> This implementation is limited to 32 devices which are allowed on
>> a single PCI bus.
>> 
>> Please note, that at the moment only function 0 of a multifunction
>> device can be passed through.
>> 
>> Signed-off-by: Oleksandr Andrushchenko 
>> ---
>> Since v9:
>> - Lock in add_virtual_device() replaced with ASSERT (thanks, Stewart)
>
> Also peeking at a few other patches where similar change remarks exist,
> I'm slightly confused by them: Is this submission v9 or v10?

Sorry, looks like I was using wrong wording. This is submission
v9. Under "Since v9" I meant "in v9 and further".

-- 
WBR, Volodymyr


RE: [EXT] Re: xen arm64 low power sleep support

2023-08-31 Thread Anthony Chan
On Thu, 30 Aug 2023, Stefano Stabellini wrote:
> On Wed, 30 Aug 2023, Anthony Chan wrote:
> > On Tue, 29 Aug 2023, Stefano Stabellini wrote:
> > > On Tue, 29 Aug 2023, Anthony Chan wrote:
> > > > Hi all,
> > > >
> > > > My name is Tony and I've been researching/developing using Xen
> > > > for potential upcoming uses in our embedded systems.  I started
> > > > with Xen using Xilinx tools about a year ago and still have lots
> > > > to learn about what it can to do in the embedded space.  So far,
> > > > I've managed to integrate Xen and Linux into an existing product
> > > > that exclusively runs bare-metal code on a ZynqMP SoC and
> > > > migrate some of the functionality into custom Linux driver/userspace.
> > > >
> > > > I'm now looking at low power support, for now at least between
> > > > Xen
> > > > (4.16) and Linux (5.15) dom0.  I've tried a few different Linux
> > > > kernel configs around power management and each time I try to
> > > > suspend from linux dom0 (via sysfs or systemctl), Xen will
> > > > watchdog on
> > > > dom0 guest.
> > > > AFAIK, Xen should trap on a 'WFI' from guests, but from what I
> > > > can tell debugging through the linux suspend process is it's
> > > > spinning in a 'suspend- to-idle' loop before it can get to
> > > > issuing a 'WFI' or using PSCI interface to notify Xen.  I'm
> > > > beginning to suspect that 'low power' support for embedded arm64
> > > > just isn't quite there yet, or am I missing something in the configs?
> > > >
> > > > I realize this could very well be a Linux 'issue' but checking
> > > > here first.  I know Xen presents a flattened device tree to
> > > > Linux without CPU idle-state nodes and maybe this is causing the
> > > > linux guest to only do the suspend- to-idle mode?  I should
> > > > mention that I'm booting up using dom0less feature if that
> > > > matters.
> > >
> > >
> > > Hi Anthony,
> > >
> > > Assuming you are using the default Xen command line parameters for
> > > Xilinx boards: sched=null vwfi=native, then if the guest uses WFI,
> > > the CPU will execute WFI directly and go into low power mode.
> > Yes, using these command line params.
> >
> > > Given the issue you are describing, I am suspecting the guest is
> > > not issuing
> > > WFI: that is simple and known to work. Instead, I suspect that
> > > Linux might be trying to use PSCI_suspend in a way that is not
> > > supported or well- implemented by Xen.
> > >
> > > Can you check? You can add a printk in Linux
> > > drivers/firmware/psci/psci.c:__psci_cpu_suspend or in Xen
> > > xen/arch/arm/vpsci.c:do_psci_0_2_cpu_suspend
> > Instrumented both places it doesn't appear to reach there.  In
> > kernel/power/suspend.c, there's a call to s2idle_loop that it's currently 
> > 'stuck'
> > in and I think it doesn't get to the psci suspend your referring
> > till afterwards, when suspend_ops->enter is called.  Unfortunately,
> > without any idle-states nodes in the FDT, the only suspend state
> > Linux is defaults to is 'suspend to idle'.
>
> The fact that Linux uses "suspend to idle" is not a problem because as
> I mentioned WFI or PSCI_suspent are not different on Xen. That part is OK.
What if using "suspend to idle" is preventing a WFI/PSCI_suspend?  Which is
what I believe I'm currently seeing in my setup.  In kernel/power/suspend.c,
suspend_devices_and_enter(), it gets into the this s2idle_loop and upon
resuming from idle, it jumps past the point where I believe a
WFI/PSCI_suspend can happen.
if (state == PM_SUSPEND_TO_IDLE) {
s2idle_loop();
goto Platform_wake;
}

> However, if the issue is not PSCI_suspend then I don't have another
> easy guess. Please post a full stack trace or more information about
> the error in Linux and I might be able to see where it is coming from.

echo mem > /sys/power/state
[   75.666385] PM: suspend entry (s2idle)
[   75.685382] Filesystems sync: 0.018 seconds
[   75.685446] Preparing system for sleep (s2idle)
[   75.695087] Freezing user space processes ... (elapsed 0.001 seconds) done.
[   75.698339] OOM killer disabled.
[   75.701618] Freezing remaining freezable tasks ... (elapsed 0.063 seconds) 
done.
[   75.767215] Suspending system (s2idle)
[   75.777682] macb ff0e.ethernet: gem-ptp-timer ptp clock unregistered.
[   75.784525] suspend-to-idle
[   75.784580] CPU: 0 PID: 548 Comm: sh Not tainted 5.15.0-xilinx-v2022.1 #1
[   75.788626] Hardware name: xlnx,zynqmp (DT)

[   75.792867] Call trace:
[   75.795373]  dump_backtrace+0x0/0x1a8
[   75.799094]  show_stack+0x18/0x30
[   75.802466]  dump_stack_lvl+0x7c/0xa0
[   75.806186]  dump_stack+0x18/0x34
[   75.809559]  suspend_devices_and_enter+0x334/0x4cc
[   75.814403]  pm_suspend+0x1f0/0x248
[   75.817950]  state_store+0xb8/0x100
[   75.821497]  kobj_attr_store+0x1c/0x30
[   75.825302]  sysfs_kf_write+0x40/0x54
[   75.829022]  kernfs_fop_write_iter+0xb8/0x170
[   75.833433]  new_sync_write+0x74/0xc8
[   75.837153]  vfs_write+0x104/0x128
[   75.840613]  

Re: [PATCH 2/7] migration: Clean up local variable shadowing

2023-08-31 Thread Peter Xu
On Thu, Aug 31, 2023 at 03:25:41PM +0200, Markus Armbruster wrote:
> Local variables shadowing other local variables or parameters make the
> code needlessly hard to understand.  Tracked down with -Wshadow=local.
> Clean up: delete inner declarations when they are actually redundant,
> else rename variables.
> 
> Signed-off-by: Markus Armbruster 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH 1/7] migration/rdma: Fix save_page method to fail on polling error

2023-08-31 Thread Peter Xu
On Thu, Aug 31, 2023 at 03:25:40PM +0200, Markus Armbruster wrote:
> qemu_rdma_save_page() reports polling error with error_report(), then
> succeeds anyway.  This is because the variable holding the polling
> status *shadows* the variable the function returns.  The latter
> remains zero.
> 
> Broken since day one, and duplicated more recently.
> 
> Fixes: 2da776db4846 (rdma: core logic)
> Fixes: b390afd8c50b (migration/rdma: Fix out of order wrid)
> Signed-off-by: Markus Armbruster 

Reviewed-by: Peter Xu 

-- 
Peter Xu




Re: [PATCH v2 4/8] xen/ppc: Implement bitops.h

2023-08-31 Thread Shawn Anastasio
On 8/29/23 8:59 AM, Jan Beulich wrote:
> On 23.08.2023 22:07, Shawn Anastasio wrote:
>> Implement bitops.h, based on Linux's implementation as of commit
>> 5321d1b1afb9a17302c6cec79f0cbf823eb0d3fc. Though it is based off of
>> Linux's implementation, this code diverges significantly in a number of
>> ways:
>>   - Bitmap entries changed to 32-bit words to match X86 and Arm on Xen
>>   - PPC32-specific code paths dropped
>>   - Formatting completely re-done to more closely line up with Xen.
>> Including 4 space indentation.
> 
> With this goal, ...
> 
>> --- a/xen/arch/ppc/include/asm/bitops.h
>> +++ b/xen/arch/ppc/include/asm/bitops.h
>> @@ -1,9 +1,335 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * Adapted from Linux's arch/powerpc/include/asm/bitops.h.
>> + *
>> + * Merged version by David Gibson .
>> + * Based on ppc64 versions by: Dave Engebretsen, Todd Inglett, Don
>> + * Reed, Pat McCarthy, Peter Bergner, Anton Blanchard.  They
>> + * originally took it from the ppc32 code.
>> + */
>>  #ifndef _ASM_PPC_BITOPS_H
>>  #define _ASM_PPC_BITOPS_H
>>
>> +#include 
>> +
>> +#define __set_bit(n,p)set_bit(n,p)
>> +#define __clear_bit(n,p)  clear_bit(n,p)
> 
> ... you want to add blanks after the commas as well. (You might also
> simply omit parameters altogether.)
> 
>> +#define BITOP_BITS_PER_WORD 32
>> +#define BITOP_MASK(nr)  (1UL << ((nr) % BITOP_BITS_PER_WORD))
>> +#define BITOP_WORD(nr)  ((nr) / BITOP_BITS_PER_WORD)
>> +#define BITS_PER_BYTE   8
>> +
>>  /* PPC bit number conversion */
>> -#define PPC_BITLSHIFT(be)   (BITS_PER_LONG - 1 - (be))
>> -#define PPC_BIT(bit)(1UL << PPC_BITLSHIFT(bit))
>> -#define PPC_BITMASK(bs, be) ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs))
>> +#define PPC_BITLSHIFT(be)(BITS_PER_LONG - 1 - (be))
>> +#define PPC_BIT(bit) (1UL << PPC_BITLSHIFT(bit))
>> +#define PPC_BITMASK(bs, be)  ((PPC_BIT(bs) - PPC_BIT(be)) | PPC_BIT(bs))
>> +
>> +/* Macro for generating the ***_bits() functions */
>> +#define DEFINE_BITOP(fn, op, prefix)
>>\
>> +static inline void fn(unsigned long mask,   
>>\
>> +volatile unsigned int *_p)  
>>\
> 
> Nit: Style. Either
> 
> static inline void fn(unsigned long mask, 
>  \
>   volatile unsigned int *_p)  
>  \
> 
> or
> 
> static inline void fn(unsigned long mask, 
>  \
> volatile unsigned int *_p)
>  \
> 
> . Also there's again an underscore-prefixed identifier here.
>

Will fix both.

>> +{   
>>\
>> +unsigned long old;  
>>\
>> +unsigned int *p = (unsigned int *)_p;   
>>\
>> +asm volatile (  
>>\
>> +prefix  
>>\
>> +"1: lwarx %0,0,%3,0\n"  
>>\
>> +#op "%I2 %0,%0,%2\n"
>>\
>> +"stwcx. %0,0,%3\n"  
>>\
>> +"bne- 1b\n" 
>>\
>> +: "=" (old), "+m" (*p)
>>\
>> +: "rK" (mask), "r" (p)  
>>\
>> +: "cc", "memory");  
>>\
> 
> The asm() body wants indenting by another four blanks (more instances below).
>

If I were to match the style used in the previous patch's atomic.h, the
body should be indented to line up with the opening ( of the asm
statement, right? I'll go ahead and do that for consistency's sake
unless you think it would be better to just leave it as-is with an extra
4 spaces of indentation.

>> +}
>> +
>> +DEFINE_BITOP(set_bits, or, "")
>> +DEFINE_BITOP(change_bits, xor, "")
>> +
>> +#define DEFINE_CLROP(fn, prefix)
>>\
>> +static inline void fn(unsigned long mask, volatile unsigned int *_p)
>>\
>> +{   
>>\
>> +unsigned long old;  
>>\
>> +unsigned int *p = (unsigned int *)_p;   
>>\
>> +asm volatile (  
>>\
>> +prefix  
>>\
>> +"1: lwarx %0,0,%3,0\n"

[libvirt test] 182579: tolerable all pass - PUSHED

2023-08-31 Thread osstest service owner
flight 182579 libvirt real [real]
http://logs.test-lab.xenproject.org/osstest/logs/182579/

Failures :-/ but no regressions.

Tests which did not succeed, but are not blocking:
 test-armhf-armhf-libvirt 16 saverestore-support-checkfail  like 182562
 test-armhf-armhf-libvirt-qcow2 15 saverestore-support-check   fail like 182562
 test-armhf-armhf-libvirt-raw 15 saverestore-support-checkfail  like 182562
 test-amd64-amd64-libvirt 15 migrate-support-checkfail   never pass
 test-amd64-i386-libvirt  15 migrate-support-checkfail   never pass
 test-amd64-i386-libvirt-xsm  15 migrate-support-checkfail   never pass
 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-arm64-arm64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-libvirt 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt 16 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-armhf-armhf-libvirt 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-qcow2 14 migrate-support-checkfail never pass
 test-arm64-arm64-libvirt-qcow2 15 saverestore-support-checkfail never pass
 test-amd64-i386-libvirt-raw  14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 15 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-vhd 14 migrate-support-checkfail   never pass
 test-armhf-armhf-libvirt-qcow2 14 migrate-support-checkfail never pass
 test-amd64-amd64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-armhf-armhf-libvirt-raw 14 migrate-support-checkfail   never pass

version targeted for testing:
 libvirt  e7d26c5dcd3b988fa02ac1e45baf2f9934623381
baseline version:
 libvirt  120724bc6d1c2f8c029e67bd91335b48c243404c

Last test of basis   182562  2023-08-30 04:18:48 Z1 days
Testing same since   182579  2023-08-31 04:18:52 Z0 days1 attempts


People who touched revisions under test:
  Andrea Bolognani 
  Laura Hild 
  Yuri Chornoivan 
  김인수 

jobs:
 build-amd64-xsm  pass
 build-arm64-xsm  pass
 build-i386-xsm   pass
 build-amd64  pass
 build-arm64  pass
 build-armhf  pass
 build-i386   pass
 build-amd64-libvirt  pass
 build-arm64-libvirt  pass
 build-armhf-libvirt  pass
 build-i386-libvirt   pass
 build-amd64-pvopspass
 build-arm64-pvopspass
 build-armhf-pvopspass
 build-i386-pvops pass
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm   pass
 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsmpass
 test-amd64-amd64-libvirt-xsm pass
 test-arm64-arm64-libvirt-xsm pass
 test-amd64-i386-libvirt-xsm  pass
 test-amd64-amd64-libvirt pass
 test-arm64-arm64-libvirt pass
 test-armhf-armhf-libvirt pass
 test-amd64-i386-libvirt  pass
 test-amd64-amd64-libvirt-pairpass
 test-amd64-i386-libvirt-pair pass
 test-arm64-arm64-libvirt-qcow2   pass
 test-armhf-armhf-libvirt-qcow2   pass
 test-arm64-arm64-libvirt-raw pass
 test-armhf-armhf-libvirt-raw pass
 test-amd64-i386-libvirt-raw  pass
 test-amd64-amd64-libvirt-vhd pass



sg-report-flight on osstest.test-lab.xenproject.org
logs: /home/logs/logs
images: /home/logs/images

Logs, config files, etc. are available at
http://logs.test-lab.xenproject.org/osstest/logs

Explanation of these 

Xens handling of MCE

2023-08-31 Thread Development
We have been trying to find documentation on how to tell Xen to forward MCE 
information to the linux kernel in Dom0 in order to let a system administrator 
be able to get notified when his system has bad memory.  However from what I 
can tell this has not been documented anywhere.

If anyone knows of documentation (or knows the answer) of what someone is 
supposed to do in order to monitor the corrected errors and monitor the 
uncorrected errors when they are running modern xen, it would be appreciated.


To clarify, (and for people not familiar):

When running old xen ( example: Xen 4.1) on a system, linux in dom0 would 
load the edac modules.  example: amd64_edac_mod , edac_mce_amd , and edac_core
Once the modules loaded, the error counts for ECC memory, and PCI, could be 
found in these "files":
   /sys/devices/system/edac/mc/mc0/ce_count
   /sys/devices/system/edac/mc/mc0/ue_count
   /sys/devices/system/edac/pci/pci0/npe_count
   /sys/devices/system/edac/pci/pci0/pe_count

However, in 2009-02, "cegger" wrote MCA/MCE_in_Xen, a proposal for having 
xen start checking the information
Xen started accessing the EDAC information (now called "MCE") at some point 
after that, which blocks the linux kernel in dom0 from accessing it.
(I also found what appears to be related sides from a presentation from 
2012 at: 
https://lkml.iu.edu/hypermail/linux/kernel/1206.3/01304/xen_vMCE_design_%28v0_2%29.pdf
 )

Now, The linux kernel compile option: CONFIG_XEN_MCE_LOG=y is documented 
as: "Allow kernel fetching MCE error from Xen platform and converting it into 
Linux mcelog format for mcelog tools".
   I imagine there must be some way on the xen side for this to work for 
CONFIG_XEN_MCE_LOG to have gotten into the linux kernel and be enabled by 
default in distributions.
   (notes: mcelog seems to have been replaced with "ras daemon", but I 
believe that it pulls information using the same kernel APT as "mcelog") (so I 
believe the final output of if you are having memory errors is pulled by doing 
"ras-mc-ctl --errors" now instead of looking in /sys/devices/system/edac/mc and 
/sys/devices/system/edac/pci)
I suspect that to check if it was working on a modern system, one would do 
"ras-mc-ctl --status" and get something implying that the xen mce interface is 
working instead of just saying "ras-mc-ctl: drivers not loaded."
Somewhere it was said that adding the xen boot parameter "mce=1" to grub 
would cause xen to forward the info to the linux kernel, but that conflicts 
with recent changes to the documentation.  Also, tested by setting "mce=1" and 
nothing appears to change.


Any help is appreciated.



Re: [PATCH v2 3/8] xen/ppc: Implement atomic.h

2023-08-31 Thread Shawn Anastasio
On 8/31/23 12:47 PM, Shawn Anastasio wrote:
> On 8/29/23 8:43 AM, Jan Beulich wrote:
>> On 23.08.2023 22:07, Shawn Anastasio wrote:
>>> +#define read_atomic(p) 
>>> \
>>> +({ 
>>> \
>>> +union {
>>> \
>>> +typeof(*(p)) val;  
>>> \
>>> +char c[0]; 
>>> \
>>
>> Using [0] here is likely to set us up for compiler complaints ...
>>
> 
> AIUI zero-length members are explicitly permitted as a GNU extension,
> but their usage here wasn't an explicit choice on my part as this macro
> was inherited from arm's atomic.h. See below.
> 
>>> +} x_;  
>>> \
>>> +read_atomic_size(p, x_.c, sizeof(*(p)));   
>>> \
>>
>> ... here. Can't this simply be c[sizeof(*(val))]? And do you need
>> a union here in the first place, when read_atomic() takes void* as
>> its 2nd parameter?
>>
> 
> Yes, I should have taken a closer look at this before importing it from
> arm. The type punning does seem entirely redundant given that
> read_atomic_size takes a void* -- I'm not sure why it was written this
> way to begin with.
> 
> In any case, I'll do away with the unnecessary union.

Quick follow up -- I think I now understand why it was written this way.
Callers are allowed to pass const pointers to read_atomic, but if the
macro just declared a local variable using typeof(*(p)), the resulting
variable would keep the const qualifier and thus be unpassable to
read_atomic_size.

It also appears that using standard C flexible array members inside of
unions isn't permitted, but the GNU 0-length array construct is. Of
course, declaring c's length as sizeof(*(p)) as you suggested works too.

As for getting rid of the union entirely then, it still ensures that
that the resulting variable has the correct alignment. We could
alternatively add an __aligned(__alignof__(*(p))) or similar to a bare
array declaration to achieve the same effect.

I think for now, I'll just leave it as-is with the union but replace the
0-length array with an array of the correct size.

Thanks,
Shawn



Re: [PATCH 4/7] block/dirty-bitmap: Clean up local variable shadowing

2023-08-31 Thread Stefan Hajnoczi
On Thu, Aug 31, 2023 at 03:25:43PM +0200, Markus Armbruster wrote:
> Local variables shadowing other local variables or parameters make the
> code needlessly hard to understand.  Tracked down with -Wshadow=local.
> Clean up: delete inner declarations when they are actually redundant,
> else rename variables.
> 
> Signed-off-by: Markus Armbruster 
> ---
>  block/monitor/bitmap-qmp-cmds.c | 2 +-
>  block/qcow2-bitmap.c| 3 +--
>  2 files changed, 2 insertions(+), 3 deletions(-)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [PATCH 5/7] block/vdi: Clean up local variable shadowing

2023-08-31 Thread Stefan Hajnoczi
On Thu, Aug 31, 2023 at 03:25:44PM +0200, Markus Armbruster wrote:
> Local variables shadowing other local variables or parameters make the
> code needlessly hard to understand.  Tracked down with -Wshadow=local.
> Clean up: delete inner declarations when they are actually redundant,
> else rename variables.
> 
> Signed-off-by: Markus Armbruster 
> ---
>  block/vdi.c | 7 +++
>  1 file changed, 3 insertions(+), 4 deletions(-)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [PATCH 6/7] block: Clean up local variable shadowing

2023-08-31 Thread Stefan Hajnoczi
On Thu, Aug 31, 2023 at 03:25:45PM +0200, Markus Armbruster wrote:
> Local variables shadowing other local variables or parameters make the
> code needlessly hard to understand.  Tracked down with -Wshadow=local.
> Clean up: delete inner declarations when they are actually redundant,
> else rename variables.
> 
> Signed-off-by: Markus Armbruster 
> ---
>  block.c  |  7 ---
>  block/rbd.c  |  2 +-
>  block/stream.c   |  1 -
>  block/vvfat.c| 34 +-
>  hw/block/xen-block.c |  6 +++---
>  5 files changed, 25 insertions(+), 25 deletions(-)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature


Re: [PATCH v1 2/2] xen/arm: Enlarge identity map space to 127TiB

2023-08-31 Thread Alexey Klimov
On Thu, 31 Aug 2023 at 12:01, Leo Yan  wrote:
>
> On some platforms, the memory regions could be:
>
>   (XEN) MODULE[0]: 0807f6df - 0807f6f3e000 Xen
>   (XEN) MODULE[1]: 0807f8054000 - 0807f8056000 Device Tree
>   (XEN) MODULE[2]: fa834000 - fc5de1d5 Ramdisk
>   (XEN) MODULE[3]: fc5df000 - ffb3f810 Kernel
>
> In this case, the Xen binary is loaded above 2TB, so Xen fails to boot
> up due to the out of the identity map space.
>
> This patch enlarges identity map space to 127TiB, which can support the
> memory space [0x0 .. 0x7eff__], thus it has flexibility for
> support different platforms.
>
> Fixes: 1c78d76b67 ("xen/arm64: mm: Introduce helpers to 
> prepare/enable/disable")
> Reported-by: Alexey Klimov 
> Signed-off-by: Leo Yan 

Feel free to use:
Tested-by: Alexey Klimov 

I confirm that I can boot Xen with these two patches and start a guest VM.

Thanks,
Alexey



[linux-linus test] 182576: regressions - FAIL

2023-08-31 Thread osstest service owner
flight 182576 linux-linus real [real]
http://logs.test-lab.xenproject.org/osstest/logs/182576/

Regressions :-(

Tests which did not succeed and are blocking,
including tests which could not be run:
 test-amd64-amd64-xl-vhd   8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-qemuu-ws16-amd64  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-qemut-win7-amd64  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-qemuu-win7-amd64  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-dom0pvh-xl-amd 14 guest-start   fail REGR. vs. 182531
 test-amd64-amd64-qemuu-nested-amd  8 xen-bootfail REGR. vs. 182531
 test-amd64-amd64-libvirt-raw  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-qemuu-nested-intel  8 xen-boot  fail REGR. vs. 182531
 test-amd64-amd64-libvirt-xsm  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-pair12 xen-boot/src_hostfail REGR. vs. 182531
 test-amd64-amd64-pair13 xen-boot/dst_hostfail REGR. vs. 182531
 test-amd64-amd64-xl-qemuu-debianhvm-amd64  8 xen-bootfail REGR. vs. 182531
 test-amd64-amd64-libvirt-qcow2  8 xen-boot   fail REGR. vs. 182531
 test-amd64-amd64-xl-pvshim8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-libvirt-pair 12 xen-boot/src_host   fail REGR. vs. 182531
 test-amd64-amd64-libvirt-pair 13 xen-boot/dst_host   fail REGR. vs. 182531
 test-amd64-amd64-xl-qemut-ws16-amd64  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-xsm   8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-qemuu-debianhvm-i386-xsm  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-qemuu-debianhvm-amd64-shadow 8 xen-boot fail REGR. vs. 
182531
 test-amd64-amd64-xl-qemuu-ovmf-amd64  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-multivcpu  8 xen-bootfail REGR. vs. 182531
 test-amd64-amd64-xl-pvhv2-amd  8 xen-bootfail REGR. vs. 182531
 test-amd64-amd64-xl-qemuu-dmrestrict-amd64-dmrestrict 8 xen-boot fail REGR. 
vs. 182531
 test-amd64-amd64-xl-qemut-stubdom-debianhvm-amd64-xsm 8 xen-boot fail REGR. 
vs. 182531
 test-amd64-amd64-xl-qemut-debianhvm-i386-xsm  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-qemut-debianhvm-amd64  8 xen-bootfail REGR. vs. 182531
 test-amd64-amd64-libvirt  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl   8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-shadow8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-pvhv2-intel  8 xen-boot  fail REGR. vs. 182531
 test-amd64-amd64-freebsd12-amd64  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-dom0pvh-xl-intel 14 guest-start fail REGR. vs. 182531
 test-amd64-amd64-freebsd11-amd64  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 8 xen-boot fail REGR. vs. 
182531
 test-amd64-amd64-pygrub   8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-credit2   8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-xl-credit1   8 xen-boot fail REGR. vs. 182531
 test-amd64-coresched-amd64-xl  8 xen-bootfail REGR. vs. 182531
 test-armhf-armhf-libvirt-raw  8 xen-boot fail REGR. vs. 182531
 test-amd64-amd64-examine-bios  8 reboot  fail REGR. vs. 182531
 test-amd64-amd64-examine  8 reboot   fail REGR. vs. 182531
 test-amd64-amd64-examine-uefi  8 reboot  fail REGR. vs. 182531

Regressions which are regarded as allowable (not blocking):
 test-amd64-amd64-xl-rtds  8 xen-boot fail REGR. vs. 182531

Tests which did not succeed, but are not blocking:
 test-armhf-armhf-libvirt 16 saverestore-support-checkfail  like 182531
 test-armhf-armhf-libvirt-qcow2 15 saverestore-support-check   fail like 182531
 test-arm64-arm64-xl  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  16 saverestore-support-checkfail   never pass
 

Re: [PATCH v2 3/8] xen/ppc: Implement atomic.h

2023-08-31 Thread Shawn Anastasio
On 8/29/23 8:43 AM, Jan Beulich wrote:
> On 23.08.2023 22:07, Shawn Anastasio wrote:
>> --- /dev/null
>> +++ b/xen/arch/ppc/include/asm/atomic.h
>> @@ -0,0 +1,390 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * PowerPC64 atomic operations
>> + *
>> + * Copyright (C) 2001 Paul Mackerras , IBM
>> + * Copyright (C) 2001 Anton Blanchard , IBM
>> + * Copyright Raptor Engineering LLC
>> + *
>> + * 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.
>> + */
> 
> License text again despite the SPDX header?
>

Will fix.

>> +#ifndef _ASM_PPC64_ATOMIC_H_
>> +#define _ASM_PPC64_ATOMIC_H_
>> +
>> +#include 
>> +
>> +#include 
>> +#include 
> 
> I can see that you need memory.h, but I can't spot a need for system.h.
>

Just confirmed, you're correct. I'll drop it.

>> +static inline int atomic_read(const atomic_t *v)
>> +{
>> +return *(volatile int *)>counter;
>> +}
>> +
>> +static inline int _atomic_read(atomic_t v)
>> +{
>> +return v.counter;
>> +}
>> +
>> +static inline void atomic_set(atomic_t *v, int i)
>> +{
>> +v->counter = i;
>> +}
>> +
>> +static inline void _atomic_set(atomic_t *v, int i)
>> +{
>> +v->counter = i;
>> +}
>> +
>> +void __bad_atomic_read(const volatile void *p, void *res);
>> +void __bad_atomic_size(void);
>> +
>> +#define build_atomic_read(name, insn, type) 
>>\
>> +static inline type name(const volatile type *addr)  
>>\
>> +{   
>>\
>> +type ret;   
>>\
>> +asm volatile ( insn "%U1%X1 %0,%1" : "=r" (ret) : "m<>" (*addr) );  
>>\
>> +return ret; 
>>\
>> +}
>> +
>> +#define build_atomic_write(name, insn, type)
>>\
>> +static inline void name(volatile type *addr, type val)  
>>\
>> +{   
>>\
>> +asm volatile ( insn "%U0%X0 %1,%0" : "=m<>" (*addr) : "r" (val) );  
>>\
>> +}
>> +
>> +#define build_add_sized(name, ldinsn, stinsn, type) 
>>\
>> +static inline void name(volatile type *addr, type val)  
>>\
>> +{   
>>\
>> +type t; 
>>\
>> +asm volatile ( "1: " ldinsn " %0,0,%3\n"
>>\
>> +   "add%I2 %0,%0,%2\n"  
>>\
>> +   stinsn " %0,0,%3 \n" 
>>\
>> +   "bne- 1b\n"  
>>\
>> +   : "=" (t), "+m" (*addr)
>>\
>> +   : "r" (val), "r" (addr)  
>>\
>> +   : "cc" );
>>\
>> +}
>> +
>> +build_atomic_read(read_u8_atomic, "lbz", uint8_t)
>> +build_atomic_read(read_u16_atomic, "lhz", uint16_t)
>> +build_atomic_read(read_u32_atomic, "lwz", uint32_t)
>> +build_atomic_read(read_u64_atomic, "ldz", uint64_t)
>> +
>> +build_atomic_write(write_u8_atomic, "stb", uint8_t)
>> +build_atomic_write(write_u16_atomic, "sth", uint16_t)
>> +build_atomic_write(write_u32_atomic, "stw", uint32_t)
>> +build_atomic_write(write_u64_atomic, "std", uint64_t)
>> +
>> +build_add_sized(add_u8_sized, "lbarx", "stbcx.",uint8_t)
>> +build_add_sized(add_u16_sized, "lharx", "sthcx.", uint16_t)
>> +build_add_sized(add_u32_sized, "lwarx", "stwcx.", uint32_t)
>> +
>> +#undef build_atomic_read
>> +#undef build_atomic_write
>> +#undef build_add_sized
>> +
>> +static always_inline void read_atomic_size(const volatile void *p, void 
>> *res,
>> +   unsigned int size)
>> +{
>> +ASSERT(IS_ALIGNED((vaddr_t) p, size));
> 
> Nit: Stray blank before p (several more below).
>

Will fix.

>> +switch ( size )
>> +{
>> +case 1:
>> +*(uint8_t *)res = read_u8_atomic(p);
>> +break;
>> +case 2:
>> +*(uint16_t *)res = read_u16_atomic(p);
>> +break;
>> +case 4:
>> +*(uint32_t *)res = read_u32_atomic(p);
>> +break;
>> +case 8:
>> +*(uint64_t *)res = read_u64_atomic(p);
>> +break;
>> +default:
>> +__bad_atomic_read(p, res);
>> +break;
>> +}
>> +}
>> +
>> +static always_inline void write_atomic_size(volatile void *p, void *val,
> 
> const void *val? (But 

Re: [PATCH v3 2/2] xen: move arm/include/asm/vm_event.h to asm-generic

2023-08-31 Thread Jan Beulich
On 31.08.2023 16:02, Oleksii wrote:
> On Thu, 2023-08-31 at 11:46 +0200, Jan Beulich wrote:
>> On 30.08.2023 18:57, Oleksii Kurochko wrote:
>>> ---
>>>  xen/arch/arm/include/asm/vm_event.h    | 66 --
>>> 
>>>  xen/include/asm-generic/asm/vm_event.h | 55 +
>>>  2 files changed, 55 insertions(+), 66 deletions(-)
>>>  delete mode 100644 xen/arch/arm/include/asm/vm_event.h
>>>  create mode 100644 xen/include/asm-generic/asm/vm_event.h
>>
>> While it's a comment on the first patch, it's really better making
>> here:
>> Did you look at Linux? They don't put an intermediate asm/ here.
>> Instead
>> see their scripts/Makefile.asm-generic. That way an arch still has
>> control which generic headers it gets access to, without duplicating
>> any
>> of them.
> 
> IIUC scripts/Makefile.asm-generic script is needed to generate a
> wrapper for a header which will contain:
> #include 
> if it is mentioned generic-y += some.h in
> arch/${ARCH}/include/asm/Kbuild.
> 
> But do we need this generated wrapper header?
> Do we need all the support of generic-y in Kbuild, etc.?

For a single header we could likely get away without. But vm_event.h is
only the first example.

> In the previous patch of this patch series, it was added inclusion of
> $(srctree)/include/asm-generic after the inclusion of
> $(srctree)/arch/$(SRCARCH)/include so it will first look if the arch-
> specific header exists, and if not then use generic one.
> 
> Probably I misunderstood you and your suggestion was to have
> scripts/Makefile.asm-generic which will generate folder asm/ with
> necessary headers in arch specific folder?

Yes.

> So basically it was just a
> question if asm/ folder should exist in $(srctree)/include/asm-generic
> or not?

Not really, no. For "#include " to work, you can't simply omit
asm/ under asm-generic/. That's where the generated wrapper headers
come into play.

> One more thing I would like to clarify is the duplicating of the
> headers you mentioned above.
> But if the architecture doesn't want to use a generic header, then it
> still needs to add the header to arch/${ARCH}/include/asm and remove
> mention of the header from arch/${ARCH}/include/asm/Kbuild.

But then it's using its own custom header, not a duplication of whatever
is the (in the case here) stub one.

Jan



[ovmf test] 182582: all pass - PUSHED

2023-08-31 Thread osstest service owner
flight 182582 ovmf real [real]
http://logs.test-lab.xenproject.org/osstest/logs/182582/

Perfect :-)
All tests in this flight passed as required
version targeted for testing:
 ovmf 4c8144dd665619731b6c3c19f4f1ae664b69fa4b
baseline version:
 ovmf c5753c3e38f3fde23eec9641cb3c433f443ff99e

Last test of basis   182573  2023-08-30 21:40:51 Z0 days
Testing same since   182582  2023-08-31 13:42:21 Z0 days1 attempts


People who touched revisions under test:
  Eduardo Cuevas Farfan 

jobs:
 build-amd64-xsm  pass
 build-i386-xsm   pass
 build-amd64  pass
 build-i386   pass
 build-amd64-libvirt  pass
 build-i386-libvirt   pass
 build-amd64-pvopspass
 build-i386-pvops pass
 test-amd64-amd64-xl-qemuu-ovmf-amd64 pass
 test-amd64-i386-xl-qemuu-ovmf-amd64  pass



sg-report-flight on osstest.test-lab.xenproject.org
logs: /home/logs/logs
images: /home/logs/images

Logs, config files, etc. are available at
http://logs.test-lab.xenproject.org/osstest/logs

Explanation of these reports, and of osstest in general, is at
http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master
http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master

Test harness code can be found at
http://xenbits.xen.org/gitweb?p=osstest.git;a=summary


Pushing revision :

To xenbits.xen.org:/home/xen/git/osstest/ovmf.git
   c5753c3e38..4c8144dd66  4c8144dd665619731b6c3c19f4f1ae664b69fa4b -> 
xen-tested-master



Re: [PATCH 7/7] qobject atomics osdep: Make a few macros more hygienic

2023-08-31 Thread Richard Henderson

On 8/31/23 06:25, Markus Armbruster wrote:

+#define PASTE(a, b) a##b


We already have glue() in qemu/compiler.h.

The rest of it looks quite sensible.


r~



Re: [QEMU PATCH v4 12/13] virtio-gpu: Initialize Venus

2023-08-31 Thread Dmitry Osipenko
On 8/31/23 13:40, Antonio Caggiano wrote:
> Hi Huang,
> 
> Thank you for pushing this forward!
> 
> On 31/08/2023 11:32, Huang Rui wrote:
>> From: Antonio Caggiano 
>>
>> Request Venus when initializing VirGL.
>>
>> Signed-off-by: Antonio Caggiano 
>> Signed-off-by: Huang Rui 
>> ---
>>
>> v1->v2:
>>  - Rebase to latest version
>>
>>   hw/display/virtio-gpu-virgl.c | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/hw/display/virtio-gpu-virgl.c
>> b/hw/display/virtio-gpu-virgl.c
>> index 83cd8c8fd0..c5a62665bd 100644
>> --- a/hw/display/virtio-gpu-virgl.c
>> +++ b/hw/display/virtio-gpu-virgl.c
>> @@ -887,6 +887,8 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
>>   }
>>   #endif
>>   +    flags |= VIRGL_RENDERER_VENUS;
>> +
> 
> VIRGL_RENDERER_VENUS is a symbol only available from virglrenderer 0.9.1
> [0] and only if VIRGL_RENDERER_UNSTABLE_APIS is defined.
> 
> Luckily for us, VIRGL_RENDERER_UNSTABLE_APIS is defined unconditionally
> from virglrenderer 0.9.0 [1], so we could check for that in
> qemu/meson.build
> 
> e.g.
> 
> 
>   if virgl.version().version_compare('>= 0.9.0')
>     message('Enabling virglrenderer unstable APIs')
>     virgl = declare_dependency(compile_args:
> '-DVIRGL_RENDERER_UNSTABLE_APIS',
>    dependencies: virgl)
>   endif
> 
> 
> Also, while testing this with various versions of virglrenderer, I
> realized there are no guarantees for Venus backend to be available in
> the linked library. Virglrenderer should be built with
> -Dvenus_experimental=true, and if that is not the case, the following
> virgl_renderer_init would fail for previous versions of virglrenderer or
> in case it has not been built with venus support.
> 
> I would suggest another approach for that which tries initializing Venus
> only if VIRGL_RENDERER_VENUS is actually defined. Then, if it fails
> cause virglrenderer has not been built with venus support, try again
> falling back to virgl only.

All the APIs will be stabilized with the upcoming virglrender 1.0
release that will happen soon. There is also a venus protocol bump, qemu
will have to bump virglrenderer's version dependency to 1.0 for venus
and other new features.

-- 
Best regards,
Dmitry




Re: [PATCH 3/7] ui: Clean up local variable shadowing

2023-08-31 Thread Peter Maydell
On Thu, 31 Aug 2023 at 14:25, Markus Armbruster  wrote:
>
> Local variables shadowing other local variables or parameters make the
> code needlessly hard to understand.  Tracked down with -Wshadow=local.
> Clean up: delete inner declarations when they are actually redundant,
> else rename variables.
>
> Signed-off-by: Markus Armbruster 


> diff --git a/ui/vnc-enc-zrle.c.inc b/ui/vnc-enc-zrle.c.inc
> index c107d8affc..edf42d4a6a 100644
> --- a/ui/vnc-enc-zrle.c.inc
> +++ b/ui/vnc-enc-zrle.c.inc
> @@ -153,11 +153,12 @@ static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL 
> *data, int w, int h,
>  }
>
>  if (use_rle) {
> -ZRLE_PIXEL *ptr = data;
> -ZRLE_PIXEL *end = ptr + w * h;
>  ZRLE_PIXEL *run_start;
>  ZRLE_PIXEL pix;
>
> +   ptr = data;
> +end = ptr + w * h;
> +
>  while (ptr < end) {
>  int len;
>  int index = 0;
> @@ -198,7 +199,7 @@ static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL 
> *data, int w, int h,
>  }
>  } else if (use_palette) { /* no RLE */
>  int bppp;
> -ZRLE_PIXEL *ptr = data;
> +ptr = data;
>
>  /* packed pixels */
>
> @@ -241,8 +242,6 @@ static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL 
> *data, int w, int h,
>  #endif
>  {
>  #ifdef ZRLE_COMPACT_PIXEL
> -ZRLE_PIXEL *ptr;
> -
>  for (ptr = data; ptr < data + w * h; ptr++) {
>  ZRLE_WRITE_PIXEL(vs, *ptr);
>  }

For this one I'm tempted to suggest instead moving the
pix and end currently at whole-function scope into their
own block, so it's clear these are actually four
completely independent uses of ptr/end. But either way

Reviewed-by: Peter Maydell 

thanks
-- PMM



Re: [PATCH 7/7] qobject atomics osdep: Make a few macros more hygienic

2023-08-31 Thread Eric Blake
On Thu, Aug 31, 2023 at 03:25:46PM +0200, Markus Armbruster wrote:

[This paragraph written last: Bear with my stream of consciousness
review below, where I end up duplicating some of the conslusions you
reached before the point where I saw where the patch was headed]

> Variables declared in macros can shadow other variables.  Much of the
> time, this is harmless, e.g.:
> 
> #define _FDT(exp)  \
> do {   \
> int ret = (exp);   \
> if (ret < 0) { \
> error_report("error creating device tree: %s: %s",   \
> #exp, fdt_strerror(ret));  \
> exit(1);   \
> }  \
> } while (0)

Which is why I've seen some projects require a strict namespace
separation: if all macro parameters and any identifiers declared in
macros use either a leading or a trailing _ (I prefer a trailing one,
to avoid risking conflicts with libc reserved namespace; but leading
is usually okay), and all other identifiers avoid that namespace, then
you will never have shadowing by calling a macro from normal code.

> 
> Harmless shadowing in h_client_architecture_support():
> 
> target_ulong ret;
> 
> [...]
> 
> ret = do_client_architecture_support(cpu, spapr, vec, fdt_bufsize);
> if (ret == H_SUCCESS) {
> _FDT((fdt_pack(spapr->fdt_blob)));
> [...]
> }
> 
> return ret;
> 
> However, we can get in trouble when the shadowed variable is used in a
> macro argument:
> 
> #define QOBJECT(obj) ({ \
> typeof(obj) o = (obj);  \
> o ? container_of(&(o)->base, QObject, base) : NULL; \
>  })
> 
> QOBJECT(o) expands into
> 
> ({
> --->typeof(o) o = (o);
> o ? container_of(&(o)->base, QObject, base) : NULL;
> })
> 
> Unintended variable name capture at --->.  We'd be saved by
> -Winit-self.  But I could certainly construct more elaborate death
> traps that don't trigger it.

Indeed, not fully understanding the preprocessor makes for some
interesting death traps.

> 
> To reduce the risk of trapping ourselves, we use variable names in
> macros that no sane person would use elsewhere.  Here's our actual
> definition of QOBJECT():
> 
> #define QOBJECT(obj) ({ \
> typeof(obj) _obj = (obj);   \
> _obj ? container_of(&(_obj)->base, QObject, base) : NULL;   \
> })

Yep, goes back to the policy I've seen of enforcing naming conventions
that ensure macros can't shadow normal code.

> 
> Works well enough until we nest macro calls.  For instance, with
> 
> #define qobject_ref(obj) ({ \
> typeof(obj) _obj = (obj);   \
> qobject_ref_impl(QOBJECT(_obj));\
> _obj;   \
> })
> 
> the expression qobject_ref(obj) expands into
> 
> ({
> typeof(obj) _obj = (obj);
> qobject_ref_impl(
> ({
> --->typeof(_obj) _obj = (_obj);
> _obj ? container_of(&(_obj)->base, QObject, base) : NULL;
> }));
> _obj;
> })
> 
> Unintended variable name capture at --->.

Yep, you've just proven how macros calling macros requires care, as we
no longer have the namespace protections.  If macro calls can only
form a DAG, it is possible to choose unique intermediate declarations
for every macro (although remembering to do that, and still keeping
the macro definition legible, may not be easy).  But if you can have
macros that form any sort of nesting loop (and we WANT to allow things
like MIN(MIN(a, b), c) - which is such a loop), dynamic naming becomes
the only solution.

> 
> The only reliable way to prevent unintended variable name capture is
> -Wshadow.

Yes, I would love to have that enabled eventually.

> 
> One blocker for enabling it is shadowing hiding in function-like
> macros like
> 
>  qdict_put(dict, "name", qobject_ref(...))
> 
> qdict_put() wraps its last argument in QOBJECT(), and the last
> argument here contains another QOBJECT().
> 
> Use dark preprocessor sorcery to make the macros that give us this
> problem use different variable names on every call.

Sounds foreboding; hopefully not many macros are affected...

> 
> Signed-off-by: Markus Armbruster 
> ---
>  include/qapi/qmp/qobject.h |  8 +---
>  include/qemu/atomic.h  | 11 ++-
>  include/qemu/osdep.h   | 34 +++---
>  3 files changed, 30 insertions(+), 23 deletions(-)

...okay, the size of the diffstat seems 

[linux-5.4 test] 182575: regressions - FAIL

2023-08-31 Thread osstest service owner
flight 182575 linux-5.4 real [real]
http://logs.test-lab.xenproject.org/osstest/logs/182575/

Regressions :-(

Tests which did not succeed and are blocking,
including tests which could not be run:
 test-armhf-armhf-xl-credit1 18 guest-start/debian.repeat fail REGR. vs. 182363
 test-armhf-armhf-xl-multivcpu 18 guest-start/debian.repeat fail in 182569 
REGR. vs. 182363

Tests which are failing intermittently (not blocking):
 test-amd64-amd64-xl-qemuu-dmrestrict-amd64-dmrestrict 15 guest-start.2 fail 
pass in 182569
 test-armhf-armhf-xl-multivcpu 14 guest-start   fail pass in 182569
 test-armhf-armhf-xl-arndale  18 guest-start/debian.repeat  fail pass in 182569

Tests which did not succeed, but are not blocking:
 test-armhf-armhf-xl-rtds 14 guest-start fail blocked in 182363
 test-armhf-armhf-xl-rtds 18 guest-start/debian.repeat fail in 182569 blocked 
in 182363
 test-armhf-armhf-xl-multivcpu 15 migrate-support-check fail in 182569 never 
pass
 test-armhf-armhf-xl-multivcpu 16 saverestore-support-check fail in 182569 
never pass
 test-armhf-armhf-xl-rtds15 migrate-support-check fail in 182569 never pass
 test-armhf-armhf-xl-rtds 16 saverestore-support-check fail in 182569 never pass
 test-armhf-armhf-libvirt 16 saverestore-support-checkfail  like 182363
 test-amd64-amd64-xl-qemuu-win7-amd64 19 guest-stopfail like 182363
 test-amd64-i386-xl-qemut-win7-amd64 19 guest-stop fail like 182363
 test-amd64-i386-xl-qemuu-win7-amd64 19 guest-stop fail like 182363
 test-armhf-armhf-xl-credit2  18 guest-start/debian.repeatfail  like 182363
 test-amd64-amd64-xl-qemut-win7-amd64 19 guest-stopfail like 182363
 test-armhf-armhf-libvirt-qcow2 15 saverestore-support-check   fail like 182363
 test-amd64-amd64-xl-qemuu-ws16-amd64 19 guest-stopfail like 182363
 test-amd64-amd64-xl-qemut-ws16-amd64 19 guest-stopfail like 182363
 test-armhf-armhf-libvirt-raw 15 saverestore-support-checkfail  like 182363
 test-amd64-i386-xl-qemut-ws16-amd64 19 guest-stop fail like 182363
 test-amd64-i386-xl-qemuu-ws16-amd64 19 guest-stop fail like 182363
 test-amd64-amd64-qemuu-nested-amd 20 debian-hvm-install/l1/l2 fail like 182363
 test-amd64-i386-libvirt-xsm  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl  16 saverestore-support-checkfail   never pass
 test-amd64-i386-xl-pvshim14 guest-start  fail   never pass
 test-amd64-amd64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-amd64-amd64-libvirt 15 migrate-support-checkfail   never pass
 test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-amd64-i386-libvirt  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-thunderx 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit1  16 saverestore-support-checkfail   never pass
 test-amd64-i386-libvirt-raw  14 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-xsm  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 15 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-xsm 16 saverestore-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  15 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-credit2  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit1  16 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-vhd 14 migrate-support-checkfail   never pass
 test-armhf-armhf-libvirt 15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-arndale  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-arndale  16 saverestore-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  15 migrate-support-checkfail   never pass
 test-armhf-armhf-xl-credit2  16 saverestore-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 14 migrate-support-checkfail   never pass
 test-arm64-arm64-libvirt-raw 15 saverestore-support-checkfail   never pass
 test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 13 migrate-support-check 
fail never pass
 test-arm64-arm64-xl-vhd  14 migrate-support-checkfail   never pass
 test-arm64-arm64-xl-vhd  15 saverestore-support-check   

Re: [PATCH v3 2/2] xen: move arm/include/asm/vm_event.h to asm-generic

2023-08-31 Thread Oleksii
On Thu, 2023-08-31 at 11:46 +0200, Jan Beulich wrote:
> On 30.08.2023 18:57, Oleksii Kurochko wrote:
> > asm/vm_event.h is common for ARM and RISC-V so it will be moved to
> > asm-generic dir.
> > 
> > Original asm/vm_event.h from ARM was updated:
> >  * use SPDX-License-Identifier.
> >  * update comment messages of stubs.
> >  * update #ifdef.
> >  * change public/domctl.h to public/vm_event.h.
> > 
> > Signed-off-by: Oleksii Kurochko 
> > Acked-by: Stefano Stabellini 
> > ---
> > Changes in V3:
> >  - add Acked-by: Stefano Stabellini  for
> > "xen: move arm/include/asm/vm_event.h to asm-generic"
> >  - update SPDX tag.
> >  - move asm/vm_event.h to asm-generic.
> > ---
> > Changes in V2:
> >  - change public/domctl.h to public/vm_event.h.
> >  - update commit message of [PATCH v2 2/2] xen: move
> > arm/include/asm/vm_event.h to stubs
> > ---
> >  xen/arch/arm/include/asm/vm_event.h    | 66 --
> > 
> >  xen/include/asm-generic/asm/vm_event.h | 55 +
> >  2 files changed, 55 insertions(+), 66 deletions(-)
> >  delete mode 100644 xen/arch/arm/include/asm/vm_event.h
> >  create mode 100644 xen/include/asm-generic/asm/vm_event.h
> 
> While it's a comment on the first patch, it's really better making
> here:
> Did you look at Linux? They don't put an intermediate asm/ here.
> Instead
> see their scripts/Makefile.asm-generic. That way an arch still has
> control which generic headers it gets access to, without duplicating
> any
> of them.

IIUC scripts/Makefile.asm-generic script is needed to generate a
wrapper for a header which will contain:
#include 
if it is mentioned generic-y += some.h in
arch/${ARCH}/include/asm/Kbuild.

But do we need this generated wrapper header?
Do we need all the support of generic-y in Kbuild, etc.?

In the previous patch of this patch series, it was added inclusion of
$(srctree)/include/asm-generic after the inclusion of
$(srctree)/arch/$(SRCARCH)/include so it will first look if the arch-
specific header exists, and if not then use generic one.

Probably I misunderstood you and your suggestion was to have
scripts/Makefile.asm-generic which will generate folder asm/ with
necessary headers in arch specific folder? So basically it was just a
question if asm/ folder should exist in $(srctree)/include/asm-generic
or not?

One more thing I would like to clarify is the duplicating of the
headers you mentioned above.
But if the architecture doesn't want to use a generic header, then it
still needs to add the header to arch/${ARCH}/include/asm and remove
mention of the header from arch/${ARCH}/include/asm/Kbuild.

~ Oleksii





Re: [PATCH 1/7] migration/rdma: Fix save_page method to fail on polling error

2023-08-31 Thread Eric Blake
On Thu, Aug 31, 2023 at 03:25:40PM +0200, Markus Armbruster wrote:
> qemu_rdma_save_page() reports polling error with error_report(), then
> succeeds anyway.  This is because the variable holding the polling
> status *shadows* the variable the function returns.  The latter
> remains zero.
> 
> Broken since day one, and duplicated more recently.
> 
> Fixes: 2da776db4846 (rdma: core logic)
> Fixes: b390afd8c50b (migration/rdma: Fix out of order wrid)

Alas, the curse of immutable git history preserving typos in commit
subjects ;) The alternative of rewriting history and breaking SHA
references is worse.

> Signed-off-by: Markus Armbruster 
> ---
>  migration/rdma.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)

Reviewed-by: Eric Blake 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org




Re: [XEN PATCH 09/13] xen/common: address violations of MISRA C:2012 Directive 4.10

2023-08-31 Thread Simone Ballarin

On 31/08/23 15:05, Jan Beulich wrote:

On 31.08.2023 14:54, Simone Ballarin wrote:

On 31/08/23 13:10, Jan Beulich wrote:

On 31.08.2023 12:08, Simone Ballarin wrote:

The danger of multi-inclusion also exists for .c files, why do you want
to avoid guards for them?


Counter question: Why only add guards to some of them? (My personal
answer is "Because it's extra clutter.")


It's not "some of them", it's exactly the ones used in an #include
directive, so I'm not getting your objection.


My point is that by adding guards only for files we presently use in some
#include directive, we set us up for introducing new violations as soon
as another .c file becomes the subject of an #include.The more that it
is unusual to add guards in .c files, i.e. it is to be expected that
people wouldn't think about this extra Misra requirement.

Jan


I can agree to partially adopt the directive: I will add a deviation for 
C files in rules.txt.


--
Simone Ballarin, M.Sc.

Field Application Engineer, BUGSENG (https://bugseng.com)




[PATCH 6/7] block: Clean up local variable shadowing

2023-08-31 Thread Markus Armbruster
Local variables shadowing other local variables or parameters make the
code needlessly hard to understand.  Tracked down with -Wshadow=local.
Clean up: delete inner declarations when they are actually redundant,
else rename variables.

Signed-off-by: Markus Armbruster 
---
 block.c  |  7 ---
 block/rbd.c  |  2 +-
 block/stream.c   |  1 -
 block/vvfat.c| 34 +-
 hw/block/xen-block.c |  6 +++---
 5 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/block.c b/block.c
index a307c151a8..7f0003d8ac 100644
--- a/block.c
+++ b/block.c
@@ -3001,7 +3001,8 @@ static BdrvChild 
*bdrv_attach_child_common(BlockDriverState *child_bs,
BdrvChildRole child_role,
uint64_t perm, uint64_t shared_perm,
void *opaque,
-   Transaction *tran, Error **errp)
+   Transaction *transaction,
+   Error **errp)
 {
 BdrvChild *new_child;
 AioContext *parent_ctx, *new_child_ctx;
@@ -3088,7 +3089,7 @@ static BdrvChild 
*bdrv_attach_child_common(BlockDriverState *child_bs,
 .old_parent_ctx = parent_ctx,
 .old_child_ctx = child_ctx,
 };
-tran_add(tran, _attach_child_common_drv, s);
+tran_add(transaction, _attach_child_common_drv, s);
 
 if (new_child_ctx != child_ctx) {
 aio_context_release(new_child_ctx);
@@ -6073,12 +6074,12 @@ void bdrv_iterate_format(void (*it)(void *opaque, const 
char *name),
 QLIST_FOREACH(drv, _drivers, list) {
 if (drv->format_name) {
 bool found = false;
-int i = count;
 
 if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, read_only)) {
 continue;
 }
 
+i = count;
 while (formats && i && !found) {
 found = !strcmp(formats[--i], drv->format_name);
 }
diff --git a/block/rbd.c b/block/rbd.c
index 978671411e..472ca05cba 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -1290,7 +1290,7 @@ static int coroutine_fn 
qemu_rbd_start_co(BlockDriverState *bs,
  * operations that exceed the current size.
  */
 if (offset + bytes > s->image_size) {
-int r = qemu_rbd_resize(bs, offset + bytes);
+r = qemu_rbd_resize(bs, offset + bytes);
 if (r < 0) {
 return r;
 }
diff --git a/block/stream.c b/block/stream.c
index e522bbdec5..007253880b 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -282,7 +282,6 @@ void stream_start(const char *job_id, BlockDriverState *bs,
 /* Make sure that the image is opened in read-write mode */
 bs_read_only = bdrv_is_read_only(bs);
 if (bs_read_only) {
-int ret;
 /* Hold the chain during reopen */
 if (bdrv_freeze_backing_chain(bs, above_base, errp) < 0) {
 return;
diff --git a/block/vvfat.c b/block/vvfat.c
index 0ddc91fc09..d7425ee602 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -777,7 +777,6 @@ static int read_directory(BDRVVVFATState* s, int 
mapping_index)
 while((entry=readdir(dir))) {
 unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
 char* buffer;
-direntry_t* direntry;
 struct stat st;
 int is_dot=!strcmp(entry->d_name,".");
 int is_dotdot=!strcmp(entry->d_name,"..");
@@ -857,7 +856,7 @@ static int read_directory(BDRVVVFATState* s, int 
mapping_index)
 
 /* fill with zeroes up to the end of the cluster */
 while(s->directory.next%(0x10*s->sectors_per_cluster)) {
-direntry_t* direntry=array_get_next(&(s->directory));
+direntry = array_get_next(&(s->directory));
 memset(direntry,0,sizeof(direntry_t));
 }
 
@@ -1962,24 +1961,24 @@ get_cluster_count_for_direntry(BDRVVVFATState* s, 
direntry_t* direntry, const ch
  * This is horribly inefficient, but that is okay, since
  * it is rarely executed, if at all.
  */
-int64_t offset = cluster2sector(s, cluster_num);
+int64_t offs = cluster2sector(s, cluster_num);
 
 vvfat_close_current_file(s);
 for (i = 0; i < s->sectors_per_cluster; i++) {
 int res;
 
 res = bdrv_is_allocated(s->qcow->bs,
-(offset + i) * BDRV_SECTOR_SIZE,
+(offs + i) * BDRV_SECTOR_SIZE,
 BDRV_SECTOR_SIZE, NULL);
 if (res < 0) {
 return -1;
 }
 if (!res) {
-res = vvfat_read(s->bs, offset, s->cluster_buffer, 1);
+res = vvfat_read(s->bs, offs, 

[PATCH 4/7] block/dirty-bitmap: Clean up local variable shadowing

2023-08-31 Thread Markus Armbruster
Local variables shadowing other local variables or parameters make the
code needlessly hard to understand.  Tracked down with -Wshadow=local.
Clean up: delete inner declarations when they are actually redundant,
else rename variables.

Signed-off-by: Markus Armbruster 
---
 block/monitor/bitmap-qmp-cmds.c | 2 +-
 block/qcow2-bitmap.c| 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/block/monitor/bitmap-qmp-cmds.c b/block/monitor/bitmap-qmp-cmds.c
index 55f778f5af..4d018423d8 100644
--- a/block/monitor/bitmap-qmp-cmds.c
+++ b/block/monitor/bitmap-qmp-cmds.c
@@ -276,7 +276,7 @@ BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *node, 
const char *target,
 
 for (lst = bms; lst; lst = lst->next) {
 switch (lst->value->type) {
-const char *name, *node;
+const char *name;
 case QTYPE_QSTRING:
 name = lst->value->u.local;
 src = bdrv_find_dirty_bitmap(bs, name);
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index 037fa2d435..ffd5cd3b23 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -1555,7 +1555,6 @@ bool 
qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
 FOR_EACH_DIRTY_BITMAP(bs, bitmap) {
 const char *name = bdrv_dirty_bitmap_name(bitmap);
 uint32_t granularity = bdrv_dirty_bitmap_granularity(bitmap);
-Qcow2Bitmap *bm;
 
 if (!bdrv_dirty_bitmap_get_persistence(bitmap) ||
 bdrv_dirty_bitmap_inconsistent(bitmap)) {
@@ -1625,7 +1624,7 @@ bool 
qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs,
 
 /* allocate clusters and store bitmaps */
 QSIMPLEQ_FOREACH(bm, bm_list, entry) {
-BdrvDirtyBitmap *bitmap = bm->dirty_bitmap;
+bitmap = bm->dirty_bitmap;
 
 if (bitmap == NULL || bdrv_dirty_bitmap_readonly(bitmap)) {
 continue;
-- 
2.41.0




[PATCH 5/7] block/vdi: Clean up local variable shadowing

2023-08-31 Thread Markus Armbruster
Local variables shadowing other local variables or parameters make the
code needlessly hard to understand.  Tracked down with -Wshadow=local.
Clean up: delete inner declarations when they are actually redundant,
else rename variables.

Signed-off-by: Markus Armbruster 
---
 block/vdi.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/block/vdi.c b/block/vdi.c
index 6c35309e04..c084105b78 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -634,7 +634,6 @@ vdi_co_pwritev(BlockDriverState *bs, int64_t offset, 
int64_t bytes,
 bmap_entry = le32_to_cpu(s->bmap[block_index]);
 if (!VDI_IS_ALLOCATED(bmap_entry)) {
 /* Allocate new block and write to it. */
-uint64_t data_offset;
 qemu_co_rwlock_upgrade(>bmap_lock);
 bmap_entry = le32_to_cpu(s->bmap[block_index]);
 if (VDI_IS_ALLOCATED(bmap_entry)) {
@@ -700,7 +699,7 @@ nonallocating_write:
 /* One or more new blocks were allocated. */
 VdiHeader *header;
 uint8_t *base;
-uint64_t offset;
+uint64_t offs;
 uint32_t n_sectors;
 
 g_free(block);
@@ -723,11 +722,11 @@ nonallocating_write:
 bmap_first /= (SECTOR_SIZE / sizeof(uint32_t));
 bmap_last /= (SECTOR_SIZE / sizeof(uint32_t));
 n_sectors = bmap_last - bmap_first + 1;
-offset = s->bmap_sector + bmap_first;
+offs = s->bmap_sector + bmap_first;
 base = ((uint8_t *)>bmap[0]) + bmap_first * SECTOR_SIZE;
 logout("will write %u block map sectors starting from entry %u\n",
n_sectors, bmap_first);
-ret = bdrv_co_pwrite(bs->file, offset * SECTOR_SIZE,
+ret = bdrv_co_pwrite(bs->file, offs * SECTOR_SIZE,
  n_sectors * SECTOR_SIZE, base, 0);
 }
 
-- 
2.41.0




[PATCH 0/7] Steps towards enabling -Wshadow=local

2023-08-31 Thread Markus Armbruster
Local variables shadowing other local variables or parameters make the
code needlessly hard to understand.  Bugs love to hide in such code.
Evidence: PATCH 1.

Enabling -Wshadow would prevent bugs like this one.  But we'd have to
clean up all the offenders first.  We got a lot of them.

Enabling -Wshadow=local should be less work for almost as much gain.
I took a stab at it.  There's a small, exciting part, and a large,
boring part.

The exciting part is dark preprocessor sorcery to let us nest macro
calls without shadowing: PATCH 7.

The boring part is cleaning up all the other warnings.  I did some
[PATCH 2-6], but ran out of steam long before finishing the job.  Some
160 unique warnings remain.

To see them, enable -Wshadow=local like so:

diff --git a/meson.build b/meson.build
index 98e68ef0b1..9fc4c7ac9d 100644
--- a/meson.build
+++ b/meson.build
@@ -466,6 +466,9 @@ warn_flags = [
   '-Wno-tautological-type-limit-compare',
   '-Wno-psabi',
   '-Wno-gnu-variable-sized-type-not-at-end',
+  '-Wshadow=local',
+  '-Wno-error=shadow=local',
+  '-Wno-error=shadow=compatible-local',
 ]
 
 if targetos != 'darwin'

You may want to drop the -Wno-error lines.

Subsystems with -Wshadow=local warnings:

virtio-gpu
virtio
Device Tree
Overall TCG CPUs
Overall Audio backends
Open Sound System (OSS) Audio backend
vhost
vhost-user-gpu
Cryptography
M68K TCG CPUs
Dump
ACPI/SMBIOS
Allwinner-a10
ARM TCG CPUs
MPS2
ASPEED BMCs
ARM SMMU
Virt
Machine core
PC Chipset
X86 TCG CPUs
PC
VT-d Emulation
IDE
ARM cores
OpenPIC interrupt controller
q800
petalogix_ml605
MicroBlaze TCG CPUs
Versatile PB
Network devices
NiosII TCG CPUs
nvme
PowerNV (Non-Virtualized)
sPAPR (pseries)
OpenTitan
RISC-V TCG CPUs
SCSI
USB
Linux user
Network packet abstractions
Network device backends
Network Block Device (NBD)
Semihosting
Memory API
Seccomp
Main loop
Hexagon TCG CPUs
X86 KVM CPUs
MIPS TCG CPUs
PowerPC TCG CPUs
TriCore TCG CPUs
Common TCG code
qtest
Throttling infrastructure
Vhost-user block device backend server

Files with -Wshadow=local warnings:

accel/tcg/tb-maint.c
audio/audio.c
audio/ossaudio.c
contrib/vhost-user-gpu/vhost-user-gpu.c
contrib/vhost-user-gpu/vugpu.h
crypto/cipher-gnutls.c.inc
crypto/tls-cipher-suites.c
disas/m68k.c
dump/dump.c
hw/acpi/cpu_hotplug.c
hw/arm/allwinner-r40.c
hw/arm/armsse.c
hw/arm/armv7m.c
hw/arm/aspeed_ast2600.c
hw/arm/smmuv3-internal.h
hw/arm/smmuv3.c
hw/arm/virt.c
hw/core/machine.c
hw/i2c/aspeed_i2c.c
hw/i2c/pm_smbus.c
hw/i386/acpi-build.c
hw/i386/acpi-microvm.c
hw/i386/intel_iommu.c
hw/i386/pc.c
hw/i386/x86.c
hw/ide/ahci.c
hw/intc/arm_gicv3_its.c
hw/intc/openpic.c
hw/loongarch/virt.c
hw/m68k/bootinfo.h
hw/microblaze/petalogix_ml605_mmu.c
hw/misc/arm_sysctl.c
hw/misc/aspeed_i3c.c
hw/net/vhost_net.c
hw/nios2/10m50_devboard.c
hw/nvme/ns.c
hw/ppc/pnv_psi.c
hw/ppc/spapr.c
hw/ppc/spapr_drc.c
hw/ppc/spapr_pci.c
hw/riscv/opentitan.c
hw/scsi/mptsas.c
hw/smbios/smbios.c
hw/usb/desc.c
hw/usb/dev-hub.c
hw/usb/dev-storage.c
hw/usb/hcd-xhci.c
hw/usb/host-libusb.c
hw/virtio/vhost.c
hw/virtio/virtio-pci.c
include/hw/cxl/cxl_device.h
include/hw/ppc/fdt.h
include/hw/virtio/virtio-gpu.h
include/sysemu/device_tree.h
linux-user/flatload.c
linux-user/mmap.c
linux-user/strace.c
linux-user/syscall.c
net/eth.c
qemu-nbd.c
semihosting/arm-compat-semi.c
softmmu/device_tree.c
softmmu/memory.c
softmmu/physmem.c
softmmu/qemu-seccomp.c
softmmu/vl.c
target/arm/tcg/mve_helper.c
target/arm/tcg/translate-m-nocp.c
target/hexagon/helper_funcs_generated.c.inc
target/hexagon/mmvec/macros.h
target/hexagon/op_helper.c
target/hexagon/translate.c
target/i386/cpu.c
target/i386/kvm/kvm.c
target/i386/tcg/seg_helper.c
target/i386/tcg/sysemu/svm_helper.c
target/i386/tcg/translate.c
target/m68k/translate.c
target/mips/tcg/msa_helper.c
target/mips/tcg/nanomips_translate.c.inc
target/mips/tcg/translate.c
target/ppc/int_helper.c
target/riscv/cpu.c
target/riscv/vector_helper.c
target/tricore/translate.c
tcg/tcg.c
tests/qtest/m48t59-test.c
tests/qtest/pflash-cfi02-test.c
tests/unit/test-throttle.c
util/vhost-user-server.c

Markus Armbruster (7):
  migration/rdma: Fix save_page method to fail on polling error
  migration: Clean up local variable shadowing
  ui: Clean up local variable shadowing
  block/dirty-bitmap: Clean up local variable shadowing
  block/vdi: Clean up local variable shadowing
  block: Clean up local variable shadowing
  qobject atomics osdep: Make a few macros more 

[PATCH 1/7] migration/rdma: Fix save_page method to fail on polling error

2023-08-31 Thread Markus Armbruster
qemu_rdma_save_page() reports polling error with error_report(), then
succeeds anyway.  This is because the variable holding the polling
status *shadows* the variable the function returns.  The latter
remains zero.

Broken since day one, and duplicated more recently.

Fixes: 2da776db4846 (rdma: core logic)
Fixes: b390afd8c50b (migration/rdma: Fix out of order wrid)
Signed-off-by: Markus Armbruster 
---
 migration/rdma.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/migration/rdma.c b/migration/rdma.c
index ca430d319d..b2e869aced 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -3281,7 +3281,8 @@ static size_t qemu_rdma_save_page(QEMUFile *f,
  */
 while (1) {
 uint64_t wr_id, wr_id_in;
-int ret = qemu_rdma_poll(rdma, rdma->recv_cq, _id_in, NULL);
+ret = qemu_rdma_poll(rdma, rdma->recv_cq, _id_in, NULL);
+
 if (ret < 0) {
 error_report("rdma migration: polling error! %d", ret);
 goto err;
@@ -3296,7 +3297,8 @@ static size_t qemu_rdma_save_page(QEMUFile *f,
 
 while (1) {
 uint64_t wr_id, wr_id_in;
-int ret = qemu_rdma_poll(rdma, rdma->send_cq, _id_in, NULL);
+ret = qemu_rdma_poll(rdma, rdma->send_cq, _id_in, NULL);
+
 if (ret < 0) {
 error_report("rdma migration: polling error! %d", ret);
 goto err;
-- 
2.41.0




[PATCH 3/7] ui: Clean up local variable shadowing

2023-08-31 Thread Markus Armbruster
Local variables shadowing other local variables or parameters make the
code needlessly hard to understand.  Tracked down with -Wshadow=local.
Clean up: delete inner declarations when they are actually redundant,
else rename variables.

Signed-off-by: Markus Armbruster 
---
 ui/gtk.c  | 14 +++---
 ui/spice-display.c|  9 +
 ui/vnc-palette.c  |  2 --
 ui/vnc.c  | 12 ++--
 ui/vnc-enc-zrle.c.inc |  9 -
 5 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/ui/gtk.c b/ui/gtk.c
index 8ba41c8f13..24c78df79e 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -930,8 +930,8 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
 GdkMonitor *monitor = gdk_display_get_monitor_at_window(dpy, win);
 GdkRectangle geometry;
 
-int x = (int)motion->x_root;
-int y = (int)motion->y_root;
+int xr = (int)motion->x_root;
+int yr = (int)motion->y_root;
 
 gdk_monitor_get_geometry(monitor, );
 
@@ -942,13 +942,13 @@ static gboolean gd_motion_event(GtkWidget *widget, 
GdkEventMotion *motion,
  * may still be only half way across the screen. Without
  * this warp, the server pointer would thus appear to hit
  * an invisible wall */
-if (x <= geometry.x || x - geometry.x >= geometry.width - 1 ||
-y <= geometry.y || y - geometry.y >= geometry.height - 1) {
+if (xr <= geometry.x || xr - geometry.x >= geometry.width - 1 ||
+yr <= geometry.y || yr - geometry.y >= geometry.height - 1) {
 GdkDevice *dev = gdk_event_get_device((GdkEvent *)motion);
-x = geometry.x + geometry.width / 2;
-y = geometry.y + geometry.height / 2;
+xr = geometry.x + geometry.width / 2;
+yr = geometry.y + geometry.height / 2;
 
-gdk_device_warp(dev, screen, x, y);
+gdk_device_warp(dev, screen, xr, yr);
 s->last_set = FALSE;
 return FALSE;
 }
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 3f3f8013d8..cbaba3bbad 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -1080,15 +1080,16 @@ static void qemu_spice_gl_update(DisplayChangeListener 
*dcl,
 }
 
 if (render_cursor) {
-int x, y;
+int ptr_x, ptr_y;
+
 qemu_mutex_lock(>lock);
-x = ssd->ptr_x;
-y = ssd->ptr_y;
+ptr_x = ssd->ptr_x;
+ptr_y = ssd->ptr_y;
 qemu_mutex_unlock(>lock);
 egl_texture_blit(ssd->gls, >blit_fb, >guest_fb,
  !y_0_top);
 egl_texture_blend(ssd->gls, >blit_fb, >cursor_fb,
-  !y_0_top, x, y, 1.0, 1.0);
+  !y_0_top, ptr_x, ptr_y, 1.0, 1.0);
 glFlush();
 }
 
diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c
index dc7c0ba997..4e88c412f0 100644
--- a/ui/vnc-palette.c
+++ b/ui/vnc-palette.c
@@ -86,8 +86,6 @@ int palette_put(VncPalette *palette, uint32_t color)
 return 0;
 }
 if (!entry) {
-VncPaletteEntry *entry;
-
 entry = >pool[palette->size];
 entry->color = color;
 entry->idx = idx;
diff --git a/ui/vnc.c b/ui/vnc.c
index 92964dcc0c..3e1fccffa3 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1584,15 +1584,15 @@ static void vnc_jobs_bh(void *opaque)
  */
 static int vnc_client_read(VncState *vs)
 {
-size_t ret;
+size_t sz;
 
 #ifdef CONFIG_VNC_SASL
 if (vs->sasl.conn && vs->sasl.runSSF)
-ret = vnc_client_read_sasl(vs);
+sz = vnc_client_read_sasl(vs);
 else
 #endif /* CONFIG_VNC_SASL */
-ret = vnc_client_read_plain(vs);
-if (!ret) {
+sz = vnc_client_read_plain(vs);
+if (!sz) {
 if (vs->disconnecting) {
 vnc_disconnect_finish(vs);
 return -1;
@@ -3118,8 +3118,8 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
 cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
 server_stride);
 if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
-int width = pixman_image_get_width(vd->server);
-tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
+int w = pixman_image_get_width(vd->server);
+tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, w);
 } else {
 int guest_bpp =
 PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
diff --git a/ui/vnc-enc-zrle.c.inc b/ui/vnc-enc-zrle.c.inc
index c107d8affc..edf42d4a6a 100644
--- a/ui/vnc-enc-zrle.c.inc
+++ b/ui/vnc-enc-zrle.c.inc
@@ -153,11 +153,12 @@ static void ZRLE_ENCODE_TILE(VncState *vs, ZRLE_PIXEL 
*data, int w, int h,
 }
 
 if (use_rle) {
-ZRLE_PIXEL *ptr = data;
-ZRLE_PIXEL *end = ptr + w * h;
 ZRLE_PIXEL *run_start;
 ZRLE_PIXEL pix;
 
+   ptr = data;
+end = ptr + w * h;
+
 while (ptr < end) {
 int len;
 int index = 0;
@@ -198,7 

[PATCH 2/7] migration: Clean up local variable shadowing

2023-08-31 Thread Markus Armbruster
Local variables shadowing other local variables or parameters make the
code needlessly hard to understand.  Tracked down with -Wshadow=local.
Clean up: delete inner declarations when they are actually redundant,
else rename variables.

Signed-off-by: Markus Armbruster 
---
 migration/block.c   | 4 ++--
 migration/ram.c | 8 +++-
 migration/rdma.c| 8 +---
 migration/vmstate.c | 2 +-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/migration/block.c b/migration/block.c
index b9580a6c7e..33b3776198 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -438,8 +438,8 @@ static int init_blk_migration(QEMUFile *f)
 /* Can only insert new BDSes now because doing so while iterating block
  * devices may end up in a deadlock (iterating the new BDSes, too). */
 for (i = 0; i < num_bs; i++) {
-BlkMigDevState *bmds = bmds_bs[i].bmds;
-BlockDriverState *bs = bmds_bs[i].bs;
+bmds = bmds_bs[i].bmds;
+bs = bmds_bs[i].bs;
 
 if (bmds) {
 ret = blk_insert_bs(bmds->blk, bs, _err);
diff --git a/migration/ram.c b/migration/ram.c
index 9040d66e61..0c202f8109 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -3517,8 +3517,6 @@ int colo_init_ram_cache(void)
 * we use the same name 'ram_bitmap' as for migration.
 */
 if (ram_bytes_total()) {
-RAMBlock *block;
-
 RAMBLOCK_FOREACH_NOT_IGNORED(block) {
 unsigned long pages = block->max_length >> TARGET_PAGE_BITS;
 block->bmap = bitmap_new(pages);
@@ -3998,12 +3996,12 @@ static int ram_load_precopy(QEMUFile *f)
 }
 }
 if (migrate_ignore_shared()) {
-hwaddr addr = qemu_get_be64(f);
+hwaddr addr2 = qemu_get_be64(f);
 if (migrate_ram_is_ignored(block) &&
-block->mr->addr != addr) {
+block->mr->addr != addr2) {
 error_report("Mismatched GPAs for block %s "
  "%" PRId64 "!= %" PRId64,
- id, (uint64_t)addr,
+ id, (uint64_t)addr2,
  (uint64_t)block->mr->addr);
 ret = -EINVAL;
 }
diff --git a/migration/rdma.c b/migration/rdma.c
index b2e869aced..c6400cf641 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -1902,9 +1902,11 @@ static int qemu_rdma_exchange_send(RDMAContext *rdma, 
RDMAControlHeader *head,
  * by waiting for a READY message.
  */
 if (rdma->control_ready_expected) {
-RDMAControlHeader resp;
-ret = qemu_rdma_exchange_get_response(rdma,
-, RDMA_CONTROL_READY, 
RDMA_WRID_READY);
+RDMAControlHeader resp_ignored;
+
+ret = qemu_rdma_exchange_get_response(rdma, _ignored,
+  RDMA_CONTROL_READY,
+  RDMA_WRID_READY);
 if (ret < 0) {
 return ret;
 }
diff --git a/migration/vmstate.c b/migration/vmstate.c
index 31842c3afb..438ea77cfa 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -97,7 +97,7 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription 
*vmsd,
 return -EINVAL;
 }
 if (vmsd->pre_load) {
-int ret = vmsd->pre_load(opaque);
+ret = vmsd->pre_load(opaque);
 if (ret) {
 return ret;
 }
-- 
2.41.0




[PATCH 7/7] qobject atomics osdep: Make a few macros more hygienic

2023-08-31 Thread Markus Armbruster
Variables declared in macros can shadow other variables.  Much of the
time, this is harmless, e.g.:

#define _FDT(exp)  \
do {   \
int ret = (exp);   \
if (ret < 0) { \
error_report("error creating device tree: %s: %s",   \
#exp, fdt_strerror(ret));  \
exit(1);   \
}  \
} while (0)

Harmless shadowing in h_client_architecture_support():

target_ulong ret;

[...]

ret = do_client_architecture_support(cpu, spapr, vec, fdt_bufsize);
if (ret == H_SUCCESS) {
_FDT((fdt_pack(spapr->fdt_blob)));
[...]
}

return ret;

However, we can get in trouble when the shadowed variable is used in a
macro argument:

#define QOBJECT(obj) ({ \
typeof(obj) o = (obj);  \
o ? container_of(&(o)->base, QObject, base) : NULL; \
 })

QOBJECT(o) expands into

({
--->typeof(o) o = (o);
o ? container_of(&(o)->base, QObject, base) : NULL;
})

Unintended variable name capture at --->.  We'd be saved by
-Winit-self.  But I could certainly construct more elaborate death
traps that don't trigger it.

To reduce the risk of trapping ourselves, we use variable names in
macros that no sane person would use elsewhere.  Here's our actual
definition of QOBJECT():

#define QOBJECT(obj) ({ \
typeof(obj) _obj = (obj);   \
_obj ? container_of(&(_obj)->base, QObject, base) : NULL;   \
})

Works well enough until we nest macro calls.  For instance, with

#define qobject_ref(obj) ({ \
typeof(obj) _obj = (obj);   \
qobject_ref_impl(QOBJECT(_obj));\
_obj;   \
})

the expression qobject_ref(obj) expands into

({
typeof(obj) _obj = (obj);
qobject_ref_impl(
({
--->typeof(_obj) _obj = (_obj);
_obj ? container_of(&(_obj)->base, QObject, base) : NULL;
}));
_obj;
})

Unintended variable name capture at --->.

The only reliable way to prevent unintended variable name capture is
-Wshadow.

One blocker for enabling it is shadowing hiding in function-like
macros like

 qdict_put(dict, "name", qobject_ref(...))

qdict_put() wraps its last argument in QOBJECT(), and the last
argument here contains another QOBJECT().

Use dark preprocessor sorcery to make the macros that give us this
problem use different variable names on every call.

Signed-off-by: Markus Armbruster 
---
 include/qapi/qmp/qobject.h |  8 +---
 include/qemu/atomic.h  | 11 ++-
 include/qemu/osdep.h   | 34 +++---
 3 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h
index 9003b71fd3..7b50fc905d 100644
--- a/include/qapi/qmp/qobject.h
+++ b/include/qapi/qmp/qobject.h
@@ -45,10 +45,12 @@ struct QObject {
 struct QObjectBase_ base;
 };
 
-#define QOBJECT(obj) ({ \
-typeof(obj) _obj = (obj);   \
-_obj ? container_of(&(_obj)->base, QObject, base) : NULL;   \
+#define QOBJECT_INTERNAL(obj, l) ({ \
+typeof(obj) PASTE(_obj, l) = (obj); \
+PASTE(_obj, l)  \
+? container_of(&(PASTE(_obj, l))->base, QObject, base) : NULL;  \
 })
+#define QOBJECT(obj) QOBJECT_INTERNAL((obj), __COUNTER__)
 
 /* Required for qobject_to() */
 #define QTYPE_CAST_TO_QNull QTYPE_QNULL
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index d95612f7a0..3f80ffac69 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -157,13 +157,14 @@
 smp_read_barrier_depends();
 #endif
 
-#define qatomic_rcu_read(ptr)  \
-({ \
+#define qatomic_rcu_read_internal(ptr, l)   \
+({  \
 qemu_build_assert(sizeof(*ptr) <= ATOMIC_REG_SIZE); \
-typeof_strip_qual(*ptr) _val;  \
-qatomic_rcu_read__nocheck(ptr, &_val); \
-_val;  \
+typeof_strip_qual(*ptr) PASTE(_val, l); \
+qatomic_rcu_read__nocheck(ptr, (_val, l));\
+PASTE(_val, l); \
 })

Re: [PATCH v3 2/2] xen: move arm/include/asm/vm_event.h to asm-generic

2023-08-31 Thread Oleksii
On Thu, 2023-08-31 at 11:46 +0200, Jan Beulich wrote:
> On 30.08.2023 18:57, Oleksii Kurochko wrote:
> > asm/vm_event.h is common for ARM and RISC-V so it will be moved to
> > asm-generic dir.
> > 
> > Original asm/vm_event.h from ARM was updated:
> >  * use SPDX-License-Identifier.
> >  * update comment messages of stubs.
> >  * update #ifdef.
> >  * change public/domctl.h to public/vm_event.h.
> > 
> > Signed-off-by: Oleksii Kurochko 
> > Acked-by: Stefano Stabellini 
> > ---
> > Changes in V3:
> >  - add Acked-by: Stefano Stabellini  for
> > "xen: move arm/include/asm/vm_event.h to asm-generic"
> >  - update SPDX tag.
> >  - move asm/vm_event.h to asm-generic.
> > ---
> > Changes in V2:
> >  - change public/domctl.h to public/vm_event.h.
> >  - update commit message of [PATCH v2 2/2] xen: move
> > arm/include/asm/vm_event.h to stubs
> > ---
> >  xen/arch/arm/include/asm/vm_event.h    | 66 --
> > 
> >  xen/include/asm-generic/asm/vm_event.h | 55 +
> >  2 files changed, 55 insertions(+), 66 deletions(-)
> >  delete mode 100644 xen/arch/arm/include/asm/vm_event.h
> >  create mode 100644 xen/include/asm-generic/asm/vm_event.h
> 
> While it's a comment on the first patch, it's really better making
> here:
> Did you look at Linux? They don't put an intermediate asm/ here.
> Instead
> see their scripts/Makefile.asm-generic. That way an arch still has
> control which generic headers it gets access to, without duplicating
> any
> of them.
Thanks. I'll look at the script.

~ Oleksii




Re: [XEN PATCH 09/13] xen/common: address violations of MISRA C:2012 Directive 4.10

2023-08-31 Thread Jan Beulich
On 31.08.2023 14:54, Simone Ballarin wrote:
> On 31/08/23 13:10, Jan Beulich wrote:
>> On 31.08.2023 12:08, Simone Ballarin wrote:
>>> The danger of multi-inclusion also exists for .c files, why do you want
>>> to avoid guards for them?
>>
>> Counter question: Why only add guards to some of them? (My personal
>> answer is "Because it's extra clutter.")
> 
> It's not "some of them", it's exactly the ones used in an #include 
> directive, so I'm not getting your objection.

My point is that by adding guards only for files we presently use in some
#include directive, we set us up for introducing new violations as soon
as another .c file becomes the subject of an #include. The more that it
is unusual to add guards in .c files, i.e. it is to be expected that
people wouldn't think about this extra Misra requirement.

Jan




[PULL 31/41] hw/usb: spelling fixes

2023-08-31 Thread Philippe Mathieu-Daudé
From: Michael Tokarev 

Signed-off-by: Michael Tokarev 
Message-ID: <20230823065335.1919380-14-...@tls.msk.ru>
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/usb/quirks.h | 2 +-
 hw/usb/ccid-card-emulated.c | 2 +-
 hw/usb/hcd-ehci.c   | 6 +++---
 hw/usb/hcd-ohci.c   | 2 +-
 hw/usb/redirect.c   | 2 +-
 hw/usb/xen-usb.c| 2 +-
 hw/usb/trace-events | 2 +-
 7 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/hw/usb/quirks.h b/hw/usb/quirks.h
index c3e595f40b..94b2c95341 100644
--- a/hw/usb/quirks.h
+++ b/hw/usb/quirks.h
@@ -67,7 +67,7 @@ static const struct usb_device_id usbredir_raw_serial_ids[] = 
{
 { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
 { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
 { USB_DEVICE(0x10C4, 0x8044) }, /* Cygnal Debug Adapter */
-{ USB_DEVICE(0x10C4, 0x804E) }, /* Software Bisque Paramount ME build-in 
converter */
+{ USB_DEVICE(0x10C4, 0x804E) }, /* Software Bisque Paramount ME built-in 
converter */
 { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
 { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */
 { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c
index c328660075..3ee9c73b87 100644
--- a/hw/usb/ccid-card-emulated.c
+++ b/hw/usb/ccid-card-emulated.c
@@ -518,7 +518,7 @@ static void emulated_realize(CCIDCardState *base, Error 
**errp)
 goto out2;
 }
 
-/* TODO: a passthru backened that works on local machine. third card 
type?*/
+/* TODO: a passthru backend that works on local machine. third card type?*/
 if (card->backend == BACKEND_CERTIFICATES) {
 if (card->cert1 != NULL && card->cert2 != NULL && card->cert3 != NULL) 
{
 ret = emulated_initialize_vcard_from_certificates(card);
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index c930c60921..19b4534c20 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -1464,7 +1464,7 @@ static int ehci_process_itd(EHCIState *ehci,
 usb_handle_packet(dev, >ipacket);
 usb_packet_unmap(>ipacket, >isgl);
 } else {
-DPRINTF("ISOCH: attempt to addess non-iso endpoint\n");
+DPRINTF("ISOCH: attempt to address non-iso endpoint\n");
 ehci->ipacket.status = USB_RET_NAK;
 ehci->ipacket.actual_length = 0;
 }
@@ -1513,7 +1513,7 @@ static int ehci_process_itd(EHCIState *ehci,
 
 
 /*  This state is the entry point for asynchronous schedule
- *  processing.  Entry here consitutes a EHCI start event state (4.8.5)
+ *  processing.  Entry here constitutes a EHCI start event state (4.8.5)
  */
 static int ehci_state_waitlisthead(EHCIState *ehci,  int async)
 {
@@ -2458,7 +2458,7 @@ static void usb_ehci_vm_state_change(void *opaque, bool 
running, RunState state)
 /*
  * The schedule rebuilt from guest memory could cause the migration dest
  * to miss a QH unlink, and fail to cancel packets, since the unlinked QH
- * will never have existed on the destination. Therefor we must flush the
+ * will never have existed on the destination. Therefore we must flush the
  * async schedule on savevm to catch any not yet noticed unlinks.
  */
 if (state == RUN_STATE_SAVE_VM) {
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index cc5cde6983..7ff1b65ced 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1355,7 +1355,7 @@ static uint32_t ohci_get_frame_remaining(OHCIState *ohci)
 if ((ohci->ctl & OHCI_CTL_HCFS) != OHCI_USB_OPERATIONAL) {
 return ohci->frt << 31;
 }
-/* Being in USB operational state guarnatees sof_time was set already. */
+/* Being in USB operational state guarantees sof_time was set already. */
 tks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - ohci->sof_time;
 if (tks < 0) {
 tks = 0;
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 4bbf8afb33..c9893df867 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -471,7 +471,7 @@ static int bufp_alloc(USBRedirDevice *dev, uint8_t *data, 
uint16_t len,
 DPRINTF("bufpq overflow, dropping packets ep %02X\n", ep);
 dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 1;
 }
-/* Since we're interupting the stream anyways, drop enough packets to get
+/* Since we're interrupting the stream anyways, drop enough packets to get
back to our target buffer size */
 if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {
 if (dev->endpoint[EP2I(ep)].bufpq_size >
diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c
index 38ee660a30..09ec326aea 100644
--- a/hw/usb/xen-usb.c
+++ b/hw/usb/xen-usb.c
@@ -451,7 +451,7 @@ static int usbback_check_and_submit(struct usbback_req 
*usbback_req)
 wValue = le16_to_cpu(ctrl->wValue);
 
 /*
- * When the device is first 

[PULL 04/41] bulk: Do not declare function prototypes using 'extern' keyword

2023-08-31 Thread Philippe Mathieu-Daudé
By default, C function prototypes declared in headers are visible,
so there is no need to declare them as 'extern' functions.
Remove this redundancy in a single bulk commit; do not modify:

  - meson.build (used to check function availability at runtime)
  - pc-bios/
  - libdecnumber/
  - tests/
  - *.c

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Peter Maydell 
Message-Id: <20230605175647.88395-5-phi...@linaro.org>
---
 bsd-user/bsd-file.h|  6 ++---
 crypto/hmacpriv.h  | 13 +--
 hw/xen/xen_pt.h|  8 +++
 include/crypto/secret_common.h | 14 +---
 include/exec/page-vary.h   |  4 ++--
 include/hw/misc/aspeed_scu.h   |  2 +-
 include/hw/nvram/npcm7xx_otp.h |  4 ++--
 include/hw/qdev-core.h |  4 ++--
 include/qemu/crc-ccitt.h   |  4 ++--
 include/qemu/osdep.h   |  4 ++--
 include/qemu/rcu.h | 14 ++--
 include/qemu/sys_membarrier.h  |  4 ++--
 include/qemu/uri.h |  6 ++---
 include/sysemu/accel-blocker.h | 14 ++--
 include/sysemu/os-win32.h  |  4 ++--
 include/user/safe-syscall.h|  4 ++--
 target/i386/sev.h  |  6 ++---
 target/mips/cpu.h  |  4 ++--
 tcg/tcg-internal.h |  4 ++--
 include/exec/memory_ldst.h.inc | 42 +-
 20 files changed, 79 insertions(+), 86 deletions(-)

diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h
index 588e0c50d4..3c00dc0056 100644
--- a/bsd-user/bsd-file.h
+++ b/bsd-user/bsd-file.h
@@ -51,10 +51,8 @@ do {\
 unlock_user(p1, arg1, 0);   \
 } while (0)
 
-extern struct iovec *lock_iovec(int type, abi_ulong target_addr, int count,
-int copy);
-extern void unlock_iovec(struct iovec *vec, abi_ulong target_addr, int count,
-int copy);
+struct iovec *lock_iovec(int type, abi_ulong target_addr, int count, int copy);
+void unlock_iovec(struct iovec *vec, abi_ulong target_addr, int count, int 
copy);
 
 int safe_open(const char *path, int flags, mode_t mode);
 int safe_openat(int fd, const char *path, int flags, mode_t mode);
diff --git a/crypto/hmacpriv.h b/crypto/hmacpriv.h
index 4387ca2587..62dfe8257a 100644
--- a/crypto/hmacpriv.h
+++ b/crypto/hmacpriv.h
@@ -28,19 +28,18 @@ struct QCryptoHmacDriver {
 void (*hmac_free)(QCryptoHmac *hmac);
 };
 
-extern void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
-  const uint8_t *key, size_t nkey,
-  Error **errp);
+void *qcrypto_hmac_ctx_new(QCryptoHashAlgorithm alg,
+   const uint8_t *key, size_t nkey,
+   Error **errp);
 extern QCryptoHmacDriver qcrypto_hmac_lib_driver;
 
 #ifdef CONFIG_AF_ALG
 
 #include "afalgpriv.h"
 
-extern QCryptoAFAlg *
-qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg,
-   const uint8_t *key, size_t nkey,
-   Error **errp);
+QCryptoAFAlg *qcrypto_afalg_hmac_ctx_new(QCryptoHashAlgorithm alg,
+ const uint8_t *key, size_t nkey,
+ Error **errp);
 extern QCryptoHmacDriver qcrypto_hmac_afalg_driver;
 
 #endif
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index b20744f7c7..31bcfdf705 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -340,11 +340,9 @@ static inline bool 
xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar)
 return s->msix && s->msix->bar_index == bar;
 }
 
-extern void *pci_assign_dev_load_option_rom(PCIDevice *dev,
-int *size,
-unsigned int domain,
-unsigned int bus, unsigned int 
slot,
-unsigned int function);
+void *pci_assign_dev_load_option_rom(PCIDevice *dev, int *size,
+ unsigned int domain, unsigned int bus,
+ unsigned int slot, unsigned int function);
 static inline bool is_igd_vga_passthrough(XenHostPCIDevice *dev)
 {
 return (xen_igd_gfx_pt_enabled()
diff --git a/include/crypto/secret_common.h b/include/crypto/secret_common.h
index 42c7ff7af6..a0a22e1abd 100644
--- a/include/crypto/secret_common.h
+++ b/include/crypto/secret_common.h
@@ -48,13 +48,11 @@ struct QCryptoSecretCommonClass {
 };
 
 
-extern int qcrypto_secret_lookup(const char *secretid,
- uint8_t **data,
- size_t *datalen,
- Error **errp);
-extern char *qcrypto_secret_lookup_as_utf8(const char *secretid,
-   Error **errp);
-extern char *qcrypto_secret_lookup_as_base64(const char *secretid,
- Error **errp);
+int qcrypto_secret_lookup(const char *secretid,
+  

Re: [XEN PATCH 09/13] xen/common: address violations of MISRA C:2012 Directive 4.10

2023-08-31 Thread Simone Ballarin

On 31/08/23 13:10, Jan Beulich wrote:

On 31.08.2023 12:08, Simone Ballarin wrote:

On 29/08/23 08:50, Jan Beulich wrote:

On 28.08.2023 15:20, Simone Ballarin wrote:

Add inclusion guards to address violations of
MISRA C:2012 Directive 4.10 ("Precautions shall be taken in order
to prevent the contents of a header file being included more than
once").

Also C files, if included somewhere, need to comply with the guideline.

Mechanical change.

Signed-off-by: Simone Ballarin 
---
   xen/common/compat/grant_table.c | 7 +++
   xen/common/coverage/gcc_4_7.c   | 5 +
   xen/common/decompress.h | 5 +
   xen/common/event_channel.h  | 5 +
   xen/common/multicall.c  | 5 +
   5 files changed, 27 insertions(+)


As already said in reply to another patch, imo .c files shouldn't gain such
guards. These are commonly referred to as "header guards" for a reason.



This is the MISRA's definition of "header file" (MISRA C:2012 Revision
1, Appendix J):

"A header file is any file that is the subject of a #include
 directive.
 Note: the filename extension is not significant."


That's completely misleading terminology then.



I might agree with you on this, but either way this is the definition to 
apply when reading the guideline. IMHO here, the best would be to use a 
separate extension for "C files intended to be included" (but that's not 
the point).



So, the guards are required if we want to comply with the directive,
otherwise we can raise a deviation.

The danger of multi-inclusion also exists for .c files, why do you want
to avoid guards for them?


Counter question: Why only add guards to some of them? (My personal
answer is "Because it's extra clutter.")

Jan



It's not "some of them", it's exactly the ones used in an #include 
directive, so I'm not getting your objection.


By the way, if the community agrees, I can deviate all C files and
drop the changes.

--
Simone Ballarin, M.Sc.

Field Application Engineer, BUGSENG (https://bugseng.com)




Re: [PATCH v7 9/9] swiotlb: search the software IO TLB only if the device makes use of it

2023-08-31 Thread Christoph Hellwig
On Wed, Aug 09, 2023 at 03:20:43PM -0600, Jonathan Corbet wrote:
> > spin_unlock_irqrestore(>dma_io_tlb_lock, flags);
> >  
> > -   /* Pairs with smp_rmb() in swiotlb_find_pool(). */
> > -   smp_wmb();
> >  found:
> > +   dev->dma_uses_io_tlb = true;
> > +   /* Pairs with smp_rmb() in is_swiotlb_buffer() */
> > +   smp_wmb();
> > +
> 
> ...and here you set it if swiotlb is used.
> 
> But, as far as I can tell, you don't actually *use* this field anywhere.
> What am I missing?

It's very much unused.  Petr, I guess you wanted to use this in
is_swiotlb_buffer to avoid the lookup unless required.  Can you send
a follow up?



Re: [XEN PATCH 12/13] xen: address violations of MISRA C:2012 Directive 4.10

2023-08-31 Thread Jan Beulich
On 31.08.2023 14:18, Simone Ballarin wrote:
> On 29/08/23 00:51, Stefano Stabellini wrote:
>> On Mon, 28 Aug 2023, Simone Ballarin wrote:
>>> Move or amended inclusion guards to address violations of
>>> MISRA C:2012 Directive 4.10 ("Precautions shall be taken in order
>>> to prevent the contents of a header file being included more than
>>> once").
>>>
>>> Inclusion guards must appear at the beginning of the headers
>>> (comments are permitted anywhere) and the #if directive cannot
>>> be used for other checks.
>>>
>>> Mechanical change.
>>>
>>> Signed-off-by: Simone Ballarin 
>>> ---
>>>   xen/include/xen/err.h   | 4 +++-
>>>   xen/include/xen/pci_ids.h   | 5 +
>>>   xen/include/xen/softirq.h   | 4 +++-
>>>   xen/include/xen/unaligned.h | 7 ---
>>>   xen/include/xen/vmap.h  | 4 +++-
>>>   5 files changed, 18 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/xen/include/xen/err.h b/xen/include/xen/err.h
>>> index 2f29b57d28..a6323d82d7 100644
>>> --- a/xen/include/xen/err.h
>>> +++ b/xen/include/xen/err.h
>>> @@ -1,5 +1,6 @@
>>> -#if !defined(__XEN_ERR_H__) && !defined(__ASSEMBLY__)
>>> +#if !defined(__XEN_ERR_H__)
>>>   #define __XEN_ERR_H__
>>> +#if !defined(__ASSEMBLY__)
>>
>> The original pattern was also guarding the header file sufficiently,
>> protecting it from double-inclusion. In fact, it is posing stricter
>> restrictions than usual (not laxer). This change is unnecessary?
> 
> The MISRA directive asks to use one of the two following forms:
> 
> 
> #if !defined ( identifier )
> #define identifier
> /* Contents of file */
> #endif
> 
> 
> 
> #ifndef identifier
> #define identifier
> /* Contents of file */
> #endif
> 
> 
> I do not see any reason for deviating, but if you ask that, I can do it.

I do not see a reason why a deviation would be needed here. Misra shouldn't
be more pedantic / restrictive than necessary to achieve its goals. Looking
at the flood of changes we've already seen, pointless changes really
shouldn't be asked for.

Jan



Re: [XEN PATCH 12/13] xen: address violations of MISRA C:2012 Directive 4.10

2023-08-31 Thread Simone Ballarin

On 29/08/23 00:51, Stefano Stabellini wrote:

On Mon, 28 Aug 2023, Simone Ballarin wrote:

Move or amended inclusion guards to address violations of
MISRA C:2012 Directive 4.10 ("Precautions shall be taken in order
to prevent the contents of a header file being included more than
once").

Inclusion guards must appear at the beginning of the headers
(comments are permitted anywhere) and the #if directive cannot
be used for other checks.

Mechanical change.

Signed-off-by: Simone Ballarin 
---
  xen/include/xen/err.h   | 4 +++-
  xen/include/xen/pci_ids.h   | 5 +
  xen/include/xen/softirq.h   | 4 +++-
  xen/include/xen/unaligned.h | 7 ---
  xen/include/xen/vmap.h  | 4 +++-
  5 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/xen/include/xen/err.h b/xen/include/xen/err.h
index 2f29b57d28..a6323d82d7 100644
--- a/xen/include/xen/err.h
+++ b/xen/include/xen/err.h
@@ -1,5 +1,6 @@
-#if !defined(__XEN_ERR_H__) && !defined(__ASSEMBLY__)
+#if !defined(__XEN_ERR_H__)
  #define __XEN_ERR_H__
+#if !defined(__ASSEMBLY__)


The original pattern was also guarding the header file sufficiently,
protecting it from double-inclusion. In fact, it is posing stricter
restrictions than usual (not laxer). This change is unnecessary?


The MISRA directive asks to use one of the two following forms:


#if !defined ( identifier )
#define identifier
/* Contents of file */
#endif



#ifndef identifier
#define identifier
/* Contents of file */
#endif


I do not see any reason for deviating, but if you ask that, I can do it.





  #include 
  #include 
@@ -54,4 +55,5 @@ static inline int __must_check PTR_RET(const void *ptr)
return IS_ERR(ptr) ? PTR_ERR(ptr) : 0;
  }
  
+#endif /* __ASSEMBLY__ */

  #endif /* __XEN_ERR_H__ */
diff --git a/xen/include/xen/pci_ids.h b/xen/include/xen/pci_ids.h
index e798477a7e..1a739d4c92 100644
--- a/xen/include/xen/pci_ids.h
+++ b/xen/include/xen/pci_ids.h
@@ -1,3 +1,6 @@
+#ifndef __XEN_PCI_IDS_H__
+#define __XEN_PCI_IDS_H__
+
  #define PCI_VENDOR_ID_AMD0x1022
  
  #define PCI_VENDOR_ID_NVIDIA 0x10de

@@ -11,3 +14,5 @@
  #define PCI_VENDOR_ID_BROADCOM   0x14e4
  
  #define PCI_VENDOR_ID_INTEL  0x8086

+
+#endif /* __XEN_PCI_IDS_H__ */
diff --git a/xen/include/xen/softirq.h b/xen/include/xen/softirq.h
index 33d6f2ecd2..092ec733b7 100644
--- a/xen/include/xen/softirq.h
+++ b/xen/include/xen/softirq.h
@@ -1,5 +1,6 @@
-#if !defined(__XEN_SOFTIRQ_H__) && !defined(__ASSEMBLY__)
+#if !defined(__XEN_SOFTIRQ_H__)
  #define __XEN_SOFTIRQ_H__
+#if !defined(__ASSEMBLY__)


same here



  /* Low-latency softirqs come first in the following list. */
  enum {
@@ -40,4 +41,5 @@ void cpu_raise_softirq_batch_finish(void);
   */
  void process_pending_softirqs(void);
  
+#endif /* __ASSEMBLY__ */

  #endif /* __XEN_SOFTIRQ_H__ */
diff --git a/xen/include/xen/unaligned.h b/xen/include/xen/unaligned.h
index 0a2b16d05d..45f03b3f1b 100644
--- a/xen/include/xen/unaligned.h
+++ b/xen/include/xen/unaligned.h
@@ -3,13 +3,14 @@
   * without faulting, and at least reasonably efficiently.  Other architectures
   * will need to have a custom asm/unaligned.h.
   */
-#ifndef __ASM_UNALIGNED_H__
-#error "xen/unaligned.h should not be included directly - include asm/unaligned.h 
instead"
-#endif
  
  #ifndef __XEN_UNALIGNED_H__

  #define __XEN_UNALIGNED_H__
  
+#ifndef __ASM_UNALIGNED_H__

+#error "xen/unaligned.h should not be included directly - include asm/unaligned.h 
instead"
+#endif
+
  #ifdef __XEN__
  #include 
  #include 
diff --git a/xen/include/xen/vmap.h b/xen/include/xen/vmap.h
index b0f7632e89..7a61dea54a 100644
--- a/xen/include/xen/vmap.h
+++ b/xen/include/xen/vmap.h
@@ -1,5 +1,6 @@
-#if !defined(__XEN_VMAP_H__) && defined(VMAP_VIRT_START)
+#if !defined(__XEN_VMAP_H__)
  #define __XEN_VMAP_H__
+#if defined(VMAP_VIRT_START)


same here



  #include 
  #include 
@@ -38,4 +39,5 @@ static inline void vm_init(void)
  vm_init_type(VMAP_DEFAULT, (void *)VMAP_VIRT_START, arch_vmap_virt_end());
  }
  
+#endif /* VMAP_VIRT_START */

  #endif /* __XEN_VMAP_H__ */
--
2.34.1





--
Simone Ballarin, M.Sc.

Field Application Engineer, BUGSENG (https://bugseng.com)




Re: [PATCH v4 6/6] xen/vpci: header: filter PCI capabilities

2023-08-31 Thread Jan Beulich
On 28.08.2023 19:56, Stewart Hildebrand wrote:
> Currently, Xen vPCI only supports virtualizing the MSI and MSI-X capabilities.
> Hide all other PCI capabilities (including extended capabilities) from domUs 
> for
> now, even though there may be certain devices/drivers that depend on being 
> able
> to discover certain capabilities.
> 
> We parse the physical PCI capabilities linked list and add vPCI register
> handlers for the next elements, inserting our own next value, thus presenting 
> a
> modified linked list to the domU.
> 
> Introduce helper functions vpci_hw_read8 and vpci_read_val. The vpci_read_val
> helper function returns a fixed value, which may be used for RAZ registers, or
> registers whose value doesn't change.
> 
> Introduce pci_find_next_cap_ttl() helper while adapting the logic from
> pci_find_next_cap() to suit our needs, and implement the existing
> pci_find_next_cap() in terms of the new helper.
> 
> Signed-off-by: Stewart Hildebrand 

Reviewed-by: Jan Beulich 

Nevertheless a couple of remarks:

> --- a/xen/drivers/pci/pci.c
> +++ b/xen/drivers/pci/pci.c
> @@ -39,31 +39,44 @@ unsigned int pci_find_cap_offset(pci_sbdf_t sbdf, 
> unsigned int cap)
>  return 0;
>  }
>  
> -unsigned int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos,
> -   unsigned int cap)
> +unsigned int pci_find_next_cap_ttl(pci_sbdf_t sbdf, unsigned int pos,
> +   bool (*is_match)(unsigned int, unsigned 
> int),
> +   unsigned int userdata, unsigned int *ttl)
>  {
> -u8 id;
> -int ttl = 48;
> +unsigned int id;
>  
> -while ( ttl-- )
> +while ( (*ttl)-- )
>  {
>  pos = pci_conf_read8(sbdf, pos);
>  if ( pos < 0x40 )
>  break;
>  
> -pos &= ~3;
> -id = pci_conf_read8(sbdf, pos + PCI_CAP_LIST_ID);
> +id = pci_conf_read8(sbdf, (pos & ~3) + PCI_CAP_LIST_ID);
>  
>  if ( id == 0xff )
>  break;
> -if ( id == cap )
> +if ( is_match(id, userdata) )
>  return pos;
>  
> -pos += PCI_CAP_LIST_NEXT;
> +pos = (pos & ~3) + PCI_CAP_LIST_NEXT;
>  }
> +
>  return 0;
>  }
>  
> +static bool cf_check is_cap_match(unsigned int id1, unsigned int id2)
> +{
> +return id1 == id2;
> +}

Personally I would have preferred to get away without yet another hook
function here, by ...

> +unsigned int pci_find_next_cap(pci_sbdf_t sbdf, unsigned int pos,
> +   unsigned int cap)
> +{
> +unsigned int ttl = 48;
> +
> +return pci_find_next_cap_ttl(sbdf, pos, is_cap_match, cap, ) & ~3;

... passing NULL here and then suitably handling the case in that
common helper.

> @@ -561,6 +573,71 @@ static int cf_check init_bars(struct pci_dev *pdev)
>  if ( rc )
>  return rc;
>  
> +if ( !is_hardware_domain(pdev->domain) )
> +{
> +if ( !(pci_conf_read16(pdev->sbdf, PCI_STATUS) & 
> PCI_STATUS_CAP_LIST) )
> +{
> +/* RAZ/WI */
> +rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
> +   PCI_CAPABILITY_LIST, 1, (void *)0);
> +if ( rc )
> +return rc;
> +}
> +else
> +{
> +/* Only expose capabilities to the guest that vPCI can handle. */
> +uint8_t next;

If this was "unsigned long", ...

> +unsigned int ttl = 48;
> +
> +next = pci_find_next_cap_ttl(pdev->sbdf, PCI_CAPABILITY_LIST,
> + vpci_cap_supported, 0, );
> +
> +rc = vpci_add_register(pdev->vpci, vpci_read_val, NULL,
> +   PCI_CAPABILITY_LIST, 1,
> +   (void *)(uintptr_t)next);

... you'd avoid the need for the double cast here and again below. Yet
then I realize that Misra would take offence at us doing so ...

Jan



Re: [RFC PATCH v4 5/6] xen/vpci: support ro mask

2023-08-31 Thread Jan Beulich
On 28.08.2023 19:56, Stewart Hildebrand wrote:
> Add support for a read-only bit mask for vPCI register handlers.
> 
> Signed-off-by: Stewart Hildebrand 
> ---
> v3->v4:
> * new patch
> 
> RFC: It seemed like a low-hanging fruit to add support for ro mask. Let me 
> know
>  what you think, and I could squash it into the status handler patch for 
> the
>  next version of the series.

I'd be fine having both in one go, fwiw.

Jan



Re: QEMU features useful for Xen development?

2023-08-31 Thread Peter Maydell
On Thu, 31 Aug 2023 at 11:49, Alex Bennée  wrote:
> Peter Maydell  writes:
> > All our MPS2/MPS3 boards are M-profile. That means we have the
> > device models for all the interesting devices on the board, but
> > it would be simpler to write the an536 board model separately.
> > (In particular, the M-profile boards are wrappers around an
> > "ARMSSE" sort-of-like-an-SoC component; there's no equivalent
> > for the Cortex-R52.)
> >
> >>   https://developer.arm.com/documentation/dai0536/latest/
>
> It's not super clear from the design notes but it does mention the
> SSE-200 sub-system as the basis for peripherals. Specifically the blocks
> are:
>
>   Arm Cortex-R52 Processor
>   Arm CoreSight SoC-400 (n/a for QEMU)
>   Cortex-M System Design Kit
>   PL022 Serial Port
>   NIC-400 Network interconnect
>
> But if writing it from scratch is simpler so be it. The real question is
> what new hardware would we need to model to be able to bring something
> up that is useful to Xen?

Just the board, basically. The SSE-200 is specifically a
dual-Cortex-M33 block; all the references to it in the
AN536 appnote look like cases where text wasn't sufficiently
cleaned up when creating it based on the M-profile doc...

-- PMM



Re: [XEN PATCH 09/13] xen/common: address violations of MISRA C:2012 Directive 4.10

2023-08-31 Thread Jan Beulich
On 31.08.2023 12:08, Simone Ballarin wrote:
> On 29/08/23 08:50, Jan Beulich wrote:
>> On 28.08.2023 15:20, Simone Ballarin wrote:
>>> Add inclusion guards to address violations of
>>> MISRA C:2012 Directive 4.10 ("Precautions shall be taken in order
>>> to prevent the contents of a header file being included more than
>>> once").
>>>
>>> Also C files, if included somewhere, need to comply with the guideline.
>>>
>>> Mechanical change.
>>>
>>> Signed-off-by: Simone Ballarin 
>>> ---
>>>   xen/common/compat/grant_table.c | 7 +++
>>>   xen/common/coverage/gcc_4_7.c   | 5 +
>>>   xen/common/decompress.h | 5 +
>>>   xen/common/event_channel.h  | 5 +
>>>   xen/common/multicall.c  | 5 +
>>>   5 files changed, 27 insertions(+)
>>
>> As already said in reply to another patch, imo .c files shouldn't gain such
>> guards. These are commonly referred to as "header guards" for a reason.
>>
> 
> This is the MISRA's definition of "header file" (MISRA C:2012 Revision 
> 1, Appendix J):
> 
>"A header file is any file that is the subject of a #include
> directive.
> Note: the filename extension is not significant."

That's completely misleading terminology then.

> So, the guards are required if we want to comply with the directive, 
> otherwise we can raise a deviation.
> 
> The danger of multi-inclusion also exists for .c files, why do you want 
> to avoid guards for them?

Counter question: Why only add guards to some of them? (My personal
answer is "Because it's extra clutter.")

Jan



[PATCH v1 2/2] xen/arm: Enlarge identity map space to 127TiB

2023-08-31 Thread Leo Yan
On some platforms, the memory regions could be:

  (XEN) MODULE[0]: 0807f6df - 0807f6f3e000 Xen
  (XEN) MODULE[1]: 0807f8054000 - 0807f8056000 Device Tree
  (XEN) MODULE[2]: fa834000 - fc5de1d5 Ramdisk
  (XEN) MODULE[3]: fc5df000 - ffb3f810 Kernel

In this case, the Xen binary is loaded above 2TB, so Xen fails to boot
up due to the out of the identity map space.

This patch enlarges identity map space to 127TiB, which can support the
memory space [0x0 .. 0x7eff__], thus it has flexibility for
support different platforms.

Fixes: 1c78d76b67 ("xen/arm64: mm: Introduce helpers to prepare/enable/disable")
Reported-by: Alexey Klimov 
Signed-off-by: Leo Yan 
---
 xen/arch/arm/include/asm/config.h | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/xen/arch/arm/include/asm/config.h 
b/xen/arch/arm/include/asm/config.h
index 21f4e68a40..3e97c95b57 100644
--- a/xen/arch/arm/include/asm/config.h
+++ b/xen/arch/arm/include/asm/config.h
@@ -87,11 +87,11 @@
  *   2G -   4G   Domheap: on-demand-mapped
  *
  * ARM64 layout:
- * 0x - 0x01ff (2TB, L0 slots [0..3])
+ * 0x - 0x7eff (127TB, L0 slots [0..253])
  *
  *  Reserved to identity map Xen
  *
- * 0x0200 - 0x027f (512GB, L0 slot [4])
+ * 0x07f0 - 0x7fff (1TB, L0 slot [254..255])
  *  (Relative offsets)
  *   0  -   2M   Unmapped
  *   2M -  10M   Xen text, data, bss
@@ -103,9 +103,6 @@
  *
  *  32G -  64G   Frametable: 56 bytes per page for 2TB of RAM
  *
- * 0x0280 - 0x7fff (125TB, L0 slots [5..255])
- *  Unused
- *
  * 0x8000 - 0x84ff (5TB, L0 slots [256..265])
  *  1:1 mapping of RAM
  *
@@ -117,7 +114,7 @@
 #define XEN_VIRT_START  _AT(vaddr_t, MB(2))
 #else
 
-#define IDENTITY_MAPPING_AREA_NR_L04
+#define IDENTITY_MAPPING_AREA_NR_L0254
 #define XEN_VM_MAPPING SLOT0(IDENTITY_MAPPING_AREA_NR_L0)
 
 #define SLOT0_ENTRY_BITS  39
-- 
2.39.2




[PATCH v1 0/2] xen/arm: Enlarge identity map space

2023-08-31 Thread Leo Yan
The latest Xen fails to boot on ADLink AVA platform.  Alexey Klimov root
caused the issue is related with the commit 1c78d76b67 ("xen/arm64: mm:
Introduce helpers to prepare/enable/disable").

This is because on ADLink AVA platform, it loads Xen hypervisor to the
address above 2TB and hence causes Xen panic:

  (XEN) MODULE[0]: 0807f6df - 0807f6f3e000 Xen
  (XEN) MODULE[1]: 0807f8054000 - 0807f8056000 Device Tree
  (XEN) MODULE[2]: fa834000 - fc5de1d5 Ramdisk
  (XEN) MODULE[3]: fc5df000 - ffb3f810 Kernel

To fix this issue, this series is to enlarge identity map space to
127 TiB and tested on ADLink AVA platform.

Note, we tested on two ADLind AVA platforms, one machine has this issue
and another machine cannot reproduce the panic.  It's likely they have
different firmware versions so one machine loads Xen hypervisor into the
high memory address and caused booting failure.


Leo Yan (2):
  xen/arm: Add macro XEN_VM_MAPPING
  xen/arm: Enlarge identity map space to 127TiB

 xen/arch/arm/include/asm/config.h | 18 --
 1 file changed, 8 insertions(+), 10 deletions(-)

-- 
2.39.2




[PATCH v1 1/2] xen/arm: Add macro XEN_VM_MAPPING

2023-08-31 Thread Leo Yan
Xen maps the virtual memory space starting from L0 slot 4, so it's open
coded for macros with the offset '4'.

For more readable, add a new macro XEN_VM_MAPPING which defines the
start slot for Xen virtual memory mapping, and all virtual memory
regions are defined based on it.

Signed-off-by: Leo Yan 
---
 xen/arch/arm/include/asm/config.h | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/xen/arch/arm/include/asm/config.h 
b/xen/arch/arm/include/asm/config.h
index 83cbf6b0cb..21f4e68a40 100644
--- a/xen/arch/arm/include/asm/config.h
+++ b/xen/arch/arm/include/asm/config.h
@@ -117,11 +117,14 @@
 #define XEN_VIRT_START  _AT(vaddr_t, MB(2))
 #else
 
+#define IDENTITY_MAPPING_AREA_NR_L04
+#define XEN_VM_MAPPING SLOT0(IDENTITY_MAPPING_AREA_NR_L0)
+
 #define SLOT0_ENTRY_BITS  39
 #define SLOT0(slot) (_AT(vaddr_t,slot) << SLOT0_ENTRY_BITS)
 #define SLOT0_ENTRY_SIZE  SLOT0(1)
 
-#define XEN_VIRT_START  (SLOT0(4) + _AT(vaddr_t, MB(2)))
+#define XEN_VIRT_START  (XEN_VM_MAPPING + _AT(vaddr_t, MB(2)))
 #endif
 
 /*
@@ -184,12 +187,10 @@
 
 #else /* ARM_64 */
 
-#define IDENTITY_MAPPING_AREA_NR_L0  4
-
-#define VMAP_VIRT_START  (SLOT0(4) + GB(1))
+#define VMAP_VIRT_START  (XEN_VM_MAPPING + GB(1))
 #define VMAP_VIRT_SIZE   GB(1)
 
-#define FRAMETABLE_VIRT_START  (SLOT0(4) + GB(32))
+#define FRAMETABLE_VIRT_START  (XEN_VM_MAPPING + GB(32))
 #define FRAMETABLE_SIZEGB(32)
 #define FRAMETABLE_NR  (FRAMETABLE_SIZE / sizeof(*frame_table))
 
-- 
2.39.2




Re: [Xen-devel] [PATCH] x86/HVM: adjust hvm_interrupt_blocked()

2023-08-31 Thread Roger Pau Monné
On Thu, Aug 31, 2023 at 12:42:58PM +0200, Roger Pau Monné wrote:
> On Fri, Oct 12, 2018 at 09:58:46AM -0600, Jan Beulich wrote:
> > First of all, hvm_intsrc_mce was not considered here at all, yet nothing
> > blocks #MC (other than an already in-progress #MC, but dealing with this
> > is not the purpose of this patch).
> > 
> > Additionally STI-shadow only blocks maskable interrupts, but not NMI.
> 
> I've found the Table 25-3 on Intel SDM vol3 quite helpful:
> 
> "Execution of STI with RFLAGS.IF = 0 blocks maskable interrupts on the
> instruction boundary following its execution.1 Setting this bit
> indicates that this blocking is in effect."
> 
> And:
> 
> "Execution of a MOV to SS or a POP to SS blocks or suppresses certain
> debug exceptions as well as interrupts (maskable and nonmaskable) on
> the instruction boundary following its execution."
> 
> Might be worth adding to the commit message IMO.

So I've found a further footnote that contains:

"Nonmaskable interrupts and system-management interrupts may also be
inhibited on the instruction boundary following such an execution of
STI."

So we want to take the more restrictive implementation of STI-shadow,
and block #NMI there also.

Thanks, Roger.



Re: QEMU features useful for Xen development?

2023-08-31 Thread Alex Bennée


Peter Maydell  writes:

> On Thu, 31 Aug 2023 at 10:53, Alex Bennée  wrote:
>>
>>
>> Peter Maydell  writes:
>>
>> > On Thu, 31 Aug 2023 at 01:57, Stefano Stabellini  
>> > wrote:
>> >> As Xen is gaining R52 and R82 support, it would be great to be able to
>> >> use QEMU for development and testing there as well, but I don't think
>> >> QEMU can emulate EL2 properly for the Cortex-R architecture. We would
>> >> need EL2 support in the GIC/timer for R52/R82 as well.
>> >
>> > We do actually have a Cortex-R52 model which at least in theory
>> > should include EL2 support, though as usual with newer QEMU
>> > stuff it quite likely has lurking bugs; I'm not sure how much
>> > testing it's had. Also there is currently no board model which
>> > will work with the Cortex-R52 so it's a bit tricky to use in practice.
>> > (What sort of board model would Xen want to use it with?)
>>
>> We already model a bunch of the mps2/mps3 images so I'm assuming adding
>> the mps3-an536 would be a fairly simple step to do (mps2tz.c is mostly
>> tweaking config values). The question is would it be a useful target for
>> Xen?
>
> All our MPS2/MPS3 boards are M-profile. That means we have the
> device models for all the interesting devices on the board, but
> it would be simpler to write the an536 board model separately.
> (In particular, the M-profile boards are wrappers around an
> "ARMSSE" sort-of-like-an-SoC component; there's no equivalent
> for the Cortex-R52.)
>
>>   https://developer.arm.com/documentation/dai0536/latest/

It's not super clear from the design notes but it does mention the
SSE-200 sub-system as the basis for peripherals. Specifically the blocks
are:

  Arm Cortex-R52 Processor
  Arm CoreSight SoC-400 (n/a for QEMU)
  Cortex-M System Design Kit
  PL022 Serial Port
  NIC-400 Network interconnect

But if writing it from scratch is simpler so be it. The real question is
what new hardware would we need to model to be able to bring something
up that is useful to Xen?

>> > The Cortex-R82 would be more work, because (unlike the R52) it's
>> > AArch64, and we don't have Armv8-R AArch64 support yet, only the AArch32.
>> >
>> > I haven't looked at whether GIC on R-profile requires any changes
>> > from the A-profile GIC; on A-profile obviously we emulate the
>> > virtualization support already.
>> >

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [QEMU PATCH v4 11/13] virtio-gpu: Support Venus capset

2023-08-31 Thread Akihiko Odaki

On 2023/08/31 18:32, Huang Rui wrote:

From: Antonio Caggiano 

Add support for the Venus capset, which enables Vulkan support through
the Venus Vulkan driver for virtio-gpu.

Signed-off-by: Antonio Caggiano 
Signed-off-by: Huang Rui 
---
  hw/display/virtio-gpu-virgl.c   | 21 +
  include/standard-headers/linux/virtio_gpu.h |  2 ++
  2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 1a996a08fc..83cd8c8fd0 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -437,6 +437,11 @@ static void virgl_cmd_get_capset_info(VirtIOGPU *g,
  virgl_renderer_get_cap_set(resp.capset_id,
 _max_version,
 _max_size);
+} else if (info.capset_index == 2) {
+resp.capset_id = VIRTIO_GPU_CAPSET_VENUS;
+virgl_renderer_get_cap_set(resp.capset_id,
+   _max_version,
+   _max_size);
  } else {
  resp.capset_max_version = 0;
  resp.capset_max_size = 0;
@@ -901,10 +906,18 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
  
  int virtio_gpu_virgl_get_num_capsets(VirtIOGPU *g)

  {
-uint32_t capset2_max_ver, capset2_max_size;
+uint32_t capset2_max_ver, capset2_max_size, num_capsets;
+num_capsets = 1;
+
  virgl_renderer_get_cap_set(VIRTIO_GPU_CAPSET_VIRGL2,
-  _max_ver,
-  _max_size);
+   _max_ver,
+   _max_size);
+num_capsets += capset2_max_ver ? 1 : 0;
+
+virgl_renderer_get_cap_set(VIRTIO_GPU_CAPSET_VENUS,
+   _max_ver,
+   _max_size);
+num_capsets += capset2_max_size ? 1 : 0;
  
-return capset2_max_ver ? 2 : 1;

+return num_capsets;
  }
diff --git a/include/standard-headers/linux/virtio_gpu.h 
b/include/standard-headers/linux/virtio_gpu.h
index 2da48d3d4c..2db643ed8f 100644
--- a/include/standard-headers/linux/virtio_gpu.h
+++ b/include/standard-headers/linux/virtio_gpu.h
@@ -309,6 +309,8 @@ struct virtio_gpu_cmd_submit {
  
  #define VIRTIO_GPU_CAPSET_VIRGL 1

  #define VIRTIO_GPU_CAPSET_VIRGL2 2
+/* 3 is reserved for gfxstream */
+#define VIRTIO_GPU_CAPSET_VENUS 4


This file is synced with scripts/update-linux-headers.sh and should not 
be modified.


  
  /* VIRTIO_GPU_CMD_GET_CAPSET_INFO */

  struct virtio_gpu_get_capset_info {




Re: [Xen-devel] [PATCH] x86/HVM: adjust hvm_interrupt_blocked()

2023-08-31 Thread Roger Pau Monné
On Fri, Oct 12, 2018 at 09:58:46AM -0600, Jan Beulich wrote:
> First of all, hvm_intsrc_mce was not considered here at all, yet nothing
> blocks #MC (other than an already in-progress #MC, but dealing with this
> is not the purpose of this patch).
> 
> Additionally STI-shadow only blocks maskable interrupts, but not NMI.

I've found the Table 25-3 on Intel SDM vol3 quite helpful:

"Execution of STI with RFLAGS.IF = 0 blocks maskable interrupts on the
instruction boundary following its execution.1 Setting this bit
indicates that this blocking is in effect."

And:

"Execution of a MOV to SS or a POP to SS blocks or suppresses certain
debug exceptions as well as interrupts (maskable and nonmaskable) on
the instruction boundary following its execution."

Might be worth adding to the commit message IMO.

> Signed-off-by: Jan Beulich 
> 
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -3771,19 +3771,24 @@ enum hvm_intblk hvm_interrupt_blocked(st
>  return intr;
>  }
>  
> -if ( (intack.source != hvm_intsrc_nmi) &&
> - !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
> -return hvm_intblk_rflags_ie;
> +if ( intack.source == hvm_intsrc_mce )
> +return hvm_intblk_none;

I've been wondering, why do we handle #MC here, instead of doing the
same as for other Traps/Exceptions and use hvm_inject_hw_exception()
directly?

>  
>  intr_shadow = hvm_funcs.get_interrupt_shadow(v);
>  
> -if ( intr_shadow & (HVM_INTR_SHADOW_STI|HVM_INTR_SHADOW_MOV_SS) )
> +if ( intr_shadow & HVM_INTR_SHADOW_MOV_SS )
>  return hvm_intblk_shadow;
>  
>  if ( intack.source == hvm_intsrc_nmi )
>  return ((intr_shadow & HVM_INTR_SHADOW_NMI) ?
>  hvm_intblk_nmi_iret : hvm_intblk_none);
>  
> +if ( intr_shadow & HVM_INTR_SHADOW_STI )
> +return hvm_intblk_shadow;
> +
> +if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
> +return hvm_intblk_rflags_ie;

I do wonder whether this code would be clearer using a `switch (
intack.source )` construct, but that's out of the scope.

Thanks, Roger.



Re: [QEMU PATCH v4 12/13] virtio-gpu: Initialize Venus

2023-08-31 Thread Antonio Caggiano

Hi Huang,

Thank you for pushing this forward!

On 31/08/2023 11:32, Huang Rui wrote:

From: Antonio Caggiano 

Request Venus when initializing VirGL.

Signed-off-by: Antonio Caggiano 
Signed-off-by: Huang Rui 
---

v1->v2:
 - Rebase to latest version

  hw/display/virtio-gpu-virgl.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 83cd8c8fd0..c5a62665bd 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -887,6 +887,8 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
  }
  #endif
  
+flags |= VIRGL_RENDERER_VENUS;

+


VIRGL_RENDERER_VENUS is a symbol only available from virglrenderer 0.9.1 
[0] and only if VIRGL_RENDERER_UNSTABLE_APIS is defined.


Luckily for us, VIRGL_RENDERER_UNSTABLE_APIS is defined unconditionally 
from virglrenderer 0.9.0 [1], so we could check for that in qemu/meson.build


e.g.


  if virgl.version().version_compare('>= 0.9.0')
message('Enabling virglrenderer unstable APIs')
virgl = declare_dependency(compile_args: 
'-DVIRGL_RENDERER_UNSTABLE_APIS',

   dependencies: virgl)
  endif


Also, while testing this with various versions of virglrenderer, I 
realized there are no guarantees for Venus backend to be available in 
the linked library. Virglrenderer should be built with 
-Dvenus_experimental=true, and if that is not the case, the following 
virgl_renderer_init would fail for previous versions of virglrenderer or 
in case it has not been built with venus support.


I would suggest another approach for that which tries initializing Venus 
only if VIRGL_RENDERER_VENUS is actually defined. Then, if it fails 
cause virglrenderer has not been built with venus support, try again 
falling back to virgl only.


e.g.

#ifdef VIRGL_RENDERER_VENUS
ret = virgl_renderer_init(g, VIRGL_RENDERER_VENUS, _gpu_3d_cbs);
if (ret != 0) {
warn_report("Failed to initialize virglrenderer with venus: 
%d", ret);

warn_report("Falling back to virgl only");
ret = virgl_renderer_init(g, 0, _gpu_3d_cbs);
}
#else
ret = virgl_renderer_init(g, 0, _gpu_3d_cbs);
#endif



  ret = virgl_renderer_init(g, flags, _gpu_3d_cbs);
  if (ret != 0) {
  error_report("virgl could not be initialized: %d", ret);


[0] 
https://gitlab.freedesktop.org/virgl/virglrenderer/-/commit/6c31f85330bb4c5aba8b82eba606971e598c6e25
[1] 
https://gitlab.freedesktop.org/virgl/virglrenderer/-/commit/491afdc42a49ec6a1b8d7cbc5c97360229002d41


Best regards,
Antonio Caggiano



Re: [QEMU PATCH v4 10/13] virtio-gpu: Resource UUID

2023-08-31 Thread Akihiko Odaki

On 2023/08/31 18:32, Huang Rui wrote:

From: Antonio Caggiano 

Enable resource UUID feature and implement command resource assign UUID.
This is done by introducing a hash table to map resource IDs to their
UUIDs.


The hash table does not seem to be stored during migration.



Signed-off-by: Antonio Caggiano 
Signed-off-by: Huang Rui 
---

v1->v2:
- Separate declarations from code.

  hw/display/trace-events|  1 +
  hw/display/virtio-gpu-base.c   |  2 ++
  hw/display/virtio-gpu-virgl.c  | 21 +
  hw/display/virtio-gpu.c| 41 ++
  include/hw/virtio/virtio-gpu.h |  4 
  5 files changed, 69 insertions(+)

diff --git a/hw/display/trace-events b/hw/display/trace-events
index 2336a0ca15..54d6894c59 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -41,6 +41,7 @@ virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) "res 
0x%x, size %" P
  virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x"
  virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x"
  virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x"
+virtio_gpu_cmd_res_assign_uuid(uint32_t res) "res 0x%x"
  virtio_gpu_cmd_res_xfer_toh_2d(uint32_t res) "res 0x%x"
  virtio_gpu_cmd_res_xfer_toh_3d(uint32_t res) "res 0x%x"
  virtio_gpu_cmd_res_xfer_fromh_3d(uint32_t res) "res 0x%x"
diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index 4f2b0ba1f3..f44388715c 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -236,6 +236,8 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t 
features,
  features |= (1 << VIRTIO_GPU_F_CONTEXT_INIT);
  }
  
+features |= (1 << VIRTIO_GPU_F_RESOURCE_UUID);

+
  return features;
  }
  
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c

index 17b634d4ee..1a996a08fc 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -36,6 +36,7 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
  {
  struct virtio_gpu_resource_create_2d c2d;
  struct virgl_renderer_resource_create_args args;
+struct virtio_gpu_simple_resource *res;
  
  VIRTIO_GPU_FILL_CMD(c2d);

  trace_virtio_gpu_cmd_res_create_2d(c2d.resource_id, c2d.format,
@@ -53,6 +54,14 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
  args.nr_samples = 0;
  args.flags = VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP;
  virgl_renderer_resource_create(, NULL, 0);
+
+res = g_new0(struct virtio_gpu_simple_resource, 1);
+if (!res) {
+cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
+return;


virglrenderer thinks the resource is alive in such a situation.


+}
+res->resource_id = c2d.resource_id;
+QTAILQ_INSERT_HEAD(>reslist, res, next);
  }
  
  static void virgl_cmd_create_resource_3d(VirtIOGPU *g,

@@ -60,6 +69,7 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
  {
  struct virtio_gpu_resource_create_3d c3d;
  struct virgl_renderer_resource_create_args args;
+struct virtio_gpu_simple_resource *res;
  
  VIRTIO_GPU_FILL_CMD(c3d);

  trace_virtio_gpu_cmd_res_create_3d(c3d.resource_id, c3d.format,
@@ -77,6 +87,14 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
  args.nr_samples = c3d.nr_samples;
  args.flags = c3d.flags;
  virgl_renderer_resource_create(, NULL, 0);
+
+res = g_new0(struct virtio_gpu_simple_resource, 1);
+if (!res) {
+cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
+return;
+}
+res->resource_id = c3d.resource_id;
+QTAILQ_INSERT_HEAD(>reslist, res, next);
  }
  
  static void virgl_resource_destroy(VirtIOGPU *g,

@@ -682,6 +700,9 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
  /* TODO add security */
  virgl_cmd_ctx_detach_resource(g, cmd);
  break;
+case VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID:
+virtio_gpu_resource_assign_uuid(g, cmd);
+break;
  case VIRTIO_GPU_CMD_GET_CAPSET_INFO:
  virgl_cmd_get_capset_info(g, cmd);
  break;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index cc4c1f81bb..770e4747e3 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -966,6 +966,37 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g,
  virtio_gpu_cleanup_mapping(g, res);
  }
  
+void virtio_gpu_resource_assign_uuid(VirtIOGPU *g,

+ struct virtio_gpu_ctrl_command *cmd)
+{
+struct virtio_gpu_simple_resource *res;
+struct virtio_gpu_resource_assign_uuid assign;
+struct virtio_gpu_resp_resource_uuid resp;
+QemuUUID *uuid = NULL;


This initialization is unnecessary.


+
+VIRTIO_GPU_FILL_CMD(assign);
+virtio_gpu_bswap_32(, sizeof(assign));
+trace_virtio_gpu_cmd_res_assign_uuid(assign.resource_id);
+
+res = virtio_gpu_find_check_resource(g, assign.resource_id, false, __func__, 
>error);
+if (!res) {
+return;
+}
+
+memset(, 0, 

Re: QEMU features useful for Xen development?

2023-08-31 Thread Ayan Kumar Halder

Hi Peter/Alex,

Appreciate your help. :)

On 31/08/2023 11:03, Peter Maydell wrote:

CAUTION: This message has originated from an External Source. Please use proper 
judgment and caution when opening attachments, clicking links, or responding to 
this email.


On Thu, 31 Aug 2023 at 10:53, Alex Bennée  wrote:


Peter Maydell  writes:


On Thu, 31 Aug 2023 at 01:57, Stefano Stabellini  wrote:

As Xen is gaining R52 and R82 support, it would be great to be able to
use QEMU for development and testing there as well, but I don't think
QEMU can emulate EL2 properly for the Cortex-R architecture. We would
need EL2 support in the GIC/timer for R52/R82 as well.

We do actually have a Cortex-R52 model which at least in theory
should include EL2 support, though as usual with newer QEMU
stuff it quite likely has lurking bugs; I'm not sure how much
testing it's had. Also there is currently no board model which
will work with the Cortex-R52 so it's a bit tricky to use in practice.
(What sort of board model would Xen want to use it with?)

We already model a bunch of the mps2/mps3 images so I'm assuming adding
the mps3-an536 would be a fairly simple step to do (mps2tz.c is mostly
tweaking config values). The question is would it be a useful target for
Xen?

All our MPS2/MPS3 boards are M-profile. That means we have the
device models for all the interesting devices on the board, but
it would be simpler to write the an536 board model separately.
(In particular, the M-profile boards are wrappers around an
"ARMSSE" sort-of-like-an-SoC component; there's no equivalent
for the Cortex-R52.)


   https://developer.arm.com/documentation/dai0536/latest/


Yes, it will be helpful if Qemu can model this board. We have a 
downstream port of Xen on R52 (upstreaming is in progress).


So, we can test the Qemu model with Xen.

Also if all works fine, we might consider adding this to the upstream 
Xen CI docker.


Out of curiosity, are you planning to add Qemu R52 SoC support to Zephyr ?

- Ayan




The Cortex-R82 would be more work, because (unlike the R52) it's
AArch64, and we don't have Armv8-R AArch64 support yet, only the AArch32.

I haven't looked at whether GIC on R-profile requires any changes
from the A-profile GIC; on A-profile obviously we emulate the
virtualization support already.


On Cortex-As, in addition to a PCI root complex and an arbitrary PCI
device, SMMUv3 emulation (both stages) and GICv3 ITS are needed to be
able to test PCI Passthrough.

We have ITS emulation support and it was recently plumbed into the
"sbsa-ref" board as it is needed for higher level SBSA compliance.


However, if I recall correctly SMMUv3
emulation in QEMU might not be complete enough to enable us to use it.

Yeah, at the moment the SMMU emulation supports stage 1 and stage 2,
but not both at the same time. This is good enough for PCI passthrough
with a Linux guest using KVM to pass a device through to a nested
Linux guest.

Is this a missing feature for SMMUv3 or something introduced in the
later revisions?

It's a missing feature. The SMMUv3 spec allows an implementation
to implement stage 1, stage 2 or both. We started with just a
stage-1-only implementation because Linux doesn't need any more.
Stage-2-only just landed recently. Nobody's looked at both-stages yet.

thanks
-- PMM





[ANNOUNCE] Call for agenda items for 7 September Community Call @ 1500 UTC

2023-08-31 Thread George Dunlap
Hi all,

The proposed agenda is in
https://cryptpad.fr/pad/#/2/pad/edit/s6D6t2vTjCkpfRIJXo8IVSWf/ and you
can edit to add items.  Alternatively, you can reply to this mail
directly.

Agenda items appreciated a few days before the call: please put your
name besides items if you edit the document.

Note the following administrative conventions for the call:
* Unless, agreed in the previous meeting otherwise, the call is on the
1st Thursday of each month at 1600 British Time (either GMT or BST)
* I usually send out a meeting reminder a few days before with a
provisional agenda

* To allow time to switch between meetings, we'll plan on starting the
agenda at 16:05 sharp.  Aim to join by 16:03 if possible to allocate
time to sort out technical difficulties 

* If you want to be CC'ed please add or remove yourself from the
sign-up-sheet at
https://cryptpad.fr/pad/#/2/pad/edit/D9vGzihPxxAOe6RFPz0sRCf+/

Best Regards
George


== Dial-in Information ==
## Meeting time
16:00 - 17:00 British time
Further International meeting times:
https://www.timeanddate.com/worldclock/meetingdetails.html?year=2023=9=7=15=0=0=1234=37=224=179


## Dial in details
Web: https://meet.jit.si/XenProjectCommunityCall

Dial-in info and pin can be found here:

https://meet.jit.si/static/dialInInfo.html?room=XenProjectCommunityCall



Re: [QEMU PATCH v4 09/13] virtio-gpu: Handle resource blob commands

2023-08-31 Thread Akihiko Odaki

On 2023/08/31 18:32, Huang Rui wrote:

From: Antonio Caggiano 

Support BLOB resources creation, mapping and unmapping by calling the
new stable virglrenderer 0.10 interface. Only enabled when available and
via the blob config. E.g. -device virtio-vga-gl,blob=true

Signed-off-by: Antonio Caggiano 
Signed-off-by: Dmitry Osipenko 
Signed-off-by: Xenia Ragiadakou 
Signed-off-by: Huang Rui 
---

v1->v2:
 - Remove unused #include "hw/virtio/virtio-iommu.h"

 - Add a local function, called virgl_resource_destroy(), that is used
   to release a vgpu resource on error paths and in resource_unref.

 - Remove virtio_gpu_virgl_resource_unmap from virtio_gpu_cleanup_mapping(),
   since this function won't be called on blob resources and also because
   blob resources are unmapped via virgl_cmd_resource_unmap_blob().

 - In virgl_cmd_resource_create_blob(), do proper cleanup in error paths
   and move QTAILQ_INSERT_HEAD(>reslist, res, next) after the resource
   has been fully initialized.

 - Memory region has a different life-cycle from virtio gpu resources
   i.e. cannot be released synchronously along with the vgpu resource.
   So, here the field "region" was changed to a pointer that will be
   released automatically once the memory region is unparented and all
   of its references have been released.
   Also, since the pointer can be used to indicate whether the blob
   is mapped, the explicit field "mapped" was removed.

 - In virgl_cmd_resource_map_blob(), add check on the value of
   res->region, to prevent beeing called twice on the same resource.

 - Remove direct references to parent_obj.

 - Separate declarations from code.

  hw/display/virtio-gpu-virgl.c  | 213 +
  hw/display/virtio-gpu.c|   4 +-
  include/hw/virtio/virtio-gpu.h |   5 +
  meson.build|   4 +
  4 files changed, 225 insertions(+), 1 deletion(-)

diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 312953ec16..17b634d4ee 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -17,6 +17,7 @@
  #include "trace.h"
  #include "hw/virtio/virtio.h"
  #include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/virtio-gpu-bswap.h"
  
  #include "ui/egl-helpers.h"
  
@@ -78,9 +79,24 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,

  virgl_renderer_resource_create(, NULL, 0);
  }
  
+static void virgl_resource_destroy(VirtIOGPU *g,

+   struct virtio_gpu_simple_resource *res)
+{
+if (!res)
+return;
+
+QTAILQ_REMOVE(>reslist, res, next);
+
+virtio_gpu_cleanup_mapping_iov(g, res->iov, res->iov_cnt);
+g_free(res->addrs);
+
+g_free(res);
+}
+
  static void virgl_cmd_resource_unref(VirtIOGPU *g,
   struct virtio_gpu_ctrl_command *cmd)
  {
+struct virtio_gpu_simple_resource *res;
  struct virtio_gpu_resource_unref unref;
  struct iovec *res_iovs = NULL;
  int num_iovs = 0;
@@ -88,13 +104,22 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
  VIRTIO_GPU_FILL_CMD(unref);
  trace_virtio_gpu_cmd_res_unref(unref.resource_id);
  
+res = virtio_gpu_find_resource(g, unref.resource_id);

+
  virgl_renderer_resource_detach_iov(unref.resource_id,
 _iovs,
 _iovs);
  if (res_iovs != NULL && num_iovs != 0) {
  virtio_gpu_cleanup_mapping_iov(g, res_iovs, num_iovs);
+if (res) {
+res->iov = NULL;
+res->iov_cnt = 0;
+}
  }
+
  virgl_renderer_resource_unref(unref.resource_id);
+
+virgl_resource_destroy(g, res);
  }
  
  static void virgl_cmd_context_create(VirtIOGPU *g,

@@ -426,6 +451,183 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
  g_free(resp);
  }
  
+#ifdef HAVE_VIRGL_RESOURCE_BLOB

+
+static void virgl_cmd_resource_create_blob(VirtIOGPU *g,
+   struct virtio_gpu_ctrl_command *cmd)
+{
+struct virtio_gpu_simple_resource *res;
+struct virtio_gpu_resource_create_blob cblob;
+struct virgl_renderer_resource_create_blob_args virgl_args = { 0 };
+int ret;
+
+VIRTIO_GPU_FILL_CMD(cblob);
+virtio_gpu_create_blob_bswap();
+trace_virtio_gpu_cmd_res_create_blob(cblob.resource_id, cblob.size);
+
+if (cblob.resource_id == 0) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
+  __func__);
+cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+return;
+}
+
+res = virtio_gpu_find_resource(g, cblob.resource_id);
+if (res) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
+  __func__, cblob.resource_id);
+cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+return;
+}
+
+res = 

Re: [QEMU PATCH v4 07/13] softmmu/memory: enable automatic deallocation of memory regions

2023-08-31 Thread Akihiko Odaki

On 2023/08/31 18:32, Huang Rui wrote:

From: Xenia Ragiadakou 

When the memory region has a different life-cycle from that of her parent,
could be automatically released, once has been unparent and once all of her
references have gone away, via the object's free callback.

However, currently, references to the memory region are held by its owner
without first incrementing the memory region object's reference count.
As a result, the automatic deallocation of the object, not taking into
account those references, results in use-after-free memory corruption.

This patch increases the reference count of the memory region object on
each memory_region_ref() and decreases it on each memory_region_unref().

Signed-off-by: Xenia Ragiadakou 
Signed-off-by: Huang Rui 
---

New patch

  softmmu/memory.c | 19 +--
  1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/softmmu/memory.c b/softmmu/memory.c
index 7d9494ce70..0fdd5eebf9 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -1797,6 +1797,15 @@ Object *memory_region_owner(MemoryRegion *mr)
  
  void memory_region_ref(MemoryRegion *mr)

  {
+if (!mr) {
+return;
+}
+
+/* Obtain a reference to prevent the memory region object
+ * from being released under our feet.
+ */
+object_ref(OBJECT(mr));
+
  /* MMIO callbacks most likely will access data that belongs
   * to the owner, hence the need to ref/unref the owner whenever
   * the memory region is in use.
@@ -1807,16 +1816,22 @@ void memory_region_ref(MemoryRegion *mr)
   * Memory regions without an owner are supposed to never go away;
   * we do not ref/unref them because it slows down DMA sensibly.
   */


The collapsed comment says:
> The memory region is a child of its owner.  As long as the
> owner doesn't call unparent itself on the memory region,
> ref-ing the owner will also keep the memory region alive.
> Memory regions without an owner are supposed to never go away;
> we do not ref/unref them because it slows down DMA sensibly.

It contradicts with this patch.


-if (mr && mr->owner) {
+if (mr->owner) {
  object_ref(mr->owner);
  }
  }
  
  void memory_region_unref(MemoryRegion *mr)

  {
-if (mr && mr->owner) {
+if (!mr) {
+return;
+}
+
+if (mr->owner) {
  object_unref(mr->owner);
  }
+
+object_unref(OBJECT(mr));
  }
  
  uint64_t memory_region_size(MemoryRegion *mr)




Re: [XEN PATCH 09/13] xen/common: address violations of MISRA C:2012 Directive 4.10

2023-08-31 Thread Simone Ballarin

On 29/08/23 08:50, Jan Beulich wrote:

On 28.08.2023 15:20, Simone Ballarin wrote:

Add inclusion guards to address violations of
MISRA C:2012 Directive 4.10 ("Precautions shall be taken in order
to prevent the contents of a header file being included more than
once").

Also C files, if included somewhere, need to comply with the guideline.

Mechanical change.

Signed-off-by: Simone Ballarin 
---
  xen/common/compat/grant_table.c | 7 +++
  xen/common/coverage/gcc_4_7.c   | 5 +
  xen/common/decompress.h | 5 +
  xen/common/event_channel.h  | 5 +
  xen/common/multicall.c  | 5 +
  5 files changed, 27 insertions(+)


As already said in reply to another patch, imo .c files shouldn't gain such
guards. These are commonly referred to as "header guards" for a reason.



This is the MISRA's definition of "header file" (MISRA C:2012 Revision 
1, Appendix J):


  "A header file is any file that is the subject of a #include
   directive.
   Note: the filename extension is not significant."

So, the guards are required if we want to comply with the directive, 
otherwise we can raise a deviation.


The danger of multi-inclusion also exists for .c files, why do you want 
to avoid guards for them?



--- a/xen/common/compat/grant_table.c
+++ b/xen/common/compat/grant_table.c
@@ -3,6 +3,10 @@
   *
   */
  
+


Nit: No double blank lines please.


+#ifndef __COMMON_COMPAT_GRANT_TABLE_C__
+#define __COMMON_COMPAT_GRANT_TABLE_C__
+
  #include 
  #include 
  
@@ -331,6 +335,9 @@ int compat_grant_table_op(

  return rc;
  }
  
+


Again here (at least).

Jan


--
Simone Ballarin, M.Sc.

Field Application Engineer, BUGSENG (https://bugseng.com)




Re: QEMU features useful for Xen development?

2023-08-31 Thread Peter Maydell
On Thu, 31 Aug 2023 at 10:53, Alex Bennée  wrote:
>
>
> Peter Maydell  writes:
>
> > On Thu, 31 Aug 2023 at 01:57, Stefano Stabellini  
> > wrote:
> >> As Xen is gaining R52 and R82 support, it would be great to be able to
> >> use QEMU for development and testing there as well, but I don't think
> >> QEMU can emulate EL2 properly for the Cortex-R architecture. We would
> >> need EL2 support in the GIC/timer for R52/R82 as well.
> >
> > We do actually have a Cortex-R52 model which at least in theory
> > should include EL2 support, though as usual with newer QEMU
> > stuff it quite likely has lurking bugs; I'm not sure how much
> > testing it's had. Also there is currently no board model which
> > will work with the Cortex-R52 so it's a bit tricky to use in practice.
> > (What sort of board model would Xen want to use it with?)
>
> We already model a bunch of the mps2/mps3 images so I'm assuming adding
> the mps3-an536 would be a fairly simple step to do (mps2tz.c is mostly
> tweaking config values). The question is would it be a useful target for
> Xen?

All our MPS2/MPS3 boards are M-profile. That means we have the
device models for all the interesting devices on the board, but
it would be simpler to write the an536 board model separately.
(In particular, the M-profile boards are wrappers around an
"ARMSSE" sort-of-like-an-SoC component; there's no equivalent
for the Cortex-R52.)

>   https://developer.arm.com/documentation/dai0536/latest/
>
> > The Cortex-R82 would be more work, because (unlike the R52) it's
> > AArch64, and we don't have Armv8-R AArch64 support yet, only the AArch32.
> >
> > I haven't looked at whether GIC on R-profile requires any changes
> > from the A-profile GIC; on A-profile obviously we emulate the
> > virtualization support already.
> >
> >> On Cortex-As, in addition to a PCI root complex and an arbitrary PCI
> >> device, SMMUv3 emulation (both stages) and GICv3 ITS are needed to be
> >> able to test PCI Passthrough.
>
> We have ITS emulation support and it was recently plumbed into the
> "sbsa-ref" board as it is needed for higher level SBSA compliance.
>
> >> However, if I recall correctly SMMUv3
> >> emulation in QEMU might not be complete enough to enable us to use it.
> >
> > Yeah, at the moment the SMMU emulation supports stage 1 and stage 2,
> > but not both at the same time. This is good enough for PCI passthrough
> > with a Linux guest using KVM to pass a device through to a nested
> > Linux guest.
>
> Is this a missing feature for SMMUv3 or something introduced in the
> later revisions?

It's a missing feature. The SMMUv3 spec allows an implementation
to implement stage 1, stage 2 or both. We started with just a
stage-1-only implementation because Linux doesn't need any more.
Stage-2-only just landed recently. Nobody's looked at both-stages yet.

thanks
-- PMM



Re: QEMU features useful for Xen development?

2023-08-31 Thread Alex Bennée


Peter Maydell  writes:

> On Thu, 31 Aug 2023 at 01:57, Stefano Stabellini  
> wrote:
>> As Xen is gaining R52 and R82 support, it would be great to be able to
>> use QEMU for development and testing there as well, but I don't think
>> QEMU can emulate EL2 properly for the Cortex-R architecture. We would
>> need EL2 support in the GIC/timer for R52/R82 as well.
>
> We do actually have a Cortex-R52 model which at least in theory
> should include EL2 support, though as usual with newer QEMU
> stuff it quite likely has lurking bugs; I'm not sure how much
> testing it's had. Also there is currently no board model which
> will work with the Cortex-R52 so it's a bit tricky to use in practice.
> (What sort of board model would Xen want to use it with?)

We already model a bunch of the mps2/mps3 images so I'm assuming adding
the mps3-an536 would be a fairly simple step to do (mps2tz.c is mostly
tweaking config values). The question is would it be a useful target for
Xen?

  https://developer.arm.com/documentation/dai0536/latest/

> The Cortex-R82 would be more work, because (unlike the R52) it's
> AArch64, and we don't have Armv8-R AArch64 support yet, only the AArch32.
>
> I haven't looked at whether GIC on R-profile requires any changes
> from the A-profile GIC; on A-profile obviously we emulate the
> virtualization support already.
>
>> On Cortex-As, in addition to a PCI root complex and an arbitrary PCI
>> device, SMMUv3 emulation (both stages) and GICv3 ITS are needed to be
>> able to test PCI Passthrough.

We have ITS emulation support and it was recently plumbed into the
"sbsa-ref" board as it is needed for higher level SBSA compliance.

>> However, if I recall correctly SMMUv3
>> emulation in QEMU might not be complete enough to enable us to use it.
>
> Yeah, at the moment the SMMU emulation supports stage 1 and stage 2,
> but not both at the same time. This is good enough for PCI passthrough
> with a Linux guest using KVM to pass a device through to a nested
> Linux guest.

Is this a missing feature for SMMUv3 or something introduced in the
later revisions?

We have sketched out the tasks for SMMUv3.2
(https://linaro.atlassian.net/browse/QEMU-558) with a view to whats
needed for RME guests to access hardware. However I think there is a lot
of other stuff needed specifically for RME including what we do about
modelling things like TDISP. Realistically it will be awhile before we
get to completing all of that.


>
> thanks
> -- PMM


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro



Re: [PATCH v3 2/2] xen: move arm/include/asm/vm_event.h to asm-generic

2023-08-31 Thread Jan Beulich
On 30.08.2023 18:57, Oleksii Kurochko wrote:
> asm/vm_event.h is common for ARM and RISC-V so it will be moved to
> asm-generic dir.
> 
> Original asm/vm_event.h from ARM was updated:
>  * use SPDX-License-Identifier.
>  * update comment messages of stubs.
>  * update #ifdef.
>  * change public/domctl.h to public/vm_event.h.
> 
> Signed-off-by: Oleksii Kurochko 
> Acked-by: Stefano Stabellini 
> ---
> Changes in V3:
>  - add Acked-by: Stefano Stabellini  for "xen: move 
> arm/include/asm/vm_event.h to asm-generic"
>  - update SPDX tag.
>  - move asm/vm_event.h to asm-generic.
> ---
> Changes in V2:
>  - change public/domctl.h to public/vm_event.h.
>  - update commit message of [PATCH v2 2/2] xen: move 
> arm/include/asm/vm_event.h to stubs
> ---
>  xen/arch/arm/include/asm/vm_event.h| 66 --
>  xen/include/asm-generic/asm/vm_event.h | 55 +
>  2 files changed, 55 insertions(+), 66 deletions(-)
>  delete mode 100644 xen/arch/arm/include/asm/vm_event.h
>  create mode 100644 xen/include/asm-generic/asm/vm_event.h

While it's a comment on the first patch, it's really better making here:
Did you look at Linux? They don't put an intermediate asm/ here. Instead
see their scripts/Makefile.asm-generic. That way an arch still has
control which generic headers it gets access to, without duplicating any
of them.

Jan



[QEMU PATCH v4 12/13] virtio-gpu: Initialize Venus

2023-08-31 Thread Huang Rui
From: Antonio Caggiano 

Request Venus when initializing VirGL.

Signed-off-by: Antonio Caggiano 
Signed-off-by: Huang Rui 
---

v1->v2:
- Rebase to latest version

 hw/display/virtio-gpu-virgl.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 83cd8c8fd0..c5a62665bd 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -887,6 +887,8 @@ int virtio_gpu_virgl_init(VirtIOGPU *g)
 }
 #endif
 
+flags |= VIRGL_RENDERER_VENUS;
+
 ret = virgl_renderer_init(g, flags, _gpu_3d_cbs);
 if (ret != 0) {
 error_report("virgl could not be initialized: %d", ret);
-- 
2.34.1




[QEMU PATCH v4 09/13] virtio-gpu: Handle resource blob commands

2023-08-31 Thread Huang Rui
From: Antonio Caggiano 

Support BLOB resources creation, mapping and unmapping by calling the
new stable virglrenderer 0.10 interface. Only enabled when available and
via the blob config. E.g. -device virtio-vga-gl,blob=true

Signed-off-by: Antonio Caggiano 
Signed-off-by: Dmitry Osipenko 
Signed-off-by: Xenia Ragiadakou 
Signed-off-by: Huang Rui 
---

v1->v2:
- Remove unused #include "hw/virtio/virtio-iommu.h"

- Add a local function, called virgl_resource_destroy(), that is used
  to release a vgpu resource on error paths and in resource_unref.

- Remove virtio_gpu_virgl_resource_unmap from virtio_gpu_cleanup_mapping(),
  since this function won't be called on blob resources and also because
  blob resources are unmapped via virgl_cmd_resource_unmap_blob().

- In virgl_cmd_resource_create_blob(), do proper cleanup in error paths
  and move QTAILQ_INSERT_HEAD(>reslist, res, next) after the resource
  has been fully initialized.

- Memory region has a different life-cycle from virtio gpu resources
  i.e. cannot be released synchronously along with the vgpu resource.
  So, here the field "region" was changed to a pointer that will be
  released automatically once the memory region is unparented and all
  of its references have been released.
  Also, since the pointer can be used to indicate whether the blob
  is mapped, the explicit field "mapped" was removed.

- In virgl_cmd_resource_map_blob(), add check on the value of
  res->region, to prevent beeing called twice on the same resource.

- Remove direct references to parent_obj.

- Separate declarations from code.

 hw/display/virtio-gpu-virgl.c  | 213 +
 hw/display/virtio-gpu.c|   4 +-
 include/hw/virtio/virtio-gpu.h |   5 +
 meson.build|   4 +
 4 files changed, 225 insertions(+), 1 deletion(-)

diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 312953ec16..17b634d4ee 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -17,6 +17,7 @@
 #include "trace.h"
 #include "hw/virtio/virtio.h"
 #include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/virtio-gpu-bswap.h"
 
 #include "ui/egl-helpers.h"
 
@@ -78,9 +79,24 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
 virgl_renderer_resource_create(, NULL, 0);
 }
 
+static void virgl_resource_destroy(VirtIOGPU *g,
+   struct virtio_gpu_simple_resource *res)
+{
+if (!res)
+return;
+
+QTAILQ_REMOVE(>reslist, res, next);
+
+virtio_gpu_cleanup_mapping_iov(g, res->iov, res->iov_cnt);
+g_free(res->addrs);
+
+g_free(res);
+}
+
 static void virgl_cmd_resource_unref(VirtIOGPU *g,
  struct virtio_gpu_ctrl_command *cmd)
 {
+struct virtio_gpu_simple_resource *res;
 struct virtio_gpu_resource_unref unref;
 struct iovec *res_iovs = NULL;
 int num_iovs = 0;
@@ -88,13 +104,22 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
 VIRTIO_GPU_FILL_CMD(unref);
 trace_virtio_gpu_cmd_res_unref(unref.resource_id);
 
+res = virtio_gpu_find_resource(g, unref.resource_id);
+
 virgl_renderer_resource_detach_iov(unref.resource_id,
_iovs,
_iovs);
 if (res_iovs != NULL && num_iovs != 0) {
 virtio_gpu_cleanup_mapping_iov(g, res_iovs, num_iovs);
+if (res) {
+res->iov = NULL;
+res->iov_cnt = 0;
+}
 }
+
 virgl_renderer_resource_unref(unref.resource_id);
+
+virgl_resource_destroy(g, res);
 }
 
 static void virgl_cmd_context_create(VirtIOGPU *g,
@@ -426,6 +451,183 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
 g_free(resp);
 }
 
+#ifdef HAVE_VIRGL_RESOURCE_BLOB
+
+static void virgl_cmd_resource_create_blob(VirtIOGPU *g,
+   struct virtio_gpu_ctrl_command *cmd)
+{
+struct virtio_gpu_simple_resource *res;
+struct virtio_gpu_resource_create_blob cblob;
+struct virgl_renderer_resource_create_blob_args virgl_args = { 0 };
+int ret;
+
+VIRTIO_GPU_FILL_CMD(cblob);
+virtio_gpu_create_blob_bswap();
+trace_virtio_gpu_cmd_res_create_blob(cblob.resource_id, cblob.size);
+
+if (cblob.resource_id == 0) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: resource id 0 is not allowed\n",
+  __func__);
+cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+return;
+}
+
+res = virtio_gpu_find_resource(g, cblob.resource_id);
+if (res) {
+qemu_log_mask(LOG_GUEST_ERROR, "%s: resource already exists %d\n",
+  __func__, cblob.resource_id);
+cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
+return;
+}
+
+res = g_new0(struct virtio_gpu_simple_resource, 1);
+if (!res) {
+cmd->error = 

[QEMU PATCH v4 10/13] virtio-gpu: Resource UUID

2023-08-31 Thread Huang Rui
From: Antonio Caggiano 

Enable resource UUID feature and implement command resource assign UUID.
This is done by introducing a hash table to map resource IDs to their
UUIDs.

Signed-off-by: Antonio Caggiano 
Signed-off-by: Huang Rui 
---

v1->v2:
   - Separate declarations from code.

 hw/display/trace-events|  1 +
 hw/display/virtio-gpu-base.c   |  2 ++
 hw/display/virtio-gpu-virgl.c  | 21 +
 hw/display/virtio-gpu.c| 41 ++
 include/hw/virtio/virtio-gpu.h |  4 
 5 files changed, 69 insertions(+)

diff --git a/hw/display/trace-events b/hw/display/trace-events
index 2336a0ca15..54d6894c59 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -41,6 +41,7 @@ virtio_gpu_cmd_res_create_blob(uint32_t res, uint64_t size) 
"res 0x%x, size %" P
 virtio_gpu_cmd_res_unref(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_attach(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_back_detach(uint32_t res) "res 0x%x"
+virtio_gpu_cmd_res_assign_uuid(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_xfer_toh_2d(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_xfer_toh_3d(uint32_t res) "res 0x%x"
 virtio_gpu_cmd_res_xfer_fromh_3d(uint32_t res) "res 0x%x"
diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index 4f2b0ba1f3..f44388715c 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -236,6 +236,8 @@ virtio_gpu_base_get_features(VirtIODevice *vdev, uint64_t 
features,
 features |= (1 << VIRTIO_GPU_F_CONTEXT_INIT);
 }
 
+features |= (1 << VIRTIO_GPU_F_RESOURCE_UUID);
+
 return features;
 }
 
diff --git a/hw/display/virtio-gpu-virgl.c b/hw/display/virtio-gpu-virgl.c
index 17b634d4ee..1a996a08fc 100644
--- a/hw/display/virtio-gpu-virgl.c
+++ b/hw/display/virtio-gpu-virgl.c
@@ -36,6 +36,7 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
 {
 struct virtio_gpu_resource_create_2d c2d;
 struct virgl_renderer_resource_create_args args;
+struct virtio_gpu_simple_resource *res;
 
 VIRTIO_GPU_FILL_CMD(c2d);
 trace_virtio_gpu_cmd_res_create_2d(c2d.resource_id, c2d.format,
@@ -53,6 +54,14 @@ static void virgl_cmd_create_resource_2d(VirtIOGPU *g,
 args.nr_samples = 0;
 args.flags = VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP;
 virgl_renderer_resource_create(, NULL, 0);
+
+res = g_new0(struct virtio_gpu_simple_resource, 1);
+if (!res) {
+cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
+return;
+}
+res->resource_id = c2d.resource_id;
+QTAILQ_INSERT_HEAD(>reslist, res, next);
 }
 
 static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
@@ -60,6 +69,7 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
 {
 struct virtio_gpu_resource_create_3d c3d;
 struct virgl_renderer_resource_create_args args;
+struct virtio_gpu_simple_resource *res;
 
 VIRTIO_GPU_FILL_CMD(c3d);
 trace_virtio_gpu_cmd_res_create_3d(c3d.resource_id, c3d.format,
@@ -77,6 +87,14 @@ static void virgl_cmd_create_resource_3d(VirtIOGPU *g,
 args.nr_samples = c3d.nr_samples;
 args.flags = c3d.flags;
 virgl_renderer_resource_create(, NULL, 0);
+
+res = g_new0(struct virtio_gpu_simple_resource, 1);
+if (!res) {
+cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
+return;
+}
+res->resource_id = c3d.resource_id;
+QTAILQ_INSERT_HEAD(>reslist, res, next);
 }
 
 static void virgl_resource_destroy(VirtIOGPU *g,
@@ -682,6 +700,9 @@ void virtio_gpu_virgl_process_cmd(VirtIOGPU *g,
 /* TODO add security */
 virgl_cmd_ctx_detach_resource(g, cmd);
 break;
+case VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID:
+virtio_gpu_resource_assign_uuid(g, cmd);
+break;
 case VIRTIO_GPU_CMD_GET_CAPSET_INFO:
 virgl_cmd_get_capset_info(g, cmd);
 break;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index cc4c1f81bb..770e4747e3 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -966,6 +966,37 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g,
 virtio_gpu_cleanup_mapping(g, res);
 }
 
+void virtio_gpu_resource_assign_uuid(VirtIOGPU *g,
+ struct virtio_gpu_ctrl_command *cmd)
+{
+struct virtio_gpu_simple_resource *res;
+struct virtio_gpu_resource_assign_uuid assign;
+struct virtio_gpu_resp_resource_uuid resp;
+QemuUUID *uuid = NULL;
+
+VIRTIO_GPU_FILL_CMD(assign);
+virtio_gpu_bswap_32(, sizeof(assign));
+trace_virtio_gpu_cmd_res_assign_uuid(assign.resource_id);
+
+res = virtio_gpu_find_check_resource(g, assign.resource_id, false, 
__func__, >error);
+if (!res) {
+return;
+}
+
+memset(, 0, sizeof(resp));
+resp.hdr.type = VIRTIO_GPU_RESP_OK_RESOURCE_UUID;
+
+uuid = g_hash_table_lookup(g->resource_uuids, 
GUINT_TO_POINTER(assign.resource_id));
+if (!uuid) {
+uuid = g_new(QemuUUID, 1);
+qemu_uuid_generate(uuid);
+

  1   2   >