Re: [PATCH v3 5/5] vhost-vdpa: add callback function for configure interrupt

2021-01-26 Thread Cindy Lu
On Wed, Jan 27, 2021 at 1:47 PM Jason Wang  wrote:
>
>
> On 2021/1/26 下午3:42, Cindy Lu wrote:
> > Add call back function for configure interrupt.
> > Set the notifier's fd to the kernel driver when vdpa start.
> > also set -1 while vdpa stop. then the kernel will release
> > the related resource
> >
> > Signed-off-by: Cindy Lu 
> > ---
> >   hw/virtio/trace-events|  2 ++
> >   hw/virtio/vhost-vdpa.c| 37 ++-
> >   include/hw/virtio/vhost-backend.h |  4 
> >   3 files changed, 42 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> > index 2060a144a2..6710835b46 100644
> > --- a/hw/virtio/trace-events
> > +++ b/hw/virtio/trace-events
> > @@ -52,6 +52,8 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, 
> > int fd) "dev: %p index:
> >   vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 
> > 0x%"PRIx64
> >   vhost_vdpa_set_owner(void *dev) "dev: %p"
> >   vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, 
> > uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p 
> > desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 
> > 0x%"PRIx64
> > +vhost_vdpa_set_config_call(void *dev, int *fd)"dev: %p fd: %p"
> > +
> >
> >   # virtio.c
> >   virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned 
> > out_num) "elem %p size %zd in_num %u out_num %u"
> > diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> > index 01d2101d09..cc1d39d663 100644
> > --- a/hw/virtio/vhost-vdpa.c
> > +++ b/hw/virtio/vhost-vdpa.c
> > @@ -467,20 +467,47 @@ static int vhost_vdpa_get_config(struct vhost_dev 
> > *dev, uint8_t *config,
> >   }
> >   return ret;
> >}
> > +static void vhost_vdpa_config_notify_start(struct vhost_dev *dev,
> > +struct VirtIODevice *vdev, bool start)
> > +{
> > +int fd, r;
> > +if (start) {
> > +fd = event_notifier_get_fd(>config_notifier);
> > +vdev->use_config_notifier = true;
> > + } else {
> > +fd = -1;
> > +vdev->use_config_notifier = false;
> > + }
> > + /*set the fd call back to vdpa driver*/
>
>
> I guess checkpatch.pl might warn here. Please try to silent checkpath.pl
> before submitting patches.
>
Actually I do have run this script, but seems not warned here. I will
pay attention next time
>
> > +r = dev->vhost_ops->vhost_set_config_call(dev, );
> > +if (r) {
> > +vdev->use_config_notifier = false;
> > +info_report("vhost_vdpa_config_notify not started!");
>
>
> This looks kind of fragile. Do we need some workaround here like:
>
> 1) filter out the features that depends on config interrupt
>
> or
>
> 2) A timer to watch the change of config space
>
> Thanks
>
sure I will add this check
>
> > +}
> > +/*active the config_notifier when vdev->use_config_notifier is true*/
> > +if ((vdev->use_config_notifier) && (start)) {
> > +event_notifier_set(>config_notifier);
> > +}
> > +return;
> >
> > +}
> >   static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
> >   {
> >   struct vhost_vdpa *v = dev->opaque;
> >   trace_vhost_vdpa_dev_start(dev, started);
> > +VirtIODevice *vdev = dev->vdev;
> > +
> >   if (started) {
> >   uint8_t status = 0;
> >   memory_listener_register(>listener, _space_memory);
> >   vhost_vdpa_set_vring_ready(dev);
> >   vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> >   vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, );
> > -
> > +/*set the configure interrupt call back*/
> > +vhost_vdpa_config_notify_start(dev, vdev, true);
> >   return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
> >   } else {
> > +vhost_vdpa_config_notify_start(dev, vdev, false);
> >   vhost_vdpa_reset_device(dev);
> >   vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> >  VIRTIO_CONFIG_S_DRIVER);
> > @@ -546,6 +573,13 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev 
> > *dev,
> >   return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
> >   }
> >
> > +static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
> > +   int *fd)
> > +{
> > +trace_vhost_vdpa_set_config_call(dev, fd);
> > +return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, fd);
> > +}
> > +
> >   static int vhost_vdpa_get_features(struct vhost_dev *dev,
> >uint64_t *features)
> >   {
> > @@ -611,4 +645,5 @@ const VhostOps vdpa_ops = {
> >   .vhost_get_device_id = vhost_vdpa_get_device_id,
> >   .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
> >   .vhost_force_iommu = vhost_vdpa_force_iommu,
> > +.vhost_set_config_call = vhost_vdpa_set_config_call,
> >   };
> > diff --git 

[PULL v1 3/3] target/microblaze: Add security attributes on memory transactions

2021-01-26 Thread Edgar E. Iglesias
From: Joe Komlodi 

Using the cfg.use_non_secure bitfield and the MMU access type, we can determine
if the access should be secure or not.

Signed-off-by: Joe Komlodi 
Reviewed-by: Edgar E. Iglesias 
Tested-by: Edgar E. Iglesias 
Message-Id: <1611274735-303873-4-git-send-email-koml...@xilinx.com>
Signed-off-by: Edgar E. Iglesias 
---
 target/microblaze/cpu.h|  3 ++-
 target/microblaze/cpu.c|  2 +-
 target/microblaze/helper.c | 26 +++---
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index 199cfb02d6..e4bba8a755 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -361,7 +361,8 @@ void mb_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
 MMUAccessType access_type,
 int mmu_idx, uintptr_t retaddr);
 void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
-hwaddr mb_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
+hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
+MemTxAttrs *attrs);
 int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index accfb23a4f..d5e8bfe11f 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -375,7 +375,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
 cc->tlb_fill = mb_cpu_tlb_fill;
 #ifndef CONFIG_USER_ONLY
 cc->do_transaction_failed = mb_cpu_transaction_failed;
-cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
+cc->get_phys_page_attrs_debug = mb_cpu_get_phys_page_attrs_debug;
 dc->vmsd = _mb_cpu;
 #endif
 device_class_set_props(dc, mb_properties);
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index cda14a14be..20dbd67313 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -46,6 +46,16 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 
 #else /* !CONFIG_USER_ONLY */
 
+static bool mb_cpu_access_is_secure(MicroBlazeCPU *cpu,
+MMUAccessType access_type)
+{
+if (access_type == MMU_INST_FETCH) {
+return !cpu->ns_axi_ip;
+} else {
+return !cpu->ns_axi_dp;
+}
+}
+
 bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
  MMUAccessType access_type, int mmu_idx,
  bool probe, uintptr_t retaddr)
@@ -55,12 +65,16 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MicroBlazeMMULookup lu;
 unsigned int hit;
 int prot;
+MemTxAttrs attrs = {};
+
+attrs.secure = mb_cpu_access_is_secure(cpu, access_type);
 
 if (mmu_idx == MMU_NOMMU_IDX) {
 /* MMU disabled or not available.  */
 address &= TARGET_PAGE_MASK;
 prot = PAGE_BITS;
-tlb_set_page(cs, address, address, prot, mmu_idx, TARGET_PAGE_SIZE);
+tlb_set_page_with_attrs(cs, address, address, attrs, prot, mmu_idx,
+TARGET_PAGE_SIZE);
 return true;
 }
 
@@ -71,7 +85,8 @@ bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 
 qemu_log_mask(CPU_LOG_MMU, "MMU map mmu=%d v=%x p=%x prot=%x\n",
   mmu_idx, vaddr, paddr, lu.prot);
-tlb_set_page(cs, vaddr, paddr, lu.prot, mmu_idx, TARGET_PAGE_SIZE);
+tlb_set_page_with_attrs(cs, vaddr, paddr, attrs, lu.prot, mmu_idx,
+TARGET_PAGE_SIZE);
 return true;
 }
 
@@ -230,7 +245,8 @@ void mb_cpu_do_interrupt(CPUState *cs)
 }
 }
 
-hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
+hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
+MemTxAttrs *attrs)
 {
 MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
 CPUMBState *env = >env;
@@ -239,6 +255,10 @@ hwaddr mb_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
 int mmu_idx = cpu_mmu_index(env, false);
 unsigned int hit;
 
+/* Caller doesn't initialize */
+*attrs = (MemTxAttrs) {};
+attrs->secure = mb_cpu_access_is_secure(cpu, MMU_DATA_LOAD);
+
 if (mmu_idx != MMU_NOMMU_IDX) {
 hit = mmu_translate(cpu, , addr, 0, 0);
 if (hit) {
-- 
2.25.1




[PULL v1 2/3] target/microblaze: use MMUAccessType instead of int in mmu_translate

2021-01-26 Thread Edgar E. Iglesias
From: Joe Komlodi 

Using MMUAccessType makes it more clear what the variable's use is.
No functional change.

Signed-off-by: Joe Komlodi 
Reviewed-by: Richard Henderson 
Reviewed-by: Edgar E. Iglesias 
Tested-by: Edgar E. Iglesias 
Message-Id: <1611274735-303873-3-git-send-email-koml...@xilinx.com>
Signed-off-by: Edgar E. Iglesias 
---
 target/microblaze/mmu.h | 2 +-
 target/microblaze/mmu.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/microblaze/mmu.h b/target/microblaze/mmu.h
index 09e4075739..b6b4b9ad60 100644
--- a/target/microblaze/mmu.h
+++ b/target/microblaze/mmu.h
@@ -84,7 +84,7 @@ typedef struct {
 } MicroBlazeMMULookup;
 
 unsigned int mmu_translate(MicroBlazeCPU *cpu, MicroBlazeMMULookup *lu,
-   target_ulong vaddr, int rw, int mmu_idx);
+   target_ulong vaddr, MMUAccessType rw, int mmu_idx);
 uint32_t mmu_read(CPUMBState *env, bool ea, uint32_t rn);
 void mmu_write(CPUMBState *env, bool ea, uint32_t rn, uint32_t v);
 void mmu_init(MicroBlazeMMU *mmu);
diff --git a/target/microblaze/mmu.c b/target/microblaze/mmu.c
index 1e426963ba..cc40f275ea 100644
--- a/target/microblaze/mmu.c
+++ b/target/microblaze/mmu.c
@@ -74,7 +74,7 @@ static void mmu_change_pid(CPUMBState *env, unsigned int 
newpid)
 
 /* rw - 0 = read, 1 = write, 2 = fetch.  */
 unsigned int mmu_translate(MicroBlazeCPU *cpu, MicroBlazeMMULookup *lu,
-   target_ulong vaddr, int rw, int mmu_idx)
+   target_ulong vaddr, MMUAccessType rw, int mmu_idx)
 {
 MicroBlazeMMU *mmu = >env.mmu;
 unsigned int i, hit = 0;
-- 
2.25.1




[PULL v1 0/3] Xilinx queue

2021-01-26 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

The following changes since commit 9cd69f1a270235b652766f00b94114f48a2d603f:

  Merge remote-tracking branch 
'remotes/stefanberger/tags/pull-tpm-2021-01-25-1' into staging (2021-01-26 
09:51:02 +)

are available in the Git repository at:

  g...@github.com:edgarigl/qemu.git 
tags/edgar/xilinx-next-2021-01-27.for-upstream

for you to fetch changes up to 43a9ede1efd12d297278d017ce7df7130672e15d:

  target/microblaze: Add security attributes on memory transactions (2021-01-27 
08:32:55 +0100)


For upstream



Joe Komlodi (3):
  target/microblaze: Add use-non-secure property
  target/microblaze: use MMUAccessType instead of int in mmu_translate
  target/microblaze: Add security attributes on memory transactions

 target/microblaze/cpu.h| 14 ++-
 target/microblaze/mmu.h|  2 +-
 target/microblaze/cpu.c| 48 +-
 target/microblaze/helper.c | 26 ++---
 target/microblaze/mmu.c|  2 +-
 5 files changed, 85 insertions(+), 7 deletions(-)

-- 
2.25.1




[PULL v1 1/3] target/microblaze: Add use-non-secure property

2021-01-26 Thread Edgar E. Iglesias
From: Joe Komlodi 

This property is used to control the security of the following interfaces
on MicroBlaze:
M_AXI_DP - data interface
M_AXI_IP - instruction interface
M_AXI_DC - dcache interface
M_AXI_IC - icache interface

It works by enabling or disabling the use of the non_secure[3:0] signals.

Interfaces and their corresponding values are taken from:
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_2/ug984-vivado-microblaze-ref.pdf
page 153.

Signed-off-by: Joe Komlodi 
Reviewed-by: Edgar E. Iglesias 
Tested-by: Edgar E. Iglesias 
Message-Id: <1611274735-303873-2-git-send-email-koml...@xilinx.com>
Signed-off-by: Edgar E. Iglesias 
---
 target/microblaze/cpu.h | 11 ++
 target/microblaze/cpu.c | 46 +
 2 files changed, 57 insertions(+)

diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index c1c264199f..199cfb02d6 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -233,6 +233,12 @@ typedef struct CPUMBState CPUMBState;
 
 #define TARGET_INSN_START_EXTRA_WORDS 1
 
+/* use-non-secure property masks */
+#define USE_NON_SECURE_M_AXI_DP_MASK 0x1
+#define USE_NON_SECURE_M_AXI_IP_MASK 0x2
+#define USE_NON_SECURE_M_AXI_DC_MASK 0x4
+#define USE_NON_SECURE_M_AXI_IC_MASK 0x8
+
 struct CPUMBState {
 uint32_t bvalue;   /* TCG temporary, only valid during a TB */
 uint32_t btarget;  /* Full resolved branch destination */
@@ -316,6 +322,7 @@ typedef struct {
 bool use_msr_instr;
 bool use_pcmp_instr;
 bool use_mmu;
+uint8_t use_non_secure;
 bool dcache_writeback;
 bool endi;
 bool dopb_bus_exception;
@@ -337,6 +344,10 @@ struct MicroBlazeCPU {
 CPUState parent_obj;
 
 /*< public >*/
+bool ns_axi_dp;
+bool ns_axi_ip;
+bool ns_axi_dc;
+bool ns_axi_ic;
 
 CPUNegativeOffsetState neg;
 CPUMBState env;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index c8e754cfb1..accfb23a4f 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -98,6 +98,38 @@ static bool mb_cpu_has_work(CPUState *cs)
 }
 
 #ifndef CONFIG_USER_ONLY
+static void mb_cpu_ns_axi_dp(void *opaque, int irq, int level)
+{
+MicroBlazeCPU *cpu = opaque;
+bool en = cpu->cfg.use_non_secure & USE_NON_SECURE_M_AXI_DP_MASK;
+
+cpu->ns_axi_dp = level & en;
+}
+
+static void mb_cpu_ns_axi_ip(void *opaque, int irq, int level)
+{
+MicroBlazeCPU *cpu = opaque;
+bool en = cpu->cfg.use_non_secure & USE_NON_SECURE_M_AXI_IP_MASK;
+
+cpu->ns_axi_ip = level & en;
+}
+
+static void mb_cpu_ns_axi_dc(void *opaque, int irq, int level)
+{
+MicroBlazeCPU *cpu = opaque;
+bool en = cpu->cfg.use_non_secure & USE_NON_SECURE_M_AXI_DC_MASK;
+
+cpu->ns_axi_dc = level & en;
+}
+
+static void mb_cpu_ns_axi_ic(void *opaque, int irq, int level)
+{
+MicroBlazeCPU *cpu = opaque;
+bool en = cpu->cfg.use_non_secure & USE_NON_SECURE_M_AXI_IC_MASK;
+
+cpu->ns_axi_ic = level & en;
+}
+
 static void microblaze_cpu_set_irq(void *opaque, int irq, int level)
 {
 MicroBlazeCPU *cpu = opaque;
@@ -248,6 +280,10 @@ static void mb_cpu_initfn(Object *obj)
 #ifndef CONFIG_USER_ONLY
 /* Inbound IRQ and FIR lines */
 qdev_init_gpio_in(DEVICE(cpu), microblaze_cpu_set_irq, 2);
+qdev_init_gpio_in_named(DEVICE(cpu), mb_cpu_ns_axi_dp, "ns_axi_dp", 1);
+qdev_init_gpio_in_named(DEVICE(cpu), mb_cpu_ns_axi_ip, "ns_axi_ip", 1);
+qdev_init_gpio_in_named(DEVICE(cpu), mb_cpu_ns_axi_dc, "ns_axi_dc", 1);
+qdev_init_gpio_in_named(DEVICE(cpu), mb_cpu_ns_axi_ic, "ns_axi_ic", 1);
 #endif
 }
 
@@ -277,6 +313,16 @@ static Property mb_properties[] = {
 DEFINE_PROP_BOOL("use-msr-instr", MicroBlazeCPU, cfg.use_msr_instr, true),
 DEFINE_PROP_BOOL("use-pcmp-instr", MicroBlazeCPU, cfg.use_pcmp_instr, 
true),
 DEFINE_PROP_BOOL("use-mmu", MicroBlazeCPU, cfg.use_mmu, true),
+/*
+ * use-non-secure enables/disables the use of the non_secure[3:0] signals.
+ * It is a bitfield where 1 = non-secure for the following bits and their
+ * corresponding interfaces:
+ * 0x1 - M_AXI_DP
+ * 0x2 - M_AXI_IP
+ * 0x4 - M_AXI_DC
+ * 0x8 - M_AXI_IC
+ */
+DEFINE_PROP_UINT8("use-non-secure", MicroBlazeCPU, cfg.use_non_secure, 0),
 DEFINE_PROP_BOOL("dcache-writeback", MicroBlazeCPU, cfg.dcache_writeback,
  false),
 DEFINE_PROP_BOOL("endianness", MicroBlazeCPU, cfg.endi, false),
-- 
2.25.1




Re: [PATCH v3 3/5] virtio-pci: add support for configure interrupt

2021-01-26 Thread Cindy Lu
On Wed, Jan 27, 2021 at 1:44 PM Jason Wang  wrote:
>
>
> On 2021/1/26 下午3:42, Cindy Lu wrote:
> > Add support for configure interrupt, use kvm_irqfd_assign and set the
> > gsi to kernel. When the configure notifier was eventfd_signal by host
> > kernel, this will finally inject an msix interrupt to guest
> >
> > Signed-off-by: Cindy Lu 
> > ---
> >   hw/virtio/virtio-pci.c | 92 ++
> >   1 file changed, 75 insertions(+), 17 deletions(-)
> >
> > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > index 36524a5728..8e192600b8 100644
> > --- a/hw/virtio/virtio-pci.c
> > +++ b/hw/virtio/virtio-pci.c
> > @@ -664,7 +664,6 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
> >   }
> >
> >   static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
> > -unsigned int queue_no,
> >   unsigned int vector)
> >   {
> >   VirtIOIRQFD *irqfd = >vector_irqfd[vector];
> > @@ -691,23 +690,17 @@ static void 
> > kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
> >   }
> >
> >   static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
> > - unsigned int queue_no,
> > + EventNotifier *n,
> >unsigned int vector)
> >   {
> >   VirtIOIRQFD *irqfd = >vector_irqfd[vector];
> > -VirtIODevice *vdev = virtio_bus_get_device(>bus);
> > -VirtQueue *vq = virtio_get_queue(vdev, queue_no);
> > -EventNotifier *n = virtio_queue_get_guest_notifier(vq);
> >   return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, 
> > irqfd->virq);
> >   }
> >
> >   static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
> > -  unsigned int queue_no,
> > +  EventNotifier *n ,
> > unsigned int vector)
> >   {
> > -VirtIODevice *vdev = virtio_bus_get_device(>bus);
> > -VirtQueue *vq = virtio_get_queue(vdev, queue_no);
> > -EventNotifier *n = virtio_queue_get_guest_notifier(vq);
> >   VirtIOIRQFD *irqfd = >vector_irqfd[vector];
> >   int ret;
> >
> > @@ -722,7 +715,8 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy 
> > *proxy, int nvqs)
> >   VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
> >   unsigned int vector;
> >   int ret, queue_no;
> > -
> > +VirtQueue *vq;
> > +EventNotifier *n;
>
>
> new line is needed.
>
will fix this
>
> >   for (queue_no = 0; queue_no < nvqs; queue_no++) {
> >   if (!virtio_queue_get_num(vdev, queue_no)) {
> >   break;
> > @@ -731,7 +725,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy 
> > *proxy, int nvqs)
> >   if (vector >= msix_nr_vectors_allocated(dev)) {
> >   continue;
> >   }
> > -ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector);
> > +ret = kvm_virtio_pci_vq_vector_use(proxy,  vector);
> >   if (ret < 0) {
> >   goto undo;
> >   }
> > @@ -739,7 +733,9 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy 
> > *proxy, int nvqs)
> >* Otherwise, delay until unmasked in the frontend.
> >*/
> >   if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> > -ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
> > +vq = virtio_get_queue(vdev, queue_no);
> > +n = virtio_queue_get_guest_notifier(vq);
> > +ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
> >   if (ret < 0) {
> >   kvm_virtio_pci_vq_vector_release(proxy, vector);
> >   goto undo;
> > @@ -755,13 +751,69 @@ undo:
> >   continue;
> >   }
> >   if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
> > -kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
> > +vq = virtio_get_queue(vdev, queue_no);
> > +n = virtio_queue_get_guest_notifier(vq);
> > +kvm_virtio_pci_irqfd_release(proxy, n, vector);
> >   }
> >   kvm_virtio_pci_vq_vector_release(proxy, vector);
> >   }
> >   return ret;
> >   }
> >
> > +static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy)
> > +{
> > +
> > +VirtIODevice *vdev = virtio_bus_get_device(>bus);
> > +unsigned int vector;
> > +int ret;
> > +EventNotifier *n = virtio_get_config_notifier(vdev);
> > +
> > +vector = vdev->config_vector ;
> > +ret = kvm_virtio_pci_vq_vector_use(proxy, vector);
> > +if (ret < 0) {
> > +goto undo;
> > +}
> > +ret = kvm_virtio_pci_irqfd_use(proxy,  n, vector);
> > +if (ret < 0) {
> > +goto undo;
> > +}
> > +return 0;
> > +undo:
> > +kvm_virtio_pci_irqfd_release(proxy, n, vector);
> > +return ret;
> > +}
>
>
> newline is needed.
>
will 

Re: [PATCH v3 2/5] vhost_net: enable configure interrupt when vhost_net start

2021-01-26 Thread Cindy Lu
On Wed, Jan 27, 2021 at 1:38 PM Jason Wang  wrote:
>
>
> On 2021/1/26 下午3:42, Cindy Lu wrote:
> > While peer is vhost vdpa, setup the configure interrupt function
> > vhost_net_start and release the resource when vhost_net_stop
> >
> > Signed-off-by: Cindy Lu 
> > ---
> >   hw/net/vhost_net.c | 19 ++-
> >   1 file changed, 18 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
> > index 24d555e764..0660da474a 100644
> > --- a/hw/net/vhost_net.c
> > +++ b/hw/net/vhost_net.c
> > @@ -345,6 +345,15 @@ int vhost_net_start(VirtIODevice *dev, NetClientState 
> > *ncs,
> >   error_report("Error binding guest notifier: %d", -r);
> >   goto err;
> >   }
> > +if (ncs->peer && ncs->peer->info->type == 
> > NET_CLIENT_DRIVER_VHOST_VDPA) {
> > +if (k->set_config_notifiers) {
> > +r = k->set_config_notifiers(qbus->parent, true);
> > +if (r < 0) {
> > +error_report("Error binding config notifier: %d", -r);
> > +goto err;
> > +}
> > +   }
> > +}
> >
> >   for (i = 0; i < total_queues; i++) {
> >   peer = qemu_get_peer(ncs, i);
> > @@ -391,7 +400,15 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState 
> > *ncs,
> >   for (i = 0; i < total_queues; i++) {
> >   vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
> >   }
> > -
> > +   if (ncs->peer && ncs->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) 
> > {
> > +if (k->set_config_notifiers) {
>
>
> It looks to me that checking k->set_config_notifier is sufficient here.
>
> Thanks
>
>
sure will fix this

> > +r = k->set_config_notifiers(qbus->parent, false);
> > +if (r < 0) {
> > +error_report("Error unbinding config notifier: %d", -r);
> > +}
> > +   assert(r >= 0);
> > +}
> > +}
> >   r = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
> >   if (r < 0) {
> >   fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);
>




Re: [PATCH 3/7] ppc/pnv: Use skiboot addresses to load kernel and ramfs

2021-01-26 Thread Cédric Le Goater
On 1/27/21 2:27 AM, Murilo Opsfelder Araújo wrote:
> Bonjour, Cédric.
> 
> On Tuesday, January 26, 2021 2:10:55 PM -03 Cédric Le Goater wrote:
>> The current settings are useful to load large kernels (with debug) but
>> it moves the initrd image in a memory region not protected by
>> skiboot. If skiboot is compiled with DEBUG=1, memory poisoning will
>> corrupt the initrd.
>>
>> Cc: Murilo Opsfelder Araujo 
>> Signed-off-by: Cédric Le Goater 
>> ---
>>
>>  If we want to increase the kernel size limit as commit b45b56baeecd
>>  ("ppc/pnv: increase kernel size limit to 256MiB") intented to do, I
>>  think we should add a machine option.
> 
> Is this a problem on bare-metal as well?
> 
> I'm wondering if we should address this the other way around by increasing
> KERNEL_LOAD_SIZE and INITRAMFS_LOAD_SIZE in skiboot to accomodate large kernel
> and initramfs images.

The different memory areas are all strictly defined here : 

  https://github.com/open-power/skiboot/blob/master/include/mem-map.h

C. 

> I think Linux debuginfo images won't get smaller with time and, assuming this
> also happens on bare-metal (I haven't verified), updating skiboot looks more
> appropriate.
> 
> Bear in mind that I'm not an skiboot expert, I'm just considering the
> possibilities.
> 
>>
>>  hw/ppc/pnv.c | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
>> index 14fc9758a973..e500c2e2437e 100644
>> --- a/hw/ppc/pnv.c
>> +++ b/hw/ppc/pnv.c
>> @@ -65,9 +65,9 @@
>>  #define FW_MAX_SIZE (16 * MiB)
>>
>>  #define KERNEL_LOAD_ADDR0x2000
>> -#define KERNEL_MAX_SIZE (256 * MiB)
>> -#define INITRD_LOAD_ADDR0x6000
>> -#define INITRD_MAX_SIZE (256 * MiB)
>> +#define KERNEL_MAX_SIZE (128 * MiB)
>> +#define INITRD_LOAD_ADDR0x2800
>> +#define INITRD_MAX_SIZE (128 * MiB)
>>
>>  static const char *pnv_chip_core_typename(const PnvChip *o)
>>  {
> 
> Cheers!
> 




Re: [PATCH] tests/acceptance: Increase the timeout in the replay tests

2021-01-26 Thread Pavel Dovgalyuk

On 27.01.2021 09:52, Thomas Huth wrote:

Our gitlab-CI just showed a failed test_ppc_mac99 since it was apparently
killed some few seconds before the test finished. Allow it some more
time to complete.

Signed-off-by: Thomas Huth 


Acked-by: Pavel Dovgalyuk 


---
  Seen in this test log:
  
https://gitlab.com/qemu-project/qemu/-/jobs/987148065/artifacts/file/build/tests/results/latest/test-results/26-tests_acceptance_replay_kernel.py_ReplayKernelNormal.test_ppc_mac99/debug.log

  tests/acceptance/replay_kernel.py | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/acceptance/replay_kernel.py 
b/tests/acceptance/replay_kernel.py
index 772633b01d..c1cb862468 100644
--- a/tests/acceptance/replay_kernel.py
+++ b/tests/acceptance/replay_kernel.py
@@ -31,7 +31,7 @@ class ReplayKernelBase(LinuxKernelTest):
  terminates.
  """
  
-timeout = 90

+timeout = 120
  KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 '
  
  def run_vm(self, kernel_path, kernel_command_line, console_pattern,







[PATCH v3 4/4] hw/mips/boston: Use bootloader helper to set GCRs

2021-01-26 Thread Jiaxun Yang
Translate embedded assembly into IO writes which is more
readable.

Also hardcode cm_base at boot time instead of reading from CP0.

Signed-off-by: Jiaxun Yang 
Reviewed-by: Philippe Mathieu-Daudé 
--
v3: Use bl_gen_write_ulong.
---
 hw/mips/boston.c | 47 ---
 1 file changed, 8 insertions(+), 39 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index b976c8199a..06e04ef8de 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -274,48 +274,18 @@ static void boston_register_types(void)
 }
 type_init(boston_register_types)
 
-static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr,
- bool is_64b)
+static void gen_firmware(uint32_t *p, hwaddr kernel_entry, hwaddr fdt_addr)
 {
 const uint32_t cm_base = 0x1610;
 const uint32_t gic_base = 0x1612;
 const uint32_t cpc_base = 0x1620;
 
-/* Move CM GCRs */
-if (is_64b) {
-stl_p(p++, 0x40287803); /* dmfc0 $8, CMGCRBase */
-stl_p(p++, 0x00084138); /* dsll $8, $8, 4 */
-} else {
-stl_p(p++, 0x40087803); /* mfc0 $8, CMGCRBase */
-stl_p(p++, 0x00084100); /* sll  $8, $8, 4 */
-}
-stl_p(p++, 0x3c09a000); /* lui  $9, 0xa000 */
-stl_p(p++, 0x01094025); /* or   $8, $9 */
-stl_p(p++, 0x3c0a | (cm_base >> 16));   /* lui  $10, cm_base >> 16 */
-if (is_64b) {
-stl_p(p++, 0xfd0a0008); /* sd   $10, 0x8($8) */
-} else {
-stl_p(p++, 0xad0a0008); /* sw   $10, 0x8($8) */
-}
-stl_p(p++, 0x012a4025); /* or   $8, $10 */
-
-/* Move & enable GIC GCRs */
-stl_p(p++, 0x3c09 | (gic_base >> 16));  /* lui  $9, gic_base >> 16 */
-stl_p(p++, 0x35290001); /* ori  $9, 0x1 */
-if (is_64b) {
-stl_p(p++, 0xfd090080); /* sd   $9, 0x80($8) */
-} else {
-stl_p(p++, 0xad090080); /* sw   $9, 0x80($8) */
-}
-
-/* Move & enable CPC GCRs */
-stl_p(p++, 0x3c09 | (cpc_base >> 16));  /* lui  $9, cpc_base >> 16 */
-stl_p(p++, 0x35290001); /* ori  $9, 0x1 */
-if (is_64b) {
-stl_p(p++, 0xfd090088); /* sd   $9, 0x88($8) */
-} else {
-stl_p(p++, 0xad090088); /* sw   $9, 0x88($8) */
-}
+bl_gen_write_ulong(, cm_base,
+cpu_mips_phys_to_kseg1(NULL, GCR_BASE_ADDR + GCR_BASE_OFS));
+bl_gen_write_ulong(, gic_base | GCR_GIC_BASE_GICEN_MSK,
+cpu_mips_phys_to_kseg1(NULL, cm_base + GCR_GIC_BASE_OFS));
+bl_gen_write_ulong(, cpc_base | GCR_CPC_BASE_CPCEN_MSK,
+cpu_mips_phys_to_kseg1(NULL, cm_base + GCR_CPC_BASE_OFS));
 
 /*
  * Setup argument registers to follow the UHI boot protocol:
@@ -529,8 +499,7 @@ static void boston_mach_init(MachineState *machine)
 }
 
 gen_firmware(memory_region_get_ram_ptr(flash) + 0x7c0,
- s->kernel_entry, s->fdt_base,
- cpu_type_is_64bit(machine->cpu_type));
+ s->kernel_entry, s->fdt_base);
 } else if (!qtest_enabled()) {
 error_report("Please provide either a -kernel or -bios argument");
 exit(1);
-- 
2.30.0




[PATCH v3 3/4] hw/mips/malta: Use bootloader helper to set BAR resgiters

2021-01-26 Thread Jiaxun Yang
Translate embedded assembly into IO writes which is more
readable.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/malta.c | 68 -
 1 file changed, 22 insertions(+), 46 deletions(-)

diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index ffd67b8293..9466fd1058 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -875,55 +875,31 @@ static void write_bootloader(uint8_t *base, uint64_t 
run_addr,
 p = (uint32_t *) (base + 0x580);
 
 /* Load BAR registers as done by YAMON */
-stl_p(p++, 0x3c09b400);  /* lui t1, 0xb400 */
-
-#ifdef TARGET_WORDS_BIGENDIAN
-stl_p(p++, 0x3c08df00);  /* lui t0, 0xdf00 */
-#else
-stl_p(p++, 0x340800df);  /* ori t0, r0, 0x00df */
-#endif
-stl_p(p++, 0xad280068);  /* sw t0, 0x0068(t1) */
-
-stl_p(p++, 0x3c09bbe0);  /* lui t1, 0xbbe0 */
-
-#ifdef TARGET_WORDS_BIGENDIAN
-stl_p(p++, 0x3c08c000);  /* lui t0, 0xc000 */
-#else
-stl_p(p++, 0x340800c0);  /* ori t0, r0, 0x00c0 */
-#endif
-stl_p(p++, 0xad280048);  /* sw t0, 0x0048(t1) */
-#ifdef TARGET_WORDS_BIGENDIAN
-stl_p(p++, 0x3c084000);  /* lui t0, 0x4000 */
-#else
-stl_p(p++, 0x34080040);  /* ori t0, r0, 0x0040 */
-#endif
-stl_p(p++, 0xad280050);  /* sw t0, 0x0050(t1) */
-
-#ifdef TARGET_WORDS_BIGENDIAN
-stl_p(p++, 0x3c088000);  /* lui t0, 0x8000 */
-#else
-stl_p(p++, 0x34080080);  /* ori t0, r0, 0x0080 */
-#endif
-stl_p(p++, 0xad280058);  /* sw t0, 0x0058(t1) */
-#ifdef TARGET_WORDS_BIGENDIAN
-stl_p(p++, 0x3c083f00);  /* lui t0, 0x3f00 */
-#else
-stl_p(p++, 0x3408003f);  /* ori t0, r0, 0x003f */
-#endif
-stl_p(p++, 0xad280060);  /* sw t0, 0x0060(t1) */
-
-#ifdef TARGET_WORDS_BIGENDIAN
-stl_p(p++, 0x3c08c100);  /* lui t0, 0xc100 */
-#else
-stl_p(p++, 0x340800c1);  /* ori t0, r0, 0x00c1 */
-#endif
-stl_p(p++, 0xad280080);  /* sw t0, 0x0080(t1) */
+/* Bus endianess is always reversed */
 #ifdef TARGET_WORDS_BIGENDIAN
-stl_p(p++, 0x3c085e00);  /* lui t0, 0x5e00 */
+#define cpu_to_gt32 cpu_to_le32
 #else
-stl_p(p++, 0x3408005e);  /* ori t0, r0, 0x005e */
+#define cpu_to_gt32 cpu_to_be32
 #endif
-stl_p(p++, 0xad280088);  /* sw t0, 0x0088(t1) */
+/* move GT64120 registers from 0x1400 to 0x1be0 */
+bl_gen_write_u32(, cpu_to_gt32(0xdf00),
+cpu_mips_phys_to_kseg1(NULL, 0x1468));
+/* setup MEM-to-PCI0 mapping */
+/* setup PCI0 io window to 0x1800-0x181f */
+bl_gen_write_u32(, cpu_to_gt32(0xc000),
+cpu_mips_phys_to_kseg1(NULL, 0x1be00048));
+bl_gen_write_u32(, cpu_to_gt32(0x4000),
+cpu_mips_phys_to_kseg1(NULL, 0x1be00050));
+/* setup PCI0 mem windows */
+bl_gen_write_u32(, cpu_to_gt32(0x8000),
+cpu_mips_phys_to_kseg1(NULL, 0x1be00058));
+bl_gen_write_u32(, cpu_to_gt32(0x3f00),
+cpu_mips_phys_to_kseg1(NULL, 0x1be00060));
+bl_gen_write_u32(, cpu_to_gt32(0xc100),
+cpu_mips_phys_to_kseg1(NULL, 0x1be00080));
+bl_gen_write_u32(, cpu_to_gt32(0x5e00),
+cpu_mips_phys_to_kseg1(NULL, 0x1be00088));
+#undef cpu_to_gt32
 
 if (semihosting_get_argc()) {
 a0 = 0;
-- 
2.30.0




[PATCH v3 1/4] hw/mips: Add a bootloader helper

2021-01-26 Thread Jiaxun Yang
Add a bootloader helper to generate simple bootloaders for kernel.
It can help us reduce inline hex hack and also keep MIPS release 6
compatibility easier.

Signed-off-by: Jiaxun Yang 
---
 include/hw/mips/bootloader.h |  49 +++
 hw/mips/bootloader.c | 164 +++
 hw/mips/meson.build  |   2 +-
 3 files changed, 214 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/mips/bootloader.h
 create mode 100644 hw/mips/bootloader.c

diff --git a/include/hw/mips/bootloader.h b/include/hw/mips/bootloader.h
new file mode 100644
index 00..2a0e1a11c9
--- /dev/null
+++ b/include/hw/mips/bootloader.h
@@ -0,0 +1,49 @@
+#ifndef HW_MIPS_BOOTLOADER_H
+#define HW_MIPS_BOOTLOADER_H
+
+#include "exec/cpu-defs.h"
+
+void bl_gen_jump_to(uint32_t **p, target_ulong jump_addr);
+void bl_gen_jump_kernel(uint32_t **p, target_ulong sp, target_ulong a0,
+target_ulong a1, target_ulong a2, target_ulong a3,
+target_ulong kernel_addr);
+void bl_gen_write_ulong(uint32_t **p, target_ulong val, target_ulong addr);
+void bl_gen_write_u32(uint32_t **p, uint32_t val, target_ulong addr);
+void bl_gen_write_u64(uint32_t **p, uint64_t val, target_ulong addr);
+
+typedef enum bl_reg {
+BL_REG_ZERO = 0,
+BL_REG_AT = 1,
+BL_REG_V0 = 2,
+BL_REG_V1 = 3,
+BL_REG_A0 = 4,
+BL_REG_A1 = 5,
+BL_REG_A2 = 6,
+BL_REG_A3 = 7,
+BL_REG_T0 = 8,
+BL_REG_T1 = 9,
+BL_REG_T2 = 10,
+BL_REG_T3 = 11,
+BL_REG_T4 = 12,
+BL_REG_T5 = 13,
+BL_REG_T6 = 14,
+BL_REG_T7 = 15,
+BL_REG_S0 = 16,
+BL_REG_S1 = 17,
+BL_REG_S2 = 18,
+BL_REG_S3 = 19,
+BL_REG_S4 = 20,
+BL_REG_S5 = 21,
+BL_REG_S6 = 22,
+BL_REG_S7 = 23,
+BL_REG_T8 = 24,
+BL_REG_T9 = 25,
+BL_REG_K0 = 26,
+BL_REG_K1 = 27,
+BL_REG_GP = 28,
+BL_REG_SP = 29,
+BL_REG_FP = 30,
+BL_REG_RA = 31,
+} bl_reg;
+
+#endif
diff --git a/hw/mips/bootloader.c b/hw/mips/bootloader.c
new file mode 100644
index 00..8989db870e
--- /dev/null
+++ b/hw/mips/bootloader.c
@@ -0,0 +1,164 @@
+/*
+ * Utility for QEMU MIPS to generate it's simple bootloader
+ *
+ * Instructions used here are carefully selected to keep compatibility with
+ * MIPS Release 6.
+ *
+ * Copyright (C) 2020 Jiaxun Yang 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "cpu.h"
+#include "hw/mips/bootloader.h"
+
+/* Base types */
+static void bl_gen_nop(uint32_t **p)
+{
+stl_p(*p, 0);
+*p = *p + 1;
+}
+
+static void bl_gen_r_type(uint32_t **p, uint8_t opcode, bl_reg rs, bl_reg rt,
+bl_reg rd, uint8_t shift, uint8_t funct)
+{
+uint32_t insn = 0;
+
+insn = deposit32(insn, 26, 6, opcode);
+insn = deposit32(insn, 21, 5, rs);
+insn = deposit32(insn, 16, 5, rt);
+insn = deposit32(insn, 11, 5, rd);
+insn = deposit32(insn, 6, 5, shift);
+insn = deposit32(insn, 0, 6, funct);
+
+stl_p(*p, insn);
+*p = *p + 1;
+}
+
+static void bl_gen_i_type(uint32_t **p, uint8_t opcode, bl_reg rs, bl_reg rt,
+uint16_t imm)
+{
+uint32_t insn = 0;
+
+insn = deposit32(insn, 26, 6, opcode);
+insn = deposit32(insn, 21, 5, rs);
+insn = deposit32(insn, 16, 5, rt);
+insn = deposit32(insn, 0, 16, imm);
+
+stl_p(*p, insn);
+*p = *p + 1;
+}
+
+static bool bootcpu_supports_isa(uint64_t isa_mask)
+{
+return cpu_supports_isa(_CPU(first_cpu)->env, isa_mask);
+}
+
+/* Single instructions */
+static void bl_gen_dsll(uint32_t **p, bl_reg rd, bl_reg rt, uint8_t sa)
+{
+if (bootcpu_supports_isa(ISA_MIPS3)) {
+bl_gen_r_type(p, 0, 0, rt, rd, sa, 0x38);
+} else {
+g_assert_not_reached(); /* unsupported */
+}
+}
+
+static void bl_gen_jalr(uint32_t **p, bl_reg rs)
+{
+bl_gen_r_type(p, 0, rs, 0, BL_REG_RA, 0, 0x9);
+}
+
+static void bl_gen_lui(uint32_t **p, bl_reg rt, uint16_t imm)
+{
+/* R6: It's a alias of AUI with RS = 0 */
+bl_gen_i_type(p, 0xf, 0, rt, imm);
+}
+
+static void bl_gen_ori(uint32_t **p, bl_reg rt, bl_reg rs, uint16_t imm)
+{
+bl_gen_i_type(p, 0xd, rs, rt, imm);
+}
+
+static void bl_gen_sw(uint32_t **p, bl_reg rt, uint8_t base, uint16_t offset)
+{
+bl_gen_i_type(p, 0x2b, base, rt, offset);
+}
+
+static void bl_gen_sd(uint32_t **p, bl_reg rt, uint8_t base, uint16_t offset)
+{
+if (bootcpu_supports_isa(ISA_MIPS3)) {
+bl_gen_i_type(p, 0x3f, base, rt, offset);
+} else {
+g_assert_not_reached(); /* unsupported */
+}
+}
+
+/* Pseudo instructions */
+static void bl_gen_li(uint32_t **p, bl_reg rt, uint32_t imm)
+{
+bl_gen_lui(p, rt, extract32(imm, 16, 16));
+bl_gen_ori(p, rt, rt, extract32(imm, 0, 16));
+}
+
+static void bl_gen_dli(uint32_t **p, bl_reg rt, uint64_t imm)
+{
+bl_gen_li(p, rt, extract64(imm, 32, 32));
+bl_gen_dsll(p, rt, rt, 16);
+bl_gen_ori(p, rt, rt, extract64(imm, 16, 

[PATCH v3 2/4] hw/mips: Use bl_gen_kernel_jump to generate bootloaders

2021-01-26 Thread Jiaxun Yang
Replace embedded binary with generated code.

Signed-off-by: Jiaxun Yang 
---
 hw/mips/boston.c| 17 ++---
 hw/mips/fuloong2e.c | 28 
 hw/mips/malta.c | 41 ++---
 3 files changed, 16 insertions(+), 70 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 467fbc1c8b..b976c8199a 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -27,6 +27,7 @@
 #include "hw/ide/ahci.h"
 #include "hw/loader.h"
 #include "hw/loader-fit.h"
+#include "hw/mips/bootloader.h"
 #include "hw/mips/cps.h"
 #include "hw/pci-host/xilinx-pcie.h"
 #include "hw/qdev-clock.h"
@@ -324,21 +325,7 @@ static void gen_firmware(uint32_t *p, hwaddr kernel_entry, 
hwaddr fdt_addr,
  * a2/$6 = 0
  * a3/$7 = 0
  */
-stl_p(p++, 0x2404fffe); /* li   $4, -2 */
-/* lui  $5, hi(fdt_addr) */
-stl_p(p++, 0x3c05 | ((fdt_addr >> 16) & 0x));
-if (fdt_addr & 0x) {/* ori  $5, lo(fdt_addr) */
-stl_p(p++, 0x34a5 | (fdt_addr & 0x));
-}
-stl_p(p++, 0x3406); /* li   $6, 0 */
-stl_p(p++, 0x3407); /* li   $7, 0 */
-
-/* Load kernel entry address & jump to it */
-/* lui  $25, hi(kernel_entry) 
*/
-stl_p(p++, 0x3c19 | ((kernel_entry >> 16) & 0x));
-/* ori  $25, lo(kernel_entry) 
*/
-stl_p(p++, 0x3739 | (kernel_entry & 0x));
-stl_p(p++, 0x0329); /* jr   $25 */
+bl_gen_jump_kernel(, 0, (int32_t)-2, fdt_addr, 0, 0, kernel_entry);
 }
 
 static const void *boston_fdt_filter(void *opaque, const void *fdt_orig,
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index bac2adbd5a..1ae84ecf92 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -33,6 +33,7 @@
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/block/flash.h"
 #include "hw/mips/mips.h"
+#include "hw/mips/bootloader.h"
 #include "hw/mips/cpudevs.h"
 #include "hw/pci/pci.h"
 #include "qemu/log.h"
@@ -185,30 +186,9 @@ static void write_bootloader(CPUMIPSState *env, uint8_t 
*base,
 /* Second part of the bootloader */
 p = (uint32_t *)(base + 0x040);
 
-/* lui a0, 0 */
-stl_p(p++, 0x3c04);
-/* ori a0, a0, 2 */
-stl_p(p++, 0x34840002);
-/* lui a1, high(ENVP_VADDR) */
-stl_p(p++, 0x3c05 | ((ENVP_VADDR >> 16) & 0x));
-/* ori a1, a0, low(ENVP_VADDR) */
-stl_p(p++, 0x34a5 | (ENVP_VADDR & 0x));
-/* lui a2, high(ENVP_VADDR + 8) */
-stl_p(p++, 0x3c06 | (((ENVP_VADDR + 8) >> 16) & 0x));
-/* ori a2, a2, low(ENVP_VADDR + 8) */
-stl_p(p++, 0x34c6 | ((ENVP_VADDR + 8) & 0x));
-/* lui a3, high(env->ram_size) */
-stl_p(p++, 0x3c07 | (loaderparams.ram_size >> 16));
-/* ori a3, a3, low(env->ram_size) */
-stl_p(p++, 0x34e7 | (loaderparams.ram_size & 0x));
-/* lui ra, high(kernel_addr) */
-stl_p(p++, 0x3c1f | ((kernel_addr >> 16) & 0x));
-/* ori ra, ra, low(kernel_addr) */
-stl_p(p++, 0x37ff | (kernel_addr & 0x));
-/* jr ra */
-stl_p(p++, 0x03e8);
-/* nop */
-stl_p(p++, 0x);
+bl_gen_jump_kernel(, ENVP_VADDR - 64, 2, ENVP_VADDR,
+   ENVP_VADDR + 8, loaderparams.ram_size,
+   kernel_addr);
 }
 
 static void main_cpu_reset(void *opaque)
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 9afc0b427b..ffd67b8293 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -37,6 +37,7 @@
 #include "hw/i2c/smbus_eeprom.h"
 #include "hw/block/flash.h"
 #include "hw/mips/mips.h"
+#include "hw/mips/bootloader.h"
 #include "hw/mips/cpudevs.h"
 #include "hw/pci/pci.h"
 #include "sysemu/sysemu.h"
@@ -844,6 +845,7 @@ static void write_bootloader_nanomips(uint8_t *base, 
uint64_t run_addr,
 static void write_bootloader(uint8_t *base, uint64_t run_addr,
  uint64_t kernel_entry)
 {
+target_ulong a0;
 uint32_t *p;
 
 /* Small bootloader */
@@ -872,30 +874,6 @@ static void write_bootloader(uint8_t *base, uint64_t 
run_addr,
 /* Second part of the bootloader */
 p = (uint32_t *) (base + 0x580);
 
-if (semihosting_get_argc()) {
-/* Preserve a0 content as arguments have been passed */
-stl_p(p++, 0x);  /* nop */
-} else {
-stl_p(p++, 0x24040002);  /* addiu a0, zero, 2 */
-}
-
-/* lui sp, high(ENVP_VADDR) */
-stl_p(p++, 0x3c1d | (((ENVP_VADDR - 64) >> 16) & 0x));
-/* ori sp, sp, low(ENVP_VADDR) */
-stl_p(p++, 0x37bd | ((ENVP_VADDR - 64) & 0x));
-/* lui a1, high(ENVP_VADDR) */
-stl_p(p++, 0x3c05 | ((ENVP_VADDR >> 16) & 0x));
-/* ori a1, a1, low(ENVP_VADDR) */
-stl_p(p++, 0x34a5 | (ENVP_VADDR & 0x));
-/* lui 

[PATCH v3 0/4] MIPS Bootloader helper

2021-01-26 Thread Jiaxun Yang
v2:
A big reconstruction. rewrite helpers with CPU feature and sepreate
changesets.
v3:
respin

Jiaxun Yang (4):
  hw/mips: Add a bootloader helper
  hw/mips: Use bl_gen_kernel_jump to generate bootloaders
  hw/mips/malta: Use bootloader helper to set BAR resgiters
  hw/mips/boston: Use bootloader helper to set GCRs

 include/hw/mips/bootloader.h |  49 +++
 hw/mips/bootloader.c | 164 +++
 hw/mips/boston.c |  64 +++---
 hw/mips/fuloong2e.c  |  28 +-
 hw/mips/malta.c  | 109 +++
 hw/mips/meson.build  |   2 +-
 6 files changed, 260 insertions(+), 156 deletions(-)
 create mode 100644 include/hw/mips/bootloader.h
 create mode 100644 hw/mips/bootloader.c

-- 
2.30.0




Re: [PATCH v4 4/4] meson: Warn when TCI is selected but TCG backend is available

2021-01-26 Thread Stefan Weil

Am 26.01.21 um 23:39 schrieb Richard Henderson:


On 1/26/21 9:44 AM, Stefan Weil wrote:

I was not talking about the TODO assertions. When I wrote TCI, I only enabled
and included code which was triggered by my testing - that's why I said the
productive code lines have 100 % test coverage. TODO assertions are not
productive code, but debug code which were made to detect new test cases. They
were successful, too, because they were triggered by some tests in `make
check-tcg`.

The TODO assertions are all bugs.

Any *real* dead code detection should have been done in
tcg/tci/tcg-target.c.inc.  What's interpreted in tcg/tci.c should be exactly
what is produced on the other side, and you are producing more than you are
consuming.



Unless the TCG opcodes in tcg/tci/tcg-target.c.inc are used in real-live 
scenarios, they are dead code, too.


Writing a test case which produces them directly (not for some real 
architecture) is not a real-live scenario.


And the remaining TODO assertions are a good indicator that the current 
tests are incomplete for native TCG because they obviously don't cover 
all TCG opcodes.


Stefan






[PATCH] tests/acceptance: Increase the timeout in the replay tests

2021-01-26 Thread Thomas Huth
Our gitlab-CI just showed a failed test_ppc_mac99 since it was apparently
killed some few seconds before the test finished. Allow it some more
time to complete.

Signed-off-by: Thomas Huth 
---
 Seen in this test log:
 
https://gitlab.com/qemu-project/qemu/-/jobs/987148065/artifacts/file/build/tests/results/latest/test-results/26-tests_acceptance_replay_kernel.py_ReplayKernelNormal.test_ppc_mac99/debug.log

 tests/acceptance/replay_kernel.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/acceptance/replay_kernel.py 
b/tests/acceptance/replay_kernel.py
index 772633b01d..c1cb862468 100644
--- a/tests/acceptance/replay_kernel.py
+++ b/tests/acceptance/replay_kernel.py
@@ -31,7 +31,7 @@ class ReplayKernelBase(LinuxKernelTest):
 terminates.
 """
 
-timeout = 90
+timeout = 120
 KERNEL_COMMON_COMMAND_LINE = 'printk.time=1 panic=-1 '
 
 def run_vm(self, kernel_path, kernel_command_line, console_pattern,
-- 
2.27.0




Re: [PATCH] libqtest: Rework qtest_rsp()

2021-01-26 Thread Thomas Huth

On 26/01/2021 16.16, Markus Armbruster wrote:

qtest_rsp() is used in two different ways: (1) return some arguments
to caller, which the caller must free, and (2) return no arguments to
caller.  Passing non-zero @expected_args gets you (1), and passing
zero gets you (2).

Having "the return value must be freed" depend on an argument this way
is less than ideal.

Provide separate functions for the two ways: (1) qtest_rsp_args()
takes @expected_args (possibly zero), and returns that number of
arguments.  Caller must free the return value always.  (2) qtest_rsp()
assumes zero, and returns nothing.

Signed-off-by: Markus Armbruster 
---
  tests/qtest/libqtest.c | 50 ++
  1 file changed, 26 insertions(+), 24 deletions(-)


Reviewed-by: Thomas Huth 




[PATCH] gitlab-ci.yml: Run check-tcg with TCI

2021-01-26 Thread Thomas Huth
It's now possible to also run the non-x86 TCG tests with TCI.

Signed-off-by: Thomas Huth 
---
 Based-on: 20210126192518.2019885-1...@weilnetz.de
 CI-run: https://gitlab.com/huth/qemu/-/jobs/988742434#L5200

 .gitlab-ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index de3a3d25b5..19602f4319 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -475,7 +475,7 @@ build-oss-fuzz:
 build-tci:
   <<: *native_build_job_definition
   variables:
-IMAGE: fedora
+IMAGE: debian-all-test-cross
   script:
 - TARGETS="aarch64 alpha arm hppa m68k microblaze moxie ppc64 s390x x86_64"
 - mkdir build
@@ -483,7 +483,6 @@ build-tci:
 - ../configure --enable-tcg-interpreter
 --target-list="$(for tg in $TARGETS; do echo -n ${tg}'-softmmu '; 
done)" || { cat config.log meson-logs/meson-log.txt && exit 1; }
 - make -j"$JOBS"
-- make run-tcg-tests-x86_64-softmmu
 - make tests/qtest/boot-serial-test tests/qtest/cdrom-test 
tests/qtest/pxe-test
 - for tg in $TARGETS ; do
 export QTEST_QEMU_BINARY="./qemu-system-${tg}" ;
@@ -492,6 +491,7 @@ build-tci:
   done
 - QTEST_QEMU_BINARY="./qemu-system-x86_64" ./tests/qtest/pxe-test
 - QTEST_QEMU_BINARY="./qemu-system-s390x" ./tests/qtest/pxe-test -m slow
+- make check-tcg
 
 # Alternate coroutines implementations are only really of interest to KVM users
 # However we can't test against KVM on Gitlab-CI so we can only run unit tests
-- 
2.27.0




Re: [PATCH v3 9/9] docs/system: riscv: Add documentation for sifive_u machine

2021-01-26 Thread Palmer Dabbelt

On Mon, 25 Jan 2021 22:00:07 PST (-0800), bmeng...@gmail.com wrote:

From: Bin Meng 

This adds detailed documentation for RISC-V `sifive_u` machine,
including the following information:

- Supported devices
- Hardware configuration information
- Boot options
- Machine-specific options
- Running Linux kernel
- Running VxWorks kernel
- Running U-Boot, and with an alternate configuration

Signed-off-by: Bin Meng 
Reviewed-by: Alistair Francis 

---

Changes in v3:
- Convert sifive_u.rst from UTF-8 to ASCII

Changes in v2:
- Correct several typos in sifive_u.rst
- Update doc to mention U-Boot v2021.01

 docs/system/riscv/sifive_u.rst | 336 +
 docs/system/target-riscv.rst   |  10 +
 2 files changed, 346 insertions(+)
 create mode 100644 docs/system/riscv/sifive_u.rst

diff --git a/docs/system/riscv/sifive_u.rst b/docs/system/riscv/sifive_u.rst
new file mode 100644
index 00..98e7562848
--- /dev/null
+++ b/docs/system/riscv/sifive_u.rst
@@ -0,0 +1,336 @@
+SiFive HiFive Unleashed (``sifive_u``)
+==
+
+SiFive HiFive Unleashed Development Board is the ultimate RISC-V development
+board featuring the Freedom U540 multi-core RISC-V processor.
+
+Supported devices
+-
+
+The ``sifive_u`` machine supports the following devices:
+
+ * 1 E51 / E31 core
+ * Up to 4 U54 / U34 cores
+ * Core Level Interruptor (CLINT)
+ * Platform-Level Interrupt Controller (PLIC)
+ * Power, Reset, Clock, Interrupt (PRCI)
+ * L2 Loosely Integrated Memory (L2-LIM)
+ * DDR memory controller
+ * 2 UARTs
+ * 1 GEM Ethernet controller
+ * 1 GPIO controller
+ * 1 One-Time Programmable (OTP) memory with stored serial number
+ * 1 DMA controller
+ * 2 QSPI controllers
+ * 1 ISSI 25WP256 flash
+ * 1 SD card in SPI mode
+
+Please note the real world HiFive Unleashed board has a fixed configuration of
+1 E51 core and 4 U54 core combination and the RISC-V core boots in 64-bit mode.
+With QEMU, one can create a machine with 1 E51 core and up to 4 U54 cores. It
+is also possible to create a 32-bit variant with the same peripherals except
+that the RISC-V cores are replaced by the 32-bit ones (E31 and U34), to help
+testing of 32-bit guest software.
+
+Hardware configuration information
+--
+
+The ``sifive_u`` machine automatically generates a device tree blob ("dtb")
+which it passes to the guest. This provides information about the addresses,
+interrupt lines and other configuration of the various devices in the system.
+Guest software should discover the devices that are present in the generated
+DTB instead of using a DTB for the real hardware, as some of the devices are
+not modeled by QEMU and trying to access these devices may cause unexpected
+behavior.
+
+Boot options
+
+
+The ``sifive_u`` machine can start using the standard -kernel functionality
+for loading a Linux kernel, a VxWorks kernel, a modified U-Boot bootloader
+(S-mode) or ELF executable with the default OpenSBI firmware image as the
+-bios. It also supports booting the unmodified U-Boot bootloader using the
+standard -bios functionality.
+
+Machine-specific options
+
+
+The following machine-specific options are supported:
+
+- serial=nnn
+
+  The board serial number. When not given, the default serial number 1 is used.
+
+  SiFive reserves the first 1 KiB of the 16 KiB OTP memory for internal use.
+  The current usage is only used to store the serial number of the board at
+  offset 0xfc. U-Boot reads the serial number from the OTP memory, and uses
+  it to generate a unique MAC address to be programmed to the on-chip GEM
+  Ethernet controller. When multiple QEMU ``sifive_u`` machines are created
+  and connected to the same subnet, they all have the same MAC address hence
+  it creates an unusable network. In such scenario, user should give different
+  values to serial= when creating different ``sifive_u`` machines.
+
+- start-in-flash
+
+  When given, QEMU's ROM codes jump to QSPI memory-mapped flash directly.
+  Otherwise QEMU will jump to DRAM or L2LIM depending on the msel= value.
+  When not given, it defaults to direct DRAM booting.
+
+- msel=[6|11]
+
+  Mode Select (MSEL[3:0]) pins value, used to control where to boot from.
+
+  The FU540 SoC supports booting from several sources, which are controlled
+  using the Mode Select pins on the chip. Typically, the boot process runs
+  through several stages before it begins execution of user-provided programs.
+  These stages typically include the following:
+
+  1. Zeroth Stage Boot Loader (ZSBL), which is contained in an on-chip mask
+ ROM and provided by QEMU. Note QEMU implemented ROM codes are not the
+ same as what is programmed in the hardware. The QEMU one is a simplified
+ version, but it provides the same functionality as the hardware.
+  2. First Stage Boot Loader (FSBL), which brings up PLLs and DDR memory.
+ This is U-Boot SPL.
+  3. Second 

Re: [PATCH v3 5/5] vhost-vdpa: add callback function for configure interrupt

2021-01-26 Thread Jason Wang



On 2021/1/26 下午3:42, Cindy Lu wrote:

Add call back function for configure interrupt.
Set the notifier's fd to the kernel driver when vdpa start.
also set -1 while vdpa stop. then the kernel will release
the related resource

Signed-off-by: Cindy Lu 
---
  hw/virtio/trace-events|  2 ++
  hw/virtio/vhost-vdpa.c| 37 ++-
  include/hw/virtio/vhost-backend.h |  4 
  3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index 2060a144a2..6710835b46 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -52,6 +52,8 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) 
"dev: %p index:
  vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 
0x%"PRIx64
  vhost_vdpa_set_owner(void *dev) "dev: %p"
  vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t 
used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 
0x%"PRIx64" used_user_addr: 0x%"PRIx64
+vhost_vdpa_set_config_call(void *dev, int *fd)"dev: %p fd: %p"
+
  
  # virtio.c

  virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) 
"elem %p size %zd in_num %u out_num %u"
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 01d2101d09..cc1d39d663 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -467,20 +467,47 @@ static int vhost_vdpa_get_config(struct vhost_dev *dev, 
uint8_t *config,
  }
  return ret;
   }
+static void vhost_vdpa_config_notify_start(struct vhost_dev *dev,
+struct VirtIODevice *vdev, bool start)
+{
+int fd, r;
+if (start) {
+fd = event_notifier_get_fd(>config_notifier);
+vdev->use_config_notifier = true;
+ } else {
+fd = -1;
+vdev->use_config_notifier = false;
+ }
+ /*set the fd call back to vdpa driver*/



I guess checkpatch.pl might warn here. Please try to silent checkpath.pl 
before submitting patches.




+r = dev->vhost_ops->vhost_set_config_call(dev, );
+if (r) {
+vdev->use_config_notifier = false;
+info_report("vhost_vdpa_config_notify not started!");



This looks kind of fragile. Do we need some workaround here like:

1) filter out the features that depends on config interrupt

or

2) A timer to watch the change of config space

Thanks



+}
+/*active the config_notifier when vdev->use_config_notifier is true*/
+if ((vdev->use_config_notifier) && (start)) {
+event_notifier_set(>config_notifier);
+}
+return;
  
+}

  static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
  {
  struct vhost_vdpa *v = dev->opaque;
  trace_vhost_vdpa_dev_start(dev, started);
+VirtIODevice *vdev = dev->vdev;
+
  if (started) {
  uint8_t status = 0;
  memory_listener_register(>listener, _space_memory);
  vhost_vdpa_set_vring_ready(dev);
  vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
  vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, );
-
+/*set the configure interrupt call back*/
+vhost_vdpa_config_notify_start(dev, vdev, true);
  return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
  } else {
+vhost_vdpa_config_notify_start(dev, vdev, false);
  vhost_vdpa_reset_device(dev);
  vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
 VIRTIO_CONFIG_S_DRIVER);
@@ -546,6 +573,13 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev *dev,
  return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
  }
  
+static int vhost_vdpa_set_config_call(struct vhost_dev *dev,

+   int *fd)
+{
+trace_vhost_vdpa_set_config_call(dev, fd);
+return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, fd);
+}
+
  static int vhost_vdpa_get_features(struct vhost_dev *dev,
   uint64_t *features)
  {
@@ -611,4 +645,5 @@ const VhostOps vdpa_ops = {
  .vhost_get_device_id = vhost_vdpa_get_device_id,
  .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
  .vhost_force_iommu = vhost_vdpa_force_iommu,
+.vhost_set_config_call = vhost_vdpa_set_config_call,
  };
diff --git a/include/hw/virtio/vhost-backend.h 
b/include/hw/virtio/vhost-backend.h
index 8a6f8e2a7a..1a2fee8994 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -125,6 +125,9 @@ typedef int (*vhost_get_device_id_op)(struct vhost_dev 
*dev, uint32_t *dev_id);
  
  typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
  
+typedef int (*vhost_set_config_call_op)(struct vhost_dev *dev,

+   int *fd);
+
  typedef struct VhostOps {
  VhostBackendType backend_type;
  vhost_backend_init vhost_backend_init;
@@ -170,6 +173,7 @@ typedef struct VhostOps {
  

Re: [PATCH v3 3/5] virtio-pci: add support for configure interrupt

2021-01-26 Thread Jason Wang



On 2021/1/26 下午3:42, Cindy Lu wrote:

Add support for configure interrupt, use kvm_irqfd_assign and set the
gsi to kernel. When the configure notifier was eventfd_signal by host
kernel, this will finally inject an msix interrupt to guest

Signed-off-by: Cindy Lu 
---
  hw/virtio/virtio-pci.c | 92 ++
  1 file changed, 75 insertions(+), 17 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 36524a5728..8e192600b8 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -664,7 +664,6 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
  }
  
  static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,

-unsigned int queue_no,
  unsigned int vector)
  {
  VirtIOIRQFD *irqfd = >vector_irqfd[vector];
@@ -691,23 +690,17 @@ static void 
kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
  }
  
  static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,

- unsigned int queue_no,
+ EventNotifier *n,
   unsigned int vector)
  {
  VirtIOIRQFD *irqfd = >vector_irqfd[vector];
-VirtIODevice *vdev = virtio_bus_get_device(>bus);
-VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-EventNotifier *n = virtio_queue_get_guest_notifier(vq);
  return kvm_irqchip_add_irqfd_notifier_gsi(kvm_state, n, NULL, 
irqfd->virq);
  }
  
  static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,

-  unsigned int queue_no,
+  EventNotifier *n ,
unsigned int vector)
  {
-VirtIODevice *vdev = virtio_bus_get_device(>bus);
-VirtQueue *vq = virtio_get_queue(vdev, queue_no);
-EventNotifier *n = virtio_queue_get_guest_notifier(vq);
  VirtIOIRQFD *irqfd = >vector_irqfd[vector];
  int ret;
  
@@ -722,7 +715,8 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)

  VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
  unsigned int vector;
  int ret, queue_no;
-
+VirtQueue *vq;
+EventNotifier *n;



new line is needed.



  for (queue_no = 0; queue_no < nvqs; queue_no++) {
  if (!virtio_queue_get_num(vdev, queue_no)) {
  break;
@@ -731,7 +725,7 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, 
int nvqs)
  if (vector >= msix_nr_vectors_allocated(dev)) {
  continue;
  }
-ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector);
+ret = kvm_virtio_pci_vq_vector_use(proxy,  vector);
  if (ret < 0) {
  goto undo;
  }
@@ -739,7 +733,9 @@ static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, 
int nvqs)
   * Otherwise, delay until unmasked in the frontend.
   */
  if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
+vq = virtio_get_queue(vdev, queue_no);
+n = virtio_queue_get_guest_notifier(vq);
+ret = kvm_virtio_pci_irqfd_use(proxy, n, vector);
  if (ret < 0) {
  kvm_virtio_pci_vq_vector_release(proxy, vector);
  goto undo;
@@ -755,13 +751,69 @@ undo:
  continue;
  }
  if (vdev->use_guest_notifier_mask && k->guest_notifier_mask) {
-kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
+vq = virtio_get_queue(vdev, queue_no);
+n = virtio_queue_get_guest_notifier(vq);
+kvm_virtio_pci_irqfd_release(proxy, n, vector);
  }
  kvm_virtio_pci_vq_vector_release(proxy, vector);
  }
  return ret;
  }
  
+static int kvm_virtio_pci_vector_config_use(VirtIOPCIProxy *proxy)

+{
+
+VirtIODevice *vdev = virtio_bus_get_device(>bus);
+unsigned int vector;
+int ret;
+EventNotifier *n = virtio_get_config_notifier(vdev);
+
+vector = vdev->config_vector ;
+ret = kvm_virtio_pci_vq_vector_use(proxy, vector);
+if (ret < 0) {
+goto undo;
+}
+ret = kvm_virtio_pci_irqfd_use(proxy,  n, vector);
+if (ret < 0) {
+goto undo;
+}
+return 0;
+undo:
+kvm_virtio_pci_irqfd_release(proxy, n, vector);
+return ret;
+}



newline is needed.



+static void kvm_virtio_pci_vector_config_release(VirtIOPCIProxy *proxy)
+{
+PCIDevice *dev = >pci_dev;
+VirtIODevice *vdev = virtio_bus_get_device(>bus);
+unsigned int vector;
+EventNotifier *n = virtio_get_config_notifier(vdev);
+vector = vdev->config_vector ;
+if (vector >= msix_nr_vectors_allocated(dev)) {
+return;
+}
+kvm_virtio_pci_irqfd_release(proxy, n, vector);
+kvm_virtio_pci_vq_vector_release(proxy, vector);
+}
+
+static int virtio_pci_set_config_notifier(DeviceState *d,  

Re: [PATCH v3 2/5] vhost_net: enable configure interrupt when vhost_net start

2021-01-26 Thread Jason Wang



On 2021/1/26 下午3:42, Cindy Lu wrote:

While peer is vhost vdpa, setup the configure interrupt function
vhost_net_start and release the resource when vhost_net_stop

Signed-off-by: Cindy Lu 
---
  hw/net/vhost_net.c | 19 ++-
  1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 24d555e764..0660da474a 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -345,6 +345,15 @@ int vhost_net_start(VirtIODevice *dev, NetClientState *ncs,
  error_report("Error binding guest notifier: %d", -r);
  goto err;
  }
+if (ncs->peer && ncs->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
+if (k->set_config_notifiers) {
+r = k->set_config_notifiers(qbus->parent, true);
+if (r < 0) {
+error_report("Error binding config notifier: %d", -r);
+goto err;
+}
+   }
+}
  
  for (i = 0; i < total_queues; i++) {

  peer = qemu_get_peer(ncs, i);
@@ -391,7 +400,15 @@ void vhost_net_stop(VirtIODevice *dev, NetClientState *ncs,
  for (i = 0; i < total_queues; i++) {
  vhost_net_stop_one(get_vhost_net(ncs[i].peer), dev);
  }
-
+   if (ncs->peer && ncs->peer->info->type == NET_CLIENT_DRIVER_VHOST_VDPA) {
+if (k->set_config_notifiers) {



It looks to me that checking k->set_config_notifier is sufficient here.

Thanks



+r = k->set_config_notifiers(qbus->parent, false);
+if (r < 0) {
+error_report("Error unbinding config notifier: %d", -r);
+}
+   assert(r >= 0);
+}
+}
  r = k->set_guest_notifiers(qbus->parent, total_queues * 2, false);
  if (r < 0) {
  fprintf(stderr, "vhost guest notifier cleanup failed: %d\n", r);





Re: [PATCH v3 1/5] virtio: add support for configure interrupt

2021-01-26 Thread Jason Wang



On 2021/1/26 下午3:42, Cindy Lu wrote:

Add configure notifier and virtio_set_config_notifier_fd_handler
in virtio



The title and commit log is kind of misleading.

I think we should use "virtio: add guest notifier for config interrupt"




Signed-off-by: Cindy Lu 
---
  hw/virtio/virtio.c | 26 ++
  include/hw/virtio/virtio-bus.h |  2 ++
  include/hw/virtio/virtio.h |  6 ++
  3 files changed, 34 insertions(+)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index ceb58fda6c..25e164cf8a 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -3502,6 +3502,16 @@ static void 
virtio_queue_guest_notifier_read(EventNotifier *n)
  }
  }
  
+static void virtio_config_read(EventNotifier *n)

+{
+VirtIODevice *vdev = container_of(n, VirtIODevice, config_notifier);
+if (!vdev->use_config_notifier) {
+return;
+}
+if (event_notifier_test_and_clear(n)) {
+virtio_notify_config(vdev);
+}
+}
  void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
  bool with_irqfd)
  {
@@ -3518,6 +3528,17 @@ void 
virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
  }
  }
  
+void virtio_set_config_notifier_fd_handler(VirtIODevice *vdev, bool assign,

+bool with_irqfd)
+{
+if (assign && !with_irqfd) {
+event_notifier_set_handler(>config_notifier,
+   virtio_config_read);
+} else {
+   event_notifier_set_handler(>config_notifier, NULL);
+}
+}
+
  EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
  {
  return >guest_notifier;
@@ -3591,6 +3612,11 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue 
*vq)
  return >host_notifier;
  }
  
+EventNotifier *virtio_get_config_notifier(VirtIODevice *vdev)

+{
+return >config_notifier;
+
+}
  void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled)
  {
  vq->host_notifier_enabled = enabled;
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index ef8abe49c5..97e13ec484 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -93,6 +93,8 @@ struct VirtioBusClass {
   */
  bool has_variable_vring_alignment;
  AddressSpace *(*get_dma_as)(DeviceState *d);
+int (*set_config_notifiers)(DeviceState *d, bool assign);
+
  };
  
  struct VirtioBusState {

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index b7ece7a6a8..79f2f78625 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -108,6 +108,8 @@ struct VirtIODevice
  bool use_guest_notifier_mask;
  AddressSpace *dma_as;
  QLIST_HEAD(, VirtQueue) *vector_queues;
+EventNotifier config_notifier;
+bool use_config_notifier;



Let's document those two fields.

Thanks



  };
  
  struct VirtioDeviceClass {

@@ -310,11 +312,15 @@ uint16_t virtio_get_queue_index(VirtQueue *vq);
  EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq);
  void virtio_queue_set_guest_notifier_fd_handler(VirtQueue *vq, bool assign,
  bool with_irqfd);
+void virtio_set_config_notifier_fd_handler(VirtIODevice *vdev, bool assign,
+bool with_irqfd);
+
  int virtio_device_start_ioeventfd(VirtIODevice *vdev);
  int virtio_device_grab_ioeventfd(VirtIODevice *vdev);
  void virtio_device_release_ioeventfd(VirtIODevice *vdev);
  bool virtio_device_ioeventfd_enabled(VirtIODevice *vdev);
  EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq);
+EventNotifier *virtio_get_config_notifier(VirtIODevice *vdev);
  void virtio_queue_set_host_notifier_enabled(VirtQueue *vq, bool enabled);
  void virtio_queue_host_notifier_read(EventNotifier *n);
  void virtio_queue_aio_set_host_notifier_handler(VirtQueue *vq, AioContext 
*ctx,





[Bug 1912777] Re: KVM_EXIT_MMIO has increased in Qemu4.0.0 when compared to Qemu 2.11.0

2021-01-26 Thread ANIMESH KUMAR SINHA
The testcase is a rather a very basic one.
Doing a mmap on a pcie device and triggering a read and write operation on the 
Virtual Address, which would in-turn trigger transaction requests on the host 
device.

I understand that Qemu v4.0 may be and old one, but the issue is that
test case execution has become rather very slow with Qemu4.0.0 and the
only thing i could notice from using tracebacks were related with
increase in KVM_MMIO_EXIT when compared with Qemu2.11.0 version.

Can it be verified as to why the number of KVM_EXIT_MMIO has increased
drastically in qemu4 when compared to Qemu2.11.0 ?

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1912777

Title:
  KVM_EXIT_MMIO has increased in Qemu4.0.0 when compared to Qemu 2.11.0

Status in QEMU:
  Incomplete
Status in Ubuntu:
  New

Bug description:
  I was able to generate trace dump in Qemu for kvm_run_exit event in both QEMU 
2.11.0 and QEMU 4.0.0
  From the trace i noticed that the number of KVM_KXIT_MMIO calls has increased 
alot and is causing delay in testcase execution.

  I executed same testcase from Qemu 2.11 and Qemu4.
  Inside Virtual machine when using qemu 2.11 testcase got completed in 11 
seconds
  but the same testcase when executed on Qemu 4.0.0 got executed in 26 seconds.

  
  I did a bit of digging and extracted the kvm_run_exit to figure out whats 
going on.

  Please find 
  Stats from Qemu2.11:

  KVM_EXIT_UNKNOWN  : 0
  KVM_EXIT_EXCEPTION: 0
  KVM_EXIT_IO   : 182513
  KVM_EXIT_HYPERCALL: 0
  KVM_EXIT_DEBUG: 0
  KVM_EXIT_HLT  : 0
  KVM_EXIT_MMIO : 216701
  KVM_EXIT_IRQ_WINDOW_OPEN  : 0
  KVM_EXIT_SHUTDOWN : 0
  KVM_EXIT_FAIL_ENTRY   : 0
  KVM_EXIT_INTR : 0
  KVM_EXIT_SET_TPR  : 0
  KVM_EXIT_TPR_ACCESS   : 0
  KVM_EXIT_S390_SIEIC   : 0
  KVM_EXIT_S390_RESET   : 0
  KVM_EXIT_DCR  : 0
  KVM_EXIT_NMI  : 0
  KVM_EXIT_INTERNAL_ERROR   : 0
  KVM_EXIT_OSI  : 0
  KVM_EXIT_PAPR_HCALL   : 0
  KVM_EXIT_S390_UCONTROL: 0
  KVM_EXIT_WATCHDOG : 0
  KVM_EXIT_S390_TSCH: 0
  KVM_EXIT_EPR  : 0
  KVM_EXIT_SYSTEM_EVENT : 0
  KVM_EXIT_S390_STSI: 0
  KVM_EXIT_IOAPIC_EOI   : 0
  KVM_EXIT_HYPERV   : 0

  KVM_RUN_EXIT  : 399214  (Total in Qemu 2.11 for a
  testcase)

  
  Stats For Qemu 4.0.0:

  VM_EXIT_UNKNOWN   : 0 
   
  KVM_EXIT_EXCEPTION: 0 
   
  KVM_EXIT_IO   : 163729
   
  KVM_EXIT_HYPERCALL: 0 
   
  KVM_EXIT_DEBUG: 0 
   
  KVM_EXIT_HLT  : 0 
   
  KVM_EXIT_MMIO : 1094231   
   
  KVM_EXIT_IRQ_WINDOW_OPEN  : 46
   
  KVM_EXIT_SHUTDOWN : 0 
   
  KVM_EXIT_FAIL_ENTRY   : 0 
   
  KVM_EXIT_INTR : 0 
   
  KVM_EXIT_SET_TPR  : 0 
   
  KVM_EXIT_TPR_ACCESS   : 0 
   
  KVM_EXIT_S390_SIEIC   : 0 
   
  KVM_EXIT_S390_RESET   : 0 
   
  KVM_EXIT_DCR  : 0

Re: [PATCH v2] virtio: Add corresponding memory_listener_unregister to unrealize

2021-01-26 Thread Jason Wang



On 2021/1/26 下午11:40, Peter Xu wrote:

On Mon, Jan 25, 2021 at 08:25:05PM +0100, Eugenio Pérez wrote:

Address space is destroyed without proper removal of its listeners with
current code. They are expected to be removed in
virtio_device_instance_finalize [1], but qemu calls it through
object_deinit, after address_space_destroy call through
device_set_realized [2].

Move it to virtio_device_unrealize, called before device_set_realized
[3] and making it symmetric with memory_listener_register in
virtio_device_realize.

v2: Delete no-op call of virtio_device_instance_finalize.
 Add backtraces.

This can be dropped from commit.


[1]

  #0  virtio_device_instance_finalize (obj=0x57de5120)
  at /home/qemu/include/hw/virtio/virtio.h:71
  #1  0x55b703c9 in object_deinit (type=0x56639860,
   obj=) at ../qom/object.c:671
  #2  object_finalize (data=0x57de5120) at ../qom/object.c:685
  #3  object_unref (objptr=0x57de5120) at ../qom/object.c:1184
  #4  0x55b4de9d in bus_free_bus_child (kid=0x57df0660)
  at ../hw/core/qdev.c:55
  #5  0x55c65003 in call_rcu_thread (opaque=opaque@entry=0x0)
  at ../util/rcu.c:281

Queued by:

  #0  bus_remove_child (bus=0x57de5098,
  child=child@entry=0x57de5120) at ../hw/core/qdev.c:60
  #1  0x55b4ee31 in device_unparent (obj=)
  at ../hw/core/qdev.c:984
  #2  0x55b70465 in object_finalize_child_property (
  obj=, name=, opaque=0x57de5120)
  at ../qom/object.c:1725
  #3  0x55b6fa17 in object_property_del_child (
  child=0x57de5120, obj=0x57ddcf90) at ../qom/object.c:645
  #4  object_unparent (obj=0x57de5120) at ../qom/object.c:664
  #5  0x55b4c071 in bus_unparent (obj=)
  at ../hw/core/bus.c:147
  #6  0x55b70465 in object_finalize_child_property (
  obj=, name=, opaque=0x57de5098)
  at ../qom/object.c:1725
  #7  0x55b6fa17 in object_property_del_child (
  child=0x57de5098, obj=0x57ddcf90) at ../qom/object.c:645
  #8  object_unparent (obj=0x57de5098) at ../qom/object.c:664
  #9  0x55b4ee19 in device_unparent (obj=)
  at ../hw/core/qdev.c:981
  #10 0x55b70465 in object_finalize_child_property (
  obj=, name=, opaque=0x57ddcf90)
  at ../qom/object.c:1725
  #11 0x55b6fa17 in object_property_del_child (
  child=0x57ddcf90, obj=0x5685da10) at ../qom/object.c:645
  #12 object_unparent (obj=0x57ddcf90) at ../qom/object.c:664
  #13 0x558dc331 in pci_for_each_device_under_bus (
  opaque=, fn=, bus=)
  at ../hw/pci/pci.c:1654

[2]

Optimizer omits pci_qdev_unrealize, called by device_set_realized, and
do_pci_unregister_device, called by pci_qdev_unrealize and caller of
address_space_destroy.

  #0  address_space_destroy (as=0x57ddd1b8)
  at ../softmmu/memory.c:2840
  #1  0x55b4fc53 in device_set_realized (obj=0x57ddcf90,
   value=, errp=0x7fffeea8f1e0)
  at ../hw/core/qdev.c:850
  #2  0x55b6eaa6 in property_set_bool (obj=0x57ddcf90,
   v=, name=, opaque=0x56650ba0,
  errp=0x7fffeea8f1e0) at ../qom/object.c:2255
  #3  0x55b70e07 in object_property_set (
   obj=obj@entry=0x57ddcf90,
   name=name@entry=0x55db99df "realized",
   v=v@entry=0x7fffe46b7500,
   errp=errp@entry=0x565bbf38 )
  at ../qom/object.c:1400
  #4  0x55b73c5f in object_property_set_qobject (
   obj=obj@entry=0x57ddcf90,
   name=name@entry=0x55db99df "realized",
   value=value@entry=0x7fffe44f6180,
   errp=errp@entry=0x565bbf38 )
  at ../qom/qom-qobject.c:28
  #5  0x55b71044 in object_property_set_bool (
   obj=0x57ddcf90, name=0x55db99df "realized",
   value=, errp=0x565bbf38 )
  at ../qom/object.c:1470
  #6  0x55921cb7 in pcie_unplug_device (bus=,
   dev=0x57ddcf90,
   opaque=) at /home/qemu/include/hw/qdev-core.h:17
  #7  0x558dc331 in pci_for_each_device_under_bus (
   opaque=, fn=,
   bus=) at ../hw/pci/pci.c:1654

[3]

  #0  virtio_device_unrealize (dev=0x57de5120)
  at ../hw/virtio/virtio.c:3680
  #1  0x55b4fc63 in device_set_realized (obj=0x57de5120,
  value=, errp=0x7fffee28df90)
  at ../hw/core/qdev.c:850
  #2  0x55b6eab6 in property_set_bool (obj=0x57de5120,
  v=, name=, opaque=0x56650ba0,
  errp=0x7fffee28df90) at ../qom/object.c:2255
  #3  0x55b70e17 in object_property_set (
  obj=obj@entry=0x57de5120,
  name=name@entry=0x55db99ff "realized",
  v=v@entry=0x7ffdd8035040,
  errp=errp@entry=0x565bbf38 )
  at ../qom/object.c:1400
  #4  0x55b73c6f in object_property_set_qobject (
  obj=obj@entry=0x57de5120,
  name=name@entry=0x55db99ff "realized",
  value=value@entry=0x7ffdd8035020,
  errp=errp@entry=0x565bbf38 )
  at 

Re: [PATCH v3 0/6] Enable plugin support on msys2/mingw

2021-01-26 Thread Yonggang Luo
Hi alex, when does plugins/next getting PR

On Tue, Oct 6, 2020 at 7:35 PM Alex Bennée  wrote:

>
> Yonggang Luo  writes:
>
> > V2-V3
> > Split following patches out
> >
> > V1-V2
> > 1. Fixes review comments
> > 2. Increase QEMU_PLUGIN_VERSION to 1 for compat  QEMU_PLUGIN_VERSION 0
> > 3. Revise the loader to support for version 0 and 1
> > 4. By export function qemu_plugin_initialize in plugin, and call it in
> loader=
> > , so
> >   we have no need call it in every plugin. And also provide a standard
> implem=
> > entation,
> >   anyway, use can also override it.
> >
> > Add this feature on msys2/mingw by using glib provided cross-platform
> dlsym f=
> > unctional.
>
> I've grabbed the first two fixes into plugins/next for now. Aside from
> fixing the review comments I'd like to have an indication that the
> proposed change to the API linking doesn't adversely affect the
> performance of the plugins.
>
> It might be worth enabling a --enable-plugins build for mingw gitlab as
> Cirrus
> seems a bit broken at the moment.
>
> Thanks,
>
>
> --
> Alex Bennée
>


-- 
 此致
礼
罗勇刚
Yours
sincerely,
Yonggang Luo


Re: [PATCH v2 5/8] hw/mips: Use bl_gen_kernel_jump to generate bootloaders

2021-01-26 Thread Jiaxun Yang

在 2021/1/7 上午1:48, Philippe Mathieu-Daudé 写道:

+Alex

On 12/15/20 7:45 AM, Jiaxun Yang wrote:

Replace embedded binary with generated code.

Signed-off-by: Jiaxun Yang 
---
  hw/mips/boston.c| 17 ++---
  hw/mips/fuloong2e.c | 28 
  hw/mips/malta.c | 41 ++---
  3 files changed, 16 insertions(+), 70 deletions(-)

diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index c3b94c68e1..b62c7d 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -27,6 +27,7 @@
  #include "hw/ide/ahci.h"
  #include "hw/loader.h"
  #include "hw/loader-fit.h"
+#include "hw/mips/bootloader.h"
  #include "hw/mips/cps.h"
  #include "hw/pci-host/xilinx-pcie.h"
  #include "hw/qdev-clock.h"
@@ -324,21 +325,7 @@ static void gen_firmware(uint32_t *p, hwaddr kernel_entry, 
hwaddr fdt_addr,
   * a2/$6 = 0
   * a3/$7 = 0
   */
-stl_p(p++, 0x2404fffe); /* li   $4, -2 */
-/* lui  $5, hi(fdt_addr) */
-stl_p(p++, 0x3c05 | ((fdt_addr >> 16) & 0x));
-if (fdt_addr & 0x) {/* ori  $5, lo(fdt_addr) */
-stl_p(p++, 0x34a5 | (fdt_addr & 0x));
-}
-stl_p(p++, 0x3406); /* li   $6, 0 */
-stl_p(p++, 0x3407); /* li   $7, 0 */
-
-/* Load kernel entry address & jump to it */
-/* lui  $25, hi(kernel_entry) 
*/
-stl_p(p++, 0x3c19 | ((kernel_entry >> 16) & 0x));
-/* ori  $25, lo(kernel_entry) 
*/
-stl_p(p++, 0x3739 | (kernel_entry & 0x));
-stl_p(p++, 0x0329); /* jr   $25 */

Eh, no delay slot NOP :)


+bl_gen_jump_kernel(, 0, (int32_t)-2, fdt_addr, 0, 0, kernel_entry);
  }
  

...


diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index 9afc0b427b..ffd67b8293 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -37,6 +37,7 @@
  #include "hw/i2c/smbus_eeprom.h"
  #include "hw/block/flash.h"
  #include "hw/mips/mips.h"
+#include "hw/mips/bootloader.h"
  #include "hw/mips/cpudevs.h"
  #include "hw/pci/pci.h"
  #include "sysemu/sysemu.h"
@@ -844,6 +845,7 @@ static void write_bootloader_nanomips(uint8_t *base, 
uint64_t run_addr,
  static void write_bootloader(uint8_t *base, uint64_t run_addr,
   uint64_t kernel_entry)
  {
+target_ulong a0;
  uint32_t *p;
  
  /* Small bootloader */

@@ -872,30 +874,6 @@ static void write_bootloader(uint8_t *base, uint64_t 
run_addr,
  /* Second part of the bootloader */
  p = (uint32_t *) (base + 0x580);
  
-if (semihosting_get_argc()) {

-/* Preserve a0 content as arguments have been passed */
-stl_p(p++, 0x);  /* nop */
-} else {
-stl_p(p++, 0x24040002);  /* addiu a0, zero, 2 */
-}
-
-/* lui sp, high(ENVP_VADDR) */
-stl_p(p++, 0x3c1d | (((ENVP_VADDR - 64) >> 16) & 0x));
-/* ori sp, sp, low(ENVP_VADDR) */
-stl_p(p++, 0x37bd | ((ENVP_VADDR - 64) & 0x));
-/* lui a1, high(ENVP_VADDR) */
-stl_p(p++, 0x3c05 | ((ENVP_VADDR >> 16) & 0x));
-/* ori a1, a1, low(ENVP_VADDR) */
-stl_p(p++, 0x34a5 | (ENVP_VADDR & 0x));
-/* lui a2, high(ENVP_VADDR + 8) */
-stl_p(p++, 0x3c06 | (((ENVP_VADDR + 8) >> 16) & 0x));
-/* ori a2, a2, low(ENVP_VADDR + 8) */
-stl_p(p++, 0x34c6 | ((ENVP_VADDR + 8) & 0x));
-/* lui a3, high(ram_low_size) */
-stl_p(p++, 0x3c07 | (loaderparams.ram_low_size >> 16));
-/* ori a3, a3, low(ram_low_size) */
-stl_p(p++, 0x34e7 | (loaderparams.ram_low_size & 0x));
-
  /* Load BAR registers as done by YAMON */
  stl_p(p++, 0x3c09b400);  /* lui t1, 0xb400 */
  
@@ -947,13 +925,14 @@ static void write_bootloader(uint8_t *base, uint64_t run_addr,

  #endif
  stl_p(p++, 0xad280088);  /* sw t0, 0x0088(t1) */
  
-/* Jump to kernel code */

-stl_p(p++, 0x3c1f |
-  ((kernel_entry >> 16) & 0x));  /* lui ra, high(kernel_entry) */
-stl_p(p++, 0x37ff |
-  (kernel_entry & 0x));  /* ori ra, ra, low(kernel_entry) 
*/
-stl_p(p++, 0x03e9);  /* jalr ra */
-stl_p(p++, 0x);  /* nop */
+if (semihosting_get_argc()) {
+a0 = 0;

I never used semihosting with Malta, but it seems you are
clearing $a0 content.


That's what original code did.
I guess when semihosting is enabled, arguments are going to be
passed by semi-syscall instead of boot registers?

Thanks.

- Jiaxun




+} else {
+a0 = 2;
+}
+bl_gen_jump_kernel(, ENVP_VADDR - 64, a0, ENVP_VADDR,
+   ENVP_VADDR + 8, loaderparams.ram_low_size,
+   kernel_entry);
  
  /* YAMON subroutines */

  p = (uint32_t *) (base + 

Re: [PATCH v3 5/5] vhost-vdpa: add callback function for configure interrupt

2021-01-26 Thread Cindy Lu
On Tue, Jan 26, 2021 at 10:53 PM Stefano Garzarella  wrote:
>
> On Tue, Jan 26, 2021 at 03:42:54PM +0800, Cindy Lu wrote:
> >Add call back function for configure interrupt.
> >Set the notifier's fd to the kernel driver when vdpa start.
> >also set -1 while vdpa stop. then the kernel will release
> >the related resource
> >
> >Signed-off-by: Cindy Lu 
> >---
> > hw/virtio/trace-events|  2 ++
> > hw/virtio/vhost-vdpa.c| 37 ++-
> > include/hw/virtio/vhost-backend.h |  4 
> > 3 files changed, 42 insertions(+), 1 deletion(-)
> >
> >diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> >index 2060a144a2..6710835b46 100644
> >--- a/hw/virtio/trace-events
> >+++ b/hw/virtio/trace-events
> >@@ -52,6 +52,8 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, 
> >int fd) "dev: %p index:
> > vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 
> > 0x%"PRIx64
> > vhost_vdpa_set_owner(void *dev) "dev: %p"
> > vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, 
> > uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p 
> > desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 
> > 0x%"PRIx64
> >+vhost_vdpa_set_config_call(void *dev, int *fd)"dev: %p fd: %p"
> >+
> >
> > # virtio.c
> > virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned 
> > out_num) "elem %p size %zd in_num %u out_num %u"
> >diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> >index 01d2101d09..cc1d39d663 100644
> >--- a/hw/virtio/vhost-vdpa.c
> >+++ b/hw/virtio/vhost-vdpa.c
> >@@ -467,20 +467,47 @@ static int vhost_vdpa_get_config(struct vhost_dev 
> >*dev, uint8_t *config,
> > }
> > return ret;
> >  }
> >+static void vhost_vdpa_config_notify_start(struct vhost_dev *dev,
> >+struct VirtIODevice *vdev, bool start)
> >+{
> >+int fd, r;
> >+if (start) {
> >+fd = event_notifier_get_fd(>config_notifier);
> >+vdev->use_config_notifier = true;
> >+ } else {
>^
> >+fd = -1;
> >+vdev->use_config_notifier = false;
> >+ }
>^
> >+ /*set the fd call back to vdpa driver*/
>^
>It seems to me that there is an extra space in these places.
>
sure, I will fix this
> >+r = dev->vhost_ops->vhost_set_config_call(dev, );
> >+if (r) {
> >+vdev->use_config_notifier = false;
> >+info_report("vhost_vdpa_config_notify not started!");
> >+}
> >+/*active the config_notifier when vdev->use_config_notifier is true*/
> >+if ((vdev->use_config_notifier) && (start)) {
> >+event_notifier_set(>config_notifier);
> >+}
> >+return;
> >
> >+}
>
> Here and also in other patches I would leave a new line between two
> functions.
>
sure. will fix this
> > static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started)
> > {
> > struct vhost_vdpa *v = dev->opaque;
> > trace_vhost_vdpa_dev_start(dev, started);
> >+VirtIODevice *vdev = dev->vdev;
> >+
> > if (started) {
> > uint8_t status = 0;
> > memory_listener_register(>listener, _space_memory);
> > vhost_vdpa_set_vring_ready(dev);
> > vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK);
> > vhost_vdpa_call(dev, VHOST_VDPA_GET_STATUS, );
> >-
> >+/*set the configure interrupt call back*/
> >+vhost_vdpa_config_notify_start(dev, vdev, true);
> > return !(status & VIRTIO_CONFIG_S_DRIVER_OK);
> > } else {
> >+vhost_vdpa_config_notify_start(dev, vdev, false);
> > vhost_vdpa_reset_device(dev);
> > vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
> >VIRTIO_CONFIG_S_DRIVER);
> >@@ -546,6 +573,13 @@ static int vhost_vdpa_set_vring_call(struct vhost_dev 
> >*dev,
> > return vhost_vdpa_call(dev, VHOST_SET_VRING_CALL, file);
> > }
> >
> >+static int vhost_vdpa_set_config_call(struct vhost_dev *dev,
> >+   int *fd)
> >+{
> >+trace_vhost_vdpa_set_config_call(dev, fd);
> >+return vhost_vdpa_call(dev, VHOST_VDPA_SET_CONFIG_CALL, fd);
> >+}
> >+
> > static int vhost_vdpa_get_features(struct vhost_dev *dev,
> >  uint64_t *features)
> > {
> >@@ -611,4 +645,5 @@ const VhostOps vdpa_ops = {
> > .vhost_get_device_id = vhost_vdpa_get_device_id,
> > .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
> > .vhost_force_iommu = vhost_vdpa_force_iommu,
> >+.vhost_set_config_call = vhost_vdpa_set_config_call,
> > };
> >diff --git a/include/hw/virtio/vhost-backend.h 
> >b/include/hw/virtio/vhost-backend.h
> >index 8a6f8e2a7a..1a2fee8994 100644
> >--- a/include/hw/virtio/vhost-backend.h
> >+++ b/include/hw/virtio/vhost-backend.h
> >@@ -125,6 +125,9 @@ typedef int (*vhost_get_device_id_op)(struct vhost_dev 
> >*dev, uint32_t *dev_id);
> >
> > typedef bool 

Re: [PATCH] spapr: Adjust firmware path of PCI devices

2021-01-26 Thread Alexey Kardashevskiy




On 25/01/2021 21:23, Greg Kurz wrote:

On Sat, 23 Jan 2021 13:36:34 +1100
Alexey Kardashevskiy  wrote:




On 23/01/2021 04:01, Greg Kurz wrote:

It is currently not possible to perform a strict boot from USB storage:

$ qemu-system-ppc64 -accel kvm -nodefaults -nographic -serial stdio \
-boot strict=on \
-device qemu-xhci \
-device usb-storage,drive=disk,bootindex=0 \
-blockdev driver=file,node-name=disk,filename=fedora-ppc64le.qcow2


SLOF **
QEMU Starting
   Build Date = Jul 17 2020 11:15:24
   FW Version = git-e18ddad8516ff2cf
   Press "s" to enter Open Firmware.

Populating /vdevice methods
Populating /vdevice/vty@7100
Populating /vdevice/nvram@7101
Populating /pci@8002000
   00  (D) : 1b36 000dserial bus [ usb-xhci ]
No NVRAM common partition, re-initializing...
Scanning USB
XHCI: Initializing
  USB Storage
 SCSI: Looking for devices
101 DISK : "QEMU QEMU HARDDISK2.5+"
Using default console: /vdevice/vty@7100

Welcome to Open Firmware

Copyright (c) 2004, 2017 IBM Corporation All rights reserved.
This program and the accompanying materials are made available
under the terms of the BSD License available at
http://www.opensource.org/licenses/bsd-license.php


Trying to load:  from: 
/pci@8002000/usb@0/storage@1/disk@101 ...
E3405: No such device

E3407: Load failed

Type 'boot' and press return to continue booting the system.
Type 'reset-all' and press return to reboot the system.


Ready!
0 >

The device tree handed over by QEMU to SLOF indeed contains:

qemu,boot-list =
"/pci@8002000/usb@0/storage@1/disk@101 HALT";

but the device node is named usb-xhci@0, not usb@0.



I'd expect it to be a return of qdev_fw_name() so in this case something
like "nec-usb-xhci" (which would still be broken) but seeing a plain
"usb" is a bit strange.



The logic under get_boot_devices_list() is a bit hard to follow
because of the multiple indirections, but AFAICT it doesn't seem
to rely on qdev_fw_name() to get the names.

None of the XHCI devices seem to be setting DeviceClass::fw_name anyway:

$ git grep fw_name hw/usb/
hw/usb/bus.c: qdev_fw_name(qdev), nr);
hw/usb/dev-hub.c:dc->fw_name = "hub";
hw/usb/dev-mtp.c:dc->fw_name = "mtp";
hw/usb/dev-network.c:dc->fw_name = "network";
hw/usb/dev-storage.c:dc->fw_name = "storage";
hw/usb/dev-uas.c:dc->fw_name = "storage";

The plain "usb" naming comes from PCI, which has its own naming
logic for PCI devices (which qemu-xhci happens to be) :



Right, this was the confusing bit for me. I thought that by just setting 
dc->fw_name to what we put in the DT should be enough but it is not.





#0  0x000100319474 in pci_dev_fw_name (len=33, buf=0x7fffd4c8 "\020", 
dev=0x7fffc3320010) at ../../hw/pci/pci.c:2533
#1  0x000100319474 in pcibus_get_fw_dev_path (dev=0x7fffc3320010) at 
../../hw/pci/pci.c:2550
#2  0x00010053118c in bus_get_fw_dev_path (dev=0x7fffc3320010, bus=) at ../../hw/core/qdev-fw.c:38
#3  0x00010053118c in qdev_get_fw_dev_path_helper (dev=0x7fffc3320010, 
p=0x7fffd728 "/pci@8002000/", size=128) at 
../../hw/core/qdev-fw.c:72
#4  0x000100531064 in qdev_get_fw_dev_path_helper (dev=0x101c864a0, p=0x7fffd728 
"/pci@8002000/", size=128) at ../../hw/core/qdev-fw.c:69
#5  0x000100531064 in qdev_get_fw_dev_path_helper (dev=0x1019f3560, p=0x7fffd728 
"/pci@8002000/", size=128) at ../../hw/core/qdev-fw.c:69
#6  0x0001005312f0 in qdev_get_fw_dev_path (dev=) at 
../../hw/core/qdev-fw.c:91
#7  0x000100588a68 in get_boot_device_path (dev=, 
ignore_suffixes=, ignore_suffixes@entry=true, suffix=) 
at ../../softmmu/bootdevice.c:211
#8  0x000100589540 in get_boot_devices_list (size=0x7fffd990) at 
../../softmmu/bootdevice.c:257
#9  0x000100606764 in spapr_dt_chosen (reset=true, fdt=0x7fffc26f0010, 
spapr=0x10149aef0) at ../../hw/ppc/spapr.c:1019



While your patch works, I wonder if we should assign fw_name to all pci
nodes to avoid similar problems in the future? Thanks,



Not sure to understand "assign fw_name to all pci nodes" ...



Basically this:

=
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index de0fae10ab9c..8a286419aaf8 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2508,7 +2508,12 @@ static char *pci_dev_fw_name(DeviceState *dev, 
char *buf, int len)

 const char *name = NULL;
 const pci_class_desc *desc =  pci_class_descriptions;
 int class = pci_get_word(d->config + PCI_CLASS_DEVICE);
+DeviceClass *dc = DEVICE_GET_CLASS(dev);

+if (dc->fw_name) {
+pstrcpy(buf, len, dc->fw_name);
+return buf;
+}
 while (desc->desc &&
   (class & ~desc->fw_ign_bits) !=
   (desc->class & ~desc->fw_ign_bits)) {
diff --git 

Re: [PATCH 3/7] ppc/pnv: Use skiboot addresses to load kernel and ramfs

2021-01-26 Thread Murilo Opsfelder Araújo
Bonjour, Cédric.

On Tuesday, January 26, 2021 2:10:55 PM -03 Cédric Le Goater wrote:
> The current settings are useful to load large kernels (with debug) but
> it moves the initrd image in a memory region not protected by
> skiboot. If skiboot is compiled with DEBUG=1, memory poisoning will
> corrupt the initrd.
> 
> Cc: Murilo Opsfelder Araujo 
> Signed-off-by: Cédric Le Goater 
> ---
> 
>  If we want to increase the kernel size limit as commit b45b56baeecd
>  ("ppc/pnv: increase kernel size limit to 256MiB") intented to do, I
>  think we should add a machine option.

Is this a problem on bare-metal as well?

I'm wondering if we should address this the other way around by increasing
KERNEL_LOAD_SIZE and INITRAMFS_LOAD_SIZE in skiboot to accomodate large kernel
and initramfs images.

I think Linux debuginfo images won't get smaller with time and, assuming this
also happens on bare-metal (I haven't verified), updating skiboot looks more
appropriate.

Bear in mind that I'm not an skiboot expert, I'm just considering the
possibilities.

> 
>  hw/ppc/pnv.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index 14fc9758a973..e500c2e2437e 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -65,9 +65,9 @@
>  #define FW_MAX_SIZE (16 * MiB)
> 
>  #define KERNEL_LOAD_ADDR0x2000
> -#define KERNEL_MAX_SIZE (256 * MiB)
> -#define INITRD_LOAD_ADDR0x6000
> -#define INITRD_MAX_SIZE (256 * MiB)
> +#define KERNEL_MAX_SIZE (128 * MiB)
> +#define INITRD_LOAD_ADDR0x2800
> +#define INITRD_MAX_SIZE (128 * MiB)
> 
>  static const char *pnv_chip_core_typename(const PnvChip *o)
>  {

Cheers!

-- 
Murilo




[PATCH v2] hw/misc: Fix arith overflow in NPCM7XX PWM module

2021-01-26 Thread wuhaotsh--- via
Fix potential overflow problem when calculating pwm_duty.
1. Ensure p->cmr and p->cnr to be from [0,65535], according to the
   hardware specification.
2. Changed duty to uint32_t. However, since MAX_DUTY * (p->cmr+1)
   can excceed UINT32_MAX, we convert them to uint64_t in computation
   and converted them back to uint32_t.
   (duty is guaranteed to be <= MAX_DUTY so it won't overflow.)

Fixes: CID 1442342
Suggested-by: Peter Maydell 
Reviewed-by: Doug Evans 
Signed-off-by: Hao Wu 
---
 hw/misc/npcm7xx_pwm.c  | 23 +++
 tests/qtest/npcm7xx_pwm-test.c |  4 ++--
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
index e99e3cc7ef..dabcb6c0f9 100644
--- a/hw/misc/npcm7xx_pwm.c
+++ b/hw/misc/npcm7xx_pwm.c
@@ -58,6 +58,9 @@ REG32(NPCM7XX_PWM_PWDR3, 0x50);
 #define NPCM7XX_CH_INV  BIT(2)
 #define NPCM7XX_CH_MOD  BIT(3)
 
+#define NPCM7XX_MAX_CMR 65535
+#define NPCM7XX_MAX_CNR 65535
+
 /* Offset of each PWM channel's prescaler in the PPR register. */
 static const int npcm7xx_ppr_base[] = { 0, 0, 8, 8 };
 /* Offset of each PWM channel's clock selector in the CSR register. */
@@ -96,7 +99,7 @@ static uint32_t npcm7xx_pwm_calculate_freq(NPCM7xxPWM *p)
 
 static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
 {
-uint64_t duty;
+uint32_t duty;
 
 if (p->running) {
 if (p->cnr == 0) {
@@ -104,7 +107,7 @@ static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
 } else if (p->cmr >= p->cnr) {
 duty = NPCM7XX_PWM_MAX_DUTY;
 } else {
-duty = NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
+duty = (uint64_t)NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 
1);
 }
 } else {
 duty = 0;
@@ -357,7 +360,13 @@ static void npcm7xx_pwm_write(void *opaque, hwaddr offset,
 case A_NPCM7XX_PWM_CNR2:
 case A_NPCM7XX_PWM_CNR3:
 p = >pwm[npcm7xx_cnr_index(offset)];
-p->cnr = value;
+if (value > NPCM7XX_MAX_CNR) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: invalid cnr value: %u", __func__, value);
+p->cnr = NPCM7XX_MAX_CNR;
+} else {
+p->cnr = value;
+}
 npcm7xx_pwm_update_output(p);
 break;
 
@@ -366,7 +375,13 @@ static void npcm7xx_pwm_write(void *opaque, hwaddr offset,
 case A_NPCM7XX_PWM_CMR2:
 case A_NPCM7XX_PWM_CMR3:
 p = >pwm[npcm7xx_cmr_index(offset)];
-p->cmr = value;
+if (value > NPCM7XX_MAX_CMR) {
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: invalid cmr value: %u", __func__, value);
+p->cmr = NPCM7XX_MAX_CMR;
+} else {
+p->cmr = value;
+}
 npcm7xx_pwm_update_output(p);
 break;
 
diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c
index 63557d2c06..3d82654b81 100644
--- a/tests/qtest/npcm7xx_pwm-test.c
+++ b/tests/qtest/npcm7xx_pwm-test.c
@@ -272,7 +272,7 @@ static uint64_t pwm_compute_freq(QTestState *qts, uint32_t 
ppr, uint32_t csr,
 
 static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
 {
-uint64_t duty;
+uint32_t duty;
 
 if (cnr == 0) {
 /* PWM is stopped. */
@@ -280,7 +280,7 @@ static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t 
cmr, bool inverted)
 } else if (cmr >= cnr) {
 duty = MAX_DUTY;
 } else {
-duty = MAX_DUTY * (cmr + 1) / (cnr + 1);
+duty = (uint64_t)MAX_DUTY * (cmr + 1) / (cnr + 1);
 }
 
 if (inverted) {
-- 
2.30.0.365.g02bc693789-goog




[PATCH 0/1] tests/acceptance/boot_linux: Switch to Fedora 32

2021-01-26 Thread Daniele Buono
Local acceptance tests run with "make check-acceptance" are now
showing some cases canceled like the following:

(01/39) tests/acceptance/boot_linux.py:BootLinuxX8664.test_pc_i440fx_tcg: 
CANCEL: Failed to download/prepare boot image (0.25 s)

Turns out, every full-vm test in boot_linux.py is trying to use a
Fedora 31 cloud image and is failing, with Avocado refusing to download
it, presumably because Fedora 31 is EOL.

This patch moves to Fedora 32, which is still supported. And seem to
work fine

The script has the image checksums hardcoded. I downloaded and verified
the checksums with the Fedora 32 GPG key, but I would feel more
confident if someone else wants to verify it too.

The checksum files are here:
https://download-ib01.fedoraproject.org/pub/fedora-secondary/releases/32/Cloud/ppc64le/images/Fedora-Cloud-32-1.6-ppc64le-CHECKSUM
https://download-ib01.fedoraproject.org/pub/fedora-secondary/releases/32/Cloud/s390x/images/Fedora-Cloud-32-1.6-s390x-CHECKSUM
https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/32/Cloud/aarch64/images/Fedora-Cloud-32-1.6-aarch64-CHECKSUM
https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/32/Cloud/x86_64/images/Fedora-Cloud-32-1.6-x86_64-CHECKSUM
and the GPG keys are available here:
https://getfedora.org/en/security/

NOTE: I tried moving to Fedora 33, but the aarch64 VM cannot boot
properly. May be worth investigating but I have no experience with ARM
so I'll leave that to someone else, if interested.

Daniele Buono (1):
  tests/acceptance/boot_linux: Switch to Fedora 32

 tests/acceptance/boot_linux.py | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

-- 
2.30.0




[PATCH 1/1] tests/acceptance/boot_linux: Switch to Fedora 32

2021-01-26 Thread Daniele Buono
Some acceptance test require a full VM image.
The tests were using Fedora 31, which is now EOL.
Probably as a consequence, the Avocado framework is not
able to download such images anymore.

Switch to Fedora 32, which is still supported.

Signed-off-by: Daniele Buono 
---
 tests/acceptance/boot_linux.py | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/tests/acceptance/boot_linux.py b/tests/acceptance/boot_linux.py
index 1da4a53d6a..b954f95f0b 100644
--- a/tests/acceptance/boot_linux.py
+++ b/tests/acceptance/boot_linux.py
@@ -48,7 +48,7 @@ class BootLinuxBase(Test):
 image_arch = 'ppc64le'
 try:
 boot = vmimage.get(
-'fedora', arch=image_arch, version='31',
+'fedora', arch=image_arch, version='32',
 checksum=self.chksum,
 algorithm='sha256',
 cache_dir=self.cache_dirs[0],
@@ -111,7 +111,7 @@ class BootLinuxX8664(BootLinux):
 :avocado: tags=arch:x86_64
 """
 
-chksum = 'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0'
+chksum = '423a4ce32fa32c50c11e3d3ff392db97a762533b81bef9d00599de518a7469c8'
 
 def test_pc_i440fx_tcg(self):
 """
@@ -160,8 +160,7 @@ class BootLinuxAarch64(BootLinux):
 :avocado: tags=machine:virt
 :avocado: tags=machine:gic-version=2
 """
-
-chksum = '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49'
+chksum = 'b367755c664a2d7a26955bbfff985855adfa2ca15e908baf15b4b176d68d3967'
 
 def add_common_args(self):
 self.vm.add_args('-bios',
@@ -217,7 +216,7 @@ class BootLinuxPPC64(BootLinux):
 :avocado: tags=arch:ppc64
 """
 
-chksum = '7c3528b85a3df4b2306e892199a9e1e43f991c506f2cc390dc4efa2026ad2f58'
+chksum = 'dd989a078d641713c55720ba3e4320b204ade6954e2bfe4570c8058dc36e2e5d'
 
 def test_pseries_tcg(self):
 """
@@ -235,7 +234,7 @@ class BootLinuxS390X(BootLinux):
 :avocado: tags=arch:s390x
 """
 
-chksum = '4caaab5a434fd4d1079149a072fdc7891e354f834d355069ca982fdcaf5a122d'
+chksum = '93e49b98fa016797a6864a95cbb7beaec86ffd61dbcd42a951158ae732dae1ec'
 
 @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
 def test_s390_ccw_virtio_tcg(self):
-- 
2.30.0




[PATCH 5/5] tests/qtest/qos-test: dump QEMU command if verbose

2021-01-26 Thread qemu_oss--- via
If qtests are run in verbose mode (i.e. if --verbose CL argument
was provided) then print the assembled qemu command line for each
test.

Use qos_printf() instead of g_test_message() to avoid the latter
cluttering the output.

Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/qos-test.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/qtest/qos-test.c b/tests/qtest/qos-test.c
index b279b6f816..f97d0a08fd 100644
--- a/tests/qtest/qos-test.c
+++ b/tests/qtest/qos-test.c
@@ -89,6 +89,9 @@ static void qos_set_machines_devices_available(void)
 
 static void restart_qemu_or_continue(char *path)
 {
+if (g_test_verbose()) {
+qos_printf("Run QEMU with: '%s'\n", path);
+}
 /* compares the current command line with the
  * one previously executed: if they are the same,
  * don't restart QEMU, if they differ, stop previous
-- 
2.20.1




[PATCH 0/5] enhance debugging with qtest framework

2021-01-26 Thread qemu_oss--- via
This series is a follow-up of the following previous series:
https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg02251.html
The 9p patches of the previous series have already been merged.

This series consists of 2 parts:

1. libqos patch 1 removes a limitation of the qtest/libqos subsystem:
   support for more than one device using the same (official) QEMU device
   name.

   Like discussed in the previous series, if nobody finds this patch useful
   then just ignore it. I needed it in the previou series before but
   eventually decided for a different approach and personally don't need it
   in near future.

2. Patches 2 to 5 enhance debugging issues with the qtest framework. I would
   appreciate if they got merged, because I still find them useful while
   working on new test cases.

Changes of these patches from derived series:

  * Squashed previous patches 1 & 2 -> [patch 1].

  * Dropped ANSI color escape sequences [patch 3].

  * Squashed previous patches 4 & 5 -> [patch 3].

  * Extended commit log to provide more details about purpose [patch 4].

Christian Schoenebeck (5):
  libqos/qgraph: add qos_node_create_driver_named()
  libqos/qgraph_internal: add qos_printf() and qos_printf_literal()
  tests/qtest/qos-test: dump qos graph if verbose
  tests/qtest/qos-test: dump environment variables if verbose
  tests/qtest/qos-test: dump QEMU command if verbose

 tests/qtest/libqos/qgraph.c  | 99 +++-
 tests/qtest/libqos/qgraph.h  | 36 ++
 tests/qtest/libqos/qgraph_internal.h | 12 
 tests/qtest/qos-test.c   | 15 -
 4 files changed, 158 insertions(+), 4 deletions(-)

-- 
2.20.1




[PATCH 4/5] tests/qtest/qos-test: dump environment variables if verbose

2021-01-26 Thread qemu_oss--- via
If qtests are run in verbose mode (i.e. if --verbose CL argument
was provided) then print all environment variables to stdout
before running the individual tests.

It is common nowadays, at least being able to output all config
vectors in a build chain, especially if it is required to
investigate build- and test-issues on foreign/remote machines,
which includes environment variables. In the context of writing
new test cases this is also useful for finding out whether there
are already some existing options for common questions like is
there a preferred location for writing test files to? Is there
a maximum size for test data? Is there a deadline for running
tests?

Use qos_printf() instead of g_test_message() to avoid the latter
cluttering the output.

Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/qos-test.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/qos-test.c b/tests/qtest/qos-test.c
index d98ef78613..b279b6f816 100644
--- a/tests/qtest/qos-test.c
+++ b/tests/qtest/qos-test.c
@@ -313,9 +313,16 @@ static void walk_path(QOSGraphNode *orig_path, int len)
  *   machine/drivers/test objects
  * - Cleans up everything
  */
-int main(int argc, char **argv)
+int main(int argc, char **argv, char** envp)
 {
 g_test_init(, , NULL);
+if (g_test_verbose()) {
+qos_printf("ENVIRONMENT VARIABLES: {\n");
+for (char **env = envp; *env != 0; env++) {
+qos_printf("\t%s\n", *env);
+}
+qos_printf("}\n");
+}
 qos_graph_init();
 module_call_init(MODULE_INIT_QOM);
 module_call_init(MODULE_INIT_LIBQOS);
-- 
2.20.1




[PATCH 2/5] libqos/qgraph_internal: add qos_printf() and qos_printf_literal()

2021-01-26 Thread qemu_oss--- via
These two are macros wrapping regular printf() call. They are intended
to be used instead of calling printf() directly in order to avoid
breaking TAP output format.

TAP output format is enabled by using --tap command line argument.
Starting with glib 2.62 it is enabled by default.

Unfortunately there is currently no public glib API available to check
whether TAP output format is enabled. For that reason qos_printf()
simply always prepends a '#' character for now.

Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/libqos/qgraph_internal.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/tests/qtest/libqos/qgraph_internal.h 
b/tests/qtest/libqos/qgraph_internal.h
index 974985dce9..c0025f5ab9 100644
--- a/tests/qtest/libqos/qgraph_internal.h
+++ b/tests/qtest/libqos/qgraph_internal.h
@@ -255,4 +255,15 @@ void qos_delete_cmd_line(const char *name);
  */
 void qos_graph_node_set_availability(const char *node, bool av);
 
+/*
+ * Prepends a '#' character in front for not breaking TAP output format.
+ */
+#define qos_printf(...) printf("# " __VA_ARGS__)
+
+/*
+ * Intended for printing something literally, i.e. for appending text as is
+ * to a line already been started by qos_printf() before.
+ */
+#define qos_printf_literal printf
+
 #endif
-- 
2.20.1




[PATCH 1/5] libqos/qgraph: add qos_node_create_driver_named()

2021-01-26 Thread qemu_oss--- via
So far the qos subsystem of the qtest framework had the limitation
that only one instance of the same official QEMU (QMP) driver name
could be created for qtests. That's because a) the created qos
node names must always be unique, b) the node name must match the
official QEMU driver name being instantiated and c) all nodes are
in a global space shared by all tests.

This patch removes this limitation by introducing a new function
qos_node_create_driver_named() which allows test case authors to
specify a node name being different from the actual associated
QEMU driver name. It fills the new 'qemu_name' field of
QOSGraphNode for that purpose.

Adjust build_driver_cmd_line() and qos_graph_node_set_availability()
to correctly deal with either accessing node name vs. node's
qemu_name correctly.

Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/libqos/qgraph.c  | 54 ++--
 tests/qtest/libqos/qgraph.h  | 16 +
 tests/qtest/libqos/qgraph_internal.h |  1 +
 3 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/tests/qtest/libqos/qgraph.c b/tests/qtest/libqos/qgraph.c
index fc49cfa879..61faf6b27d 100644
--- a/tests/qtest/libqos/qgraph.c
+++ b/tests/qtest/libqos/qgraph.c
@@ -153,6 +153,7 @@ static QOSGraphNode *create_node(const char *name, 
QOSNodeType type)
 static void destroy_node(void *val)
 {
 QOSGraphNode *node = val;
+g_free(node->qemu_name);
 g_free(node->command_line);
 g_free(node);
 }
@@ -286,7 +287,8 @@ static void build_machine_cmd_line(QOSGraphNode *node, 
const char *args)
  */
 static void build_driver_cmd_line(QOSGraphNode *node)
 {
-node->command_line = g_strconcat(" -device ", node->name, NULL);
+const char *name = node->qemu_name ?: node->name;
+node->command_line = g_strconcat(" -device ", name, NULL);
 }
 
 /* qos_print_cb(): callback prints all path found by the DFS algorithm. */
@@ -631,6 +633,15 @@ void qos_node_create_driver(const char *name, 
QOSCreateDriverFunc function)
 node->u.driver.constructor = function;
 }
 
+void qos_node_create_driver_named(const char *name, const char *qemu_name,
+  QOSCreateDriverFunc function)
+{
+QOSGraphNode *node = create_node(name, QNODE_DRIVER);
+node->qemu_name = g_strdup(qemu_name);
+build_driver_cmd_line(node);
+node->u.driver.constructor = function;
+}
+
 void qos_node_contains(const char *container, const char *contained,
QOSGraphEdgeOptions *opts, ...)
 {
@@ -663,7 +674,7 @@ void qos_node_consumes(const char *consumer, const char 
*interface,
 add_edge(interface, consumer, QEDGE_CONSUMED_BY, opts);
 }
 
-void qos_graph_node_set_availability(const char *node, bool av)
+static void qos_graph_node_set_availability_explicit(const char *node, bool av)
 {
 QOSGraphEdgeList *elist;
 QOSGraphNode *n = search_node(node);
@@ -678,9 +689,46 @@ void qos_graph_node_set_availability(const char *node, 
bool av)
 }
 QSLIST_FOREACH_SAFE(e, elist, edge_list, next) {
 if (e->type == QEDGE_CONTAINS || e->type == QEDGE_PRODUCES) {
-qos_graph_node_set_availability(e->dest, av);
+qos_graph_node_set_availability_explicit(e->dest, av);
+}
+}
+}
+
+/*
+ * Behaves as qos_graph_node_set_availability_explicit(), except that the
+ * former always matches by node name only, whereas this function matches both
+ * by node name and node's optional 'qemu_name' field.
+ */
+void qos_graph_node_set_availability(const char *node, bool av)
+{
+GList *l;
+QOSGraphEdgeList *elist;
+QOSGraphEdge *e, *next;
+QOSGraphNode *n;
+GList *keys = g_hash_table_get_keys(node_table);
+
+for (l = keys; l != NULL; l = l->next) {
+const gchar *key = l->data;
+n = g_hash_table_lookup(node_table, key);
+/*
+ * node's 'qemu_name' is set if there is more than one device with
+ * the same QEMU (QMP) device name
+ */
+const char *node_name = n->qemu_name ?: n->name;
+if (g_strcmp0(node_name, node) == 0) {
+n->available = av;
+elist = get_edgelist(n->name);
+if (elist) {
+QSLIST_FOREACH_SAFE(e, elist, edge_list, next) {
+if (e->type == QEDGE_CONTAINS || e->type == QEDGE_PRODUCES)
+{
+qos_graph_node_set_availability_explicit(e->dest, av);
+}
+}
+}
 }
 }
+g_list_free(keys);
 }
 
 void qos_graph_foreach_test_path(QOSTestCallback fn)
diff --git a/tests/qtest/libqos/qgraph.h b/tests/qtest/libqos/qgraph.h
index 5f63d352ca..f472949f68 100644
--- a/tests/qtest/libqos/qgraph.h
+++ b/tests/qtest/libqos/qgraph.h
@@ -452,6 +452,22 @@ void qos_node_create_machine_args(const char *name,
  */
 void qos_node_create_driver(const char *name, QOSCreateDriverFunc function);
 
+/**
+ * Behaves as qos_node_create_driver() with the extension of 

[PATCH 3/5] tests/qtest/qos-test: dump qos graph if verbose

2021-01-26 Thread qemu_oss--- via
If qtests were run in verbose mode (i.e. if --verbose CL argument was
provided) then dump the generated qos graph (all nodes and edges,
along with their current individual availability status) to stdout,
which allows to identify problems in the created qos graph e.g. when
writing new qos tests.

See API doc comment on function qos_dump_graph() for details.

Signed-off-by: Christian Schoenebeck 
---
 tests/qtest/libqos/qgraph.c | 45 +
 tests/qtest/libqos/qgraph.h | 20 +
 tests/qtest/qos-test.c  |  3 +++
 3 files changed, 68 insertions(+)

diff --git a/tests/qtest/libqos/qgraph.c b/tests/qtest/libqos/qgraph.c
index 61faf6b27d..b3b1a31f81 100644
--- a/tests/qtest/libqos/qgraph.c
+++ b/tests/qtest/libqos/qgraph.c
@@ -805,3 +805,48 @@ void qos_delete_cmd_line(const char *name)
 node->command_line = NULL;
 }
 }
+
+void qos_dump_graph(void)
+{
+GList *keys;
+GList *l;
+QOSGraphEdgeList *list;
+QOSGraphEdge *e, *next;
+QOSGraphNode *dest_node, *node;
+
+qos_printf("ALL QGRAPH EDGES: {\n");
+keys = g_hash_table_get_keys(edge_table);
+for (l = keys; l != NULL; l = l->next) {
+const gchar *key = l->data;
+qos_printf("\t src='%s'\n", key);
+list = get_edgelist(key);
+QSLIST_FOREACH_SAFE(e, list, edge_list, next) {
+dest_node = g_hash_table_lookup(node_table, e->dest);
+qos_printf("\t\t|-> dest='%s' type=%d (node=%p)",
+   e->dest, e->type, dest_node);
+if (!dest_node) {
+qos_printf_literal(" <--- ERROR !");
+}
+qos_printf_literal("\n");
+}
+}
+g_list_free(keys);
+qos_printf("}\n");
+
+qos_printf("ALL QGRAPH NODES: {\n");
+keys = g_hash_table_get_keys(node_table);
+for (l = keys; l != NULL; l = l->next) {
+const gchar *key = l->data;
+node = g_hash_table_lookup(node_table, key);
+qos_printf("\t name='%s' ", key);
+if (node->qemu_name) {
+qos_printf_literal("qemu_name='%s' ", node->qemu_name);
+}
+qos_printf_literal("type=%d cmd_line='%s' [%s]\n",
+   node->type, node->command_line,
+   node->available ? "available" : "UNAVAILBLE"
+);
+}
+g_list_free(keys);
+qos_printf("}\n");
+}
diff --git a/tests/qtest/libqos/qgraph.h b/tests/qtest/libqos/qgraph.h
index f472949f68..07a32535f1 100644
--- a/tests/qtest/libqos/qgraph.h
+++ b/tests/qtest/libqos/qgraph.h
@@ -586,5 +586,25 @@ QOSGraphObject *qos_machine_new(QOSGraphNode *node, 
QTestState *qts);
 QOSGraphObject *qos_driver_new(QOSGraphNode *node, QOSGraphObject *parent,
QGuestAllocator *alloc, void *arg);
 
+/**
+ * Just for debugging purpose: prints all currently existing nodes and
+ * edges to stdout.
+ *
+ * All qtests add themselves to the overall qos graph by calling qgraph
+ * functions that add device nodes and edges between the individual graph
+ * nodes for tests. As the actual graph is assmbled at runtime by the qos
+ * subsystem, it is sometimes not obvious how the overall graph looks like.
+ * E.g. when writing new tests it may happen that those new tests are simply
+ * ignored by the qtest framework.
+ *
+ * This function allows to identify problems in the created qgraph. Keep in
+ * mind: only tests with a path down from the actual test case node (leaf) up
+ * to the graph's root node are actually executed by the qtest framework. And
+ * the qtest framework uses QMP to automatically check which QEMU drivers are
+ * actually currently available, and accordingly qos marks certain pathes as
+ * 'unavailable' in such cases (e.g. when QEMU was compiled without support for
+ * a certain feature).
+ */
+void qos_dump_graph(void);
 
 #endif
diff --git a/tests/qtest/qos-test.c b/tests/qtest/qos-test.c
index 8fdf87b183..d98ef78613 100644
--- a/tests/qtest/qos-test.c
+++ b/tests/qtest/qos-test.c
@@ -322,6 +322,9 @@ int main(int argc, char **argv)
 qos_set_machines_devices_available();
 
 qos_graph_foreach_test_path(walk_path);
+if (g_test_verbose()) {
+qos_dump_graph();
+}
 g_test_run();
 qtest_end();
 qos_graph_destroy();
-- 
2.20.1




Re: [PATCH] docs/system: Deprecate `-cpu ...,+feature,-feature` syntax

2021-01-26 Thread John Snow

On 1/21/21 4:39 AM, Daniel P. Berrangé wrote:

On Wed, Jan 20, 2021 at 03:12:41PM -0500, Eduardo Habkost wrote:

The ordering semantics of +feature/-feature is tricky and not
obvious, and it requires a custom option parser.  Deprecate that
syntax so we can eventually remove the custom -cpu option parser
and plus_features/minus_features global variables in i386.

Signed-off-by: Eduardo Habkost 
---
  docs/system/deprecated.rst | 14 ++
  1 file changed, 14 insertions(+)


Ideally we would also print a warning on stderr when this deprecated
style is used.



+1.

It might break some tests to do that, though, but if it's not too 
gruesome it's probably worth it.





Re: [PATCH 6/6] hw/i2c: Implement NPCM7XX SMBus Module FIFO Mode

2021-01-26 Thread Corey Minyard
On Tue, Jan 26, 2021 at 11:32:37AM -0800, wuhaotsh--- via wrote:
> +
> +static void npcm7xx_smbus_read_byte_fifo(NPCM7xxSMBusState *s)
> +{
> +uint8_t received_bytes = NPCM7XX_SMBRXF_STS_RX_BYTES(s->rxf_sts);
> +
> +if (received_bytes == 0) {
> +npcm7xx_smbus_recv_fifo(s);
> +return;
> +}
> +
> +s->sda = s->rx_fifo[s->rx_cur];
> +s->rx_cur = (s->rx_cur + 1u) % NPCM7XX_SMBUS_FIFO_SIZE;
> +--s->rxf_sts;

This open-coded decrement seems a little risky.  Are you sure in every
case that s->rxf_sts > 0?  There's no way what's running in the VM can
game this and cause a buffer overrun?  One caller to this function seems
to protect against this, and another does not.

Other than this, I didn't see any issues with this patch.

-corey



Re: [PATCH] IOMMU and ATS not supported by vhost-user filesystem.

2021-01-26 Thread Leonardo Augusto Guimarães Garcia

On 1/26/21 4:45 PM, Dr. David Alan Gilbert wrote:

* lagar...@linux.ibm.com (lagar...@linux.ibm.com) wrote:

From: Leonardo Garcia 

Currently, as IOMMU and ATS are not supported, if a user mistakenly set
any of them and tries to mount the vhost-user filesystem inside the
guest, whenever the user tries to access the mount point, the system
will hang forever.

Signed-off-by: Leonardo Garcia 
---
  hw/virtio/vhost-user-fs-pci.c | 7 +++
  hw/virtio/vhost-user-fs.c | 5 +
  2 files changed, 12 insertions(+)

diff --git a/hw/virtio/vhost-user-fs-pci.c b/hw/virtio/vhost-user-fs-pci.c
index 2ed8492b3f..564d1fd108 100644
--- a/hw/virtio/vhost-user-fs-pci.c
+++ b/hw/virtio/vhost-user-fs-pci.c
@@ -11,6 +11,8 @@
   * top-level directory.
   */
  
+#include "qemu/osdep.h"

+#include "qapi/error.h"
  #include "qemu/osdep.h"
  #include "hw/qdev-properties.h"
  #include "hw/virtio/vhost-user-fs.h"
@@ -45,6 +47,11 @@ static void vhost_user_fs_pci_realize(VirtIOPCIProxy 
*vpci_dev, Error **errp)
  vpci_dev->nvectors = dev->vdev.conf.num_request_queues + 2;
  }
  
+if (vpci_dev->flags & VIRTIO_PCI_FLAG_ATS) {

+error_setg(errp, "ATS is currently not supported with 
vhost-user-fs-pci");
+return;
+}
+
  qdev_realize(vdev, BUS(_dev->bus), errp);
  }
  
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c

index ac4fc34b36..914d68b3ee 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -203,6 +203,11 @@ static void vuf_device_realize(DeviceState *dev, Error 
**errp)
  return;
  }
  
+if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {

+error_setg(errp, "IOMMU is currently not supported with 
vhost-user-fs");
+return;
+}

Yes, I've seen this problem - however, I'm a little confused; isn't the
negotiation of features on virtio supposed to happen automatically?
If so, how come it's managing to set VIRTIO_F_IOMMU_PLATFORM?



It is easy to set by passing iommu_platform=on on the QEMU command line. 
Something like this:


-device 
vhost-user-fs-pci,chardev=chr-vu-fs0,queue-size=512,tag=myfs,iommu_platform=on,ats=on


I understand this is a user error, but QEMU should not allow this 
configuration as it doesn't work.


Cheers,

Leo




Dave


  if (!vhost_user_init(>vhost_user, >conf.chardev, errp)) {
  return;
  }
--
2.29.2





Re: [PATCH 4/6] hw/arm: Add I2C device tree for Quanta GSJ

2021-01-26 Thread Corey Minyard
On Tue, Jan 26, 2021 at 11:32:35AM -0800, wuhaotsh--- via wrote:
> Add an I2C device tree for Quanta GSJ. We only included devices with
> existing QEMU implementation, including AT24 EEPROM and temperature
> sensors.
> 
> Reviewed-by: Doug Evans
> Reviewed-by: Tyrong Ting
> Signed-off-by: Hao Wu 
> ---
>  hw/arm/npcm7xx_boards.c | 17 +
>  1 file changed, 17 insertions(+)
> 
> diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
> index 2d82f48848..1418629e06 100644
> --- a/hw/arm/npcm7xx_boards.c
> +++ b/hw/arm/npcm7xx_boards.c
> @@ -19,6 +19,7 @@
>  #include "exec/address-spaces.h"
>  #include "hw/arm/npcm7xx.h"
>  #include "hw/core/cpu.h"
> +#include "hw/i2c/smbus_eeprom.h"
>  #include "hw/loader.h"
>  #include "hw/qdev-properties.h"
>  #include "qapi/error.h"
> @@ -112,6 +113,21 @@ static void npcm750_evb_i2c_init(NPCM7xxState *soc)
>  i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
>  }
>  
> +static void quanta_gsj_i2c_init(NPCM7xxState *soc)
> +{
> +uint8_t *eeprom_buf0 = g_malloc0(32 * 1024);
> +uint8_t *eeprom_buf1 = g_malloc0(32 * 1024);

This is kind of pointless because the smbus eeprom is 256 bytes.

It would be nice to modify the smbus eeprom code to take different
sizes, if you want to submit a patch.

-corey

> +
> +i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x48);
> +i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x48);
> +i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x48);
> +i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x48);
> +smbus_eeprom_init_one(npcm7xx_i2c_get_bus(soc, 9), 0x55, eeprom_buf0);
> +smbus_eeprom_init_one(npcm7xx_i2c_get_bus(soc, 10), 0x55, eeprom_buf1);
> +
> +/* TODO: Add addtional i2c devices. */
> +}
> +
>  static void npcm750_evb_init(MachineState *machine)
>  {
>  NPCM7xxState *soc;
> @@ -137,6 +153,7 @@ static void quanta_gsj_init(MachineState *machine)
>  npcm7xx_load_bootrom(machine, soc);
>  npcm7xx_connect_flash(>fiu[0], 0, "mx25l25635e",
>drive_get(IF_MTD, 0, 0));
> +quanta_gsj_i2c_init(soc);
>  npcm7xx_load_kernel(machine, soc);
>  }
>  
> -- 
> 2.30.0.365.g02bc693789-goog
> 
> 



Re: [PATCH 2/6] hw/i2c: Implement NPCM7XX SMBus Module Single Mode

2021-01-26 Thread Corey Minyard
On Tue, Jan 26, 2021 at 11:32:33AM -0800, wuhaotsh--- via wrote:
> This commit implements the single-byte mode of the SMBus.
> 
> Each Nuvoton SoC has 16 System Management Bus (SMBus). These buses
> compliant with SMBus and I2C protocol.
> 
> This patch implements the single-byte mode of the SMBus. In this mode,
> the user sends or receives a byte each time. The SMBus device transmits
> it to the underlying i2c device and sends an interrupt back to the QEMU
> guest.

I don't see any functional issues with this.

The register order in the switch statements is rather confusing.  I see
that it's the order of the registers in memory, but it kind of threw me
at first.  That's ok, I think, though a comment might be welcome.

The VMStateDescription structure is not necessary, and is misleading,
as there's no support for VMState transfer on this system, and you
haven't put anything into it, anyway.  So you should probably remove
that.

Reviewed-by: Corey Minyard 

-corey

> 
> Reviewed-by: Doug Evans
> Reviewed-by: Tyrong Ting
> Signed-off-by: Hao Wu 
> ---
>  docs/system/arm/nuvoton.rst|   2 +-
>  hw/arm/npcm7xx.c   |  68 ++-
>  hw/i2c/meson.build |   1 +
>  hw/i2c/npcm7xx_smbus.c | 766 +
>  hw/i2c/trace-events|  11 +
>  include/hw/arm/npcm7xx.h   |   2 +
>  include/hw/i2c/npcm7xx_smbus.h |  88 
>  7 files changed, 921 insertions(+), 17 deletions(-)
>  create mode 100644 hw/i2c/npcm7xx_smbus.c
>  create mode 100644 include/hw/i2c/npcm7xx_smbus.h
> 
> diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
> index a1786342e2..34fc799b2d 100644
> --- a/docs/system/arm/nuvoton.rst
> +++ b/docs/system/arm/nuvoton.rst
> @@ -43,6 +43,7 @@ Supported devices
>   * GPIO controller
>   * Analog to Digital Converter (ADC)
>   * Pulse Width Modulation (PWM)
> + * SMBus controller (SMBF)
>  
>  Missing devices
>  ---
> @@ -58,7 +59,6 @@ Missing devices
>  
>   * Ethernet controllers (GMAC and EMC)
>   * USB device (USBD)
> - * SMBus controller (SMBF)
>   * Peripheral SPI controller (PSPI)
>   * SD/MMC host
>   * PECI interface
> diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
> index d1fe9bd1df..8f596ffd69 100644
> --- a/hw/arm/npcm7xx.c
> +++ b/hw/arm/npcm7xx.c
> @@ -104,6 +104,22 @@ enum NPCM7xxInterrupt {
>  NPCM7XX_OHCI_IRQ= 62,
>  NPCM7XX_PWM0_IRQ= 93,   /* PWM module 0 */
>  NPCM7XX_PWM1_IRQ,   /* PWM module 1 */
> +NPCM7XX_SMBUS0_IRQ  = 64,
> +NPCM7XX_SMBUS1_IRQ,
> +NPCM7XX_SMBUS2_IRQ,
> +NPCM7XX_SMBUS3_IRQ,
> +NPCM7XX_SMBUS4_IRQ,
> +NPCM7XX_SMBUS5_IRQ,
> +NPCM7XX_SMBUS6_IRQ,
> +NPCM7XX_SMBUS7_IRQ,
> +NPCM7XX_SMBUS8_IRQ,
> +NPCM7XX_SMBUS9_IRQ,
> +NPCM7XX_SMBUS10_IRQ,
> +NPCM7XX_SMBUS11_IRQ,
> +NPCM7XX_SMBUS12_IRQ,
> +NPCM7XX_SMBUS13_IRQ,
> +NPCM7XX_SMBUS14_IRQ,
> +NPCM7XX_SMBUS15_IRQ,
>  NPCM7XX_GPIO0_IRQ   = 116,
>  NPCM7XX_GPIO1_IRQ,
>  NPCM7XX_GPIO2_IRQ,
> @@ -152,6 +168,26 @@ static const hwaddr npcm7xx_pwm_addr[] = {
>  0xf0104000,
>  };
>  
> +/* Direct memory-mapped access to each SMBus Module. */
> +static const hwaddr npcm7xx_smbus_addr[] = {
> +0xf008,
> +0xf0081000,
> +0xf0082000,
> +0xf0083000,
> +0xf0084000,
> +0xf0085000,
> +0xf0086000,
> +0xf0087000,
> +0xf0088000,
> +0xf0089000,
> +0xf008a000,
> +0xf008b000,
> +0xf008c000,
> +0xf008d000,
> +0xf008e000,
> +0xf008f000,
> +};
> +
>  static const struct {
>  hwaddr regs_addr;
>  uint32_t unconnected_pins;
> @@ -353,6 +389,11 @@ static void npcm7xx_init(Object *obj)
>  object_initialize_child(obj, "gpio[*]", >gpio[i], 
> TYPE_NPCM7XX_GPIO);
>  }
>  
> +for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
> +object_initialize_child(obj, "smbus[*]", >smbus[i],
> +TYPE_NPCM7XX_SMBUS);
> +}
> +
>  object_initialize_child(obj, "ehci", >ehci, TYPE_NPCM7XX_EHCI);
>  object_initialize_child(obj, "ohci", >ohci, TYPE_SYSBUS_OHCI);
>  
> @@ -509,6 +550,17 @@ static void npcm7xx_realize(DeviceState *dev, Error 
> **errp)
> npcm7xx_irq(s, NPCM7XX_GPIO0_IRQ + i));
>  }
>  
> +/* SMBus modules. Cannot fail. */
> +QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_smbus_addr) != 
> ARRAY_SIZE(s->smbus));
> +for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
> +Object *obj = OBJECT(>smbus[i]);
> +
> +sysbus_realize(SYS_BUS_DEVICE(obj), _abort);
> +sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm7xx_smbus_addr[i]);
> +sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
> +   npcm7xx_irq(s, NPCM7XX_SMBUS0_IRQ + i));
> +}
> +
>  /* USB Host */
>  object_property_set_bool(OBJECT(>ehci), "companion-enable", true,
>   _abort);
> @@ -576,22 +628,6 @@ static void 

Re: [PATCH v4 4/4] meson: Warn when TCI is selected but TCG backend is available

2021-01-26 Thread Richard Henderson
On 1/26/21 9:44 AM, Stefan Weil wrote:
> I was not talking about the TODO assertions. When I wrote TCI, I only enabled
> and included code which was triggered by my testing - that's why I said the
> productive code lines have 100 % test coverage. TODO assertions are not
> productive code, but debug code which were made to detect new test cases. They
> were successful, too, because they were triggered by some tests in `make
> check-tcg`.

The TODO assertions are all bugs.

Any *real* dead code detection should have been done in
tcg/tci/tcg-target.c.inc.  What's interpreted in tcg/tci.c should be exactly
what is produced on the other side, and you are producing more than you are
consuming.

> It should pass now unless you get timeouts for some tests. Please tell me if
> more TODO assertions are triggered by new tests.

case INDEX_op_ld8s_i32:
TODO();
break;

Can be triggered by

target/arm/translate-a64.c:1061:
tcg_gen_ld8s_i64(tcg_dest, cpu_env, vect_off);
target/arm/translate-a64.c:1090:
tcg_gen_ld8s_i32(tcg_dest, cpu_env, vect_off);
target/arm/translate.c:1210:
tcg_gen_ld8s_i32(dest, cpu_env, off);

target/s390x/translate_vx.c.inc:81:
tcg_gen_ld8s_i64(dst, cpu_env, offs);
target/s390x/translate_vx.c.inc:111:
tcg_gen_ld8s_i32(dst, cpu_env, offs);

case INDEX_op_ld16s_i32:
TODO();
break;

Can be triggered by

target/arm/translate-a64.c:1064:
tcg_gen_ld16s_i64(tcg_dest, cpu_env, vect_off);
target/arm/translate-a64.c:1093:
tcg_gen_ld16s_i32(tcg_dest, cpu_env, vect_off);
target/arm/translate.c:1216:
tcg_gen_ld16s_i32(dest, cpu_env, off);
target/s390x/translate_vx.c.inc:84:
tcg_gen_ld16s_i64(dst, cpu_env, offs);
target/s390x/translate_vx.c.inc:114:
tcg_gen_ld16s_i32(dst, cpu_env, offs);

All of which are target vector instructions.
I'm sure it would be trivial to whip up test cases for them, but I don't see
that as my job.

Please maintain this code properly or give it up.


r~



Re: [PATCH] vfio/migrate: Move switch of dirty tracking into vfio_memory_listener

2021-01-26 Thread Alex Williamson


Kirti?  Migration experts?  Thanks,

Alex

On Mon, 11 Jan 2021 15:34:39 +0800
Keqian Zhu  wrote:

> For now the switch of vfio dirty page tracking is integrated into
> the vfio_save_handler, it causes some problems [1].
> 
> The object of dirty tracking is guest memory, but the object of
> the vfio_save_handler is device state. This mixed logic produces
> unnecessary coupling and conflicts:
> 
> 1. Coupling: Their saving granule is different (perVM vs perDevice).
>vfio will enable dirty_page_tracking for each devices, actually
>once is enough.
> 2. Conflicts: The ram_save_setup() traverses all memory_listeners
>to execute their log_start() and log_sync() hooks to get the
>first round dirty bitmap, which is used by the bulk stage of
>ram saving. However, it can't get dirty bitmap from vfio, as
>@savevm_ram_handlers is registered before @vfio_save_handler.
> 
> Move the switch of vfio dirty_page_tracking into vfio_memory_listener
> can solve above problems. Besides, Do not require devices in SAVING
> state for vfio_sync_dirty_bitmap().
> 
> [1] https://www.spinics.net/lists/kvm/msg229967.html
> 
> Reported-by: Zenghui Yu 
> Signed-off-by: Keqian Zhu 
> ---
>  hw/vfio/common.c| 53 +
>  hw/vfio/migration.c | 35 --
>  2 files changed, 44 insertions(+), 44 deletions(-)
> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index 6ff1daa763..9128cd7ee1 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -311,7 +311,7 @@ bool vfio_mig_active(void)
>  return true;
>  }
>  
> -static bool vfio_devices_all_saving(VFIOContainer *container)
> +static bool vfio_devices_all_dirty_tracking(VFIOContainer *container)
>  {
>  VFIOGroup *group;
>  VFIODevice *vbasedev;
> @@ -329,13 +329,8 @@ static bool vfio_devices_all_saving(VFIOContainer 
> *container)
>  return false;
>  }
>  
> -if (migration->device_state & VFIO_DEVICE_STATE_SAVING) {
> -if ((vbasedev->pre_copy_dirty_page_tracking == 
> ON_OFF_AUTO_OFF)
> -&& (migration->device_state & 
> VFIO_DEVICE_STATE_RUNNING)) {
> -return false;
> -}
> -continue;
> -} else {
> +if ((vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF)
> +&& (migration->device_state & VFIO_DEVICE_STATE_RUNNING)) {
>  return false;
>  }
>  }
> @@ -987,6 +982,44 @@ static void vfio_listener_region_del(MemoryListener 
> *listener,
>  }
>  }
>  
> +static void vfio_set_dirty_page_tracking(VFIOContainer *container, bool 
> start)
> +{
> +int ret;
> +struct vfio_iommu_type1_dirty_bitmap dirty = {
> +.argsz = sizeof(dirty),
> +};
> +
> +if (start) {
> +dirty.flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_START;
> +} else {
> +dirty.flags = VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP;
> +}
> +
> +ret = ioctl(container->fd, VFIO_IOMMU_DIRTY_PAGES, );
> +if (ret) {
> +error_report("Failed to set dirty tracking flag 0x%x errno: %d",
> + dirty.flags, errno);
> +}
> +}
> +
> +static void vfio_listener_log_start(MemoryListener *listener,
> +MemoryRegionSection *section,
> +int old, int new)
> +{
> +VFIOContainer *container = container_of(listener, VFIOContainer, 
> listener);
> +
> +vfio_set_dirty_page_tracking(container, true);
> +}
> +
> +static void vfio_listener_log_stop(MemoryListener *listener,
> +   MemoryRegionSection *section,
> +   int old, int new)
> +{
> +VFIOContainer *container = container_of(listener, VFIOContainer, 
> listener);
> +
> +vfio_set_dirty_page_tracking(container, false);
> +}
> +
>  static int vfio_get_dirty_bitmap(VFIOContainer *container, uint64_t iova,
>   uint64_t size, ram_addr_t ram_addr)
>  {
> @@ -1128,7 +1161,7 @@ static void vfio_listerner_log_sync(MemoryListener 
> *listener,
>  return;
>  }
>  
> -if (vfio_devices_all_saving(container)) {
> +if (vfio_devices_all_dirty_tracking(container)) {
>  vfio_sync_dirty_bitmap(container, section);
>  }
>  }
> @@ -1136,6 +1169,8 @@ static void vfio_listerner_log_sync(MemoryListener 
> *listener,
>  static const MemoryListener vfio_memory_listener = {
>  .region_add = vfio_listener_region_add,
>  .region_del = vfio_listener_region_del,
> +.log_start = vfio_listener_log_start,
> +.log_stop = vfio_listener_log_stop,
>  .log_sync = vfio_listerner_log_sync,
>  };
>  
> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> index 00daa50ed8..c0f646823a 100644
> --- a/hw/vfio/migration.c
> +++ b/hw/vfio/migration.c
> @@ -395,40 +395,10 @@ static int vfio_load_device_config_state(QEMUFile *f, 
> void 

Re: [PATCH V6 0/6] hw/block/nvme: support multi-path for ctrl/ns

2021-01-26 Thread Minwoo Im
On 21-01-27 05:39:29, Keith Busch wrote:
> This came out looking cleaner than I had initially expected. Thanks for
> seeing this feature through!
> 
> Reviewed-by: Keith Busch 

Thanks Keith for the review!



Re: [PATCH v2 8/9] tests/docker: Add dockerfile for Alpine Linux

2021-01-26 Thread John Snow

On 1/19/21 8:41 AM, Thomas Huth wrote:

On 18/01/2021 11.33, Daniel P. Berrangé wrote:

On Mon, Jan 18, 2021 at 02:38:07PM +0800, Jiaxun Yang wrote:

Alpine Linux[1] is a security-oriented, lightweight Linux distribution
based on musl libc and busybox.

It it popular among Docker guests and embedded applications.

Adding it to test against different libc.

[1]: https://alpinelinux.org/

Signed-off-by: Jiaxun Yang 
---
  tests/docker/dockerfiles/alpine.docker | 57 ++
  1 file changed, 57 insertions(+)
  create mode 100644 tests/docker/dockerfiles/alpine.docker

diff --git a/tests/docker/dockerfiles/alpine.docker 
b/tests/docker/dockerfiles/alpine.docker

new file mode 100644
index 00..5be5198d00
--- /dev/null
+++ b/tests/docker/dockerfiles/alpine.docker
@@ -0,0 +1,57 @@
+
+FROM alpine:edge
+
+RUN apk update
+RUN apk upgrade
+
+# Please keep this list sorted alphabetically
+ENV PACKAGES \
+    alsa-lib-dev \
+    bash \
+    bison \


This shouldn't be required.


bison and flex were required to avoid some warnings in the past while 
compiling the dtc submodule ... but I thought we got rid of the problem 
at one point in time, so this can be removed now, indeed.



+    build-base \


This seems to be a meta packae that pulls in other
misc toolchain packages. Please list the pieces we
need explicitly instead.


Looking at the "Depends" list on 
https://pkgs.alpinelinux.org/package/v3.3/main/x86/build-base there are 
only 6 dependencies and we need most of those for QEMU anyway, so I 
think it is ok to keep build-base here.



+    coreutils \
+    curl-dev \
+    flex \


This shouldn't be needed.


+    git \
+    glib-dev \
+    glib-static \
+    gnutls-dev \
+    gtk+3.0-dev \
+    libaio-dev \
+    libcap-dev \


Should not be required, as we use cap-ng.


Right.


+    libcap-ng-dev \
+    libjpeg-turbo-dev \
+    libnfs-dev \
+    libpng-dev \
+    libseccomp-dev \
+    libssh-dev \
+    libusb-dev \
+    libxml2-dev \
+    linux-headers \


Is this really needed ? We don't install kernel-headers on other
distros AFAICT.


I tried a build without this package, and it works fine indeed.


+    lzo-dev \
+    mesa-dev \
+    mesa-egl \
+    mesa-gbm \
+    meson \
+    ncurses-dev \
+    ninja \
+    paxmark \


What is this needed for ?


Seems like it also can be dropped.


+    perl \
+    pulseaudio-dev \
+    python3 \
+    py3-sphinx \
+    shadow \


Is this really needed ?


See:
https://www.spinics.net/lists/kvm/msg231556.html

I can remove the superfluous packages when picking up the patch, no need 
to respin just because of this.


  Thomas




You can refer to my post earlier this January for a "minimal" Alpine 
Linux build, if you wish.


My goal was to find the smallest set of packages possible without 
passing any explicit configure flags.


I wonder if it's worth having layered "core build" and "test build" 
images so that we can smoke test the minimalistic build from time to 
time -- I seem to recall Dan posting information about a dependency 
management tool for Dockerfiles, but I admit I didn't look too closely 
at what problem that solves, exactly.


--js




Re: [RFC PATCH v2 2/3] vfio: Set the priority of the VFIO VM state change handler explicitly

2021-01-26 Thread Alex Williamson
On Wed, 9 Dec 2020 16:09:18 +0800
Shenming Lu  wrote:

> In the VFIO VM state change handler, VFIO devices are transitioned
> in the _SAVING state, which should keep them from sending interrupts.

Is this comment accurate?  It's my expectation that _SAVING has no
bearing on a device generating interrupts.  Interrupt generation must
be allowed to continue so long as the device is _RUNNING.  Thanks,

Alex

> Then we can save the pending states of all interrupts in the GIC VM
> state change handler (on ARM).
> 
> So we have to set the priority of the VFIO VM state change handler
> explicitly (like virtio devices) to ensure it is called before the
> GIC's in saving.
> 
> Signed-off-by: Shenming Lu 
> Reviewed-by: Kirti Wankhede 
> ---
>  hw/vfio/migration.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> index 3b9de1353a..97ea82b100 100644
> --- a/hw/vfio/migration.c
> +++ b/hw/vfio/migration.c
> @@ -862,7 +862,8 @@ static int vfio_migration_init(VFIODevice *vbasedev,
>  register_savevm_live(id, VMSTATE_INSTANCE_ID_ANY, 1, 
> _vfio_handlers,
>   vbasedev);
>  
> -migration->vm_state = 
> qemu_add_vm_change_state_handler(vfio_vmstate_change,
> +migration->vm_state = qdev_add_vm_change_state_handler(vbasedev->dev,
> +   
> vfio_vmstate_change,
> vbasedev);
>  migration->migration_state.notify = vfio_migration_state_notifier;
>  add_migration_state_change_notifier(>migration_state);




Re: [RFC PATCH v2 3/3] vfio: Avoid disabling and enabling vectors repeatedly in VFIO migration

2021-01-26 Thread Alex Williamson
On Wed, 9 Dec 2020 16:09:19 +0800
Shenming Lu  wrote:

> Different from the normal situation when the guest starts, we can
> know the max unmasked vetctor (at the beginning) after msix_load()
> in VFIO migration. So in order to avoid ineffectively disabling and

s/ineffectively/inefficiently/?  It's "effective" either way I think.

> enabling vectors repeatedly, let's allocate all needed vectors first
> and then enable these unmasked vectors one by one without disabling.
> 
> Signed-off-by: Shenming Lu 
> ---
>  hw/pci/msix.c | 17 +
>  hw/vfio/pci.c | 10 --
>  include/hw/pci/msix.h |  2 ++
>  3 files changed, 27 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/pci/msix.c b/hw/pci/msix.c
> index 67e34f34d6..bf291d3ff8 100644
> --- a/hw/pci/msix.c
> +++ b/hw/pci/msix.c
> @@ -557,6 +557,23 @@ unsigned int msix_nr_vectors_allocated(const PCIDevice 
> *dev)
>  return dev->msix_entries_nr;
>  }
>  
> +int msix_get_max_unmasked_vector(PCIDevice *dev)
> +{
> +int max_unmasked_vector = -1;
> +int vector;
> +
> +if ((dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] &
> +(MSIX_ENABLE_MASK | MSIX_MASKALL_MASK)) == MSIX_ENABLE_MASK) {
> +for (vector = 0; vector < dev->msix_entries_nr; vector++) {
> +if (!msix_is_masked(dev, vector)) {
> +max_unmasked_vector = vector;
> +}
> +}
> +}
> +
> +return max_unmasked_vector;
> +}

Comments from QEMU PCI folks?

> +
>  static int msix_set_notifier_for_vector(PCIDevice *dev, unsigned int vector)
>  {
>  MSIMessage msg;
> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
> index 51dc373695..e755ed2514 100644
> --- a/hw/vfio/pci.c
> +++ b/hw/vfio/pci.c
> @@ -568,6 +568,9 @@ static void vfio_msix_vector_release(PCIDevice *pdev, 
> unsigned int nr)
>  
>  static void vfio_msix_enable(VFIOPCIDevice *vdev)
>  {
> +int max_unmasked_vector = msix_get_max_unmasked_vector(>pdev);
> +unsigned int used_vector = MAX(max_unmasked_vector, 0);
> +

The above PCI function could also be done inline here pretty easily too:

unsigned int nr, max_vec = 0;

if (!msix_masked(>pdev))
for (nr = 0; nr < msix_nr_vectors_allocated(>pdev); nr++) {
if (!msix_is_masked(>pdev, nr)) {
max_vec = nr;
}
}
}

It's a bit cleaner than the msix utility function, imo. 

>  vfio_disable_interrupts(vdev);
>  
>  vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->msix->entries);
> @@ -586,9 +589,12 @@ static void vfio_msix_enable(VFIOPCIDevice *vdev)
>   * triggering to userspace, then immediately release the vector, leaving
>   * the physical device with no vectors enabled, but MSI-X enabled, just
>   * like the guest view.
> + * If there are unmasked vectors (such as in migration) which will be
> + * enabled soon, we can allocate them here to avoid ineffectively 
> disabling
> + * and enabling vectors repeatedly later.

It just happens that migration triggers this usage model where the
MSI-X enable bit is set with vectors unmasked in the vector table, but
this is not unique to migration, guests can follow this pattern as well.
Has this been tested with a variety of guests?  Logically it seems
correct, but always good to prove so.  Thanks,

Alex

>   */
> -vfio_msix_vector_do_use(>pdev, 0, NULL, NULL);
> -vfio_msix_vector_release(>pdev, 0);
> +vfio_msix_vector_do_use(>pdev, used_vector, NULL, NULL);
> +vfio_msix_vector_release(>pdev, used_vector);
>  
>  if (msix_set_vector_notifiers(>pdev, vfio_msix_vector_use,
>vfio_msix_vector_release, NULL)) {
> diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h
> index 4c4a60c739..4bfb463fa6 100644
> --- a/include/hw/pci/msix.h
> +++ b/include/hw/pci/msix.h
> @@ -23,6 +23,8 @@ void msix_uninit_exclusive_bar(PCIDevice *dev);
>  
>  unsigned int msix_nr_vectors_allocated(const PCIDevice *dev);
>  
> +int msix_get_max_unmasked_vector(PCIDevice *dev);
> +
>  void msix_save(PCIDevice *dev, QEMUFile *f);
>  void msix_load(PCIDevice *dev, QEMUFile *f);
>  




Re: [RFC PATCH v2 1/3] vfio: Move the saving of the config space to the right place in VFIO migration

2021-01-26 Thread Alex Williamson
On Thu, 10 Dec 2020 10:21:21 +0800
Shenming Lu  wrote:

> On 2020/12/10 2:34, Alex Williamson wrote:
> > On Wed, 9 Dec 2020 13:29:47 +0100
> > Cornelia Huck  wrote:
> >   
> >> On Wed, 9 Dec 2020 16:09:17 +0800
> >> Shenming Lu  wrote:
> >>  
> >>> On ARM64 the VFIO SET_IRQS ioctl is dependent on the VM interrupt
> >>> setup, if the restoring of the VFIO PCI device config space is
> >>> before the VGIC, an error might occur in the kernel.
> >>>
> >>> So we move the saving of the config space to the non-iterable
> >>> process, so that it will be called after the VGIC according to
> >>> their priorities.
> >>>
> >>> As for the possible dependence of the device specific migration
> >>> data on it's config space, we can let the vendor driver to
> >>> include any config info it needs in its own data stream.
> >>> (Should we note this in the header file linux-headers/linux/vfio.h?)
> >>
> >> Given that the header is our primary source about how this interface
> >> should act, we need to properly document expectations about what will
> >> be saved/restored when there (well, in the source file in the kernel.)
> >> That goes in both directions: what a userspace must implement, and what
> >> a vendor driver can rely on.  
> 
> Yeah, in order to make the vendor driver and QEMU cooperate better, we might
> need to document some expectations about the data section in the migration
> region...
> >>
> >> [Related, but not a todo for you: I think we're still missing proper
> >> documentation of the whole migration feature.]  
> > 
> > Yes, we never saw anything past v1 of the documentation patch.  Thanks,
> >   
> 
> By the way, is there anything unproper with this patch? Wish your suggestion. 
> :-)

I'm really hoping for some feedback from Kirti, I understand the NVIDIA
vGPU driver to have some dependency on this.  Thanks,

Alex

> >>> Signed-off-by: Shenming Lu 
> >>> ---
> >>>  hw/vfio/migration.c | 25 +++--
> >>>  1 file changed, 15 insertions(+), 10 deletions(-)
> > 
> > .
> >   
> 




Handling multiple inheritance [for CXL]

2021-01-26 Thread Ben Widawsky
I'm working on CXL 2.0 type 3 memory devices [1]. In short, these are PCIe 
devices
that have persistent memory on them. As such, it would be nice to inherit from
both a PCI_DEVICE class as well as an NVDIMM device class.

Truth be told, using TYPE_MEMORY_DEVICE as the interface does provide most of
what I need. I'm wondering what the best way to handle this is. Currently, the
only thing NVDIMM class provides is write/read_label_data, this is driven by
_DSM. For CXL, the mechanism to read/write the equivalent area is not done via
_DSM, but done directly via a mailbox interface. However, the intent is the
same, and so utilizing similar code seems ideal.

If there's a desire to unify these code paths, I'd need something like multiple
inheritance. I'm looking for some feedback here on how to do it.

Thanks.
Ben

[1]: 
https://lore.kernel.org/qemu-devel/20210105165323.783725-1-ben.widaw...@intel.com/



Re: [PATCH v5 03/10] iotests: Move try_remove to iotests.py

2021-01-26 Thread John Snow

On 1/18/21 5:57 AM, Max Reitz wrote:

Signed-off-by: Max Reitz 
Reviewed-by: Eric Blake 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Willian Rampazzo 
---
  tests/qemu-iotests/124|  8 +---
  tests/qemu-iotests/iotests.py | 11 +++
  2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/tests/qemu-iotests/124 b/tests/qemu-iotests/124
index 3705cbb6b3..e40eeb50b9 100755
--- a/tests/qemu-iotests/124
+++ b/tests/qemu-iotests/124
@@ -22,6 +22,7 @@
  
  import os

  import iotests
+from iotests import try_remove
  
  
  def io_write_patterns(img, patterns):

@@ -29,13 +30,6 @@ def io_write_patterns(img, patterns):
  iotests.qemu_io('-c', 'write -P%s %s %s' % pattern, img)
  
  
-def try_remove(img):

-try:
-os.remove(img)
-except OSError:
-pass
-
-
  def transaction_action(action, **kwargs):
  return {
  'type': action,
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 52facb8e04..a69b4cdc4e 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -523,12 +523,15 @@ class FilePath:
  return False
  
  
+def try_remove(img):

+try:
+os.remove(img)
+except OSError:
+pass
+
  def file_path_remover():
  for path in reversed(file_path_remover.paths):
-try:
-os.remove(path)
-except OSError:
-pass
+try_remove(path)
  
  
  def file_path(*names, base_dir=test_dir):




For what it's worth, at the time I wrote this I barely knew Python. I'd 
use FileNotFoundError instead now, which is a subclass of OSError.


Not your baby, not your problem.

Reviewed-by: John Snow 




Re: [PATCH v5 02/10] iotests/297: Rewrite in Python and extend reach

2021-01-26 Thread John Snow

On 1/18/21 5:57 AM, Max Reitz wrote:

Instead of checking iotests.py only, check all Python files in the
qemu-iotests/ directory.  Of course, most of them do not pass, so there
is an extensive skip list for now.  (The only files that do pass are
209, 254, 283, and iotests.py.)



Chiming in to say that I tried to tackle this before; I wrote some 
preliminary cleanups and sent to the list as an "WIP RFC" or something 
like that in earlyish 2020. I paid attention to qed.py and the other 
non-numerical files.


Maybe badly rotted by now, I don't know.


(Alternatively, we could have the opposite, i.e. an explicit list of
files that we do want to check, but I think it is better to check files
by default.)



I agree. Stop the bleeding first and worry about the rest after.


Unless started in debug mode (./check -d), the output has no information
on which files are tested, so we will not have a problem e.g. with
backports, where some files may be missing when compared to upstream.

Besides the technical rewrite, some more things are changed:

- For the pylint invocation, PYTHONPATH is adjusted.  This mirrors
   setting MYPYPATH for mypy.

- Also, MYPYPATH is now derived from PYTHONPATH, so that we include
   paths set by the environment.  Maybe at some point we want to let the
   check script add '../../python/' to PYTHONPATH so that iotests.py does
   not need to do that.



Does this solve an observed problem, or is it preventative? I ran into 
trouble once by pointing mypy to my system python libraries; it seemed 
to have a check that explicitly warned me against such tricks.


I guess for now, if it works, it works. :o)


- Passing --notes=FIXME,XXX to pylint suppresses warnings for TODO
   comments.  TODO is fine, we do not need 297 to complain about such
   comments.



Agreed. You can also edit pylintrc to choose which keywords trigger the 
check -- "TODO" is probably fine, but "FIXME" is maybe a shade worse. 
Season to taste.



- The "Success" line from mypy's output is suppressed, because (A) it
   does not add useful information, and (B) it would leak information
   about the files having been tested to the reference output, which we
   decidedly do not want.

Suggested-by: Vladimir Sementsov-Ogievskiy 
Signed-off-by: Max Reitz 
---
  tests/qemu-iotests/297 | 112 +
  tests/qemu-iotests/297.out |   5 +-
  2 files changed, 92 insertions(+), 25 deletions(-)

diff --git a/tests/qemu-iotests/297 b/tests/qemu-iotests/297
index 5c5420712b..e3db3e061e 100755
--- a/tests/qemu-iotests/297
+++ b/tests/qemu-iotests/297
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env python3
  #
  # Copyright (C) 2020 Red Hat, Inc.


You could bump it up, if you wanted.


  #
@@ -15,30 +15,98 @@
  # You should have received a copy of the GNU General Public License
  # along with this program.  If not, see .
  
-seq=$(basename $0)

-echo "QA output created by $seq"
+import os
+import re
+import shutil
+import subprocess
+import sys
  
-status=1	# failure is the default!

+import iotests
  
-# get standard environment

-. ./common.rc
  
-if ! type -p "pylint-3" > /dev/null; then

-_notrun "pylint-3 not found"
-fi
-if ! type -p "mypy" > /dev/null; then
-_notrun "mypy not found"
-fi
+# TODO: Empty this list!
+SKIP_FILES = (
+'030', '040', '041', '044', '045', '055', '056', '057', '065', '093',
+'096', '118', '124', '129', '132', '136', '139', '147', '148', '149',
+'151', '152', '155', '163', '165', '169', '194', '196', '199', '202',
+'203', '205', '206', '207', '208', '210', '211', '212', '213', '216',
+'218', '219', '222', '224', '228', '234', '235', '236', '237', '238',
+'240', '242', '245', '246', '248', '255', '256', '257', '258', '260',
+'262', '264', '266', '274', '277', '280', '281', '295', '296', '298',
+'299', '300', '302', '303', '304', '307',
+'nbd-fault-injector.py', 'qcow2.py', 'qcow2_format.py', 'qed.py'
+)
  
-pylint-3 --score=n iotests.py
  
-MYPYPATH=../../python/ mypy --warn-unused-configs --disallow-subclassing-any \

---disallow-any-generics --disallow-incomplete-defs \
---disallow-untyped-decorators --no-implicit-optional \
---warn-redundant-casts --warn-unused-ignores \
---no-implicit-reexport iotests.py
+def is_python_file(filename):
+if not os.path.isfile(filename):
+return False
  
-# success, all done

-echo "*** done"
-rm -f $seq.full
-status=0
+if filename.endswith('.py'):
+return True
+
+with open(filename) as f:
+try:
+first_line = f.readline()
+return re.match('^#!.*python', first_line) is not None
+except UnicodeDecodeError:  # Ignore binary files
+return False
+
+




+def run_linters():
+files = [filename for filename in (set(os.listdir('.')) - set(SKIP_FILES))
+ if is_python_file(filename)]
+
+iotests.logger.debug('Files to be checked:')
+iotests.logger.debug(', 

Re: [PATCH v5 01/10] iotests.py: Assume a couple of variables as given

2021-01-26 Thread John Snow

On 1/18/21 5:57 AM, Max Reitz wrote:

There are a couple of environment variables that we fetch with
os.environ.get() without supplying a default.  Clearly they are required
and expected to be set by the ./check script (as evidenced by
execute_setup_common(), which checks for test_dir and
qemu_default_machine to be set, and aborts if they are not).

Using .get() this way has the disadvantage of returning an Optional[str]
type, which mypy will complain about when tests just assume these values
to be str.

Use [] instead, which raises a KeyError for environment variables that
are not set.  When this exception is raised, catch it and move the abort
code from execute_setup_common() there.



Good idea.


Drop the 'assert iotests.sock_dir is not None' from iotest 300, because
that sort of thing is precisely what this patch wants to prevent.

Signed-off-by: Max Reitz 
Reviewed-by: Vladimir Sementsov-Ogievskiy 
Reviewed-by: Willian Rampazzo 


Reviewed-by: John Snow 




Re: [PATCH 1/1] x86/cpu: Populate SVM CPUID feature bits

2021-01-26 Thread Paolo Bonzini

On 26/01/21 21:24, Wei Huang wrote:

Newer AMD CPUs will add CPUID_0x800A_EDX[28] bit, which indicates
that SVM instructions (VMRUN/VMSAVE/VMLOAD) will trigger #VMEXIT before
CPU checking their EAX against reserved memory regions. This change will
allow the hypervisor to avoid intercepting #GP and emulating SVM
instructions. KVM turns on this CPUID bit for nested VMs. In order to
support it, let us populate this bit, along with other SVM feature bits,
in FEAT_SVM.

Signed-off-by: Wei Huang 
---
  target/i386/cpu.c |  6 +++---
  target/i386/cpu.h | 24 ++--
  2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 72a79e6019b5..85e529157659 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -926,11 +926,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
  "npt", "lbrv", "svm-lock", "nrip-save",
  "tsc-scale", "vmcb-clean",  "flushbyasid", "decodeassists",
  NULL, NULL, "pause-filter", NULL,
-"pfthreshold", NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+"pfthreshold", "avic", NULL, "v-vmsave-vmload",
+"vgif", NULL, NULL, NULL,
  NULL, NULL, NULL, NULL,
  NULL, NULL, NULL, NULL,
+"svme-addr-chk", NULL, NULL, NULL,
  },
  .cpuid = { .eax = 0x800A, .reg = R_EDX, },
  .tcg_features = TCG_SVM_FEATURES,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d23a5b340a8d..b39ec505de96 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -670,16 +670,20 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
  #define CPUID_EXT3_PERFCORE (1U << 23)
  #define CPUID_EXT3_PERFNB  (1U << 24)
  
-#define CPUID_SVM_NPT  (1U << 0)

-#define CPUID_SVM_LBRV (1U << 1)
-#define CPUID_SVM_SVMLOCK  (1U << 2)
-#define CPUID_SVM_NRIPSAVE (1U << 3)
-#define CPUID_SVM_TSCSCALE (1U << 4)
-#define CPUID_SVM_VMCBCLEAN(1U << 5)
-#define CPUID_SVM_FLUSHASID(1U << 6)
-#define CPUID_SVM_DECODEASSIST (1U << 7)
-#define CPUID_SVM_PAUSEFILTER  (1U << 10)
-#define CPUID_SVM_PFTHRESHOLD  (1U << 12)
+#define CPUID_SVM_NPT (1U << 0)
+#define CPUID_SVM_LBRV(1U << 1)
+#define CPUID_SVM_SVMLOCK (1U << 2)
+#define CPUID_SVM_NRIPSAVE(1U << 3)
+#define CPUID_SVM_TSCSCALE(1U << 4)
+#define CPUID_SVM_VMCBCLEAN   (1U << 5)
+#define CPUID_SVM_FLUSHASID   (1U << 6)
+#define CPUID_SVM_DECODEASSIST(1U << 7)
+#define CPUID_SVM_PAUSEFILTER (1U << 10)
+#define CPUID_SVM_PFTHRESHOLD (1U << 12)
+#define CPUID_SVM_AVIC(1U << 13)
+#define CPUID_SVM_V_VMSAVE_VMLOAD (1U << 15)
+#define CPUID_SVM_VGIF(1U << 16)
+#define CPUID_SVM_SVME_ADDR_CHK   (1U << 28)
  
  /* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */

  #define CPUID_7_0_EBX_FSGSBASE  (1U << 0)



Queued, thanks.

Paolo




Re: [PATCH V6 4/6] hw/block/nvme: support for multi-controller in subsystem

2021-01-26 Thread Minwoo Im
On 21-01-26 09:57:23, Keith Busch wrote:
> On Tue, Jan 26, 2021 at 09:52:48AM +0900, Minwoo Im wrote:
> > On 21-01-25 10:11:43, Keith Busch wrote:
> > > On Mon, Jan 25, 2021 at 07:03:32PM +0100, Klaus Jensen wrote:
> > > > On Jan 24 11:54, Minwoo Im wrote:
> > > > > We have nvme-subsys and nvme devices mapped together.  To support
> > > > > multi-controller scheme to this setup, controller identifier(id) has 
> > > > > to
> > > > > be managed.  Earlier, cntlid(controller id) used to be always 0 
> > > > > because
> > > > > we didn't have any subsystem scheme that controller id matters.
> > > > > 
> > > > > This patch introduced 'cntlid' attribute to the nvme controller
> > > > > instance(NvmeCtrl) and make it allocated by the nvme-subsys device
> > > > > mapped to the controller.  If nvme-subsys is not given to the
> > > > > controller, then it will always be 0 as it was.
> > > > > 
> > > > > Added 'ctrls' array in the nvme-subsys instance to manage attached
> > > > > controllers to the subsystem with a limit(32).  This patch didn't take
> > > > > list for the controllers to make it seamless with nvme-ns device.
> > > > > 
> > > > > Signed-off-by: Minwoo Im 
> > > > > ---
> > > > >  hw/block/nvme-subsys.c | 21 +
> > > > >  hw/block/nvme-subsys.h |  4 
> > > > >  hw/block/nvme.c| 29 +
> > > > >  hw/block/nvme.h|  1 +
> > > > >  4 files changed, 55 insertions(+)
> > > > > 
> > > > > diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> > > > > index b525fca14103..7138389be4bd 100644
> > > > > --- a/hw/block/nvme.c
> > > > > +++ b/hw/block/nvme.c
> > > > > @@ -4481,6 +4484,10 @@ static void nvme_init_ctrl(NvmeCtrl *n, 
> > > > > PCIDevice *pci_dev)
> > > > >  id->psd[0].enlat = cpu_to_le32(0x10);
> > > > >  id->psd[0].exlat = cpu_to_le32(0x4);
> > > > >  
> > > > > +if (n->subsys) {
> > > > > +id->cmic |= NVME_CMIC_MULTI_CTRL;
> > > > > +}
> > > > 
> > > > Since multiple controllers show up with a PCIe port of their own, do we
> > > > need to set bit 0 (NVME_CMIC_MULTI_PORT?) as well? Or am I
> > > > misunderstanding that bit?
> > > 
> > > AIUI, if you report this MULTI_PORT bit, then each PCI device in the
> > > subsystem needs to report a different "Port Number" in their PCIe Link
> > > Capabilities register. I don't think we can manipulate that value from
> > > the nvme "device", but I also don't know what a host should do with this
> > > information even if we could. So, I think it's safe to leave it at 0.
> > 
> > AFAIK, If we leave it to 0, kernel will not allocate disk for multi-path
> > case (e.g., nvmeXcYnZ).
> 
> Kernel only checks for MULTI_CTRL. It doesn't do anything with MULTI_PORT.

Please forgive me that I took this discussion as MULTI_CTRL rather than
MULTI_PORT.  Please ignore this noise ;)

Thanks!



[PATCH 1/1] x86/cpu: Populate SVM CPUID feature bits

2021-01-26 Thread Wei Huang
Newer AMD CPUs will add CPUID_0x800A_EDX[28] bit, which indicates
that SVM instructions (VMRUN/VMSAVE/VMLOAD) will trigger #VMEXIT before
CPU checking their EAX against reserved memory regions. This change will
allow the hypervisor to avoid intercepting #GP and emulating SVM
instructions. KVM turns on this CPUID bit for nested VMs. In order to
support it, let us populate this bit, along with other SVM feature bits,
in FEAT_SVM.

Signed-off-by: Wei Huang 
---
 target/i386/cpu.c |  6 +++---
 target/i386/cpu.h | 24 ++--
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 72a79e6019b5..85e529157659 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -926,11 +926,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 "npt", "lbrv", "svm-lock", "nrip-save",
 "tsc-scale", "vmcb-clean",  "flushbyasid", "decodeassists",
 NULL, NULL, "pause-filter", NULL,
-"pfthreshold", NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+"pfthreshold", "avic", NULL, "v-vmsave-vmload",
+"vgif", NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
+"svme-addr-chk", NULL, NULL, NULL,
 },
 .cpuid = { .eax = 0x800A, .reg = R_EDX, },
 .tcg_features = TCG_SVM_FEATURES,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d23a5b340a8d..b39ec505de96 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -670,16 +670,20 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_EXT3_PERFCORE (1U << 23)
 #define CPUID_EXT3_PERFNB  (1U << 24)
 
-#define CPUID_SVM_NPT  (1U << 0)
-#define CPUID_SVM_LBRV (1U << 1)
-#define CPUID_SVM_SVMLOCK  (1U << 2)
-#define CPUID_SVM_NRIPSAVE (1U << 3)
-#define CPUID_SVM_TSCSCALE (1U << 4)
-#define CPUID_SVM_VMCBCLEAN(1U << 5)
-#define CPUID_SVM_FLUSHASID(1U << 6)
-#define CPUID_SVM_DECODEASSIST (1U << 7)
-#define CPUID_SVM_PAUSEFILTER  (1U << 10)
-#define CPUID_SVM_PFTHRESHOLD  (1U << 12)
+#define CPUID_SVM_NPT (1U << 0)
+#define CPUID_SVM_LBRV(1U << 1)
+#define CPUID_SVM_SVMLOCK (1U << 2)
+#define CPUID_SVM_NRIPSAVE(1U << 3)
+#define CPUID_SVM_TSCSCALE(1U << 4)
+#define CPUID_SVM_VMCBCLEAN   (1U << 5)
+#define CPUID_SVM_FLUSHASID   (1U << 6)
+#define CPUID_SVM_DECODEASSIST(1U << 7)
+#define CPUID_SVM_PAUSEFILTER (1U << 10)
+#define CPUID_SVM_PFTHRESHOLD (1U << 12)
+#define CPUID_SVM_AVIC(1U << 13)
+#define CPUID_SVM_V_VMSAVE_VMLOAD (1U << 15)
+#define CPUID_SVM_VGIF(1U << 16)
+#define CPUID_SVM_SVME_ADDR_CHK   (1U << 28)
 
 /* Support RDFSBASE/RDGSBASE/WRFSBASE/WRGSBASE */
 #define CPUID_7_0_EBX_FSGSBASE  (1U << 0)
-- 
2.29.2




Re: [PATCH V6 0/6] hw/block/nvme: support multi-path for ctrl/ns

2021-01-26 Thread Keith Busch
This came out looking cleaner than I had initially expected. Thanks for
seeing this feature through!

Reviewed-by: Keith Busch 



[Bug 1913344] [NEW] Exynos4210 UART peripheral data loss

2021-01-26 Thread Iris Johnson
Public bug reported:

Currently the Exynos4210 UART (hw/char/exynos4210_uart.c) incorrectly
reports however many empty bytes are available in the FIFO when queried
for receive capacity. However this peripheral supports a polled mode
where only a single byte can be submitted at a time and the FIFO is
unused, meaning that in polled mode data is lost since it's written into
the FIFO and the polling code in FIFO disabled mode only returns the
value in the RX data register.

Even worse, potentially enabling the FIFO without a FIFO reset will
create a weird situation where data is already in the FIFO whenever data
came in faster than the polling could pick it up (which is basically
always).

This change obscured the issue in
https://bugs.launchpad.net/qemu/+bug/1913341, which instead presented as
strange data loss until I locally resolved this issue.

I have a patch ready for the bug and will submit it later today, I'm
just filing for clarity.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1913344

Title:
   Exynos4210 UART peripheral data loss

Status in QEMU:
  New

Bug description:
  Currently the Exynos4210 UART (hw/char/exynos4210_uart.c) incorrectly
  reports however many empty bytes are available in the FIFO when
  queried for receive capacity. However this peripheral supports a
  polled mode where only a single byte can be submitted at a time and
  the FIFO is unused, meaning that in polled mode data is lost since
  it's written into the FIFO and the polling code in FIFO disabled mode
  only returns the value in the RX data register.

  Even worse, potentially enabling the FIFO without a FIFO reset will
  create a weird situation where data is already in the FIFO whenever
  data came in faster than the polling could pick it up (which is
  basically always).

  This change obscured the issue in
  https://bugs.launchpad.net/qemu/+bug/1913341, which instead presented
  as strange data loss until I locally resolved this issue.

  I have a patch ready for the bug and will submit it later today, I'm
  just filing for clarity.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1913344/+subscriptions



[Bug 1913341] [NEW] Chardev behavior breaks polling based devices

2021-01-26 Thread Iris Johnson
Public bug reported:

Currently in latest QEMU (9cd69f1a270235b652766f00b94114f48a2d603f at
this time) the behavior of chardev sources is that when processed
(before IO polling occurs), the chardev source will check the amount of
space for reading.

If it reports more than 0 bytes available to accept the read and a
callback is not set, the code will set a child source connected to the
QIOChannel submitted to the original source. If there's no buffer space
reported, it will check for an active source, if registered it will
detach this source.

Next time the loop fires, if the buffer now reports space (most likely
the guest has run, emptying some bytes from the buffer), it will setup
the callback again.

However, if we have a stupid simple device (or driver) that doesn't have
buffers big enough to fit an available write when one is sent (say a
single byte buffer, polled serial port), then the poll will be set, the
poll will occur and return quickly, then the callback will (depending on
the backend chardev used) most likely read the 1 byte it has space for
from the source, push it over to the frontend hardware side, and the IO
loop will run again.

Most likely the guest will not clear this byte before the next io loop
cycle, meaning that the next prepare call on the source will see a full
buffer in the guest and remove the poll for the data source, to allow
the guest time to run to clear the buffer. Except, without a poll or a
timeout set, the io loop might now block forever, since there's no
report from the guest after clearing that buffer. This only returns in a
sane amount of time because often some other device/timer is scheduled
which sets a timeout on the poll to a reasonable time.

I don't have a simple submittable bit of code to replicate at the moment
but connecting a serial port to a pty then writing a large amount of
data, while a guest that doesn't enable the fifo spins on an rx ready
register, you can observe that RX on the guest takes anywhere from 1s to
forever per byte.

This logic all occurs in chardev/char-io.c

Fixing this can be as simple as removing the logic to detach the child
event source and changing the attach logic to only occur if there's
buffer space and the poll isn't already setup. That fix could cause flow
control issues potentially if the io runs on the same thread as the
emulated guest (I am not sure about the details of this) and the guest
is in a tight loop doing the poll. I don't see that as happening but the
logic might be there for a reason.

Another option is to set a timeout when the source gets removed, forcing
the poll to exit with a fixed delay, this delay could potentially be
derived from something like the baud rate set, forcing a minimum time
before forward progress.

If removing the logic isn't an option, another solution is to make the
emulated hardware code itself kick the IO loop and trigger it to
reschedule the poll. Similar to how the non-blocking write logic works,
the read logic could recognize when the buffer has been emptied and
reschedule the hw on the guest. In theory this sounds nice, but for it
to work would require adding logic to all the emulated chardev frontends
and in reality would likely be going through the effort to remove the
callback only to within a few nanoseconds potentially want to add it
back.

I'm planning to submit a patch with just outright removing the logic,
but am filing this bug as a place to reference since tracking down this
problem is non-obvious.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1913341

Title:
  Chardev behavior breaks polling based devices

Status in QEMU:
  New

Bug description:
  Currently in latest QEMU (9cd69f1a270235b652766f00b94114f48a2d603f at
  this time) the behavior of chardev sources is that when processed
  (before IO polling occurs), the chardev source will check the amount
  of space for reading.

  If it reports more than 0 bytes available to accept the read and a
  callback is not set, the code will set a child source connected to the
  QIOChannel submitted to the original source. If there's no buffer
  space reported, it will check for an active source, if registered it
  will detach this source.

  Next time the loop fires, if the buffer now reports space (most likely
  the guest has run, emptying some bytes from the buffer), it will setup
  the callback again.

  However, if we have a stupid simple device (or driver) that doesn't
  have buffers big enough to fit an available write when one is sent
  (say a single byte buffer, polled serial port), then the poll will be
  set, the poll will occur and return quickly, then the callback will
  (depending on the backend chardev used) most likely read the 1 byte it
  has space for from the source, push it over to the frontend hardware
  side, and the IO loop will run again.

  Most 

Re: [PATCH v4 4/4] meson: Warn when TCI is selected but TCG backend is available

2021-01-26 Thread Stefan Weil

Am 26.01.21 um 21:07 schrieb Paolo Bonzini:


On 26/01/21 20:44, Stefan Weil wrote:


Yes, I tested with latest git master and did not notice that 
--enable-tcg-interpreter was broken.


Paolo's patch fixed that.I could reproduce the fatal assertions which 
were all caused by the same missing TCG opcode implementation.


My patch _broke_ that.  Richard fixed it.

Paolo



Sorry for the confusion in my e-mail. Yes, you are right.

Stefan




Re: [PATCH v4 4/4] meson: Warn when TCI is selected but TCG backend is available

2021-01-26 Thread Paolo Bonzini

On 26/01/21 20:44, Stefan Weil wrote:


Yes, I tested with latest git master and did not notice that 
--enable-tcg-interpreter was broken.


Paolo's patch fixed that.I could reproduce the fatal assertions which 
were all caused by the same missing TCG opcode implementation.


My patch _broke_ that.  Richard fixed it.

Paolo




Re: [PATCH] coroutine-sigaltstack: Add SIGUSR2 mutex

2021-01-26 Thread Laszlo Ersek
On 01/26/21 14:16, Max Reitz wrote:
> On 26.01.21 13:44, Vladimir Sementsov-Ogievskiy wrote:
>> 25.01.2021 15:03, Max Reitz wrote:
>>> Disposition (action) for any given signal is global for the process.
>>> When two threads run coroutine-sigaltstack's qemu_coroutine_new()
>>> concurrently, they may interfere with each other: One of them may revert
>>> the SIGUSR2 handler to SIG_DFL, between the other thread (a) setting up
>>> coroutine_trampoline() as the handler and (b) raising SIGUSR2.  That
>>> SIGUSR2 will then terminate the QEMU process abnormally.
>>>
>>> We have to ensure that only one thread at a time can modify the
>>> process-global SIGUSR2 handler.  To do so, wrap the whole section where
>>> that is done in a mutex.
>>>
>>> Alternatively, we could for example have the SIGUSR2 handler always be
>>> coroutine_trampoline(), so there would be no need to invoke sigaction()
>>> in qemu_coroutine_new().  Laszlo has posted a patch to do so here:
>>>
>>>   
>>> https://lists.nongnu.org/archive/html/qemu-devel/2021-01/msg05962.html
>>>
>>> However, given that coroutine-sigaltstack is more of a fallback
>>> implementation for platforms that do not support ucontext, that change
>>> may be a bit too invasive to be comfortable with it.  The mutex proposed
>>> here may negatively impact performance, but the change is much simpler.
>>>
>>> Signed-off-by: Max Reitz 
>>> ---
>>>   util/coroutine-sigaltstack.c | 9 +
>>>   1 file changed, 9 insertions(+)
>>>
>>> diff --git a/util/coroutine-sigaltstack.c b/util/coroutine-sigaltstack.c
>>> index aade82afb8..e99b8a4f9c 100644
>>> --- a/util/coroutine-sigaltstack.c
>>> +++ b/util/coroutine-sigaltstack.c
>>> @@ -157,6 +157,7 @@ Coroutine *qemu_coroutine_new(void)
>>>   sigset_t sigs;
>>>   sigset_t osigs;
>>>   sigjmp_buf old_env;
>>> +    static pthread_mutex_t sigusr2_mutex = PTHREAD_MUTEX_INITIALIZER;
>>>   /* The way to manipulate stack is with the sigaltstack
>>> function. We
>>>    * prepare a stack, with it delivering a signal to ourselves
>>> and then
>>> @@ -186,6 +187,12 @@ Coroutine *qemu_coroutine_new(void)
>>>   sa.sa_handler = coroutine_trampoline;
>>>   sigfillset(_mask);
>>>   sa.sa_flags = SA_ONSTACK;
>>> +
>>> +    /*
>>> + * sigaction() is a process-global operation.  We must not run
>>> + * this code in multiple threads at once.
>>> + */
>>> +    pthread_mutex_lock(_mutex);
>>>   if (sigaction(SIGUSR2, , ) != 0) {
>>>   abort();
>>>   }
>>> @@ -234,6 +241,8 @@ Coroutine *qemu_coroutine_new(void)
>>>    * Restore the old SIGUSR2 signal handler and mask
>>>    */
>>>   sigaction(SIGUSR2, , NULL);
>>> +    pthread_mutex_unlock(_mutex);
>>> +
>>>   pthread_sigmask(SIG_SETMASK, , NULL);
>>>   /*
>>>
>>
>> weak:
>> Reviewed-by: Vladimir Sementsov-Ogievskiy 
>>
>> Side thought: so, sigaltstack coroutine implementation is not
>> thread-safe. Is that the only bug?
> 
> It would be great if I could tell you for sure whether there’s no bug in
> some piece of code. :)
> 
>> Or actually, the whole implementation should be revisited to check,
>> could it be used with iothreads or not?
> 
> Judging from the discussion I had with Laszlo, I’m definitely not the
> right person to do so, because for example I don’t know the ins and outs
> of signal handling.
> 
> I can only tell you it’s the only issue I’ve seen, and that there’s just
> not much more code in coroutine-sigaltstack.c than the code around
> qemu_coroutine_new().
> 
>> Shouldn't we just state that sigaltstack coroutine implementation
>> doesn't support iothreads? And do error out on iothread creation if
>> sigaltstack coroutines is in use?
> 
> I’m not sure whether that would be better than potentially having a bug
> in it.  What you’re proposing is effectively breaking all iothreads
> usage on MacOS.  If I were a MacOS user, I’d rather risk encountering
> bugs than that.
> 
> (And it isn’t like we know it’s unstable with iothreads; I haven’t seen
> it breaking with this patch applied yet, and I don’t think there’s
> reason to believe it would be.  qemu_coroutine_new() together with
> coroutine_trampoline() sets up a coroutine environment, and the rest of
> the code just consists of sigsetjmp() and siglongjmp().  I believe
> Laszlo hat some open questions about signal masking done by those
> functions, but I don’t think that has anything to do with multithreading.)

I've no open questions regarding the signal masking done by sigsetjmp()
and siglongjmp(). I was briefly confused by sigsetjmp() potentially
saving the signal mask into the "env" buffer even if "savemask" were
zero (POSIX allows this behavior), but then I re-learned that
siglongjmp() is *required to ignore* that potentially-saved mask in
"env" if "savemask" was 0 in the first place.

So the end result is as expected, it's just that the distribution of
responsibilities is potentially non-intuitive (i.e., why permit the
"save" function to stash some crap, 

Re: [PATCH v4 1/4] configure: Fix --enable-tcg-interpreter

2021-01-26 Thread Stefan Weil

Am 25.01.21 um 15:45 schrieb Philippe Mathieu-Daudé:


From: Richard Henderson 

The configure option was backward, and we failed to
pass the value on to meson.

Fixes: 23a77b2d18b ("build-system: clean up TCG/TCI configury")
Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <2021012429.35563-1-richard.hender...@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé 
---
  configure | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)



Tested-by: Stefan Weil 

Thanks,

Stefan




Re: [PATCH] IOMMU and ATS not supported by vhost-user filesystem.

2021-01-26 Thread Dr. David Alan Gilbert
* lagar...@linux.ibm.com (lagar...@linux.ibm.com) wrote:
> From: Leonardo Garcia 
> 
> Currently, as IOMMU and ATS are not supported, if a user mistakenly set
> any of them and tries to mount the vhost-user filesystem inside the
> guest, whenever the user tries to access the mount point, the system
> will hang forever.
> 
> Signed-off-by: Leonardo Garcia 
> ---
>  hw/virtio/vhost-user-fs-pci.c | 7 +++
>  hw/virtio/vhost-user-fs.c | 5 +
>  2 files changed, 12 insertions(+)
> 
> diff --git a/hw/virtio/vhost-user-fs-pci.c b/hw/virtio/vhost-user-fs-pci.c
> index 2ed8492b3f..564d1fd108 100644
> --- a/hw/virtio/vhost-user-fs-pci.c
> +++ b/hw/virtio/vhost-user-fs-pci.c
> @@ -11,6 +11,8 @@
>   * top-level directory.
>   */
>  
> +#include "qemu/osdep.h"
> +#include "qapi/error.h"
>  #include "qemu/osdep.h"
>  #include "hw/qdev-properties.h"
>  #include "hw/virtio/vhost-user-fs.h"
> @@ -45,6 +47,11 @@ static void vhost_user_fs_pci_realize(VirtIOPCIProxy 
> *vpci_dev, Error **errp)
>  vpci_dev->nvectors = dev->vdev.conf.num_request_queues + 2;
>  }
>  
> +if (vpci_dev->flags & VIRTIO_PCI_FLAG_ATS) {
> +error_setg(errp, "ATS is currently not supported with 
> vhost-user-fs-pci");
> +return;
> +}
> +
>  qdev_realize(vdev, BUS(_dev->bus), errp);
>  }
>  
> diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
> index ac4fc34b36..914d68b3ee 100644
> --- a/hw/virtio/vhost-user-fs.c
> +++ b/hw/virtio/vhost-user-fs.c
> @@ -203,6 +203,11 @@ static void vuf_device_realize(DeviceState *dev, Error 
> **errp)
>  return;
>  }
>  
> +if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
> +error_setg(errp, "IOMMU is currently not supported with 
> vhost-user-fs");
> +return;
> +}

Yes, I've seen this problem - however, I'm a little confused; isn't the
negotiation of features on virtio supposed to happen automatically?
If so, how come it's managing to set VIRTIO_F_IOMMU_PLATFORM?

Dave

>  if (!vhost_user_init(>vhost_user, >conf.chardev, errp)) {
>  return;
>  }
> -- 
> 2.29.2
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK




Re: [PATCH] gitlab-ci.yml: Exclude some redundant targets in build-without-default-features

2021-01-26 Thread Wainer dos Santos Moschetta



On 1/26/21 2:23 PM, Thomas Huth wrote:

The build-without-default-features job is running quite long and sometimes
already hits the 1h time limit. Exclude some targets which do not provide
additional test coverage here (since we e.g. also already test other targets
of the same type, just with different endianess, or a 64-bit superset) to
avoid that we hit the timeout here so easily.

Signed-off-by: Thomas Huth 
---
  .gitlab-ci.yml | 1 +
  1 file changed, 1 insertion(+)



Reviewed-by: Wainer dos Santos Moschetta 




diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e2f9c99e27..8e0416f11b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -610,6 +610,7 @@ build-without-default-features:
variables:
  IMAGE: debian-amd64
  CONFIGURE_ARGS: --without-default-features --disable-user
+
--target-list-exclude=arm-softmmu,i386-softmmu,mipsel-softmmu,mips64-softmmu,ppc-softmmu
  MAKE_CHECK_ARGS: check-unit
  
  check-patch:





Re: [PATCH v4 4/4] meson: Warn when TCI is selected but TCG backend is available

2021-01-26 Thread Stefan Weil

Am 26.01.21 um 18:24 schrieb Alex Bennée:

I'm going to go out on a limb and guess you have commit:

   23a77b2d18 (build-system: clean up TCG/TCI configury)

which temporarily has the effect of disabling TCI. See

   Subject: Re: [PATCH v4 1/4] configure: Fix --enable-tcg-interpreter
   From: Paolo Bonzini 
   Message-ID: <2b8b6291-b54c-b285-ae38-21f067a84...@redhat.com>
   Date: Mon, 25 Jan 2021 17:36:42 +0100

with that fix fixed I see the same failures as Richard:

   ./qemu-arm ./tests/tcg/arm-linux-user/fcvt > /dev/null
   TODO ../../tcg/tci.c:614: tcg_qemu_tb_exec()
   ../../tcg/tci.c:614: tcg fatal error
   qemu: uncaught target signal 11 (Segmentation fault) - core dumped
   fish: “./qemu-arm ./tests/tcg/arm-linu…” terminated by signal SIGSEGV 
(Address boundary error)

which does raise the question before today when was the last time anyone
attempted to run check-tcg on this?



Yes, I tested with latest git master and did not notice that 
--enable-tcg-interpreter was broken.


Paolo's patch fixed that.I could reproduce the fatal assertions which 
were all caused by the same missing TCG opcode implementation.


I have sent a trivial patch which adds that implementation and fixes all 
segmentation faults.




Daniel, regarding your comment: TCI has 100 % test coverage for the
productive code lines.

By what tests? The fact you don't hit asserts in your day to day testing
doesn't mean there are features missing that are easily tripped up or
that TCI got it right.



I was not talking about the TODO assertions. When I wrote TCI, I only 
enabled and included code which was triggered by my testing - that's why 
I said the productive code lines have 100 % test coverage. TODO 
assertions are not productive code, but debug code which were made to 
detect new test cases. They were successful, too, because they were 
triggered by some tests in `make check-tcg`.




All code lines which were never tested raise an
assertion, so can easily be identified (and fixed as soon as there is a
test case which triggers such an assertion). The known deficits are
speed, missing TCG opcodes, unimplemented TCG opcodes because of missing
test cases and missing support for some host architectures.



As soon as I was aware of the new test cases, adding the missing TCG 
opcode implementation was not difficult.




Passing check-tcg would be a minimum for me.



It should pass now unless you get timeouts for some tests. Please tell 
me if more TODO assertions are triggered by new tests.


Stefan






Re: [PATCH v2 00/12] buildsys: Do not build various objects if not necessary

2021-01-26 Thread Philippe Mathieu-Daudé
On 1/26/21 5:09 PM, Markus Armbruster wrote:
> Philippe Mathieu-Daudé  writes:
> 
>> On 1/26/21 3:57 PM, Alex Bennée wrote:
>>>
>>> Philippe Mathieu-Daudé  writes:
>>>
 In this series we deselect a bunch of features when they
 not required, so less objects are built.

 While this reduce pressure on CI and slow systems, this is
 particularly helpful for developers regularly testing multiple
 build configurations.

 All CI tests pass:
 https://gitlab.com/philmd/qemu/-/pipelines/245654160

 Supersedes: <20210120151916.1167448-1-phi...@redhat.com>
>>>
>>> Series looks good to me but I guess you need some sub-system feedback.
>>
>> Yeah, I will wait for Markus feedback on qapi/ before respining (with
>> target/ fix), ...
> 
> Maybe I'm naive today, but to me this looks like a case of "if it still
> builds, it's fine".
> 
> Anything in particular you want my feedback for?

You are listed as qapi/ maintainer with Michael :)

QAPI
M: Markus Armbruster 
M: Michael Roth 
S: Supported
F: qapi/

If it is fine to you, then I'll respin addressing Paolo's comments.

Thanks :)

Phil.




[PATCH 4/6] hw/arm: Add I2C device tree for Quanta GSJ

2021-01-26 Thread wuhaotsh--- via
Add an I2C device tree for Quanta GSJ. We only included devices with
existing QEMU implementation, including AT24 EEPROM and temperature
sensors.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 2d82f48848..1418629e06 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -19,6 +19,7 @@
 #include "exec/address-spaces.h"
 #include "hw/arm/npcm7xx.h"
 #include "hw/core/cpu.h"
+#include "hw/i2c/smbus_eeprom.h"
 #include "hw/loader.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
@@ -112,6 +113,21 @@ static void npcm750_evb_i2c_init(NPCM7xxState *soc)
 i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
 }
 
+static void quanta_gsj_i2c_init(NPCM7xxState *soc)
+{
+uint8_t *eeprom_buf0 = g_malloc0(32 * 1024);
+uint8_t *eeprom_buf1 = g_malloc0(32 * 1024);
+
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x48);
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x48);
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), "tmp105", 0x48);
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 4), "tmp105", 0x48);
+smbus_eeprom_init_one(npcm7xx_i2c_get_bus(soc, 9), 0x55, eeprom_buf0);
+smbus_eeprom_init_one(npcm7xx_i2c_get_bus(soc, 10), 0x55, eeprom_buf1);
+
+/* TODO: Add addtional i2c devices. */
+}
+
 static void npcm750_evb_init(MachineState *machine)
 {
 NPCM7xxState *soc;
@@ -137,6 +153,7 @@ static void quanta_gsj_init(MachineState *machine)
 npcm7xx_load_bootrom(machine, soc);
 npcm7xx_connect_flash(>fiu[0], 0, "mx25l25635e",
   drive_get(IF_MTD, 0, 0));
+quanta_gsj_i2c_init(soc);
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.30.0.365.g02bc693789-goog




[PATCH 1/6] hw/arm: Remove GPIO from unimplemented NPCM7XX

2021-01-26 Thread wuhaotsh--- via
NPCM7XX GPIO devices have been implemented in hw/gpio/npcm7xx-gpio.c. So
we removed them from the unimplemented devices list.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu
---
 hw/arm/npcm7xx.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index 72040d4079..d1fe9bd1df 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -576,14 +576,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
 create_unimplemented_device("npcm7xx.kcs",  0xf0007000,   4 * KiB);
 create_unimplemented_device("npcm7xx.gfxi", 0xf000e000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[0]",  0xf001,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[1]",  0xf0011000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[2]",  0xf0012000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[3]",  0xf0013000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[4]",  0xf0014000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[5]",  0xf0015000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[6]",  0xf0016000,   4 * KiB);
-create_unimplemented_device("npcm7xx.gpio[7]",  0xf0017000,   4 * KiB);
 create_unimplemented_device("npcm7xx.smbus[0]", 0xf008,   4 * KiB);
 create_unimplemented_device("npcm7xx.smbus[1]", 0xf0081000,   4 * KiB);
 create_unimplemented_device("npcm7xx.smbus[2]", 0xf0082000,   4 * KiB);
-- 
2.30.0.365.g02bc693789-goog




[PATCH 5/6] hw/i2c: Add a QTest for NPCM7XX SMBus Device

2021-01-26 Thread wuhaotsh--- via
This patch adds a QTest for NPCM7XX SMBus's single byte mode. It sends a
byte to a device in the evaluation board, and verify the retrieved value
is equivalent to the sent value.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
---
 tests/qtest/meson.build  |   1 +
 tests/qtest/npcm7xx_smbus-test.c | 352 +++
 2 files changed, 353 insertions(+)
 create mode 100644 tests/qtest/npcm7xx_smbus-test.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 16d04625b8..aa62d59817 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -138,6 +138,7 @@ qtests_npcm7xx = \
'npcm7xx_gpio-test',
'npcm7xx_pwm-test',
'npcm7xx_rng-test',
+   'npcm7xx_smbus-test',
'npcm7xx_timer-test',
'npcm7xx_watchdog_timer-test']
 qtests_arm = \
diff --git a/tests/qtest/npcm7xx_smbus-test.c b/tests/qtest/npcm7xx_smbus-test.c
new file mode 100644
index 00..4594b107df
--- /dev/null
+++ b/tests/qtest/npcm7xx_smbus-test.c
@@ -0,0 +1,352 @@
+/*
+ * QTests for Nuvoton NPCM7xx SMBus Modules.
+ *
+ * Copyright 2020 Google 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.
+ *
+ * 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 General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/bitops.h"
+#include "libqos/i2c.h"
+#include "libqos/libqtest.h"
+#include "hw/misc/tmp105_regs.h"
+
+#define NR_SMBUS_DEVICES16
+#define SMBUS_ADDR(x)   (0xf008 + 0x1000 * (x))
+#define SMBUS_IRQ(x)(64 + (x))
+
+#define EVB_DEVICE_ADDR 0x48
+#define INVALID_DEVICE_ADDR 0x01
+
+const int evb_bus_list[] = {0, 1, 2, 6};
+
+/* Offsets */
+enum CommonRegister {
+OFFSET_SDA = 0x0,
+OFFSET_ST  = 0x2,
+OFFSET_CST = 0x4,
+OFFSET_CTL1= 0x6,
+OFFSET_ADDR1   = 0x8,
+OFFSET_CTL2= 0xa,
+OFFSET_ADDR2   = 0xc,
+OFFSET_CTL3= 0xe,
+OFFSET_CST2= 0x18,
+OFFSET_CST3= 0x19,
+};
+
+enum NPCM7xxSMBusBank0Register {
+OFFSET_ADDR3   = 0x10,
+OFFSET_ADDR7   = 0x11,
+OFFSET_ADDR4   = 0x12,
+OFFSET_ADDR8   = 0x13,
+OFFSET_ADDR5   = 0x14,
+OFFSET_ADDR9   = 0x15,
+OFFSET_ADDR6   = 0x16,
+OFFSET_ADDR10  = 0x17,
+OFFSET_CTL4= 0x1a,
+OFFSET_CTL5= 0x1b,
+OFFSET_SCLLT   = 0x1c,
+OFFSET_FIF_CTL = 0x1d,
+OFFSET_SCLHT   = 0x1e,
+};
+
+enum NPCM7xxSMBusBank1Register {
+OFFSET_FIF_CTS  = 0x10,
+OFFSET_FAIR_PER = 0x11,
+OFFSET_TXF_CTL  = 0x12,
+OFFSET_T_OUT= 0x14,
+OFFSET_TXF_STS  = 0x1a,
+OFFSET_RXF_STS  = 0x1c,
+OFFSET_RXF_CTL  = 0x1e,
+};
+
+/* ST fields */
+#define ST_STP  BIT(7)
+#define ST_SDASTBIT(6)
+#define ST_BER  BIT(5)
+#define ST_NEGACK   BIT(4)
+#define ST_STASTR   BIT(3)
+#define ST_NMATCH   BIT(2)
+#define ST_MODE BIT(1)
+#define ST_XMIT BIT(0)
+
+/* CST fields */
+#define CST_ARPMATCHBIT(7)
+#define CST_MATCHAF BIT(6)
+#define CST_TGSCL   BIT(5)
+#define CST_TSDABIT(4)
+#define CST_GCMATCH BIT(3)
+#define CST_MATCH   BIT(2)
+#define CST_BB  BIT(1)
+#define CST_BUSYBIT(0)
+
+/* CST2 fields */
+#define CST2_INSTTS BIT(7)
+#define CST2_MATCH7FBIT(6)
+#define CST2_MATCH6FBIT(5)
+#define CST2_MATCH5FBIT(4)
+#define CST2_MATCH4FBIT(3)
+#define CST2_MATCH3FBIT(2)
+#define CST2_MATCH2FBIT(1)
+#define CST2_MATCH1FBIT(0)
+
+/* CST3 fields */
+#define CST3_EO_BUSYBIT(7)
+#define CST3_MATCH10F   BIT(2)
+#define CST3_MATCH9FBIT(1)
+#define CST3_MATCH8FBIT(0)
+
+/* CTL1 fields */
+#define CTL1_STASTREBIT(7)
+#define CTL1_NMINTE BIT(6)
+#define CTL1_GCMEN  BIT(5)
+#define CTL1_ACKBIT(4)
+#define CTL1_EOBINTEBIT(3)
+#define CTL1_INTEN  BIT(2)
+#define CTL1_STOP   BIT(1)
+#define CTL1_START  BIT(0)
+
+/* CTL2 fields */
+#define CTL2_SCLFRQ(rv) extract8((rv), 1, 6)
+#define CTL2_ENABLE BIT(0)
+
+/* CTL3 fields */
+#define CTL3_SCL_LVLBIT(7)
+#define CTL3_SDA_LVLBIT(6)
+#define CTL3_BNK_SELBIT(5)
+#define CTL3_400K_MODE  BIT(4)
+#define CTL3_IDL_START  BIT(3)
+#define CTL3_ARPMEN BIT(2)
+#define CTL3_SCLFRQ(rv) extract8((rv), 0, 2)
+
+/* ADDR fields */
+#define ADDR_EN BIT(7)
+#define ADDR_A(rv)  extract8((rv), 0, 6)
+
+
+static void check_running(QTestState *qts, uint64_t base_addr)
+{
+g_assert_true(qtest_readb(qts, 

[PATCH 6/6] hw/i2c: Implement NPCM7XX SMBus Module FIFO Mode

2021-01-26 Thread wuhaotsh--- via
This patch implements the FIFO mode of the SMBus module. In FIFO, the
user transmits or receives at most 16 bytes at a time. The FIFO mode
allows the module to transmit large amount of data faster than single
byte mode.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
---
 hw/i2c/npcm7xx_smbus.c   | 331 +--
 hw/i2c/trace-events  |   1 +
 include/hw/i2c/npcm7xx_smbus.h   |  25 +++
 tests/qtest/npcm7xx_smbus-test.c | 149 +-
 4 files changed, 490 insertions(+), 16 deletions(-)

diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
index e8a8fdbaff..19a9cdb179 100644
--- a/hw/i2c/npcm7xx_smbus.c
+++ b/hw/i2c/npcm7xx_smbus.c
@@ -27,7 +27,7 @@
 #include "trace.h"
 
 #define NPCM7XX_SMBUS_VERSION 1
-#define NPCM7XX_SMBUS_FIFO_EN 0
+#define NPCM7XX_SMBUS_FIFO_EN 1
 
 enum NPCM7xxSMBusCommonRegister {
 NPCM7XX_SMB_SDA = 0x0,
@@ -132,10 +132,41 @@ enum NPCM7xxSMBusBank1Register {
 #define NPCM7XX_ADDR_EN BIT(7)
 #define NPCM7XX_ADDR_A(rv)  extract8((rv), 0, 6)
 
+/* FIFO Mode Register Fields */
+/* FIF_CTL fields */
+#define NPCM7XX_SMBFIF_CTL_FIFO_EN  BIT(4)
+#define NPCM7XX_SMBFIF_CTL_FAIR_RDY_IE  BIT(2)
+#define NPCM7XX_SMBFIF_CTL_FAIR_RDY BIT(1)
+#define NPCM7XX_SMBFIF_CTL_FAIR_BUSYBIT(0)
+/* FIF_CTS fields */
+#define NPCM7XX_SMBFIF_CTS_STR  BIT(7)
+#define NPCM7XX_SMBFIF_CTS_CLR_FIFO BIT(6)
+#define NPCM7XX_SMBFIF_CTS_RFTE_IE  BIT(3)
+#define NPCM7XX_SMBFIF_CTS_RXF_TXE  BIT(1)
+/* TXF_CTL fields */
+#define NPCM7XX_SMBTXF_CTL_THR_TXIE BIT(6)
+#define NPCM7XX_SMBTXF_CTL_TX_THR(rv)   extract8((rv), 0, 5)
+/* T_OUT fields */
+#define NPCM7XX_SMBT_OUT_ST BIT(7)
+#define NPCM7XX_SMBT_OUT_IE BIT(6)
+#define NPCM7XX_SMBT_OUT_CLKDIV(rv) extract8((rv), 0, 6)
+/* TXF_STS fields */
+#define NPCM7XX_SMBTXF_STS_TX_THST  BIT(6)
+#define NPCM7XX_SMBTXF_STS_TX_BYTES(rv) extract8((rv), 0, 5)
+/* RXF_STS fields */
+#define NPCM7XX_SMBRXF_STS_RX_THST  BIT(6)
+#define NPCM7XX_SMBRXF_STS_RX_BYTES(rv) extract8((rv), 0, 5)
+/* RXF_CTL fields */
+#define NPCM7XX_SMBRXF_CTL_THR_RXIE BIT(6)
+#define NPCM7XX_SMBRXF_CTL_LAST BIT(5)
+#define NPCM7XX_SMBRXF_CTL_RX_THR(rv)   extract8((rv), 0, 5)
+
 #define KEEP_OLD_BIT(o, n, b)   (((n) & (~(b))) | ((o) & (b)))
 #define WRITE_ONE_CLEAR(o, n, b)((n) & (b) ? (o) & (~(b)) : (o))
 
 #define NPCM7XX_SMBUS_ENABLED(s)((s)->ctl2 & NPCM7XX_SMBCTL2_ENABLE)
+#define NPCM7XX_SMBUS_FIFO_ENABLED(s) (NPCM7XX_SMBUS_FIFO_EN && \
+(s)->fif_ctl & NPCM7XX_SMBFIF_CTL_FIFO_EN)
 
 /* Reset values */
 #define NPCM7XX_SMB_ST_INIT_VAL 0x00
@@ -150,6 +181,14 @@ enum NPCM7xxSMBusBank1Register {
 #define NPCM7XX_SMB_ADDR_INIT_VAL   0x00
 #define NPCM7XX_SMB_SCLLT_INIT_VAL  0x00
 #define NPCM7XX_SMB_SCLHT_INIT_VAL  0x00
+#define NPCM7XX_SMB_FIF_CTL_INIT_VAL 0x00
+#define NPCM7XX_SMB_FIF_CTS_INIT_VAL 0x00
+#define NPCM7XX_SMB_FAIR_PER_INIT_VAL 0x00
+#define NPCM7XX_SMB_TXF_CTL_INIT_VAL 0x00
+#define NPCM7XX_SMB_T_OUT_INIT_VAL 0x3f
+#define NPCM7XX_SMB_TXF_STS_INIT_VAL 0x00
+#define NPCM7XX_SMB_RXF_STS_INIT_VAL 0x00
+#define NPCM7XX_SMB_RXF_CTL_INIT_VAL 0x01
 
 static uint8_t npcm7xx_smbus_get_version(void)
 {
@@ -169,7 +208,13 @@ static void npcm7xx_smbus_update_irq(NPCM7xxSMBusState *s)
(s->ctl1 & NPCM7XX_SMBCTL1_STASTRE &&
 s->st & NPCM7XX_SMBST_SDAST) ||
(s->ctl1 & NPCM7XX_SMBCTL1_EOBINTE &&
-s->cst3 & NPCM7XX_SMBCST3_EO_BUSY));
+s->cst3 & NPCM7XX_SMBCST3_EO_BUSY) ||
+   (s->rxf_ctl & NPCM7XX_SMBRXF_CTL_THR_RXIE &&
+s->rxf_sts & NPCM7XX_SMBRXF_STS_RX_THST) ||
+   (s->txf_ctl & NPCM7XX_SMBTXF_CTL_THR_TXIE &&
+s->txf_sts & NPCM7XX_SMBTXF_STS_TX_THST) ||
+   (s->fif_cts & NPCM7XX_SMBFIF_CTS_RFTE_IE &&
+s->fif_cts & NPCM7XX_SMBFIF_CTS_RXF_TXE));
 
 if (level) {
 s->cst2 |= NPCM7XX_SMBCST2_INTSTS;
@@ -187,6 +232,13 @@ static void npcm7xx_smbus_nack(NPCM7xxSMBusState *s)
 s->status = NPCM7XX_SMBUS_STATUS_NEGACK;
 }
 
+static void npcm7xx_smbus_clear_buffer(NPCM7xxSMBusState *s)
+{
+s->fif_cts &= ~NPCM7XX_SMBFIF_CTS_RXF_TXE;
+s->txf_sts = 0;
+s->rxf_sts = 0;
+}
+
 static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, uint8_t value)
 {
 int rv = i2c_send(s->bus, value);
@@ -195,6 +247,15 @@ static void npcm7xx_smbus_send_byte(NPCM7xxSMBusState *s, 
uint8_t value)
 npcm7xx_smbus_nack(s);
 } else {
 s->st |= NPCM7XX_SMBST_SDAST;
+if (NPCM7XX_SMBUS_FIFO_ENABLED(s)) {
+s->fif_cts |= NPCM7XX_SMBFIF_CTS_RXF_TXE;
+if (NPCM7XX_SMBTXF_STS_TX_BYTES(s->txf_sts) ==
+NPCM7XX_SMBTXF_CTL_TX_THR(s->txf_ctl)) {
+

[PATCH 3/6] hw/arm: Add I2C device tree for NPCM750 eval board

2021-01-26 Thread wuhaotsh--- via
Add an I2C device tree for NPCM750 evaluation board.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
---
 hw/arm/npcm7xx_boards.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
index 3fdd5cab01..2d82f48848 100644
--- a/hw/arm/npcm7xx_boards.c
+++ b/hw/arm/npcm7xx_boards.c
@@ -98,6 +98,20 @@ static NPCM7xxState *npcm7xx_create_soc(MachineState 
*machine,
 return NPCM7XX(obj);
 }
 
+static I2CBus *npcm7xx_i2c_get_bus(NPCM7xxState *soc, uint32_t num)
+{
+g_assert(num < ARRAY_SIZE(soc->smbus));
+return I2C_BUS(qdev_get_child_bus(DEVICE(>smbus[num]), "i2c-bus"));
+}
+
+static void npcm750_evb_i2c_init(NPCM7xxState *soc)
+{
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 0), "tmp105", 0x48);
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 1), "tmp105", 0x48);
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 2), "tmp105", 0x48);
+i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
+}
+
 static void npcm750_evb_init(MachineState *machine)
 {
 NPCM7xxState *soc;
@@ -108,6 +122,7 @@ static void npcm750_evb_init(MachineState *machine)
 
 npcm7xx_load_bootrom(machine, soc);
 npcm7xx_connect_flash(>fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
+npcm750_evb_i2c_init(soc);
 npcm7xx_load_kernel(machine, soc);
 }
 
-- 
2.30.0.365.g02bc693789-goog




[PATCH 0/6] hw/i2c: Add NPCM7XX SMBus Device

2021-01-26 Thread wuhaotsh--- via
This patch set implements the System manager bus (SMBus) module in NPCM7XX
SoC. Basically, it emulates the data transactions of the module, not the
SDA/SCL levels. We have also added a QTest which contains read and write
operations for both single-byte and FIFO mode, and added basic I2C device
trees for npcm750-evb and quanta-gsj boards.

We also cleaned up the unimplemented GPIO devices in npcm7xx.c since they
are already implemented.

Hao Wu (6):
  hw/arm: Remove GPIO from unimplemented NPCM7XX
  hw/i2c: Implement NPCM7XX SMBus Module Single Mode
  hw/arm: Add I2C device tree for NPCM750 eval board
  hw/arm: Add I2C device tree for Quanta GSJ
  hw/i2c: Add a QTest for NPCM7XX SMBus Device
  hw/i2c: Implement NPCM7XX SMBus Module FIFO Mode

 docs/system/arm/nuvoton.rst  |2 +-
 hw/arm/npcm7xx.c |   76 ++-
 hw/arm/npcm7xx_boards.c  |   32 +
 hw/i2c/meson.build   |1 +
 hw/i2c/npcm7xx_smbus.c   | 1071 ++
 hw/i2c/trace-events  |   12 +
 include/hw/arm/npcm7xx.h |2 +
 include/hw/i2c/npcm7xx_smbus.h   |  113 
 tests/qtest/meson.build  |1 +
 tests/qtest/npcm7xx_smbus-test.c |  495 ++
 10 files changed, 1780 insertions(+), 25 deletions(-)
 create mode 100644 hw/i2c/npcm7xx_smbus.c
 create mode 100644 include/hw/i2c/npcm7xx_smbus.h
 create mode 100644 tests/qtest/npcm7xx_smbus-test.c

-- 
2.30.0.365.g02bc693789-goog




[PATCH 2/6] hw/i2c: Implement NPCM7XX SMBus Module Single Mode

2021-01-26 Thread wuhaotsh--- via
This commit implements the single-byte mode of the SMBus.

Each Nuvoton SoC has 16 System Management Bus (SMBus). These buses
compliant with SMBus and I2C protocol.

This patch implements the single-byte mode of the SMBus. In this mode,
the user sends or receives a byte each time. The SMBus device transmits
it to the underlying i2c device and sends an interrupt back to the QEMU
guest.

Reviewed-by: Doug Evans
Reviewed-by: Tyrong Ting
Signed-off-by: Hao Wu 
---
 docs/system/arm/nuvoton.rst|   2 +-
 hw/arm/npcm7xx.c   |  68 ++-
 hw/i2c/meson.build |   1 +
 hw/i2c/npcm7xx_smbus.c | 766 +
 hw/i2c/trace-events|  11 +
 include/hw/arm/npcm7xx.h   |   2 +
 include/hw/i2c/npcm7xx_smbus.h |  88 
 7 files changed, 921 insertions(+), 17 deletions(-)
 create mode 100644 hw/i2c/npcm7xx_smbus.c
 create mode 100644 include/hw/i2c/npcm7xx_smbus.h

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index a1786342e2..34fc799b2d 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -43,6 +43,7 @@ Supported devices
  * GPIO controller
  * Analog to Digital Converter (ADC)
  * Pulse Width Modulation (PWM)
+ * SMBus controller (SMBF)
 
 Missing devices
 ---
@@ -58,7 +59,6 @@ Missing devices
 
  * Ethernet controllers (GMAC and EMC)
  * USB device (USBD)
- * SMBus controller (SMBF)
  * Peripheral SPI controller (PSPI)
  * SD/MMC host
  * PECI interface
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index d1fe9bd1df..8f596ffd69 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -104,6 +104,22 @@ enum NPCM7xxInterrupt {
 NPCM7XX_OHCI_IRQ= 62,
 NPCM7XX_PWM0_IRQ= 93,   /* PWM module 0 */
 NPCM7XX_PWM1_IRQ,   /* PWM module 1 */
+NPCM7XX_SMBUS0_IRQ  = 64,
+NPCM7XX_SMBUS1_IRQ,
+NPCM7XX_SMBUS2_IRQ,
+NPCM7XX_SMBUS3_IRQ,
+NPCM7XX_SMBUS4_IRQ,
+NPCM7XX_SMBUS5_IRQ,
+NPCM7XX_SMBUS6_IRQ,
+NPCM7XX_SMBUS7_IRQ,
+NPCM7XX_SMBUS8_IRQ,
+NPCM7XX_SMBUS9_IRQ,
+NPCM7XX_SMBUS10_IRQ,
+NPCM7XX_SMBUS11_IRQ,
+NPCM7XX_SMBUS12_IRQ,
+NPCM7XX_SMBUS13_IRQ,
+NPCM7XX_SMBUS14_IRQ,
+NPCM7XX_SMBUS15_IRQ,
 NPCM7XX_GPIO0_IRQ   = 116,
 NPCM7XX_GPIO1_IRQ,
 NPCM7XX_GPIO2_IRQ,
@@ -152,6 +168,26 @@ static const hwaddr npcm7xx_pwm_addr[] = {
 0xf0104000,
 };
 
+/* Direct memory-mapped access to each SMBus Module. */
+static const hwaddr npcm7xx_smbus_addr[] = {
+0xf008,
+0xf0081000,
+0xf0082000,
+0xf0083000,
+0xf0084000,
+0xf0085000,
+0xf0086000,
+0xf0087000,
+0xf0088000,
+0xf0089000,
+0xf008a000,
+0xf008b000,
+0xf008c000,
+0xf008d000,
+0xf008e000,
+0xf008f000,
+};
+
 static const struct {
 hwaddr regs_addr;
 uint32_t unconnected_pins;
@@ -353,6 +389,11 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "gpio[*]", >gpio[i], 
TYPE_NPCM7XX_GPIO);
 }
 
+for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
+object_initialize_child(obj, "smbus[*]", >smbus[i],
+TYPE_NPCM7XX_SMBUS);
+}
+
 object_initialize_child(obj, "ehci", >ehci, TYPE_NPCM7XX_EHCI);
 object_initialize_child(obj, "ohci", >ohci, TYPE_SYSBUS_OHCI);
 
@@ -509,6 +550,17 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
npcm7xx_irq(s, NPCM7XX_GPIO0_IRQ + i));
 }
 
+/* SMBus modules. Cannot fail. */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_smbus_addr) != ARRAY_SIZE(s->smbus));
+for (i = 0; i < ARRAY_SIZE(s->smbus); i++) {
+Object *obj = OBJECT(>smbus[i]);
+
+sysbus_realize(SYS_BUS_DEVICE(obj), _abort);
+sysbus_mmio_map(SYS_BUS_DEVICE(obj), 0, npcm7xx_smbus_addr[i]);
+sysbus_connect_irq(SYS_BUS_DEVICE(obj), 0,
+   npcm7xx_irq(s, NPCM7XX_SMBUS0_IRQ + i));
+}
+
 /* USB Host */
 object_property_set_bool(OBJECT(>ehci), "companion-enable", true,
  _abort);
@@ -576,22 +628,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
 create_unimplemented_device("npcm7xx.kcs",  0xf0007000,   4 * KiB);
 create_unimplemented_device("npcm7xx.gfxi", 0xf000e000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[0]", 0xf008,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[1]", 0xf0081000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[2]", 0xf0082000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[3]", 0xf0083000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[4]", 0xf0084000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[5]", 0xf0085000,   4 * KiB);
-create_unimplemented_device("npcm7xx.smbus[6]", 0xf0086000,   4 * KiB);
-

[PATCH] tcg/tci: Implement INDEX_op_ld16u_i32

2021-01-26 Thread Stefan Weil
This fixes `make check-tcg`.

Signed-off-by: Stefan Weil 
---
 tcg/tci.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tcg/tci.c b/tcg/tci.c
index 2311aa7d3a..42354d8ebb 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -611,7 +611,10 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState 
*env,
 TODO();
 break;
 case INDEX_op_ld16u_i32:
-TODO();
+t0 = *tb_ptr++;
+t1 = tci_read_r(regs, _ptr);
+t2 = tci_read_s32(_ptr);
+tci_write_reg16(regs, t0, *(uint16_t *)(t1 + t2));
 break;
 case INDEX_op_ld16s_i32:
 TODO();
-- 
2.29.2




Re: [PATCH] gitlab-ci.yml: Exclude some redundant targets in build-without-default-features

2021-01-26 Thread Philippe Mathieu-Daudé
On 1/26/21 6:23 PM, Thomas Huth wrote:
> The build-without-default-features job is running quite long and sometimes
> already hits the 1h time limit. Exclude some targets which do not provide
> additional test coverage here (since we e.g. also already test other targets
> of the same type, just with different endianess, or a 64-bit superset) to
> avoid that we hit the timeout here so easily.
> 
> Signed-off-by: Thomas Huth 
> ---
>  .gitlab-ci.yml | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Philippe Mathieu-Daudé 




[Bug 1907042] Re: assert issue locates in hw/usb/core.c:727: usb_ep_get: Assertion `pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT' failed

2021-01-26 Thread Alexander Bulekov
This looks like a dupe of https://bugs.launchpad.net/qemu/+bug/1525123/
, though through OHCI rather than XHCI

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1907042

Title:
  assert issue locates in hw/usb/core.c:727: usb_ep_get: Assertion `pid
  == USB_TOKEN_IN || pid == USB_TOKEN_OUT' failed

Status in QEMU:
  New

Bug description:
  Hello,

  An assertion failure was found in hw/usb/core.c:727 in latest version
  5.2.0.

  Reproduced environment is as follows:
  Host: ubuntu 18.04
  Guest: ubuntu 18.04

  QEMU boot command line:
  qemu-system-x86_64 -enable-kvm -boot c -m 4G -drive 
format=qcow2,file=./ubuntu.img -nic user,hostfwd=tcp:0.0.0.0:-:22 -device 
pci-ohci,id=ohci -device usb-tablet,bus=ohci.0,port=1,id=usbdev1 -trace usb\*

  Backtrace is as follows:
  #0  0x7f13fff14438 in __GI_raise (sig=sig@entry=6) at 
../sysdeps/unix/sysv/linux/raise.c:54
  #1  0x7f13fff1603a in __GI_abort () at abort.c:89
  #2  0x7f13fff0cbe7 in __assert_fail_base (fmt=, 
assertion=assertion@entry=0x55f97745ffe0 "pid == USB_TOKEN_IN || pid == 
USB_TOKEN_OUT", file=file@entry=0x55f97745f6c0 "../hw/usb/core.c", 
line=line@entry=727, function=function@entry=0x55f9774606e0 
<__PRETTY_FUNCTION__.22877> "usb_ep_get") at assert.c:92
  #3  0x7f13fff0cc92 in __GI___assert_fail (assertion=0x55f97745ffe0 "pid 
== USB_TOKEN_IN || pid == USB_TOKEN_OUT", file=0x55f97745f6c0 
"../hw/usb/core.c", line=727, function=0x55f9774606e0 
<__PRETTY_FUNCTION__.22877> "usb_ep_get") at assert.c:101
  #4  0x55f975bfc9b2 in usb_ep_get (dev=0x6230c500, pid=45, ep=1) at 
../hw/usb/core.c:727
  #5  0x55f975f945db in ohci_service_td (ohci=0x627191f0, 
ed=0x7ffcd9308410) at ../hw/usb/hcd-ohci.c:1044
  #6  0x55f975f95d5e in ohci_service_ed_list (ohci=0x627191f0, 
head=857580576, completion=0) at ../hw/usb/hcd-ohci.c:1200
  #7  0x55f975f9656d in ohci_process_lists (ohci=0x627191f0, 
completion=0) at ../hw/usb/hcd-ohci.c:1238
  #8  0x55f975f9725c in ohci_frame_boundary (opaque=0x627191f0) at 
../hw/usb/hcd-ohci.c:1281
  #9  0x55f977212494 in timerlist_run_timers (timer_list=0x60b5b060) at 
../util/qemu-timer.c:574
  #10 0x55f9772126db in qemu_clock_run_timers (type=QEMU_CLOCK_VIRTUAL) at 
../util/qemu-timer.c:588
  #11 0x55f977212fde in qemu_clock_run_all_timers () at 
../util/qemu-timer.c:670
  #12 0x55f9772d5717 in main_loop_wait (nonblocking=0) at 
../util/main-loop.c:531
  #13 0x55f97695100c in qemu_main_loop () at ../softmmu/vl.c:1677
  #14 0x55f9758f7601 in main (argc=16, argv=0x7ffcd930, 
envp=0x7ffcd9308910) at ../softmmu/main.c:50
  #15 0x7f13ffeff840 in __libc_start_main (main=0x55f9758f75b0 , 
argc=16, argv=0x7ffcd930, init=, fini=, 
rtld_fini=, stack_end=0x7ffcd9308878) at ../csu/libc-start.c:291
  #16 0x55f9758f74a9 in _start ()

  
  The poc is attached.

  Thanks.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1907042/+subscriptions



[PATCH] IOMMU and ATS not supported by vhost-user filesystem.

2021-01-26 Thread lagarcia
From: Leonardo Garcia 

Currently, as IOMMU and ATS are not supported, if a user mistakenly set
any of them and tries to mount the vhost-user filesystem inside the
guest, whenever the user tries to access the mount point, the system
will hang forever.

Signed-off-by: Leonardo Garcia 
---
 hw/virtio/vhost-user-fs-pci.c | 7 +++
 hw/virtio/vhost-user-fs.c | 5 +
 2 files changed, 12 insertions(+)

diff --git a/hw/virtio/vhost-user-fs-pci.c b/hw/virtio/vhost-user-fs-pci.c
index 2ed8492b3f..564d1fd108 100644
--- a/hw/virtio/vhost-user-fs-pci.c
+++ b/hw/virtio/vhost-user-fs-pci.c
@@ -11,6 +11,8 @@
  * top-level directory.
  */
 
+#include "qemu/osdep.h"
+#include "qapi/error.h"
 #include "qemu/osdep.h"
 #include "hw/qdev-properties.h"
 #include "hw/virtio/vhost-user-fs.h"
@@ -45,6 +47,11 @@ static void vhost_user_fs_pci_realize(VirtIOPCIProxy 
*vpci_dev, Error **errp)
 vpci_dev->nvectors = dev->vdev.conf.num_request_queues + 2;
 }
 
+if (vpci_dev->flags & VIRTIO_PCI_FLAG_ATS) {
+error_setg(errp, "ATS is currently not supported with 
vhost-user-fs-pci");
+return;
+}
+
 qdev_realize(vdev, BUS(_dev->bus), errp);
 }
 
diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c
index ac4fc34b36..914d68b3ee 100644
--- a/hw/virtio/vhost-user-fs.c
+++ b/hw/virtio/vhost-user-fs.c
@@ -203,6 +203,11 @@ static void vuf_device_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) {
+error_setg(errp, "IOMMU is currently not supported with 
vhost-user-fs");
+return;
+}
+
 if (!vhost_user_init(>vhost_user, >conf.chardev, errp)) {
 return;
 }
-- 
2.29.2




Re: [PATCH 1/6] virtiofsd: Drop ->vu_dispatch_rwlock while waiting for thread to exit

2021-01-26 Thread Vivek Goyal
On Tue, Jan 26, 2021 at 04:56:00PM +0100, Greg Kurz wrote:
> On Mon, 25 Jan 2021 13:01:10 -0500
> Vivek Goyal  wrote:
> 
> > When we are shutting down virtqueues, virtio_loop() receives a message
> > VHOST_USER_GET_VRING_BASE from master. We acquire ->vu_dispatch_rwlock
> > and get into the process of shutting down virtqueue. In one of the
> > final steps, we are waiting for fv_queue_thread() to exit/finish and
> > wait with ->vu_dispatch_rwlock held.
> > 
> > But it is possible that fv_queue_thread() itself is waiting to get
> > ->vu_dispatch_rwlock (With --thread-pool=0 option). If requests
> > are being processed by fv_queue_worker(), then fv_queue_worker()
> > can wait for the ->vu_dispatch_rwlock, and fv_queue_thread() will
> > wait for fv_queue_worker() before thread pool can be stopped.
> > 
> > IOW, if guest is shutdown uncleanly (some sort of emergency reboot),
> > it is possible that virtiofsd is processing a fs request and
> > qemu initiates device shutdown sequence. In that case there seem
> > to be two options. Either abort the existing request completely or
> > let existing request finish.
> > 
> > This patch is taking second approach. That is drop the ->vu_dispatch_rwlock
> > temporarily so that fv_queue_thread() can finish and deadlock does not
> > happen.
> > 
> > ->vu_dispatch_rwlock provides mutual exclusion between virtio_loop()
> > (handling vhost-user protocol messages) and fv_queue_thread() (handling
> > fuse filesystem requests). Rational seems to be that protocol message
> > might change queue memory mappings, so we don't want both to proceed
> > at the same time.
> > 
> > In this case queue is shutting down, so I hope it is fine for 
> > fv_queue_thread() to send response back while virtio_loop() is still 
> > waiting (and not handling
> 
> It looks this lacks a \n after "fine for"

Hi Greg,

Will fix.

> 
> > any further vho-user protocol messages).
> > 
> > IOW, assumption here is that while virto_loop is blocked processing
> > VHOST_USER_GET_VRING_BASE message, it is still ok to send back the
> > response on vq by fv_queue_thread().
> > 
> > Signed-off-by: Vivek Goyal 
> > ---
> >  tools/virtiofsd/fuse_virtio.c | 14 ++
> >  1 file changed, 14 insertions(+)
> > 
> > diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c
> > index 9577eaa68d..6805d8ba01 100644
> > --- a/tools/virtiofsd/fuse_virtio.c
> > +++ b/tools/virtiofsd/fuse_virtio.c
> > @@ -813,11 +813,20 @@ static void fv_queue_cleanup_thread(struct fv_VuDev 
> > *vud, int qidx)
> >  fuse_log(FUSE_LOG_ERR, "Eventfd_write for queue %d: %s\n",
> >   qidx, strerror(errno));
> >  }
> > +
> > +/*
> > + * Drop ->vu_dispath_rwlock and reacquire. We are about to wait for
> > + * for fv_queue_thread() and that might require ->vu_dispatch_rwlock
> > + * to finish.
> > + */
> > +pthread_rwlock_unlock(>vu_dispatch_rwlock);
> >  ret = pthread_join(ourqi->thread, NULL);
> >  if (ret) {
> >  fuse_log(FUSE_LOG_ERR, "%s: Failed to join thread idx %d err %d\n",
> >   __func__, qidx, ret);
> >  }
> > +pthread_rwlock_wrlock(>vu_dispatch_rwlock);
> > +
> 
> So this is assuming that fv_queue_cleanup_thread() is called with
> vu_dispatch_rwlock already taken for writing, but there are no
> clear evidence in the code why it should care for the locking at
> all in the first place.
> 
> On the contrary, one of its two callers is a vhost-user callback,
> in which we can reasonably have this assumption, while we can
> have the opposite assumption for the other one in virtio_loop().
> 
> This makes me think that the drop/reacquire trick should only
> be done in fv_queue_set_started(), instead of...

I think this sounds reasonable. I will drop lock/re-acquire in
fv_queue_set_started() around the call to fv_queue_cleanup_thread().

> 
> >  pthread_mutex_destroy(>vq_lock);
> >  close(ourqi->kill_fd);
> >  ourqi->kick_fd = -1;
> > @@ -952,7 +961,11 @@ int virtio_loop(struct fuse_session *se)
> >  /*
> >   * Make sure all fv_queue_thread()s quit on exit, as we're about to
> >   * free virtio dev and fuse session, no one should access them anymore.
> > + * Hold ->vu_dispatch_rwlock in write mode as fv_queue_cleanup_thread()
> > + * assumes mutex is locked and unlocks/re-locks it.
> >   */
> > +
> > +pthread_rwlock_wrlock(>virtio_dev->vu_dispatch_rwlock);
> 
> 
> ... artificially introducing another critical section here.
> 
> The issue isn't even specific to vu_dispatch_rwlock actually :
> fv_queue_cleanup_thread() shouldn't be called with any lock
> held because it might sleep in pthread_join() and cause a
> deadlock all the same. So I'd rather document that instead :
> drop all locks before calling fv_queue_cleanup_thread().

Sounds good. Will do.

> 
> Also, since pthread_rwlock_wrlock() can fail, I think we should
> always check it's return value, at least with an assert() like
> already 

Re: [PATCH v3] configure: Only build s390-ccw BIOS when system emulation is built

2021-01-26 Thread Thomas Huth

On 25/01/2021 17.58, Philippe Mathieu-Daudé wrote:

It is pointless to build the s390-ccw BIOS when only user-mode
emulation is built. Only build it when s390 system mode emulation
is selected.

Signed-off-by: Philippe Mathieu-Daudé 
---
v3: Restrict to s390x host (thuth)
v2: Restrict to s390x-softmmu target (thuth)
---
  configure | 8 +++-
  1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index dcc5ea7d630..4751d3e352d 100755
--- a/configure
+++ b/configure
@@ -5372,8 +5372,14 @@ if { test "$cpu" = "i386" || test "$cpu" = "x86_64"; } 
&& \
  done
  fi
  
+s390_ccw_bios=no

+# Only build s390-ccw bios if we're targetting s390x system emulation
+case $target_list in
+  *"s390x-softmmu"*) s390_ccw_bios=yes
+  ;;
+esac
  # Only build s390-ccw bios if we're on s390x and the compiler has -march=z900
-if test "$cpu" = "s390x" ; then
+if test "$cpu" = "s390x" && test "$s390_ccw_bios" = yes; then


Looks good to me now ... but maybe it could even be done simpler (without 
the case statement) by simply doing:


 if test "$cpu" = "s390x" && echo "$target_list" | grep -q s390x-softmmu ; then
 ...

?

 Thomas




Re: [PATCH v2 1/2] tests/qtest: Only run fuzz-megasas-test if megasas device is available

2021-01-26 Thread Thomas Huth

On 26/01/2021 19.01, Alexander Bulekov wrote:

On 210126 1851, Thomas Huth wrote:

On 26/01/2021 12.16, Philippe Mathieu-Daudé wrote:

This test fails when QEMU is built without the megasas device,
restrict it to its availability.

Signed-off-by: Philippe Mathieu-Daudé 
---
   tests/qtest/fuzz-megasas-test.c | 49 +
   tests/qtest/fuzz-test.c | 25 -
   MAINTAINERS |  1 +
   tests/qtest/meson.build |  4 ++-
   4 files changed, 53 insertions(+), 26 deletions(-)
   create mode 100644 tests/qtest/fuzz-megasas-test.c

diff --git a/tests/qtest/fuzz-megasas-test.c b/tests/qtest/fuzz-megasas-test.c
new file mode 100644
index 000..940a76bf25a
--- /dev/null
+++ b/tests/qtest/fuzz-megasas-test.c
@@ -0,0 +1,49 @@
+/*
+ * QTest fuzzer-generated testcase for megasas device
+ *
+ * Copyright (c) 2020 Li Qiang 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqos/libqtest.h"
+
+/*
+ * This used to trigger the assert in scsi_dma_complete
+ * https://bugs.launchpad.net/qemu/+bug/1878263
+ */
+static void test_lp1878263_megasas_zero_iov_cnt(void)
+{
+QTestState *s;
+
+s = qtest_init("-nographic -monitor none -serial none "
+   "-M q35 -device megasas -device scsi-cd,drive=null0 "
+   "-blockdev driver=null-co,read-zeroes=on,node-name=null0");
+qtest_outl(s, 0xcf8, 0x80001818);
+qtest_outl(s, 0xcfc, 0xc101);
+qtest_outl(s, 0xcf8, 0x8000181c);
+qtest_outl(s, 0xcf8, 0x80001804);
+qtest_outw(s, 0xcfc, 0x7);
+qtest_outl(s, 0xcf8, 0x8000186a);
+qtest_writeb(s, 0x14, 0xfe);
+qtest_writeb(s, 0x0, 0x02);
+qtest_outb(s, 0xc1c0, 0x17);
+qtest_quit(s);
+}
+
+int main(int argc, char **argv)
+{
+const char *arch = qtest_get_arch();
+
+g_test_init(, , NULL);
+
+if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt",
+   test_lp1878263_megasas_zero_iov_cnt);
+}
+
+return g_test_run();
+}
diff --git a/tests/qtest/fuzz-test.c b/tests/qtest/fuzz-test.c
index cdb1100a0b8..6188fbb8e96 100644
--- a/tests/qtest/fuzz-test.c
+++ b/tests/qtest/fuzz-test.c
@@ -11,29 +11,6 @@
   #include "libqos/libqtest.h"
-/*
- * This used to trigger the assert in scsi_dma_complete
- * https://bugs.launchpad.net/qemu/+bug/1878263
- */
-static void test_lp1878263_megasas_zero_iov_cnt(void)
-{
-QTestState *s;
-
-s = qtest_init("-nographic -monitor none -serial none "
-   "-M q35 -device megasas -device scsi-cd,drive=null0 "
-   "-blockdev driver=null-co,read-zeroes=on,node-name=null0");
-qtest_outl(s, 0xcf8, 0x80001818);
-qtest_outl(s, 0xcfc, 0xc101);
-qtest_outl(s, 0xcf8, 0x8000181c);
-qtest_outl(s, 0xcf8, 0x80001804);
-qtest_outw(s, 0xcfc, 0x7);
-qtest_outl(s, 0xcf8, 0x8000186a);
-qtest_writeb(s, 0x14, 0xfe);
-qtest_writeb(s, 0x0, 0x02);
-qtest_outb(s, 0xc1c0, 0x17);
-qtest_quit(s);
-}
-
   static void test_lp1878642_pci_bus_get_irq_level_assert(void)
   {
   QTestState *s;
@@ -104,8 +81,6 @@ int main(int argc, char **argv)
   g_test_init(, , NULL);
   if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
-qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt",
-   test_lp1878263_megasas_zero_iov_cnt);
   qtest_add_func("fuzz/test_lp1878642_pci_bus_get_irq_level_assert",
  test_lp1878642_pci_bus_get_irq_level_assert);
   qtest_add_func("fuzz/test_mmio_oob_from_memory_region_cache",
diff --git a/MAINTAINERS b/MAINTAINERS
index 34359a99b8e..44cd74b03cd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1925,6 +1925,7 @@ S: Supported
   F: hw/scsi/megasas.c
   F: hw/scsi/mfi.h
   F: tests/qtest/megasas-test.c
+F: tests/qtest/fuzz-megasas-test.c
   Network packet abstractions
   M: Dmitry Fleytman 
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 16d04625b8b..85682d0dfce 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -4,7 +4,9 @@
 subdir_done()
   endif
-qtests_generic = [
+qtests_generic = \
+  (config_all_devices.has_key('CONFIG_MEGASAS_SCSI_PCI') ? 
['fuzz-megasas-test'] : []) + \
+  [
 'cdrom-test',
 'device-introspect-test',
 'machine-none-test',



Reviewed-by: Thomas Huth 

I assume Alexander will take this patch through his fuzzer branch now? Or
shall I take it via the qtest branch?


I can take take this through my branch, unless thats somehow inconvenient.


That's perfectly fine!

 Thanks,
  Thomas




Re: [PATCH v2 1/2] tests/qtest: Only run fuzz-megasas-test if megasas device is available

2021-01-26 Thread Alexander Bulekov
On 210126 1851, Thomas Huth wrote:
> On 26/01/2021 12.16, Philippe Mathieu-Daudé wrote:
> > This test fails when QEMU is built without the megasas device,
> > restrict it to its availability.
> > 
> > Signed-off-by: Philippe Mathieu-Daudé 
> > ---
> >   tests/qtest/fuzz-megasas-test.c | 49 +
> >   tests/qtest/fuzz-test.c | 25 -
> >   MAINTAINERS |  1 +
> >   tests/qtest/meson.build |  4 ++-
> >   4 files changed, 53 insertions(+), 26 deletions(-)
> >   create mode 100644 tests/qtest/fuzz-megasas-test.c
> > 
> > diff --git a/tests/qtest/fuzz-megasas-test.c 
> > b/tests/qtest/fuzz-megasas-test.c
> > new file mode 100644
> > index 000..940a76bf25a
> > --- /dev/null
> > +++ b/tests/qtest/fuzz-megasas-test.c
> > @@ -0,0 +1,49 @@
> > +/*
> > + * QTest fuzzer-generated testcase for megasas device
> > + *
> > + * Copyright (c) 2020 Li Qiang 
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or 
> > later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +
> > +#include "libqos/libqtest.h"
> > +
> > +/*
> > + * This used to trigger the assert in scsi_dma_complete
> > + * https://bugs.launchpad.net/qemu/+bug/1878263
> > + */
> > +static void test_lp1878263_megasas_zero_iov_cnt(void)
> > +{
> > +QTestState *s;
> > +
> > +s = qtest_init("-nographic -monitor none -serial none "
> > +   "-M q35 -device megasas -device scsi-cd,drive=null0 "
> > +   "-blockdev 
> > driver=null-co,read-zeroes=on,node-name=null0");
> > +qtest_outl(s, 0xcf8, 0x80001818);
> > +qtest_outl(s, 0xcfc, 0xc101);
> > +qtest_outl(s, 0xcf8, 0x8000181c);
> > +qtest_outl(s, 0xcf8, 0x80001804);
> > +qtest_outw(s, 0xcfc, 0x7);
> > +qtest_outl(s, 0xcf8, 0x8000186a);
> > +qtest_writeb(s, 0x14, 0xfe);
> > +qtest_writeb(s, 0x0, 0x02);
> > +qtest_outb(s, 0xc1c0, 0x17);
> > +qtest_quit(s);
> > +}
> > +
> > +int main(int argc, char **argv)
> > +{
> > +const char *arch = qtest_get_arch();
> > +
> > +g_test_init(, , NULL);
> > +
> > +if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
> > +qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt",
> > +   test_lp1878263_megasas_zero_iov_cnt);
> > +}
> > +
> > +return g_test_run();
> > +}
> > diff --git a/tests/qtest/fuzz-test.c b/tests/qtest/fuzz-test.c
> > index cdb1100a0b8..6188fbb8e96 100644
> > --- a/tests/qtest/fuzz-test.c
> > +++ b/tests/qtest/fuzz-test.c
> > @@ -11,29 +11,6 @@
> >   #include "libqos/libqtest.h"
> > -/*
> > - * This used to trigger the assert in scsi_dma_complete
> > - * https://bugs.launchpad.net/qemu/+bug/1878263
> > - */
> > -static void test_lp1878263_megasas_zero_iov_cnt(void)
> > -{
> > -QTestState *s;
> > -
> > -s = qtest_init("-nographic -monitor none -serial none "
> > -   "-M q35 -device megasas -device scsi-cd,drive=null0 "
> > -   "-blockdev 
> > driver=null-co,read-zeroes=on,node-name=null0");
> > -qtest_outl(s, 0xcf8, 0x80001818);
> > -qtest_outl(s, 0xcfc, 0xc101);
> > -qtest_outl(s, 0xcf8, 0x8000181c);
> > -qtest_outl(s, 0xcf8, 0x80001804);
> > -qtest_outw(s, 0xcfc, 0x7);
> > -qtest_outl(s, 0xcf8, 0x8000186a);
> > -qtest_writeb(s, 0x14, 0xfe);
> > -qtest_writeb(s, 0x0, 0x02);
> > -qtest_outb(s, 0xc1c0, 0x17);
> > -qtest_quit(s);
> > -}
> > -
> >   static void test_lp1878642_pci_bus_get_irq_level_assert(void)
> >   {
> >   QTestState *s;
> > @@ -104,8 +81,6 @@ int main(int argc, char **argv)
> >   g_test_init(, , NULL);
> >   if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
> > -qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt",
> > -   test_lp1878263_megasas_zero_iov_cnt);
> >   qtest_add_func("fuzz/test_lp1878642_pci_bus_get_irq_level_assert",
> >  test_lp1878642_pci_bus_get_irq_level_assert);
> >   qtest_add_func("fuzz/test_mmio_oob_from_memory_region_cache",
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 34359a99b8e..44cd74b03cd 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1925,6 +1925,7 @@ S: Supported
> >   F: hw/scsi/megasas.c
> >   F: hw/scsi/mfi.h
> >   F: tests/qtest/megasas-test.c
> > +F: tests/qtest/fuzz-megasas-test.c
> >   Network packet abstractions
> >   M: Dmitry Fleytman 
> > diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> > index 16d04625b8b..85682d0dfce 100644
> > --- a/tests/qtest/meson.build
> > +++ b/tests/qtest/meson.build
> > @@ -4,7 +4,9 @@
> > subdir_done()
> >   endif
> > -qtests_generic = [
> > +qtests_generic = \
> > +  (config_all_devices.has_key('CONFIG_MEGASAS_SCSI_PCI') ? 
> > ['fuzz-megasas-test'] : []) + \
> > +  [
> > 'cdrom-test',
> > 'device-introspect-test',
> > 'machine-none-test',
> > 
> 
> 

Re: [PATCH v4 4/4] meson: Warn when TCI is selected but TCG backend is available

2021-01-26 Thread Alex Bennée


Stefan Weil  writes:

> Am 25.01.21 um 23:35 schrieb Richard Henderson:
>> On 1/25/21 11:02 AM, Stefan Weil wrote:
>>> Am 25.01.21 um 20:02 schrieb Richard Henderson:
 On 1/25/21 8:58 AM, Stefan Weil wrote:
> I have no evidence that TCI is less reliable than TCG, so I would not 
> write
> that.
 It can't pass make check-tcg.
>>> Where does it fail? Maybe an expected timeout problem which can be solved by
>>> increasing the timeouts for TCI?
>>>
>>> I have just run a local test of `make check-tcg` with native TCG and with 
>>> TCI
>>> and did not see a difference. But I noticed that in both cases many tests 
>>> show
>>> "skipped".
>> You need to enable docker or podman for your development, so that you get all
>> of the cross-compilers.
>>
>> Then:
>>
>>TESTfcvt on arm
>> TODO ../qemu/tcg/tci.c:614: tcg_qemu_tb_exec()
>> ../qemu/tcg/tci.c:614: tcg fatal error
>> qemu: uncaught target signal 11 (Segmentation fault) - core dumped
>>
>>TESTfloat_convs on m68k
>> TODO ../qemu/tcg/tci.c:614: tcg_qemu_tb_exec()
>> ../qemu/tcg/tci.c:614: tcg fatal error
>> qemu: uncaught target signal 11 (Segmentation fault) - core dumped
>>
>> which is of course one of the TODO assertions.
>> It's positively criminal those still exist in the code.
>
>
> I installed podman and repeated `make check-tcg`. The log file still 
> shows 87 lines with "SKIPPED". There is also a gdb core dump, several 
> warnings, but nothing related to TCI. Both tests cited above seem to 
> work without a problem.

I'm going to go out on a limb and guess you have commit:

  23a77b2d18 (build-system: clean up TCG/TCI configury)

which temporarily has the effect of disabling TCI. See

  Subject: Re: [PATCH v4 1/4] configure: Fix --enable-tcg-interpreter
  From: Paolo Bonzini 
  Message-ID: <2b8b6291-b54c-b285-ae38-21f067a84...@redhat.com>
  Date: Mon, 25 Jan 2021 17:36:42 +0100

with that fix fixed I see the same failures as Richard:

  ./qemu-arm ./tests/tcg/arm-linux-user/fcvt > /dev/null
  TODO ../../tcg/tci.c:614: tcg_qemu_tb_exec()
  ../../tcg/tci.c:614: tcg fatal error
  qemu: uncaught target signal 11 (Segmentation fault) - core dumped
  fish: “./qemu-arm ./tests/tcg/arm-linu…” terminated by signal SIGSEGV 
(Address boundary error)

which does raise the question before today when was the last time anyone
attempted to run check-tcg on this?

> The complete log file is available from 
> https://qemu.weilnetz.de/test/check-tcg.txt.
>
> Daniel, regarding your comment: TCI has 100 % test coverage for the 
> productive code lines.

By what tests? The fact you don't hit asserts in your day to day testing
doesn't mean there are features missing that are easily tripped up or
that TCI got it right.

> All code lines which were never tested raise an 
> assertion, so can easily be identified (and fixed as soon as there is a 
> test case which triggers such an assertion). The known deficits are 
> speed, missing TCG opcodes, unimplemented TCG opcodes because of missing 
> test cases and missing support for some host architectures.

Passing check-tcg would be a minimum for me.

-- 
Alex Bennée



Re: [PATCH V6 4/6] hw/block/nvme: support for multi-controller in subsystem

2021-01-26 Thread Keith Busch
On Tue, Jan 26, 2021 at 09:52:48AM +0900, Minwoo Im wrote:
> On 21-01-25 10:11:43, Keith Busch wrote:
> > On Mon, Jan 25, 2021 at 07:03:32PM +0100, Klaus Jensen wrote:
> > > On Jan 24 11:54, Minwoo Im wrote:
> > > > We have nvme-subsys and nvme devices mapped together.  To support
> > > > multi-controller scheme to this setup, controller identifier(id) has to
> > > > be managed.  Earlier, cntlid(controller id) used to be always 0 because
> > > > we didn't have any subsystem scheme that controller id matters.
> > > > 
> > > > This patch introduced 'cntlid' attribute to the nvme controller
> > > > instance(NvmeCtrl) and make it allocated by the nvme-subsys device
> > > > mapped to the controller.  If nvme-subsys is not given to the
> > > > controller, then it will always be 0 as it was.
> > > > 
> > > > Added 'ctrls' array in the nvme-subsys instance to manage attached
> > > > controllers to the subsystem with a limit(32).  This patch didn't take
> > > > list for the controllers to make it seamless with nvme-ns device.
> > > > 
> > > > Signed-off-by: Minwoo Im 
> > > > ---
> > > >  hw/block/nvme-subsys.c | 21 +
> > > >  hw/block/nvme-subsys.h |  4 
> > > >  hw/block/nvme.c| 29 +
> > > >  hw/block/nvme.h|  1 +
> > > >  4 files changed, 55 insertions(+)
> > > > 
> > > > diff --git a/hw/block/nvme.c b/hw/block/nvme.c
> > > > index b525fca14103..7138389be4bd 100644
> > > > --- a/hw/block/nvme.c
> > > > +++ b/hw/block/nvme.c
> > > > @@ -4481,6 +4484,10 @@ static void nvme_init_ctrl(NvmeCtrl *n, 
> > > > PCIDevice *pci_dev)
> > > >  id->psd[0].enlat = cpu_to_le32(0x10);
> > > >  id->psd[0].exlat = cpu_to_le32(0x4);
> > > >  
> > > > +if (n->subsys) {
> > > > +id->cmic |= NVME_CMIC_MULTI_CTRL;
> > > > +}
> > > 
> > > Since multiple controllers show up with a PCIe port of their own, do we
> > > need to set bit 0 (NVME_CMIC_MULTI_PORT?) as well? Or am I
> > > misunderstanding that bit?
> > 
> > AIUI, if you report this MULTI_PORT bit, then each PCI device in the
> > subsystem needs to report a different "Port Number" in their PCIe Link
> > Capabilities register. I don't think we can manipulate that value from
> > the nvme "device", but I also don't know what a host should do with this
> > information even if we could. So, I think it's safe to leave it at 0.
> 
> AFAIK, If we leave it to 0, kernel will not allocate disk for multi-path
> case (e.g., nvmeXcYnZ).

Kernel only checks for MULTI_CTRL. It doesn't do anything with MULTI_PORT.



Re: [PATCH v2 3/2] MAINTAINERS: Cover fuzzer reproducer tests within 'Device Fuzzing'

2021-01-26 Thread Thomas Huth

On 26/01/2021 12.28, Philippe Mathieu-Daudé wrote:

When we started to commit the fuzzer QTest reproducers to
fuzz-test.c in commit d8dd1095019 ("qtest: add fuzz test case"),
we forgot to add the corresponding MAINTAINERS entry. Do it now.

Signed-off-by: Philippe Mathieu-Daudé 
---
  MAINTAINERS | 1 +
  1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e275c81fd49..1b88753b325 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2571,6 +2571,7 @@ R: Stefan Hajnoczi 
  R: Thomas Huth 
  S: Maintained
  F: tests/qtest/fuzz/
+F: tests/qtest/fuzz-*test.c
  F: scripts/oss-fuzz/
  F: docs/devel/fuzzing.rst


Reviewed-by: Thomas Huth 




Re: [PATCH v2 2/2] tests/qtest: Only run fuzz-virtio-scsi when virtio-scsi is available

2021-01-26 Thread Thomas Huth

On 26/01/2021 12.16, Philippe Mathieu-Daudé wrote:

This test fails when QEMU is built without the virtio-scsi device,
restrict it to its availability.

Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/qtest/fuzz-test.c | 51 
  tests/qtest/fuzz-virtio-scsi-test.c | 75 +
  MAINTAINERS |  1 +
  tests/qtest/meson.build |  1 +
  4 files changed, 77 insertions(+), 51 deletions(-)
  create mode 100644 tests/qtest/fuzz-virtio-scsi-test.c

diff --git a/tests/qtest/fuzz-test.c b/tests/qtest/fuzz-test.c
index 6188fbb8e96..d112798afe3 100644
--- a/tests/qtest/fuzz-test.c
+++ b/tests/qtest/fuzz-test.c
@@ -25,55 +25,6 @@ static void test_lp1878642_pci_bus_get_irq_level_assert(void)
  qtest_quit(s);
  }
  
-/*

- * Here a MemoryRegionCache pointed to an MMIO region but had a
- * larger size than the underlying region.
- */
-static void test_mmio_oob_from_memory_region_cache(void)
-{
-QTestState *s;
-
-s = qtest_init("-M pc-q35-5.2 -display none -m 512M "
-  "-device virtio-scsi,num_queues=8,addr=03.0 ");
-
-qtest_outl(s, 0xcf8, 0x80001811);
-qtest_outb(s, 0xcfc, 0x6e);
-qtest_outl(s, 0xcf8, 0x80001824);
-qtest_outl(s, 0xcf8, 0x80001813);
-qtest_outl(s, 0xcfc, 0xa08);
-qtest_outl(s, 0xcf8, 0x80001802);
-qtest_outl(s, 0xcfc, 0x5a175a63);
-qtest_outb(s, 0x6e08, 0x9e);
-qtest_writeb(s, 0x9f003, 0xff);
-qtest_writeb(s, 0x9f004, 0x01);
-qtest_writeb(s, 0x9e012, 0x0e);
-qtest_writeb(s, 0x9e01b, 0x0e);
-qtest_writeb(s, 0x9f006, 0x01);
-qtest_writeb(s, 0x9f008, 0x01);
-qtest_writeb(s, 0x9f00a, 0x01);
-qtest_writeb(s, 0x9f00c, 0x01);
-qtest_writeb(s, 0x9f00e, 0x01);
-qtest_writeb(s, 0x9f010, 0x01);
-qtest_writeb(s, 0x9f012, 0x01);
-qtest_writeb(s, 0x9f014, 0x01);
-qtest_writeb(s, 0x9f016, 0x01);
-qtest_writeb(s, 0x9f018, 0x01);
-qtest_writeb(s, 0x9f01a, 0x01);
-qtest_writeb(s, 0x9f01c, 0x01);
-qtest_writeb(s, 0x9f01e, 0x01);
-qtest_writeb(s, 0x9f020, 0x01);
-qtest_writeb(s, 0x9f022, 0x01);
-qtest_writeb(s, 0x9f024, 0x01);
-qtest_writeb(s, 0x9f026, 0x01);
-qtest_writeb(s, 0x9f028, 0x01);
-qtest_writeb(s, 0x9f02a, 0x01);
-qtest_writeb(s, 0x9f02c, 0x01);
-qtest_writeb(s, 0x9f02e, 0x01);
-qtest_writeb(s, 0x9f030, 0x01);
-qtest_outb(s, 0x6e10, 0x00);
-qtest_quit(s);
-}
-
  int main(int argc, char **argv)
  {
  const char *arch = qtest_get_arch();
@@ -83,8 +34,6 @@ int main(int argc, char **argv)
  if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
  qtest_add_func("fuzz/test_lp1878642_pci_bus_get_irq_level_assert",
 test_lp1878642_pci_bus_get_irq_level_assert);
-qtest_add_func("fuzz/test_mmio_oob_from_memory_region_cache",
-   test_mmio_oob_from_memory_region_cache);
  }
  
  return g_test_run();

diff --git a/tests/qtest/fuzz-virtio-scsi-test.c 
b/tests/qtest/fuzz-virtio-scsi-test.c
new file mode 100644
index 000..aaf6d10e189
--- /dev/null
+++ b/tests/qtest/fuzz-virtio-scsi-test.c
@@ -0,0 +1,75 @@
+/*
+ * QTest fuzzer-generated testcase for virtio-scsi device
+ *
+ * Copyright (c) 2020 Li Qiang 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqos/libqtest.h"
+
+/*
+ * Here a MemoryRegionCache pointed to an MMIO region but had a
+ * larger size than the underlying region.
+ */
+static void test_mmio_oob_from_memory_region_cache(void)
+{
+QTestState *s;
+
+s = qtest_init("-M pc-q35-5.2 -display none -m 512M "
+   "-device virtio-scsi,num_queues=8,addr=03.0 ");
+
+qtest_outl(s, 0xcf8, 0x80001811);
+qtest_outb(s, 0xcfc, 0x6e);
+qtest_outl(s, 0xcf8, 0x80001824);
+qtest_outl(s, 0xcf8, 0x80001813);
+qtest_outl(s, 0xcfc, 0xa08);
+qtest_outl(s, 0xcf8, 0x80001802);
+qtest_outl(s, 0xcfc, 0x5a175a63);
+qtest_outb(s, 0x6e08, 0x9e);
+qtest_writeb(s, 0x9f003, 0xff);
+qtest_writeb(s, 0x9f004, 0x01);
+qtest_writeb(s, 0x9e012, 0x0e);
+qtest_writeb(s, 0x9e01b, 0x0e);
+qtest_writeb(s, 0x9f006, 0x01);
+qtest_writeb(s, 0x9f008, 0x01);
+qtest_writeb(s, 0x9f00a, 0x01);
+qtest_writeb(s, 0x9f00c, 0x01);
+qtest_writeb(s, 0x9f00e, 0x01);
+qtest_writeb(s, 0x9f010, 0x01);
+qtest_writeb(s, 0x9f012, 0x01);
+qtest_writeb(s, 0x9f014, 0x01);
+qtest_writeb(s, 0x9f016, 0x01);
+qtest_writeb(s, 0x9f018, 0x01);
+qtest_writeb(s, 0x9f01a, 0x01);
+qtest_writeb(s, 0x9f01c, 0x01);
+qtest_writeb(s, 0x9f01e, 0x01);
+qtest_writeb(s, 0x9f020, 0x01);
+qtest_writeb(s, 0x9f022, 0x01);
+qtest_writeb(s, 0x9f024, 0x01);
+qtest_writeb(s, 0x9f026, 0x01);
+qtest_writeb(s, 0x9f028, 0x01);
+qtest_writeb(s, 

Re: [PATCH v2 1/2] tests/qtest: Only run fuzz-megasas-test if megasas device is available

2021-01-26 Thread Thomas Huth

On 26/01/2021 12.16, Philippe Mathieu-Daudé wrote:

This test fails when QEMU is built without the megasas device,
restrict it to its availability.

Signed-off-by: Philippe Mathieu-Daudé 
---
  tests/qtest/fuzz-megasas-test.c | 49 +
  tests/qtest/fuzz-test.c | 25 -
  MAINTAINERS |  1 +
  tests/qtest/meson.build |  4 ++-
  4 files changed, 53 insertions(+), 26 deletions(-)
  create mode 100644 tests/qtest/fuzz-megasas-test.c

diff --git a/tests/qtest/fuzz-megasas-test.c b/tests/qtest/fuzz-megasas-test.c
new file mode 100644
index 000..940a76bf25a
--- /dev/null
+++ b/tests/qtest/fuzz-megasas-test.c
@@ -0,0 +1,49 @@
+/*
+ * QTest fuzzer-generated testcase for megasas device
+ *
+ * Copyright (c) 2020 Li Qiang 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "libqos/libqtest.h"
+
+/*
+ * This used to trigger the assert in scsi_dma_complete
+ * https://bugs.launchpad.net/qemu/+bug/1878263
+ */
+static void test_lp1878263_megasas_zero_iov_cnt(void)
+{
+QTestState *s;
+
+s = qtest_init("-nographic -monitor none -serial none "
+   "-M q35 -device megasas -device scsi-cd,drive=null0 "
+   "-blockdev driver=null-co,read-zeroes=on,node-name=null0");
+qtest_outl(s, 0xcf8, 0x80001818);
+qtest_outl(s, 0xcfc, 0xc101);
+qtest_outl(s, 0xcf8, 0x8000181c);
+qtest_outl(s, 0xcf8, 0x80001804);
+qtest_outw(s, 0xcfc, 0x7);
+qtest_outl(s, 0xcf8, 0x8000186a);
+qtest_writeb(s, 0x14, 0xfe);
+qtest_writeb(s, 0x0, 0x02);
+qtest_outb(s, 0xc1c0, 0x17);
+qtest_quit(s);
+}
+
+int main(int argc, char **argv)
+{
+const char *arch = qtest_get_arch();
+
+g_test_init(, , NULL);
+
+if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt",
+   test_lp1878263_megasas_zero_iov_cnt);
+}
+
+return g_test_run();
+}
diff --git a/tests/qtest/fuzz-test.c b/tests/qtest/fuzz-test.c
index cdb1100a0b8..6188fbb8e96 100644
--- a/tests/qtest/fuzz-test.c
+++ b/tests/qtest/fuzz-test.c
@@ -11,29 +11,6 @@
  
  #include "libqos/libqtest.h"
  
-/*

- * This used to trigger the assert in scsi_dma_complete
- * https://bugs.launchpad.net/qemu/+bug/1878263
- */
-static void test_lp1878263_megasas_zero_iov_cnt(void)
-{
-QTestState *s;
-
-s = qtest_init("-nographic -monitor none -serial none "
-   "-M q35 -device megasas -device scsi-cd,drive=null0 "
-   "-blockdev driver=null-co,read-zeroes=on,node-name=null0");
-qtest_outl(s, 0xcf8, 0x80001818);
-qtest_outl(s, 0xcfc, 0xc101);
-qtest_outl(s, 0xcf8, 0x8000181c);
-qtest_outl(s, 0xcf8, 0x80001804);
-qtest_outw(s, 0xcfc, 0x7);
-qtest_outl(s, 0xcf8, 0x8000186a);
-qtest_writeb(s, 0x14, 0xfe);
-qtest_writeb(s, 0x0, 0x02);
-qtest_outb(s, 0xc1c0, 0x17);
-qtest_quit(s);
-}
-
  static void test_lp1878642_pci_bus_get_irq_level_assert(void)
  {
  QTestState *s;
@@ -104,8 +81,6 @@ int main(int argc, char **argv)
  g_test_init(, , NULL);
  
  if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {

-qtest_add_func("fuzz/test_lp1878263_megasas_zero_iov_cnt",
-   test_lp1878263_megasas_zero_iov_cnt);
  qtest_add_func("fuzz/test_lp1878642_pci_bus_get_irq_level_assert",
 test_lp1878642_pci_bus_get_irq_level_assert);
  qtest_add_func("fuzz/test_mmio_oob_from_memory_region_cache",
diff --git a/MAINTAINERS b/MAINTAINERS
index 34359a99b8e..44cd74b03cd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1925,6 +1925,7 @@ S: Supported
  F: hw/scsi/megasas.c
  F: hw/scsi/mfi.h
  F: tests/qtest/megasas-test.c
+F: tests/qtest/fuzz-megasas-test.c
  
  Network packet abstractions

  M: Dmitry Fleytman 
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 16d04625b8b..85682d0dfce 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -4,7 +4,9 @@
subdir_done()
  endif
  
-qtests_generic = [

+qtests_generic = \
+  (config_all_devices.has_key('CONFIG_MEGASAS_SCSI_PCI') ? 
['fuzz-megasas-test'] : []) + \
+  [
'cdrom-test',
'device-introspect-test',
'machine-none-test',



Reviewed-by: Thomas Huth 

I assume Alexander will take this patch through his fuzzer branch now? Or 
shall I take it via the qtest branch?


 Thomas




Re: [PATCH v2] docs/devel: Explain how acceptance tests can be skipped

2021-01-26 Thread Thomas Huth

On 15/01/2021 22.00, Wainer dos Santos Moschetta wrote:

Documented under the "Acceptance tests using the Avocado Framework"
section in testing.rst how environment variables are used to skip tests.

Signed-off-by: Wainer dos Santos Moschetta 
---
v2:
  - Made the changes Thomas pointed out.

  docs/devel/testing.rst | 62 ++
  1 file changed, 62 insertions(+)

diff --git a/docs/devel/testing.rst b/docs/devel/testing.rst
index 0aa7a13bba..9f8b77c8ec 100644
--- a/docs/devel/testing.rst
+++ b/docs/devel/testing.rst
@@ -871,6 +871,68 @@ qemu_bin
  
  The exact QEMU binary to be used on QEMUMachine.
  
+Skipping tests

+--
+The Avocado framework provides Python decorators which allow for easily skip
+tests running under certain conditions. For example, on the lack of a binary
+on the test system or when the running environment is a CI system. For further
+information about those decorators, please refer to::
+
+  
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#skipping-tests
+
+While the conditions for skipping tests are often specifics of each one, there
+are recurring scenarios identified by the QEMU developers and the use of
+environment variables became a kind of standard way to enable/disable tests.
+
+Here is a list of the most used variables:
+
+AVOCADO_ALLOW_LARGE_STORAGE
+~~~
+Tests which are going to fetch or produce assets considered *large* are not
+going to run unless that `AVOCADO_ALLOW_LARGE_STORAGE=1` is exported on
+the environment.
+
+The definition of *large* is a bit arbitrary here, but it usually means an
+asset which occupies at least 1GB of size on disk when uncompressed.
+
+AVOCADO_ALLOW_UNTRUSTED_CODE
+
+There are tests which will boot a kernel image or firmware that can be
+considered not safe to run on the developer's workstation, thus they are
+skipped by default. The definition of *not safe* is also arbitrary but
+usually it means a blob which either its source or build process aren't
+public available.
+
+You should export `AVOCADO_ALLOW_UNTRUSTED_CODE=1` on the environment in
+order to allow tests which make use of those kind of assets.
+
+AVOCADO_TIMEOUT_EXPECTED
+
+The Avocado framework has a timeout mechanism which interrupts tests to avoid 
the
+test suite of getting stuck. The timeout value can be set via test parameter or
+property defined in the test class, for further details::
+
+  
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#setting-a-test-timeout
+
+Even though the timeout can be set by the test developer, there are some tests
+that may not have a well-defined limit of time to finish under certain
+conditions. For example, tests that take longer to execute when QEMU is
+compiled with debug flags. Therefore, the `AVOCADO_TIMEOUT_EXPECTED` variable
+has been used to determine whether those tests should run or not.
+
+GITLAB_CI
+~
+A number of tests are flagged to not run on the GitLab CI. Usually because
+they proved to the flaky or there are constraints on the CI environment which
+would make them fail. If you encounter a similar situation then use that
+variable as shown on the code snippet below to skip the test:
+
+.. code::
+
+  @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
+  def test(self):
+  do_something()


Reviewed-by: Thomas Huth 

I can take this trough my testing branch.




[PATCH v6 6/6] sev/i386: Enable an SEV-ES guest based on SEV policy

2021-01-26 Thread Tom Lendacky
From: Tom Lendacky 

Update the sev_es_enabled() function return value to be based on the SEV
policy that has been specified. SEV-ES is enabled if SEV is enabled and
the SEV-ES policy bit is set in the policy object.

Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Tom Lendacky 
---
 target/i386/sev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index badc141554..62ecc28cf6 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -371,7 +371,7 @@ sev_enabled(void)
 bool
 sev_es_enabled(void)
 {
-return false;
+return sev_enabled() && (sev_guest->policy & SEV_POLICY_ES);
 }
 
 uint64_t
-- 
2.30.0




[PATCH v6 5/6] kvm/i386: Use a per-VM check for SMM capability

2021-01-26 Thread Tom Lendacky
From: Tom Lendacky 

SMM is not currently supported for an SEV-ES guest by KVM. Change the SMM
capability check from a KVM-wide check to a per-VM check in order to have
a finer-grained SMM capability check.

Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Suggested-by: Sean Christopherson 
Signed-off-by: Tom Lendacky 
---
 target/i386/kvm/kvm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index bb6bfc19de..37fca43cd9 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -135,7 +135,7 @@ int kvm_has_pit_state2(void)
 
 bool kvm_has_smm(void)
 {
-return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM);
+return kvm_vm_check_extension(kvm_state, KVM_CAP_X86_SMM);
 }
 
 bool kvm_has_adjust_clock_stable(void)
-- 
2.30.0




[PATCH v6 4/6] sev/i386: Don't allow a system reset under an SEV-ES guest

2021-01-26 Thread Tom Lendacky
From: Tom Lendacky 

An SEV-ES guest does not allow register state to be altered once it has
been measured. When an SEV-ES guest issues a reboot command, Qemu will
reset the vCPU state and resume the guest. This will cause failures under
SEV-ES. Prevent that from occuring by introducing an arch-specific
callback that returns a boolean indicating whether vCPUs are resettable.

Cc: Peter Maydell 
Cc: Aurelien Jarno 
Cc: Jiaxun Yang 
Cc: Aleksandar Rikalo 
Cc: David Gibson 
Cc: David Hildenbrand 
Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Tom Lendacky 
---
 accel/kvm/kvm-all.c   |  5 +
 include/sysemu/cpus.h |  2 ++
 include/sysemu/hw_accel.h |  5 +
 include/sysemu/kvm.h  | 10 ++
 softmmu/cpus.c|  5 +
 softmmu/runstate.c|  3 +++
 target/arm/kvm.c  |  5 +
 target/i386/kvm/kvm.c |  6 ++
 target/mips/kvm.c |  5 +
 target/ppc/kvm.c  |  5 +
 target/s390x/kvm.c|  5 +
 11 files changed, 56 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 410879cf94..6c099a3869 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2414,6 +2414,11 @@ void kvm_flush_coalesced_mmio_buffer(void)
 s->coalesced_flush_in_progress = false;
 }
 
+bool kvm_cpu_check_are_resettable(void)
+{
+return kvm_arch_cpu_check_are_resettable();
+}
+
 static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
 {
 if (!cpu->vcpu_dirty) {
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index e8156728c6..1cb4f9dbeb 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -57,6 +57,8 @@ extern int icount_align_option;
 /* Unblock cpu */
 void qemu_cpu_kick_self(void);
 
+bool cpus_are_resettable(void);
+
 void cpu_synchronize_all_states(void);
 void cpu_synchronize_all_post_reset(void);
 void cpu_synchronize_all_post_init(void);
diff --git a/include/sysemu/hw_accel.h b/include/sysemu/hw_accel.h
index ffed6192a3..61672f9b32 100644
--- a/include/sysemu/hw_accel.h
+++ b/include/sysemu/hw_accel.h
@@ -22,4 +22,9 @@ void cpu_synchronize_post_reset(CPUState *cpu);
 void cpu_synchronize_post_init(CPUState *cpu);
 void cpu_synchronize_pre_loadvm(CPUState *cpu);
 
+static inline bool cpu_check_are_resettable(void)
+{
+return kvm_enabled() ? kvm_cpu_check_are_resettable() : true;
+}
+
 #endif /* QEMU_HW_ACCEL_H */
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 875ca101e3..3e265cea3d 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -573,4 +573,14 @@ int kvm_get_max_memslots(void);
 /* Notify resamplefd for EOI of specific interrupts. */
 void kvm_resample_fd_notify(int gsi);
 
+/**
+ * kvm_cpu_check_are_resettable - return whether CPUs can be reset
+ *
+ * Returns: true: CPUs are resettable
+ *  false: CPUs are not resettable
+ */
+bool kvm_cpu_check_are_resettable(void);
+
+bool kvm_arch_cpu_check_are_resettable(void);
+
 #endif
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
index 1dc20b9dc3..89de46eae0 100644
--- a/softmmu/cpus.c
+++ b/softmmu/cpus.c
@@ -194,6 +194,11 @@ void cpu_synchronize_pre_loadvm(CPUState *cpu)
 }
 }
 
+bool cpus_are_resettable(void)
+{
+return cpu_check_are_resettable();
+}
+
 int64_t cpus_get_virtual_clock(void)
 {
 /*
diff --git a/softmmu/runstate.c b/softmmu/runstate.c
index beee050815..1813691898 100644
--- a/softmmu/runstate.c
+++ b/softmmu/runstate.c
@@ -527,6 +527,9 @@ void qemu_system_reset_request(ShutdownCause reason)
 if (reboot_action == REBOOT_ACTION_SHUTDOWN &&
 reason != SHUTDOWN_CAUSE_SUBSYSTEM_RESET) {
 shutdown_requested = reason;
+} else if (!cpus_are_resettable()) {
+error_report("cpus are not resettable, terminating");
+shutdown_requested = reason;
 } else {
 reset_requested = reason;
 }
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index ffe186de8d..00e124c812 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1045,3 +1045,8 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
 {
 return (data - 32) & 0x;
 }
+
+bool kvm_arch_cpu_check_are_resettable(void)
+{
+return true;
+}
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index aaae79557d..bb6bfc19de 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -27,6 +27,7 @@
 #include "sysemu/kvm_int.h"
 #include "sysemu/runstate.h"
 #include "kvm_i386.h"
+#include "sev_i386.h"
 #include "hyperv.h"
 #include "hyperv-proto.h"
 
@@ -4788,3 +4789,8 @@ bool kvm_has_waitpkg(void)
 {
 return has_msr_umwait;
 }
+
+bool kvm_arch_cpu_check_are_resettable(void)
+{
+return !sev_es_enabled();
+}
diff --git a/target/mips/kvm.c b/target/mips/kvm.c
index 84fb10ea35..123ec1be7e 100644
--- a/target/mips/kvm.c
+++ b/target/mips/kvm.c
@@ -1290,3 +1290,8 @@ int mips_kvm_type(MachineState *machine, const char 
*vm_type)
 
 return -1;
 }
+
+bool kvm_arch_cpu_check_are_resettable(void)
+{
+return true;
+}
diff --git a/target/ppc/kvm.c 

[PATCH v6 3/6] sev/i386: Allow AP booting under SEV-ES

2021-01-26 Thread Tom Lendacky
From: Tom Lendacky 

When SEV-ES is enabled, it is not possible modify the guests register
state after it has been initially created, encrypted and measured.

Normally, an INIT-SIPI-SIPI request is used to boot the AP. However, the
hypervisor cannot emulate this because it cannot update the AP register
state. For the very first boot by an AP, the reset vector CS segment
value and the EIP value must be programmed before the register has been
encrypted and measured. Search the guest firmware for the guest for a
specific GUID that tells Qemu the value of the reset vector to use.

Cc: Paolo Bonzini 
Cc: "Michael S. Tsirkin" 
Cc: Marcel Apfelbaum 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Cc: Marcelo Tosatti 
Signed-off-by: Tom Lendacky 
---
 accel/kvm/kvm-all.c| 64 
 accel/stubs/kvm-stub.c |  5 +++
 hw/i386/pc_sysfw.c | 10 +-
 include/sysemu/kvm.h   | 16 +
 include/sysemu/sev.h   |  3 ++
 target/i386/kvm/kvm.c  |  2 ++
 target/i386/sev.c  | 74 ++
 7 files changed, 173 insertions(+), 1 deletion(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 3feb17d965..410879cf94 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -39,6 +39,7 @@
 #include "qemu/main-loop.h"
 #include "trace.h"
 #include "hw/irq.h"
+#include "sysemu/kvm.h"
 #include "sysemu/sev.h"
 #include "qapi/visitor.h"
 #include "qapi/qapi-types-common.h"
@@ -126,6 +127,12 @@ struct KVMState
 /* memory encryption */
 void *memcrypt_handle;
 int (*memcrypt_encrypt_data)(void *handle, uint8_t *ptr, uint64_t len);
+int (*memcrypt_save_reset_vector)(void *handle, void *flash_ptr,
+  uint64_t flash_size, uint32_t *addr);
+
+uint32_t reset_cs;
+uint32_t reset_ip;
+bool reset_data_valid;
 
 /* For "info mtree -f" to tell if an MR is registered in KVM */
 int nr_as;
@@ -245,6 +252,62 @@ int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
 return 1;
 }
 
+void kvm_memcrypt_set_reset_vector(CPUState *cpu)
+{
+X86CPU *x86;
+CPUX86State *env;
+
+/* Only update if we have valid reset information */
+if (!kvm_state->reset_data_valid) {
+return;
+}
+
+/* Do not update the BSP reset state */
+if (cpu->cpu_index == 0) {
+return;
+}
+
+x86 = X86_CPU(cpu);
+env = >env;
+
+cpu_x86_load_seg_cache(env, R_CS, 0xf000, kvm_state->reset_cs, 0x,
+   DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
+   DESC_R_MASK | DESC_A_MASK);
+
+env->eip = kvm_state->reset_ip;
+}
+
+int kvm_memcrypt_save_reset_vector(void *flash_ptr, uint64_t flash_size)
+{
+CPUState *cpu;
+uint32_t addr;
+int ret;
+
+if (kvm_memcrypt_enabled() &&
+kvm_state->memcrypt_save_reset_vector) {
+
+addr = 0;
+ret = kvm_state->memcrypt_save_reset_vector(kvm_state->memcrypt_handle,
+flash_ptr, flash_size,
+);
+if (ret) {
+return ret;
+}
+
+if (addr) {
+kvm_state->reset_cs = addr & 0x;
+kvm_state->reset_ip = addr & 0x;
+kvm_state->reset_data_valid = true;
+
+CPU_FOREACH(cpu) {
+kvm_memcrypt_set_reset_vector(cpu);
+}
+}
+}
+
+return 0;
+}
+
 /* Called with KVMMemoryListener.slots_lock held */
 static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
 {
@@ -2216,6 +2279,7 @@ static int kvm_init(MachineState *ms)
 }
 
 kvm_state->memcrypt_encrypt_data = sev_encrypt_data;
+kvm_state->memcrypt_save_reset_vector = sev_es_save_reset_vector;
 }
 
 ret = kvm_arch_init(ms, s);
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
index 680e099463..162c28429e 100644
--- a/accel/stubs/kvm-stub.c
+++ b/accel/stubs/kvm-stub.c
@@ -91,6 +91,11 @@ int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
   return 1;
 }
 
+int kvm_memcrypt_save_reset_vector(void *flash_ptr, uint64_t flash_size)
+{
+return -ENOSYS;
+}
+
 #ifndef CONFIG_USER_ONLY
 int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
 {
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 436b78c587..edec28842d 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -248,7 +248,8 @@ static void pc_system_flash_map(PCMachineState *pcms,
 PFlashCFI01 *system_flash;
 MemoryRegion *flash_mem;
 void *flash_ptr;
-int ret, flash_size;
+uint64_t flash_size;
+int ret;
 
 assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);
 
@@ -301,6 +302,13 @@ static void pc_system_flash_map(PCMachineState *pcms,
  * search for them
  */
 pc_system_parse_ovmf_flash(flash_ptr, flash_size);
+
+ret = kvm_memcrypt_save_reset_vector(flash_ptr, 

[PATCH v6 2/6] sev/i386: Require in-kernel irqchip support for SEV-ES guests

2021-01-26 Thread Tom Lendacky
From: Tom Lendacky 

In prep for AP booting, require the use of in-kernel irqchip support. This
lessens the Qemu support burden required to boot APs.

Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Reviewed-by: Dr. David Alan Gilbert 
Signed-off-by: Tom Lendacky 
---
 target/i386/sev.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/i386/sev.c b/target/i386/sev.c
index fce2128c07..ddec7ebaa7 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -776,6 +776,12 @@ sev_guest_init(const char *id)
 sev->api_minor = status.api_minor;
 
 if (sev_es_enabled()) {
+if (!kvm_kernel_irqchip_allowed()) {
+error_report("%s: SEV-ES guests require in-kernel irqchip support",
+ __func__);
+goto err;
+}
+
 if (!(status.flags & SEV_STATUS_FLAGS_CONFIG_ES)) {
 error_report("%s: guest policy requires SEV-ES, but "
  "host SEV-ES support unavailable",
-- 
2.30.0




[PATCH v6 1/6] sev/i386: Add initial support for SEV-ES

2021-01-26 Thread Tom Lendacky
From: Tom Lendacky 

Provide initial support for SEV-ES. This includes creating a function to
indicate the guest is an SEV-ES guest (which will return false until all
support is in place), performing the proper SEV initialization and
ensuring that the guest CPU state is measured as part of the launch.

Cc: Paolo Bonzini 
Cc: Richard Henderson 
Cc: Eduardo Habkost 
Reviewed-by: Dr. David Alan Gilbert 
Co-developed-by: Jiri Slaby 
Signed-off-by: Jiri Slaby 
Signed-off-by: Tom Lendacky 
---
 target/i386/cpu.c  |  1 +
 target/i386/sev-stub.c |  6 ++
 target/i386/sev.c  | 44 --
 target/i386/sev_i386.h |  1 +
 4 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 72a79e6019..0415d8a99c 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5987,6 +5987,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
uint32_t count,
 break;
 case 0x801F:
 *eax = sev_enabled() ? 0x2 : 0;
+*eax |= sev_es_enabled() ? 0x8 : 0;
 *ebx = sev_get_cbit_position();
 *ebx |= sev_get_reduced_phys_bits() << 6;
 *ecx = 0;
diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c
index c1fecc2101..229a2ee77b 100644
--- a/target/i386/sev-stub.c
+++ b/target/i386/sev-stub.c
@@ -49,8 +49,14 @@ SevCapability *sev_get_capabilities(Error **errp)
 error_setg(errp, "SEV is not available in this QEMU");
 return NULL;
 }
+
 int sev_inject_launch_secret(const char *hdr, const char *secret,
  uint64_t gpa, Error **errp)
 {
 return 1;
 }
+
+bool sev_es_enabled(void)
+{
+return false;
+}
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 1546606811..fce2128c07 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -360,6 +360,12 @@ sev_enabled(void)
 return !!sev_guest;
 }
 
+bool
+sev_es_enabled(void)
+{
+return false;
+}
+
 uint64_t
 sev_get_me_mask(void)
 {
@@ -580,6 +586,20 @@ sev_launch_update_data(SevGuestState *sev, uint8_t *addr, 
uint64_t len)
 return ret;
 }
 
+static int
+sev_launch_update_vmsa(SevGuestState *sev)
+{
+int ret, fw_error;
+
+ret = sev_ioctl(sev->sev_fd, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL, _error);
+if (ret) {
+error_report("%s: LAUNCH_UPDATE_VMSA ret=%d fw_error=%d '%s'",
+__func__, ret, fw_error, fw_error_to_str(fw_error));
+}
+
+return ret;
+}
+
 static void
 sev_launch_get_measure(Notifier *notifier, void *unused)
 {
@@ -592,6 +612,14 @@ sev_launch_get_measure(Notifier *notifier, void *unused)
 return;
 }
 
+if (sev_es_enabled()) {
+/* measure all the VM save areas before getting launch_measure */
+ret = sev_launch_update_vmsa(sev);
+if (ret) {
+exit(1);
+}
+}
+
 measurement = g_new0(struct kvm_sev_launch_measure, 1);
 
 /* query the measurement blob length */
@@ -686,7 +714,7 @@ sev_guest_init(const char *id)
 {
 SevGuestState *sev;
 char *devname;
-int ret, fw_error;
+int ret, fw_error, cmd;
 uint32_t ebx;
 uint32_t host_cbitpos;
 struct sev_user_data_status status = {};
@@ -747,8 +775,20 @@ sev_guest_init(const char *id)
 sev->api_major = status.api_major;
 sev->api_minor = status.api_minor;
 
+if (sev_es_enabled()) {
+if (!(status.flags & SEV_STATUS_FLAGS_CONFIG_ES)) {
+error_report("%s: guest policy requires SEV-ES, but "
+ "host SEV-ES support unavailable",
+ __func__);
+goto err;
+}
+cmd = KVM_SEV_ES_INIT;
+} else {
+cmd = KVM_SEV_INIT;
+}
+
 trace_kvm_sev_init();
-ret = sev_ioctl(sev->sev_fd, KVM_SEV_INIT, NULL, _error);
+ret = sev_ioctl(sev->sev_fd, cmd, NULL, _error);
 if (ret) {
 error_report("%s: failed to initialize ret=%d fw_error=%d '%s'",
  __func__, ret, fw_error, fw_error_to_str(fw_error));
diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h
index 4db6960f60..4f9a5e9b21 100644
--- a/target/i386/sev_i386.h
+++ b/target/i386/sev_i386.h
@@ -29,6 +29,7 @@
 #define SEV_POLICY_SEV  0x20
 
 extern bool sev_enabled(void);
+extern bool sev_es_enabled(void);
 extern uint64_t sev_get_me_mask(void);
 extern SevInfo *sev_get_info(void);
 extern uint32_t sev_get_cbit_position(void);
-- 
2.30.0




[PATCH v6 0/6] Qemu SEV-ES guest support

2021-01-26 Thread Tom Lendacky
From: Tom Lendacky 

This patch series provides support for launching an SEV-ES guest.

Secure Encrypted Virtualization - Encrypted State (SEV-ES) expands on the
SEV support to protect the guest register state from the hypervisor. See
"AMD64 Architecture Programmer's Manual Volume 2: System Programming",
section "15.35 Encrypted State (SEV-ES)" [1].

In order to allow a hypervisor to perform functions on behalf of a guest,
there is architectural support for notifying a guest's operating system
when certain types of VMEXITs are about to occur. This allows the guest to
selectively share information with the hypervisor to satisfy the requested
function. The notification is performed using a new exception, the VMM
Communication exception (#VC). The information is shared through the
Guest-Hypervisor Communication Block (GHCB) using the VMGEXIT instruction.
The GHCB format and the protocol for using it is documented in "SEV-ES
Guest-Hypervisor Communication Block Standardization" [2].

The main areas of the Qemu code that are updated to support SEV-ES are
around the SEV guest launch process and AP booting in order to support
booting multiple vCPUs.

There are no new command line switches required. Instead, the desire for
SEV-ES is presented using the SEV policy object. Bit 2 of the SEV policy
object indicates that SEV-ES is required.

The SEV launch process is updated in two ways. The first is that a the
KVM_SEV_ES_INIT ioctl is used to initialize the guest instead of the
standard KVM_SEV_INIT ioctl. The second is that before the SEV launch
measurement is calculated, the LAUNCH_UPDATE_VMSA SEV API is invoked for
each vCPU that Qemu has created. Once the LAUNCH_UPDATE_VMSA API has been
invoked, no direct changes to the guest register state can be made.

AP booting poses some interesting challenges. The INIT-SIPI-SIPI sequence
is typically used to boot the APs. However, the hypervisor is not allowed
to update the guest registers. For the APs, the reset vector must be known
in advance. An OVMF method to provide a known reset vector address exists
by providing an SEV information block, identified by UUID, near the end of
the firmware [3]. OVMF will program the jump to the actual reset vector in
this area of memory. Since the memory location is known in advance, an AP
can be created with the known reset vector address as its starting CS:IP.
The GHCB document [2] talks about how SMP booting under SEV-ES is
performed. SEV-ES also requires the use of the in-kernel irqchip support
in order to minimize the changes required to Qemu to support AP booting.

[1] https://www.amd.com/system/files/TechDocs/24593.pdf
[2] https://developer.amd.com/wp-content/resources/56421.pdf
[3] 30937f2f98c4 ("OvmfPkg: Use the SEV-ES work area for the SEV-ES AP reset 
vector")

https://github.com/tianocore/edk2/commit/30937f2f98c42496f2f143fe8374ae7f7e684847

Cc: Aleksandar Rikalo 
Cc: Aurelien Jarno 
Cc: David Gibson 
Cc: David Hildenbrand 
Cc: Eduardo Habkost 
Cc: Jiaxun Yang 
Cc: Marcel Apfelbaum 
Cc: Marcelo Tosatti 
Cc: "Michael S. Tsirkin" 
Cc: Paolo Bonzini 
Cc: Peter Maydell 
Cc: Richard Henderson 

---

These patches are based on commit:
9cd69f1a27 ("Merge remote-tracking branch 
'remotes/stefanberger/tags/pull-tpm-2021-01-25-1' into staging")

Additionally, these patches pre-req the following patch series that has
not yet been accepted into the Qemu tree:

[PATCH v2 0/2] sev: enable secret injection to a self described area in OVMF
  https://lore.kernel.org/qemu-devel/20201214154429.11023-1-j...@linux.ibm.com/

A version of the tree can be found at:
https://github.com/AMDESE/qemu/tree/sev-es-v14

Changes since v5:
- Rework the reset prevention patch to not issue the error message if the
  --no-reboot option has been specified for SEV-ES guests.

Changes since v4:
- Add support for an updated Firmware GUID table implementation, that
  is now present in OVMF SEV-ES firmware, when searching for the reset
  vector information. The code will check for the new implementation
  first, followed by the original implementation to maintain backward
  compatibility.

Changes since v3:
- Use the QemuUUID structure for GUID definitions
- Use SEV-ES policy bit definition from target/i386/sev_i386.h
- Update SMM support to a per-VM check in order to check SMM capability
  at the VM level since SEV-ES guests don't currently support SMM
- Make the CPU resettable check an arch-specific check

Changes since v2:
- Add in-kernel irqchip requirement for SEV-ES guests

Changes since v1:
- Fixed checkpatch.pl errors/warnings

Tom Lendacky (6):
  sev/i386: Add initial support for SEV-ES
  sev/i386: Require in-kernel irqchip support for SEV-ES guests
  sev/i386: Allow AP booting under SEV-ES
  sev/i386: Don't allow a system reset under an SEV-ES guest
  kvm/i386: Use a per-VM check for SMM capability
  sev/i386: Enable an SEV-ES guest based on SEV policy

 accel/kvm/kvm-all.c   |  69 +
 accel/stubs/kvm-stub.c|   5 ++
 

[PATCH] gitlab-ci.yml: Exclude some redundant targets in build-without-default-features

2021-01-26 Thread Thomas Huth
The build-without-default-features job is running quite long and sometimes
already hits the 1h time limit. Exclude some targets which do not provide
additional test coverage here (since we e.g. also already test other targets
of the same type, just with different endianess, or a 64-bit superset) to
avoid that we hit the timeout here so easily.

Signed-off-by: Thomas Huth 
---
 .gitlab-ci.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e2f9c99e27..8e0416f11b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -610,6 +610,7 @@ build-without-default-features:
   variables:
 IMAGE: debian-amd64
 CONFIGURE_ARGS: --without-default-features --disable-user
+
--target-list-exclude=arm-softmmu,i386-softmmu,mipsel-softmmu,mips64-softmmu,ppc-softmmu
 MAKE_CHECK_ARGS: check-unit
 
 check-patch:
-- 
2.27.0




Re: [Virtio-fs] [PATCH v2] virtiofsd: prevent opening of special files (CVE-2020-35517)

2021-01-26 Thread Greg Kurz
On Tue, 26 Jan 2021 10:35:02 +
Stefan Hajnoczi  wrote:

> A well-behaved FUSE client does not attempt to open special files with
> FUSE_OPEN because they are handled on the client side (e.g. device nodes
> are handled by client-side device drivers).
> 
> The check to prevent virtiofsd from opening special files is missing in
> a few cases, most notably FUSE_OPEN. A malicious client can cause
> virtiofsd to open a device node, potentially allowing the guest to
> escape. 

or pretty much anything nasty you can think of, e.g. DoS if the malicious
client repeatedly asks virtiofsd to open FIFOs the other side of which is
never opened.

> This can be exploited by a modified guest device driver. It is
> not exploitable from guest userspace since the guest kernel will handle
> special files inside the guest instead of sending FUSE requests.
> 
> This patch adds the missing checks to virtiofsd. This is a short-term
> solution because it does not prevent a compromised virtiofsd process
> from opening device nodes on the host.
> 
> Reported-by: Alex Xu 
> Fixes: CVE-2020-35517
> Reviewed-by: Dr. David Alan Gilbert 
> Reviewed-by: Vivek Goyal 
> Signed-off-by: Stefan Hajnoczi 
> ---

The patch looks pretty good to me. It just seems to be missing a change in
lo_create():

fd = openat(parent_inode->fd, name, (fi->flags | O_CREAT) & ~O_NOFOLLOW,
mode);

A malicious guest could have created anything called ${name} in this directory
before calling FUSE_CREATE and we'll open it blindly, or I'm missing something ?

> v2:
>  * Add doc comment clarifying that symlinks are traversed client-side
>[Daniel]
> 
> This issue was diagnosed on public IRC and is therefore already known
> and not embargoed.
> 
> A stronger fix, and the long-term solution, is for users to mount the
> shared directory and any sub-mounts with nodev, as well as nosuid and
> noexec. Unfortunately virtiofsd cannot do this automatically because
> bind mounts added by the user after virtiofsd has launched would not be
> detected. I suggest the following:
> 
> 1. Modify libvirt and Kata Containers to explicitly set these mount
>options.
> 2. Then modify virtiofsd to check that the shared directory has the
>necessary options at startup. Refuse to start if the options are
>missing so that the user is aware of the security requirements.
> 
> As a bonus this also increases the likelihood that other host processes
> besides virtiofsd will be protected by nosuid/noexec/nodev so that a
> malicious guest cannot drop these files in place and then arrange for a
> host process to come across them.
> 
> Additionally, user namespaces have been discussed. They seem like a
> worthwhile addition as an unprivileged or privilege-separated mode
> although there are limitations with respect to security xattrs and the
> actual uid/gid stored on the host file system not corresponding to the
> guest uid/gid.
> ---
>  tools/virtiofsd/passthrough_ll.c | 85 +---
>  1 file changed, 57 insertions(+), 28 deletions(-)
> 
> diff --git a/tools/virtiofsd/passthrough_ll.c 
> b/tools/virtiofsd/passthrough_ll.c
> index 5fb36d9407..b722f43809 100644
> --- a/tools/virtiofsd/passthrough_ll.c
> +++ b/tools/virtiofsd/passthrough_ll.c
> @@ -555,6 +555,30 @@ static int lo_fd(fuse_req_t req, fuse_ino_t ino)
>  return fd;
>  }
>  
> +/*
> + * Open a file descriptor for an inode. Returns -EBADF if the inode is not a
> + * regular file or a directory. Use this helper function instead of raw
> + * openat(2) to prevent security issues when a malicious client opens special
> + * files such as block device nodes. Symlink inodes are also rejected since
> + * symlinks must already have been traversed on the client side.
> + */
> +static int lo_inode_open(struct lo_data *lo, struct lo_inode *inode,
> + int open_flags)
> +{
> +g_autofree char *fd_str = g_strdup_printf("%d", inode->fd);
> +int fd;
> +
> +if (!S_ISREG(inode->filetype) && !S_ISDIR(inode->filetype)) {
> +return -EBADF;
> +}
> +
> +fd = openat(lo->proc_self_fd, fd_str, open_flags);
> +if (fd < 0) {
> +return -errno;
> +}
> +return fd;
> +}
> +
>  static void lo_init(void *userdata, struct fuse_conn_info *conn)
>  {
>  struct lo_data *lo = (struct lo_data *)userdata;
> @@ -684,8 +708,7 @@ static void lo_setattr(fuse_req_t req, fuse_ino_t ino, 
> struct stat *attr,
>  if (fi) {
>  truncfd = fd;
>  } else {
> -sprintf(procname, "%i", ifd);
> -truncfd = openat(lo->proc_self_fd, procname, O_RDWR);
> +truncfd = lo_inode_open(lo, inode, O_RDWR);
>  if (truncfd < 0) {
>  goto out_err;
>  }
> @@ -1725,7 +1748,6 @@ static struct lo_inode_plock 
> *lookup_create_plock_ctx(struct lo_data *lo,
>pid_t pid, int *err)
>  {
>  struct lo_inode_plock *plock;
> -

Re: [PATCH v4 0/6] Qemu SEV-ES guest support

2021-01-26 Thread Paolo Bonzini

On 26/01/21 18:13, Tom Lendacky wrote:

Also, the new version will have a prereq against another patch series that
has not been accepted yet:

   [PATCH v2 0/2] sev: enable secret injection to a self described area in OVMF

   https://lore.kernel.org/qemu-devel/20201214154429.11023-1-j...@linux.ibm.com/


David reviewed it today, so even if a v3 will be needed that shouldn't 
be a problem for SEV-ES itself.


Paolo




  1   2   3   4   >