[PATCH] vfio/pci: Add system call KVM_VERIFY_MSI to verify every MSI vector

2022-11-07 Thread chenxiang via
From: Xiang Chen 

Currently the numbers of MSI vectors come from register PCI_MSI_FLAGS
which should be power-of-2, but in some scenaries it is not the same as
the number that driver requires in guest, for example, a PCI driver wants
to allocate 6 MSI vecotrs in guest, but as the limitation, it will allocate
8 MSI vectors. So it requires 8 MSI vectors in qemu while the driver in
guest only wants to allocate 6 MSI vectors.

When GICv4.1 is enabled, we can see some exception print as following for
above scenaro:
vfio-pci :3a:00.1: irq bypass producer (token 8f08224d) 
registration fails:66311

To avoid the issue, add system call KVM_VERIFY_MSI to verify whether every
MSI vecotor is valid and adjust the numver of MSI vectors.

This is qemu part of adding system call KVM_VERIFY_MSI.

Signed-off-by: Xiang Chen 
---
 accel/kvm/kvm-all.c   | 19 +++
 hw/vfio/pci.c | 13 +
 include/sysemu/kvm.h  |  2 ++
 linux-headers/linux/kvm.h |  1 +
 4 files changed, 35 insertions(+)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f99b0be..19c8b84 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1918,6 +1918,25 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
 return kvm_set_irq(s, route->kroute.gsi, 1);
 }
 
+int kvm_irqchip_verify_msi_route(KVMState *s, int vector, PCIDevice *dev)
+{
+if (pci_available && dev && kvm_msi_devid_required()) {
+   MSIMessage msg = {0, 0};
+   struct kvm_msi msi;
+
+   msg = pci_get_msi_message(dev, vector);
+   msi.address_lo = (uint32_t)msg.address;
+   msi.address_hi = msg.address >> 32;
+   msi.devid = pci_requester_id(dev);
+   msi.data = le32_to_cpu(msg.data);
+   msi.flags = KVM_MSI_VALID_DEVID;
+   memset(msi.pad, 0, sizeof(msi.pad));
+
+   return kvm_vm_ioctl(s, KVM_VERIFY_MSI, );
+}
+return 0;
+}
+
 int kvm_irqchip_add_msi_route(KVMRouteChange *c, int vector, PCIDevice *dev)
 {
 struct kvm_irq_routing_entry kroute = {};
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 939dcc3..8dae0e4 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -660,6 +660,7 @@ static void vfio_msix_enable(VFIOPCIDevice *vdev)
 static void vfio_msi_enable(VFIOPCIDevice *vdev)
 {
 int ret, i;
+int msi_invalid = 0;
 
 vfio_disable_interrupts(vdev);
 
@@ -671,6 +672,18 @@ static void vfio_msi_enable(VFIOPCIDevice *vdev)
 vfio_prepare_kvm_msi_virq_batch(vdev);
 
 vdev->nr_vectors = msi_nr_vectors_allocated(>pdev);
+
+/*
+ * Verify whether every msi interrupt is valid as the number of
+ * MSI vectors comes from PCI device registers which may be not the
+ * same as the number of vectors that driver requires.
+ */
+for (i = 0; i < vdev->nr_vectors; i++) {
+   ret = kvm_irqchip_verify_msi_route(kvm_state, i, >pdev);
+   if (ret < 0)
+   msi_invalid++;
+}
+vdev->nr_vectors -= msi_invalid;
 retry:
 vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->nr_vectors);
 
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index e9a97ed..aca6e5b 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -482,6 +482,8 @@ void kvm_cpu_synchronize_state(CPUState *cpu);
 
 void kvm_init_cpu_signals(CPUState *cpu);
 
+int kvm_irqchip_verify_msi_route(KVMState *s, int vector, PCIDevice *dev);
+
 /**
  * kvm_irqchip_add_msi_route - Add MSI route for specific vector
  * @c:  KVMRouteChange instance.
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index ebdafa5..ac59350 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -1540,6 +1540,7 @@ struct kvm_s390_ucas_mapping {
 #define KVM_PPC_SVM_OFF  _IO(KVMIO,  0xb3)
 #define KVM_ARM_MTE_COPY_TAGS_IOR(KVMIO,  0xb4, struct 
kvm_arm_copy_mte_tags)
 
+#define KVM_VERIFY_MSI_IOW(KVMIO,  0xb5, struct kvm_msi)
 /* ioctl for vm fd */
 #define KVM_CREATE_DEVICE_IOWR(KVMIO,  0xe0, struct kvm_create_device)
 
-- 
2.8.1




[PATCH] KVM: Add system call KVM_VERIFY_MSI to verify MSI vector

2022-11-07 Thread chenxiang via
From: Xiang Chen 

Currently the numbers of MSI vectors come from register PCI_MSI_FLAGS
which should be power-of-2, but in some scenaries it is not the same as
the number that driver requires in guest, for example, a PCI driver wants
to allocate 6 MSI vecotrs in guest, but as the limitation, it will allocate
8 MSI vectors. So it requires 8 MSI vectors in qemu while the driver in
guest only wants to allocate 6 MSI vectors.

When GICv4.1 is enabled, we can see some exception print as following for
above scenaro:
vfio-pci :3a:00.1: irq bypass producer (token 8f08224d) 
registration fails:66311

In order to verify whether a MSI vector is valid, add KVM_VERIFY_MSI to do
that. If there is a mapping, return 0, otherwise return negative value.

This is the kernel part of adding system call KVM_VERIFY_MSI.

Signed-off-by: Xiang Chen 
---
 arch/arm64/kvm/vgic/vgic-irqfd.c |  5 +
 arch/arm64/kvm/vgic/vgic-its.c   | 36 
 arch/arm64/kvm/vgic/vgic.h   |  1 +
 include/linux/kvm_host.h |  2 +-
 include/uapi/linux/kvm.h |  2 ++
 virt/kvm/kvm_main.c  |  9 +
 6 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/vgic/vgic-irqfd.c b/arch/arm64/kvm/vgic/vgic-irqfd.c
index 475059b..2312da6 100644
--- a/arch/arm64/kvm/vgic/vgic-irqfd.c
+++ b/arch/arm64/kvm/vgic/vgic-irqfd.c
@@ -98,6 +98,11 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
return vgic_its_inject_msi(kvm, );
 }
 
+int kvm_verify_msi(struct kvm *kvm, struct kvm_msi *msi)
+{
+   return vgic_its_verify_msi(kvm, msi);
+}
+
 /**
  * kvm_arch_set_irq_inatomic: fast-path for irqfd injection
  */
diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 24d7778..cae6183 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -767,6 +767,42 @@ int vgic_its_inject_cached_translation(struct kvm *kvm, 
struct kvm_msi *msi)
return 0;
 }
 
+int vgic_its_verify_msi(struct kvm *kvm, struct kvm_msi *msi)
+{
+   struct vgic_its *its;
+   struct its_ite *ite;
+   struct kvm_vcpu *vcpu;
+   int ret = 0;
+
+   if (!irqchip_in_kernel(kvm) || (msi->flags & ~KVM_MSI_VALID_DEVID))
+   return -EINVAL;
+
+   if (!vgic_has_its(kvm))
+   return -ENODEV;
+
+   its = vgic_msi_to_its(kvm, msi);
+   if (IS_ERR(its))
+   return PTR_ERR(its);
+
+   mutex_lock(>its_lock);
+   if (!its->enabled) {
+   ret = -EBUSY;
+   goto unlock;
+   }
+   ite = find_ite(its, msi->devid, msi->data);
+   if (!ite || !its_is_collection_mapped(ite->collection)) {
+   ret = -E_ITS_INT_UNMAPPED_INTERRUPT;
+   goto unlock;
+   }
+
+   vcpu = kvm_get_vcpu(kvm, ite->collection->target_addr);
+   if (!vcpu)
+   ret = -E_ITS_INT_UNMAPPED_INTERRUPT;
+unlock:
+   mutex_unlock(>its_lock);
+   return ret;
+}
+
 /*
  * Queries the KVM IO bus framework to get the ITS pointer from the given
  * doorbell address.
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index 0c8da72..d452150 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -240,6 +240,7 @@ int kvm_vgic_register_its_device(void);
 void vgic_enable_lpis(struct kvm_vcpu *vcpu);
 void vgic_flush_pending_lpis(struct kvm_vcpu *vcpu);
 int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
+int vgic_its_verify_msi(struct kvm *kvm, struct kvm_msi *msi);
 int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr 
*attr);
 int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
 int offset, u32 *val);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 32f259f..7923352 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1597,7 +1597,7 @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
 int kvm_request_irq_source_id(struct kvm *kvm);
 void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id);
 bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args);
-
+int kvm_verify_msi(struct kvm *kvm, struct kvm_msi *msi);
 /*
  * Returns a pointer to the memslot if it contains gfn.
  * Otherwise returns NULL.
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 0d5d441..72b28f8 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1543,6 +1543,8 @@ struct kvm_s390_ucas_mapping {
 #define KVM_PPC_SVM_OFF  _IO(KVMIO,  0xb3)
 #define KVM_ARM_MTE_COPY_TAGS_IOR(KVMIO,  0xb4, struct 
kvm_arm_copy_mte_tags)
 
+#define KVM_VERIFY_MSI_IOW(KVMIO,  0xb5, struct kvm_msi)
+
 /* ioctl for vm fd */
 #define KVM_CREATE_DEVICE_IOWR(KVMIO,  0xe0, struct kvm_create_device)
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index e30f1b4..439bdd7 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ 

Re: [PATCH v4 10/11] Hexagon (target/hexagon) Use direct block chaining for direct jump/branch

2022-11-07 Thread Richard Henderson

On 11/8/22 15:05, Taylor Simpson wrote:

  static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu)
  {
+DisasContext *ctx = container_of(db, DisasContext, base);
+ctx->branch_cond = TCG_COND_NEVER;
  }


Typically this would go in hexagon_tr_init_disas_context as well, but I don't suppose it 
really matters.



r~



Re: [PATCH v4 03/11] Hexagon (target/hexagon) Add overrides for S2_asr_r_r_sat/S2_asl_r_r_sat

2022-11-07 Thread Richard Henderson

On 11/8/22 15:05, Taylor Simpson wrote:

+/* Shift left with saturation */
+static void gen_shl_sat(TCGv dst, TCGv src, TCGv shift_amt)
+{
+TCGv_i64 src64 = tcg_temp_local_new_i64();
+TCGv_i64 shift64 = tcg_temp_new_i64();
+TCGv_i64 dst64 = tcg_temp_new_i64();
+TCGv dst_sar = tcg_temp_new();
+TCGv ovf = tcg_temp_new();
+TCGv satval = tcg_temp_new();
+TCGv min = tcg_constant_tl(0x8000);
+TCGv max = tcg_constant_tl(0x7fff);
+
+/*
+ * dst64 = (int64_t)src << (int64_t)shift_amt
+ * dst = (int32_t)dst64
+ * dst_sar = dst >> shift_amt
+ * if (dst_sar != src) {
+ * usr.OVF = 1
+ * dst = src < 0 ? min : max
+ * }
+ */
+tcg_gen_ext_i32_i64(src64, src);
+tcg_gen_ext_i32_i64(shift64, shift_amt);
+tcg_gen_shl_i64(dst64, src64, shift64);
+
+tcg_gen_extrl_i64_i32(dst, dst64);
+tcg_gen_sar_tl(dst_sar, dst, shift_amt);


I don't think this is quite right.  In particular:


+static void gen_asr_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV)
+{
+TCGv shift_amt = tcg_temp_local_new();
+TCGLabel *positive = gen_new_label();
+TCGLabel *done = gen_new_label();
+
+tcg_gen_sextract_i32(shift_amt, RtV, 0, 7);


This suggests shift amounts -64 ... 63.


+tcg_gen_brcondi_tl(TCG_COND_GE, shift_amt, 0, positive);
+
+/* Negative shift amount => shift left */
+tcg_gen_neg_tl(shift_amt, shift_amt);


-64 -> 64.

So!  We have two out-of-range shifts in gen_shl_sat, both i64 and i32.
If we fix one, then we don't even need the extension to i64 either.

Consider

/*
 * sh32 = shift & 31;
 * dst = sh32 == shift ? src : 0;
 * dst <<= sh32;
 * dst_sar = dst >> sh32;
 * if (dst_sar != src) ...
 */
tcg_gen_andi_i32(sh32, shift_amt, 31);
tcg_gen_movcond_i32(TCG_COND_EQ, dst,
sh32, shift_amt,
src, tcg_constant_i32(0));
tcg_gen_shl_i32(dst, dst, sh32);
tcg_gen_sar_i32(dst_sar, dst, sh32);


r~




Re: [PATCH v4 07/11] Hexagon (target/hexagon) Add overrides for direct call instructions

2022-11-07 Thread Richard Henderson

On 11/8/22 15:05, Taylor Simpson wrote:

Add overrides for
 J2_call
 J2_callt
 J2_callf

Signed-off-by: Taylor Simpson
---
  target/hexagon/gen_tcg.h |  8 ++
  target/hexagon/genptr.c  | 55 
  2 files changed, 63 insertions(+)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v9 4/8] KVM: Use gfn instead of hva for mmu_notifier_retry

2022-11-07 Thread Chao Peng
On Fri, Nov 04, 2022 at 10:29:48PM +, Sean Christopherson wrote:
> On Fri, Nov 04, 2022, Chao Peng wrote:
> > On Thu, Oct 27, 2022 at 11:29:14AM +0100, Fuad Tabba wrote:
> > > Hi,
> > > 
> > > On Tue, Oct 25, 2022 at 4:19 PM Chao Peng  
> > > wrote:
> > > >
> > > > Currently in mmu_notifier validate path, hva range is recorded and then
> > > > checked against in the mmu_notifier_retry_hva() of the page fault path.
> > > > However, for the to be introduced private memory, a page fault may not
> > > > have a hva associated, checking gfn(gpa) makes more sense.
> > > >
> > > > For existing non private memory case, gfn is expected to continue to
> > > > work. The only downside is when aliasing multiple gfns to a single hva,
> > > > the current algorithm of checking multiple ranges could result in a much
> > > > larger range being rejected. Such aliasing should be uncommon, so the
> > > > impact is expected small.
> > > >
> > > > It also fixes a bug in kvm_zap_gfn_range() which has already been using
> > > 
> > > nit: Now it's kvm_unmap_gfn_range().
> > 
> > Forgot to mention: the bug is still with kvm_zap_gfn_range(). It calls
> > kvm_mmu_invalidate_begin/end with a gfn range but before this series
> > kvm_mmu_invalidate_begin/end actually accept a hva range. Note it's
> > unrelated to whether we use kvm_zap_gfn_range() or kvm_unmap_gfn_range()
> > in the following patch (patch 05).
> 
> Grr, in the future, if you find an existing bug, please send a patch.  At the
> very least, report the bug.

Agreed, this can be sent out separately from this series.

> The APICv case that this was added for could very
> well be broken because of this, and the resulting failures would be an 
> absolute
> nightmare to debug.

Given the apicv_inhibit should be rare, the change looks good to me.
Just to be clear, your will send out this fix, right?

Chao

> 
> Compile tested only...
> 
> --
> From: Sean Christopherson 
> Date: Fri, 4 Nov 2022 22:20:33 +
> Subject: [PATCH] KVM: x86/mmu: Block all page faults during
>  kvm_zap_gfn_range()
> 
> When zapping a GFN range, pass 0 => ALL_ONES for the to-be-invalidated
> range to effectively block all page faults while the zap is in-progress.
> The invalidation helpers take a host virtual address, whereas zapping a
> GFN obviously provides a guest physical address and with the wrong unit
> of measurement (frame vs. byte).
> 
> Alternatively, KVM could walk all memslots to get the associated HVAs,
> but thanks to SMM, that would require multiple lookups.  And practically
> speaking, kvm_zap_gfn_range() usage is quite rare and not a hot path,
> e.g. MTRR and CR0.CD are almost guaranteed to be done only on vCPU0
> during boot, and APICv inhibits are similarly infrequent operations.
> 
> Fixes: edb298c663fc ("KVM: x86/mmu: bump mmu notifier count in 
> kvm_zap_gfn_range")
> Cc: sta...@vger.kernel.org
> Cc: Maxim Levitsky 
> Signed-off-by: Sean Christopherson 
> ---
>  arch/x86/kvm/mmu/mmu.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> index 6f81539061d6..1ccb769f62af 100644
> --- a/arch/x86/kvm/mmu/mmu.c
> +++ b/arch/x86/kvm/mmu/mmu.c
> @@ -6056,7 +6056,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t 
> gfn_start, gfn_t gfn_end)
>  
>   write_lock(>mmu_lock);
>  
> - kvm_mmu_invalidate_begin(kvm, gfn_start, gfn_end);
> + kvm_mmu_invalidate_begin(kvm, 0, -1ul);
>  
>   flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end);
>  
> @@ -6070,7 +6070,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t 
> gfn_start, gfn_t gfn_end)
>   kvm_flush_remote_tlbs_with_address(kvm, gfn_start,
>  gfn_end - gfn_start);
>  
> - kvm_mmu_invalidate_end(kvm, gfn_start, gfn_end);
> + kvm_mmu_invalidate_end(kvm, 0, -1ul);
>  
>   write_unlock(>mmu_lock);
>  }
> 
> base-commit: c12879206e47730ff5ab255bbf625b28ade4028f
> -- 



Re: [PULL v4 00/83] pci,pc,virtio: features, tests, fixes, cleanups

2022-11-07 Thread Michael S. Tsirkin
On Mon, Nov 07, 2022 at 05:47:16PM -0500, Michael S. Tsirkin wrote:
> Changes from v3:
> Applied and squashed fix by Ani for modular build breakage
> Reordered Julia's patches to avoid bisect breakage
> Checkpatch fixes for Jason's patches
> Added Alex's patch to partially address virtio is_started mess
> There is a bigger issue found by Christian A. Ehrhardt, that
> still needs work
> checkpatch change to avoid breaking on Jason's patches (to make ci pass)
> 
> Changes from v2:
> Fixed a bug in error handling in vhost: Change the sequence of device 
> start.
> Contributor placed on watchlist ;)
> Dropped virtio: re-order vm_running and use_started checks
> Due to failures detected by gitlab.
> We'll have to fix it differently.
> Updated expected files for core-count test to fix bisect.
> 
> Changes from v1
> Applied and squashed fixes by Igor, Lei He, Hesham Almatary for
> bugs that tripped up the pipeline.
> Updated expected files for core-count test.
> 
> 
> 
> The following changes since commit a11f65ec1b8adcb012b89c92819cbda4dc25aaf1:
> 
>   Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into 
> staging (2022-11-01 13:49:33 -0400)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream
> 
> for you to fetch changes up to 1ef47f40dce3d5b176ddf76d57b5bfa2efb0b3c6:

 5e75ffd664258d3d2fd3d27e92e2748024f53bca now - I found and fixed a typo in a 
comment in checkpatch and re-pushed


> 
>   checkpatch: better pattern for inline comments (2022-11-07 14:25:51 -0500)
> 
> 
> pci,pc,virtio: features, tests, fixes, cleanups
> 
> lots of acpi rework
> first version of biosbits infrastructure
> ASID support in vhost-vdpa
> core_count2 support in smbios
> PCIe DOE emulation
> virtio vq reset
> HMAT support
> part of infrastructure for viommu support in vhost-vdpa
> VTD PASID support
> fixes, tests all over the place
> 
> Signed-off-by: Michael S. Tsirkin 
> 
> 
> Akihiko Odaki (1):
>   msix: Assert that specified vector is in range
> 
> Alex Bennée (1):
>   hw/virtio: introduce virtio_device_should_start
> 
> Ani Sinha (7):
>   hw/i386/e820: remove legacy reserved entries for e820
>   acpi/tests/avocado/bits: initial commit of test scripts that are run by 
> biosbits
>   acpi/tests/avocado/bits: disable acpi PSS tests that are failing in 
> biosbits
>   acpi/tests/avocado/bits: add biosbits config file for running bios tests
>   acpi/tests/avocado/bits: add acpi and smbios avocado tests that uses 
> biosbits
>   acpi/tests/avocado/bits/doc: add a doc file to describe the acpi bits 
> test
>   MAINTAINERS: add myself as the maintainer for acpi biosbits avocado 
> tests
> 
> Bernhard Beschow (3):
>   hw/i386/acpi-build: Remove unused struct
>   hw/i386/acpi-build: Resolve redundant attribute
>   hw/i386/acpi-build: Resolve north rather than south bridges
> 
> Brice Goglin (4):
>   hmat acpi: Don't require initiator value in -numa
>   tests: acpi: add and whitelist *.hmat-noinitiator expected blobs
>   tests: acpi: q35: add test for hmat nodes without initiators
>   tests: acpi: q35: update expected blobs *.hmat-noinitiators expected 
> HMAT:
> 
> Christian A. Ehrhardt (1):
>   hw/acpi/erst.c: Fix memory handling issues
> 
> Cindy Lu (1):
>   vfio: move implement of vfio_get_xlat_addr() to memory.c
> 
> David Daney (1):
>   virtio-rng-pci: Allow setting nvectors, so we can use MSI-X
> 
> Eric Auger (1):
>   hw/virtio/virtio-iommu-pci: Enforce the device is plugged on the root 
> bus
> 
> Gregory Price (1):
>   hw/i386/pc.c: CXL Fixed Memory Window should not reserve e820 in bios
> 
> Hesham Almatary (3):
>   tests: Add HMAT AArch64/virt empty table files
>   tests: acpi: aarch64/virt: add a test for hmat nodes with no initiators
>   tests: virt: Update expected *.acpihmatvirt tables
> 
> Huai-Cheng Kuo (3):
>   hw/pci: PCIe Data Object Exchange emulation
>   hw/cxl/cdat: CXL CDAT Data Object Exchange implementation
>   hw/mem/cxl-type3: Add CXL CDAT Data Object Exchange
> 
> Igor Mammedov (11):
>   acpi: pc: vga: use AcpiDevAmlIf interface to build VGA device 
> descriptors
>   tests: acpi: whitelist DSDT before generating PCI-ISA bridge AML 
> automatically
>   acpi: pc/q35: drop ad-hoc PCI-ISA bridge AML routines and let bus 
> ennumeration generate AML
>   tests: acpi: update expected DSDT after ISA bridge is moved directly 
> under PCI host bridge
>   tests: acpi: whitelist DSDT before generating ICH9_SMB AML automatically
>   acpi: add get_dev_aml_func() helper
>   acpi: enumerate SMB bridge automatically along with other PCI devices
>   tests: acpi: update expected blobs
>   tests: 

[PATCH v3] checkpatch: better pattern for inline comments

2022-11-07 Thread Michael S. Tsirkin
checkpatch is unhappy about this line:

WARNING: Block comments use a leading /* on a separate line
#50: FILE: hw/acpi/nvdimm.c:1074:
+   aml_equal(aml_sizeof(pckg), aml_int(1)) /* 1 element? 
*/));

but there's nothing wrong with it - the check is just too simplistic. It
will also miss lines which mix inline and block comments.

Instead, let's strip all inline comments from a line and then check for block
comments.

Signed-off-by: Michael S. Tsirkin 
---

since v2:
fix typo in a comment

 scripts/checkpatch.pl | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index e3e3b43076..6ecabfb2b5 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1681,8 +1681,10 @@ sub process {
 # Block comment styles
 
# Block comments use /* on a line of its own
-   if ($rawline !~ m@^\+.*/\*.*\*/[ \t)}]*$@ &&#inline /*...*/
-   $rawline =~ m@^\+.*/\*\*?+[ \t]*[^ \t]@) { # /* or /** 
non-blank
+   my $commentline = $rawline;
+   while ($commentline =~ s@^(\+.*)/\*.*\*/@$1@o) { # remove 
inline /*...*/
+   }
+   if ($commentline =~ m@^\+.*/\*\*?+[ \t]*[^ \t]@) { # /* or /** 
non-blank
WARN("Block comments use a leading /* on a separate 
line\n" . $herecurr);
}
 
-- 
MST




[PATCH] LOCK GUARDS: replace manual lock()/unlock() calls to QEMU_LOCK_GUARD()

2022-11-07 Thread nyoro . gachu
From: Samker 

This is patch replaces WITH_QEMU_LOCK_GUARD() call with the
QEMU_LOCK_GUARD()

Signed-off-by: Samker 
---
 softmmu/physmem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/softmmu/physmem.c b/softmmu/physmem.c
index fb00596777..907491ae17 100644
--- a/softmmu/physmem.c
+++ b/softmmu/physmem.c
@@ -3115,7 +3115,7 @@ void cpu_register_map_client(QEMUBH *bh)
 {
 MapClient *client = g_malloc(sizeof(*client));
 
-WITH_QEMU_LOCK_GUARD(_client_list_lock);
+QEMU_LOCK_GUARD(_client_list_lock);
 client->bh = bh;
 QLIST_INSERT_HEAD(_client_list, client, link);
 if (!qatomic_read(_use)) {
@@ -3143,7 +3143,7 @@ void cpu_unregister_map_client(QEMUBH *bh)
 {
 MapClient *client;
 
-WITH_QEMU_LOCK_GUARD(_client_list_lock);
+QEMU_LOCK_GUARD(_client_list_lock);
 QLIST_FOREACH(client, _client_list, link) {
 if (client->bh == bh) {
 cpu_unregister_map_client_do(client);
-- 
2.25.1




[PULL 0/2] Net patches

2022-11-07 Thread Jason Wang
The following changes since commit 524fc737431d240f9d9f10aaf381003092868bac:

  util/log: Ignore per-thread flag if global file already there (2022-11-07 
16:00:02 -0500)

are available in the git repository at:

  https://github.com/jasowang/qemu.git tags/net-pull-request

for you to fetch changes up to fd2c87c7b0c97be2ac8d334885419f51f5963b51:

  tests/qtest: netdev: test stream and dgram backends (2022-11-08 12:10:26 
+0800)




Laurent Vivier (1):
  tests/qtest: netdev: test stream and dgram backends

Si-Wei Liu (1):
  vhost-vdpa: fix assert !virtio_net_get_subqueue(nc)->async_tx.elem in 
virtio_net_reset

 net/vhost-vdpa.c|   2 +-
 tests/qtest/meson.build |   2 +
 tests/qtest/netdev-socket.c | 435 
 3 files changed, 438 insertions(+), 1 deletion(-)
 create mode 100644 tests/qtest/netdev-socket.c





[PULL 2/2] tests/qtest: netdev: test stream and dgram backends

2022-11-07 Thread Jason Wang
From: Laurent Vivier 

Signed-off-by: Laurent Vivier 
Acked-by: Michael S. Tsirkin 
Signed-off-by: Jason Wang 
---
 tests/qtest/meson.build |   2 +
 tests/qtest/netdev-socket.c | 435 
 2 files changed, 437 insertions(+)
 create mode 100644 tests/qtest/netdev-socket.c

diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index c07a5b1..43d075b 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -27,6 +27,7 @@ qtests_generic = [
   'test-hmp',
   'qos-test',
   'readconfig-test',
+  'netdev-socket',
 ]
 if config_host.has_key('CONFIG_MODULES')
   qtests_generic += [ 'modules-test' ]
@@ -304,6 +305,7 @@ qtests = {
   'tpm-tis-device-swtpm-test': [io, tpmemu_files, 'tpm-tis-util.c'],
   'tpm-tis-device-test': [io, tpmemu_files, 'tpm-tis-util.c'],
   'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'),
+  'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
 }
 
 gvnc = dependency('gvnc-1.0', required: false)
diff --git a/tests/qtest/netdev-socket.c b/tests/qtest/netdev-socket.c
new file mode 100644
index 000..dd46214
--- /dev/null
+++ b/tests/qtest/netdev-socket.c
@@ -0,0 +1,435 @@
+/*
+ * QTest testcase for netdev stream and dgram
+ *
+ * Copyright (c) 2022 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include 
+#include "../unit/socket-helpers.h"
+#include "libqtest.h"
+
+#define CONNECTION_TIMEOUT5
+
+#define EXPECT_STATE(q, e, t) \
+do {  \
+char *resp = qtest_hmp(q, "info network");\
+if (t) {  \
+strrchr(resp, t)[0] = 0;  \
+} \
+g_test_timer_start(); \
+while (g_test_timer_elapsed() < CONNECTION_TIMEOUT) { \
+if (strcmp(resp, e) == 0) {   \
+break;\
+} \
+g_free(resp); \
+resp = qtest_hmp(q, "info network");  \
+if (t) {  \
+strrchr(resp, t)[0] = 0;  \
+} \
+} \
+g_assert_cmpstr(resp, ==, e); \
+g_free(resp); \
+} while (0)
+
+static char *tmpdir;
+
+static int inet_get_free_port_socket_ipv4(int sock)
+{
+struct sockaddr_in addr;
+socklen_t len;
+
+memset(, 0, sizeof(addr));
+addr.sin_family = AF_INET;
+addr.sin_addr.s_addr = INADDR_ANY;
+addr.sin_port = 0;
+if (bind(sock, (struct sockaddr *), sizeof(addr)) < 0) {
+return -1;
+}
+
+len = sizeof(addr);
+if (getsockname(sock,  (struct sockaddr *), ) < 0) {
+return -1;
+}
+
+return ntohs(addr.sin_port);
+}
+
+static int inet_get_free_port_socket_ipv6(int sock)
+{
+struct sockaddr_in6 addr;
+socklen_t len;
+
+memset(, 0, sizeof(addr));
+addr.sin6_family = AF_INET6;
+addr.sin6_addr = in6addr_any;
+addr.sin6_port = 0;
+if (bind(sock, (struct sockaddr *), sizeof(addr)) < 0) {
+return -1;
+}
+
+len = sizeof(addr);
+if (getsockname(sock,  (struct sockaddr *), ) < 0) {
+return -1;
+}
+
+return ntohs(addr.sin6_port);
+}
+
+static int inet_get_free_port_multiple(int nb, int *port, bool ipv6)
+{
+int sock[nb];
+int i;
+
+for (i = 0; i < nb; i++) {
+sock[i] = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0);
+if (sock[i] < 0) {
+break;
+}
+port[i] = ipv6 ? inet_get_free_port_socket_ipv6(sock[i]) :
+ inet_get_free_port_socket_ipv4(sock[i]);
+if (port[i] == -1) {
+break;
+}
+}
+
+nb = i;
+for (i = 0; i < nb; i++) {
+closesocket(sock[i]);
+}
+
+return nb;
+}
+
+static int inet_get_free_port(bool ipv6)
+{
+int nb, port;
+
+nb = inet_get_free_port_multiple(1, , ipv6);
+g_assert_cmpint(nb, ==, 1);
+
+return port;
+}
+
+static void test_stream_inet_ipv4(void)
+{
+QTestState *qts0, *qts1;
+char *expect;
+int port;
+
+port = inet_get_free_port(false);
+qts0 = qtest_initf("-nodefaults "
+   "-netdev stream,id=st0,server=true,addr.type=inet,"
+   "addr.ipv4=on,addr.ipv6=off,"
+   "addr.host=127.0.0.1,addr.port=%d", port);
+
+EXPECT_STATE(qts0, "st0: index=0,type=stream,\r\n", 0);
+
+qts1 = qtest_initf("-nodefaults "
+   "-netdev stream,server=false,id=st0,addr.type=inet,"
+   

[PULL 1/2] vhost-vdpa: fix assert !virtio_net_get_subqueue(nc)->async_tx.elem in virtio_net_reset

2022-11-07 Thread Jason Wang
From: Si-Wei Liu 

The citing commit has incorrect code in vhost_vdpa_receive() that returns
zero instead of full packet size to the caller. This renders pending packets
unable to be freed so then get clogged in the tx queue forever. When device
is being reset later on, below assertion failure ensues:

0  0x7f86d53bb387 in raise () from /lib64/libc.so.6
1  0x7f86d53bca78 in abort () from /lib64/libc.so.6
2  0x7f86d53b41a6 in __assert_fail_base () from /lib64/libc.so.6
3  0x7f86d53b4252 in __assert_fail () from /lib64/libc.so.6
4  0x55b8f6ff6fcc in virtio_net_reset (vdev=) at 
/usr/src/debug/qemu/hw/net/virtio-net.c:563
5  0x55b8f7012fcf in virtio_reset (opaque=0x55b8faf881f0) at 
/usr/src/debug/qemu/hw/virtio/virtio.c:1993
6  0x55b8f71f0086 in virtio_bus_reset (bus=bus@entry=0x55b8faf88178) at 
/usr/src/debug/qemu/hw/virtio/virtio-bus.c:102
7  0x55b8f71f1620 in virtio_pci_reset (qdev=) at 
/usr/src/debug/qemu/hw/virtio/virtio-pci.c:1845
8  0x55b8f6fafc6c in memory_region_write_accessor (mr=, 
addr=, value=,
   size=, shift=, mask=, 
attrs=...) at /usr/src/debug/qemu/memory.c:483
9  0x55b8f6fadce9 in access_with_adjusted_size (addr=addr@entry=20, 
value=value@entry=0x7f867e7fb7e8, size=size@entry=1,
   access_size_min=, access_size_max=, 
access_fn=0x55b8f6fafc20 ,
   mr=0x55b8faf80a50, attrs=...) at /usr/src/debug/qemu/memory.c:544
10 0x55b8f6fb1d0b in memory_region_dispatch_write 
(mr=mr@entry=0x55b8faf80a50, addr=addr@entry=20, data=0, op=,
   attrs=attrs@entry=...) at /usr/src/debug/qemu/memory.c:1470
11 0x55b8f6f62ada in flatview_write_continue (fv=fv@entry=0x7f86ac04cd20, 
addr=addr@entry=549755813908, attrs=...,
   attrs@entry=..., buf=buf@entry=0x7f86d0223028 , len=len@entry=1, addr1=20, l=1,
   mr=0x55b8faf80a50) at /usr/src/debug/qemu/exec.c:3266
12 0x55b8f6f62c8f in flatview_write (fv=0x7f86ac04cd20, addr=549755813908, 
attrs=...,
   buf=0x7f86d0223028 , len=1) at 
/usr/src/debug/qemu/exec.c:3306
13 0x55b8f6f674cb in address_space_write (as=, 
addr=, attrs=..., buf=,
   len=) at /usr/src/debug/qemu/exec.c:3396
14 0x55b8f6f67575 in address_space_rw (as=, addr=, attrs=..., attrs@entry=...,
   buf=buf@entry=0x7f86d0223028 , 
len=, is_write=)
   at /usr/src/debug/qemu/exec.c:3406
15 0x55b8f6fc1cc8 in kvm_cpu_exec (cpu=cpu@entry=0x55b8f9aa0e10) at 
/usr/src/debug/qemu/accel/kvm/kvm-all.c:2410
16 0x55b8f6fa5f5e in qemu_kvm_cpu_thread_fn (arg=0x55b8f9aa0e10) at 
/usr/src/debug/qemu/cpus.c:1318
17 0x55b8f7336e16 in qemu_thread_start (args=0x55b8f9ac8480) at 
/usr/src/debug/qemu/util/qemu-thread-posix.c:519
18 0x7f86d575aea5 in start_thread () from /lib64/libpthread.so.0
19 0x7f86d5483b2d in clone () from /lib64/libc.so.6

Make vhost_vdpa_receive() return the size passed in as is, so that the
caller qemu_deliver_packet_iov() would eventually propagate it back to
virtio_net_flush_tx() to release pending packets from the async_tx queue.
Which corresponds to the drop path where qemu_sendv_packet_async() returns
non-zero in virtio_net_flush_tx().

Fixes: 846a1e85da64 ("vdpa: Add dummy receive callback")
Cc: Eugenio Perez Martin 
Signed-off-by: Si-Wei Liu 
Signed-off-by: Jason Wang 
---
 net/vhost-vdpa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index e370ecb..6811089 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -210,7 +210,7 @@ static bool vhost_vdpa_check_peer_type(NetClientState *nc, 
ObjectClass *oc,
 static ssize_t vhost_vdpa_receive(NetClientState *nc, const uint8_t *buf,
   size_t size)
 {
-return 0;
+return size;
 }
 
 static NetClientInfo net_vhost_vdpa_info = {
-- 
2.7.4




[PATCH v4 06/11] Hexagon (target/hexagon) Remove next_PC from runtime state

2022-11-07 Thread Taylor Simpson
The imported files don't properly mark all CONDEXEC instructions, so
we add some logic to hex_common.py to add the attribute.

Acked-by: Richard Henderson 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/cpu.h|  1 -
 target/hexagon/gen_tcg.h|  6 ++
 target/hexagon/macros.h |  2 +-
 target/hexagon/translate.h  |  2 +-
 target/hexagon/op_helper.c  |  6 +++---
 target/hexagon/translate.c  | 29 +++--
 target/hexagon/gen_helper_funcs.py  |  4 
 target/hexagon/gen_helper_protos.py |  3 +++
 target/hexagon/gen_tcg_funcs.py |  3 +++
 target/hexagon/hex_common.py| 20 
 10 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 2a65a57bab..ff8c26272d 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -78,7 +78,6 @@ typedef struct CPUArchState {
 target_ulong gpr[TOTAL_PER_THREAD_REGS];
 target_ulong pred[NUM_PREGS];
 target_ulong branch_taken;
-target_ulong next_PC;
 
 /* For comparing with LLDB on target - see adjust_stack_ptrs function */
 target_ulong last_pc_dumped;
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index d38db72ce9..df279ab43b 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -612,6 +612,12 @@
 tcg_temp_free(tmp); \
 } while (0)
 
+#define fGEN_TCG_J2_pause(SHORTCODE) \
+do { \
+uiV = uiV; \
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->next_PC); \
+} while (0)
+
 /* r0 = asr(r1, r2):sat */
 #define fGEN_TCG_S2_asr_r_r_sat(SHORTCODE) \
 gen_asr_r_r_sat(RdV, RsV, RtV)
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 6e7a6a156a..903503540e 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -400,7 +400,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int 
shift)
 #endif
 #define fREAD_PC() (PC)
 
-#define fREAD_NPC() (env->next_PC & (0xfffe))
+#define fREAD_NPC() (next_PC & (0xfffe))
 
 #define fREAD_P0() (READ_PREG(0))
 #define fREAD_P3() (READ_PREG(3))
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index b8fcf615e8..96509a4da7 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -30,6 +30,7 @@ typedef struct DisasContext {
 DisasContextBase base;
 Packet *pkt;
 Insn *insn;
+uint32_t next_PC;
 uint32_t mem_idx;
 uint32_t num_packets;
 uint32_t num_insns;
@@ -134,7 +135,6 @@ static inline void ctx_log_qreg_write(DisasContext *ctx,
 
 extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
 extern TCGv hex_pred[NUM_PREGS];
-extern TCGv hex_next_PC;
 extern TCGv hex_this_PC;
 extern TCGv hex_slot_cancelled;
 extern TCGv hex_branch_taken;
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 84391e25eb..aad0195eb6 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -119,12 +119,12 @@ static void write_new_pc(CPUHexagonState *env, bool 
pkt_has_multi_cof,
   "ignoring the second one\n");
 } else {
 fCHECK_PCALIGN(addr);
-env->next_PC = addr;
+env->gpr[HEX_REG_PC] = addr;
 env->branch_taken = 1;
 }
 } else {
 fCHECK_PCALIGN(addr);
-env->next_PC = addr;
+env->gpr[HEX_REG_PC] = addr;
 }
 }
 
@@ -299,7 +299,7 @@ void HELPER(debug_commit_end)(CPUHexagonState *env, int 
has_st0, int has_st1)
 }
 }
 
-HEX_DEBUG_LOG("Next PC = " TARGET_FMT_lx "\n", env->next_PC);
+HEX_DEBUG_LOG("Next PC = " TARGET_FMT_lx "\n", env->gpr[HEX_REG_PC]);
 HEX_DEBUG_LOG("Exec counters: pkt = " TARGET_FMT_lx
   ", insn = " TARGET_FMT_lx
   ", hvx = " TARGET_FMT_lx "\n",
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 9efc6c88aa..fa6415936c 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -31,7 +31,6 @@
 
 TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
 TCGv hex_pred[NUM_PREGS];
-TCGv hex_next_PC;
 TCGv hex_this_PC;
 TCGv hex_slot_cancelled;
 TCGv hex_branch_taken;
@@ -120,7 +119,6 @@ static void gen_exec_counters(DisasContext *ctx)
 static void gen_end_tb(DisasContext *ctx)
 {
 gen_exec_counters(ctx);
-tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
 tcg_gen_exit_tb(NULL, 0);
 ctx->base.is_jmp = DISAS_NORETURN;
 }
@@ -128,7 +126,7 @@ static void gen_end_tb(DisasContext *ctx)
 static void gen_exception_end_tb(DisasContext *ctx, int excp)
 {
 gen_exec_counters(ctx);
-tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], hex_next_PC);
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->next_PC);
 gen_exception_raw(excp);
 ctx->base.is_jmp = DISAS_NORETURN;
 
@@ -204,6 +202,24 @@ static bool need_pred_written(Packet *pkt)
 return check_for_attrib(pkt, A_WRITES_PRED_REG);
 }
 
+static bool need_next_PC(DisasContext *ctx)
+{
+Packet *pkt = ctx->pkt;

[PATCH v4 04/11] Hexagon (target/hexagon) Only use branch_taken when packet has multi cof

2022-11-07 Thread Taylor Simpson
When a packet has more than one change-of-flow instruction, only the first
one to branch is considered.  We use the branch_taken variable to keep
track of this.

However, when there is a single cof instruction, we don't need the same
amount of bookkeeping.

We add the pkt_has_multi_cof member to the Packet structure, and pass this
information to the needed functions.

When there is a generated helper function with cof, the generator will
pass this pkt_has_multi_cof as a runtime value.

Acked-by: Richard Henderson 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/insn.h   |  1 +
 target/hexagon/macros.h |  2 +-
 target/hexagon/decode.c | 15 +--
 target/hexagon/op_helper.c  | 24 +++-
 target/hexagon/translate.c  |  4 +++-
 target/hexagon/gen_helper_funcs.py  |  5 -
 target/hexagon/gen_helper_protos.py |  8 ++--
 target/hexagon/gen_tcg_funcs.py |  5 +
 target/hexagon/hex_common.py|  3 +++
 9 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index cb92586802..775c4c183d 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -57,6 +57,7 @@ struct Packet {
 
 /* Pre-decodes about COF */
 bool pkt_has_cof;  /* Has any change-of-flow */
+bool pkt_has_multi_cof;/* Has more than one change-of-flow */
 bool pkt_has_endloop;
 
 bool pkt_has_dczeroa;
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 93ee4739a1..8fd8123cec 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -407,7 +407,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int 
shift)
 
 #define fCHECK_PCALIGN(A)
 
-#define fWRITE_NPC(A) write_new_pc(env, A)
+#define fWRITE_NPC(A) write_new_pc(env, pkt_has_multi_cof != 0, A)
 
 #define fBRANCH(LOC, TYPE)  fWRITE_NPC(LOC)
 #define fJUMPR(REGNO, TARGET, TYPE) fBRANCH(TARGET, COF_TYPE_JUMPR)
diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 6b73b5c60c..041c8de751 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -388,6 +388,7 @@ static void decode_set_insn_attr_fields(Packet *pkt)
 uint16_t opcode;
 
 pkt->pkt_has_cof = false;
+pkt->pkt_has_multi_cof = false;
 pkt->pkt_has_endloop = false;
 pkt->pkt_has_dczeroa = false;
 
@@ -412,13 +413,23 @@ static void decode_set_insn_attr_fields(Packet *pkt)
 }
 }
 
-pkt->pkt_has_cof |= decode_opcode_can_jump(opcode);
+if (decode_opcode_can_jump(opcode)) {
+if (pkt->pkt_has_cof) {
+pkt->pkt_has_multi_cof = true;
+}
+pkt->pkt_has_cof = true;
+}
 
 pkt->insn[i].is_endloop = decode_opcode_ends_loop(opcode);
 
 pkt->pkt_has_endloop |= pkt->insn[i].is_endloop;
 
-pkt->pkt_has_cof |= pkt->pkt_has_endloop;
+if (pkt->pkt_has_endloop) {
+if (pkt->pkt_has_cof) {
+pkt->pkt_has_multi_cof = true;
+}
+pkt->pkt_has_cof = true;
+}
 }
 }
 
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 085afc3274..84391e25eb 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -104,20 +104,26 @@ static void log_store64(CPUHexagonState *env, 
target_ulong addr,
 env->mem_log_stores[slot].data64 = val;
 }
 
-static void write_new_pc(CPUHexagonState *env, target_ulong addr)
+static void write_new_pc(CPUHexagonState *env, bool pkt_has_multi_cof,
+ target_ulong addr)
 {
 HEX_DEBUG_LOG("write_new_pc(0x" TARGET_FMT_lx ")\n", addr);
 
-/*
- * If more than one branch is taken in a packet, only the first one
- * is actually done.
- */
-if (env->branch_taken) {
-HEX_DEBUG_LOG("INFO: multiple branches taken in same packet, "
-  "ignoring the second one\n");
+if (pkt_has_multi_cof) {
+/*
+ * If more than one branch is taken in a packet, only the first one
+ * is actually done.
+ */
+if (env->branch_taken) {
+HEX_DEBUG_LOG("INFO: multiple branches taken in same packet, "
+  "ignoring the second one\n");
+} else {
+fCHECK_PCALIGN(addr);
+env->next_PC = addr;
+env->branch_taken = 1;
+}
 } else {
 fCHECK_PCALIGN(addr);
-env->branch_taken = 1;
 env->next_PC = addr;
 }
 }
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 0940d0f2c1..1d872d72b6 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -248,7 +248,9 @@ static void gen_start_packet(DisasContext *ctx)
 tcg_gen_movi_tl(hex_slot_cancelled, 0);
 }
 if (pkt->pkt_has_cof) {
-tcg_gen_movi_tl(hex_branch_taken, 0);
+if (pkt->pkt_has_multi_cof) {
+tcg_gen_movi_tl(hex_branch_taken, 0);
+  

[PATCH v4 02/11] Hexagon (target/hexagon) Fix predicated assignment to .tmp and .cur

2022-11-07 Thread Taylor Simpson
Here are example instructions with a predicated .tmp/.cur assignment
if (p1) v12.tmp = vmem(r7 + #0)
if (p0) v12.cur = vmem(r9 + #0)
The .tmp/.cur indicates that references to v12 in the same packet
take the result of the load.  However, when the predicate is false,
the value at the start of the packet should be used.  After the packet
commits, the .tmp value is dropped, but the .cur value is maintained.

To fix this bug, we preload the original value from the HVX register
into the temporary used for the result.

Test cases added to tests/tcg/hexagon/hvx_misc.c

Acked-by: Richard Henderson 
Co-authored-by: Matheus Tavares Bernardino 
Signed-off-by: Matheus Tavares Bernardino 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/translate.h  |  6 +++
 tests/tcg/hexagon/hvx_misc.c| 72 +
 target/hexagon/gen_tcg_funcs.py | 12 ++
 3 files changed, 90 insertions(+)

diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 115e29b84f..b8fcf615e8 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -86,6 +86,12 @@ static inline bool is_preloaded(DisasContext *ctx, int num)
 return test_bit(num, ctx->regs_written);
 }
 
+static inline bool is_vreg_preloaded(DisasContext *ctx, int num)
+{
+return test_bit(num, ctx->vregs_updated) ||
+   test_bit(num, ctx->vregs_updated_tmp);
+}
+
 intptr_t ctx_future_vreg_off(DisasContext *ctx, int regnum,
  int num, bool alloc_ok);
 intptr_t ctx_tmp_vreg_off(DisasContext *ctx, int regnum,
diff --git a/tests/tcg/hexagon/hvx_misc.c b/tests/tcg/hexagon/hvx_misc.c
index 6e2c9ab3cd..53d5c9b44f 100644
--- a/tests/tcg/hexagon/hvx_misc.c
+++ b/tests/tcg/hexagon/hvx_misc.c
@@ -541,6 +541,75 @@ static void test_vshuff(void)
 check_output_b(__LINE__, 1);
 }
 
+static void test_load_tmp_predicated(void)
+{
+void *p0 = buffer0;
+void *p1 = buffer1;
+void *pout = output;
+bool pred = true;
+
+for (int i = 0; i < BUFSIZE; i++) {
+/*
+ * Load into v12 as .tmp with a predicate
+ * When the predicate is true, we get the vector from buffer1[i]
+ * When the predicate is false, we get a vector of all 1's
+ * Regardless of the predicate, the next packet should have
+ * a vector of all 1's
+ */
+asm("v3 = vmem(%0 + #0)\n\t"
+"r1 = #1\n\t"
+"v12 = vsplat(r1)\n\t"
+"p1 = !cmp.eq(%3, #0)\n\t"
+"{\n\t"
+"if (p1) v12.tmp = vmem(%1 + #0)\n\t"
+"v4.w = vadd(v12.w, v3.w)\n\t"
+"}\n\t"
+"v4.w = vadd(v4.w, v12.w)\n\t"
+"vmem(%2 + #0) = v4\n\t"
+: : "r"(p0), "r"(p1), "r"(pout), "r"(pred)
+: "r1", "p1", "v12", "v3", "v4", "v6", "memory");
+p0 += sizeof(MMVector);
+p1 += sizeof(MMVector);
+pout += sizeof(MMVector);
+
+for (int j = 0; j < MAX_VEC_SIZE_BYTES / 4; j++) {
+expect[i].w[j] =
+pred ? buffer0[i].w[j] + buffer1[i].w[j] + 1
+ : buffer0[i].w[j] + 2;
+}
+pred = !pred;
+}
+
+check_output_w(__LINE__, BUFSIZE);
+}
+
+static void test_load_cur_predicated(void)
+{
+bool pred = true;
+for (int i = 0; i < BUFSIZE; i++) {
+asm volatile("p0 = !cmp.eq(%3, #0)\n\t"
+ "v3 = vmem(%0+#0)\n\t"
+ /*
+  * Preload v4 to make sure that the assignment from the
+  * packet below is not being ignored when pred is false.
+  */
+ "r0 = #0x01237654\n\t"
+ "v4 = vsplat(r0)\n\t"
+ "{\n\t"
+ "if (p0) v3.cur = vmem(%1+#0)\n\t"
+ "v4 = v3\n\t"
+ "}\n\t"
+ "vmem(%2+#0) = v4\n\t"
+ :
+ : "r"([i]), "r"([i]),
+   "r"([i]), "r"(pred)
+ : "r0", "p0", "v3", "v4", "memory");
+expect[i] = pred ? buffer1[i] : buffer0[i];
+pred = !pred;
+}
+check_output_w(__LINE__, BUFSIZE);
+}
+
 int main()
 {
 init_buffers();
@@ -578,6 +647,9 @@ int main()
 
 test_vshuff();
 
+test_load_tmp_predicated();
+test_load_cur_predicated();
+
 puts(err ? "FAIL" : "PASS");
 return err ? 1 : 0;
 }
diff --git a/target/hexagon/gen_tcg_funcs.py b/target/hexagon/gen_tcg_funcs.py
index 02a6565685..ca5fde91cc 100755
--- a/target/hexagon/gen_tcg_funcs.py
+++ b/target/hexagon/gen_tcg_funcs.py
@@ -173,6 +173,18 @@ def genptr_decl(f, tag, regtype, regid, regno):
 f.write("ctx_future_vreg_off(ctx, %s%sN," % \
 (regtype, regid))
 f.write(" 1, true);\n");
+if 'A_CONDEXEC' in hex_common.attribdict[tag]:
+f.write("if (!is_vreg_preloaded(ctx, %s)) {\n" % 

[PATCH v4 05/11] Hexagon (target/hexagon) Remove PC from the runtime state

2022-11-07 Thread Taylor Simpson
Add pc field to Packet structure
For helpers that need PC, pass an extra argument
Remove slot arg from conditional jump helpers
On a trap0, copy pkt->pc into hex_gpr[HEX_REG_PC]

Reviewed-by: Richard Henderson 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h| 7 +++
 target/hexagon/insn.h   | 1 +
 target/hexagon/macros.h | 2 +-
 target/hexagon/translate.c  | 9 +
 target/hexagon/gen_helper_funcs.py  | 4 
 target/hexagon/gen_helper_protos.py | 3 +++
 target/hexagon/gen_tcg_funcs.py | 3 +++
 target/hexagon/hex_common.py| 6 +-
 8 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index b5fe22a07a..d38db72ce9 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -750,4 +750,11 @@
 RsV = RsV; \
 } while (0)
 
+#define fGEN_TCG_J2_trap0(SHORTCODE) \
+do { \
+uiV = uiV; \
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->pkt->pc); \
+TCGv excp = tcg_constant_tl(HEX_EXCP_TRAP0); \
+gen_helper_raise_exception(cpu_env, excp); \
+} while (0)
 #endif
diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index 775c4c183d..3e7a22c91e 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -54,6 +54,7 @@ typedef struct Instruction Insn;
 struct Packet {
 uint16_t num_insns;
 uint16_t encod_pkt_size_in_bytes;
+uint32_t pc;
 
 /* Pre-decodes about COF */
 bool pkt_has_cof;  /* Has any change-of-flow */
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 8fd8123cec..6e7a6a156a 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -398,7 +398,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int 
shift)
 #else
 #define fREAD_GP() READ_REG(HEX_REG_GP)
 #endif
-#define fREAD_PC() (READ_REG(HEX_REG_PC))
+#define fREAD_PC() (PC)
 
 #define fREAD_NPC() (env->next_PC & (0xfffe))
 
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 1d872d72b6..9efc6c88aa 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -194,11 +194,6 @@ static bool check_for_attrib(Packet *pkt, int attrib)
 return false;
 }
 
-static bool need_pc(Packet *pkt)
-{
-return check_for_attrib(pkt, A_IMPLICIT_READS_PC);
-}
-
 static bool need_slot_cancelled(Packet *pkt)
 {
 return check_for_attrib(pkt, A_CONDEXEC);
@@ -241,9 +236,6 @@ static void gen_start_packet(DisasContext *ctx)
 }
 
 /* Initialize the runtime state for packet semantics */
-if (need_pc(pkt)) {
-tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->base.pc_next);
-}
 if (need_slot_cancelled(pkt)) {
 tcg_gen_movi_tl(hex_slot_cancelled, 0);
 }
@@ -772,6 +764,7 @@ static void decode_and_translate_packet(CPUHexagonState 
*env, DisasContext *ctx)
 }
 
 if (decode_packet(nwords, words, , false) > 0) {
+pkt.pc = ctx->base.pc_next;
 HEX_DEBUG_PRINT_PKT();
 ctx->pkt = 
 gen_start_packet(ctx);
diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index c4fc609b31..024f70d166 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -241,6 +241,10 @@ def gen_helper_function(f, tag, tagregs, tagimms):
 if (hex_common.need_pkt_has_multi_cof(tag)):
 f.write(", uint32_t pkt_has_multi_cof")
 
+if hex_common.need_PC(tag):
+if i > 0: f.write(", ")
+f.write("target_ulong PC")
+i += 1
 if hex_common.need_slot(tag):
 if i > 0: f.write(", ")
 f.write("uint32_t slot")
diff --git a/target/hexagon/gen_helper_protos.py 
b/target/hexagon/gen_helper_protos.py
index 8c6b36d8d8..00c48dff7c 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -85,6 +85,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
 if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1
 if hex_common.need_part1(tag): def_helper_size += 1
 if hex_common.need_slot(tag): def_helper_size += 1
+if hex_common.need_PC(tag): def_helper_size += 1
 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
 ## The return type is void
 f.write(', void' )
@@ -93,6 +94,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
 if hex_common.need_pkt_has_multi_cof(tag): def_helper_size += 1
 if hex_common.need_part1(tag): def_helper_size += 1
 if hex_common.need_slot(tag): def_helper_size += 1
+if hex_common.need_PC(tag): def_helper_size += 1
 f.write('DEF_HELPER_%s(%s' % (def_helper_size, tag))
 
 ## Generate the qemu DEF_HELPER type for each result
@@ -131,6 +133,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
 ## Add the arguments for the instruction pkt_has_multi_cof, 

[PATCH v4 01/11] Hexagon (target/hexagon) Add pkt and insn to DisasContext

2022-11-07 Thread Taylor Simpson
This enables us to reduce the number of parameters to many functions
In particular, the generated functions previously took all 3 as arguments

Not only does this simplify the code, it improves the translation time

Reviewed-by: Richard Henderson 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg_hvx.h|   6 +-
 target/hexagon/insn.h   |   7 +-
 target/hexagon/macros.h |  10 +--
 target/hexagon/mmvec/macros.h   |   4 +-
 target/hexagon/translate.h  |   9 ++-
 target/hexagon/genptr.c |   6 +-
 target/hexagon/translate.c  | 120 +---
 target/hexagon/gen_tcg_funcs.py |  15 ++--
 8 files changed, 89 insertions(+), 88 deletions(-)

diff --git a/target/hexagon/gen_tcg_hvx.h b/target/hexagon/gen_tcg_hvx.h
index cdcc9382bb..083f4d92c6 100644
--- a/target/hexagon/gen_tcg_hvx.h
+++ b/target/hexagon/gen_tcg_hvx.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  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
@@ -697,7 +697,7 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 #define fGEN_TCG_NEWVAL_VEC_STORE(GET_EA, INC) \
 do { \
 GET_EA; \
-gen_vreg_store(ctx, insn, pkt, EA, OsN_off, insn->slot, true); \
+gen_vreg_store(ctx, EA, OsN_off, insn->slot, true); \
 INC; \
 } while (0)
 
@@ -736,7 +736,7 @@ static inline void assert_vhist_tmp(DisasContext *ctx)
 PRED; \
 tcg_gen_brcondi_tl(TCG_COND_EQ, LSB, 0, false_label); \
 tcg_temp_free(LSB); \
-gen_vreg_store(ctx, insn, pkt, EA, SRCOFF, insn->slot, ALIGN); \
+gen_vreg_store(ctx, EA, SRCOFF, insn->slot, ALIGN); \
 INC; \
 tcg_gen_br(end_label); \
 gen_set_label(false_label); \
diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index aa26389147..cb92586802 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  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
@@ -28,10 +28,7 @@ struct Instruction;
 struct Packet;
 struct DisasContext;
 
-typedef void (*SemanticInsn)(CPUHexagonState *env,
- struct DisasContext *ctx,
- struct Instruction *insn,
- struct Packet *pkt);
+typedef void (*SemanticInsn)(struct DisasContext *ctx);
 
 struct Instruction {
 SemanticInsn generate;/* pointer to genptr routine */
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index c8805bdaeb..93ee4739a1 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -94,9 +94,9 @@
  */
 #define CHECK_NOSHUF(VA, SIZE) \
 do { \
-if (insn->slot == 0 && pkt->pkt_has_store_s1) { \
+if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
 probe_noshuf_load(VA, SIZE, ctx->mem_idx); \
-process_store(ctx, pkt, 1); \
+process_store(ctx, 1); \
 } \
 } while (0)
 
@@ -105,12 +105,12 @@
 TCGLabel *label = gen_new_label(); \
 tcg_gen_brcondi_tl(TCG_COND_EQ, PRED, 0, label); \
 GET_EA; \
-if (insn->slot == 0 && pkt->pkt_has_store_s1) { \
+if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
 probe_noshuf_load(EA, SIZE, ctx->mem_idx); \
 } \
 gen_set_label(label); \
-if (insn->slot == 0 && pkt->pkt_has_store_s1) { \
-process_store(ctx, pkt, 1); \
+if (insn->slot == 0 && ctx->pkt->pkt_has_store_s1) { \
+process_store(ctx, 1); \
 } \
 } while (0)
 
diff --git a/target/hexagon/mmvec/macros.h b/target/hexagon/mmvec/macros.h
index 8345753580..8c864e8c68 100644
--- a/target/hexagon/mmvec/macros.h
+++ b/target/hexagon/mmvec/macros.h
@@ -288,7 +288,7 @@
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMV(EA, SRC) \
-gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, true)
+gen_vreg_store(ctx, EA, SRC##_off, insn->slot, true)
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMVQ(EA, SRC, MASK) \
@@ -300,7 +300,7 @@
 #endif
 #ifdef QEMU_GENERATE
 #define fSTOREMMVU(EA, SRC) \
-gen_vreg_store(ctx, insn, pkt, EA, SRC##_off, insn->slot, false)
+gen_vreg_store(ctx, EA, SRC##_off, insn->slot, false)
 #endif
 #define fVFOREACH(WIDTH, VAR) for (VAR = 0; VAR < fVELEM(WIDTH); VAR++)
 #define fVARRAY_ELEMENT_ACCESS(ARRAY, TYPE, INDEX) \
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index a245172827..115e29b84f 100644
--- a/target/hexagon/translate.h
+++ 

[PATCH v4 07/11] Hexagon (target/hexagon) Add overrides for direct call instructions

2022-11-07 Thread Taylor Simpson
Add overrides for
J2_call
J2_callt
J2_callf

Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h |  8 ++
 target/hexagon/genptr.c  | 55 
 2 files changed, 63 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index df279ab43b..1bdc787a02 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -612,6 +612,14 @@
 tcg_temp_free(tmp); \
 } while (0)
 
+#define fGEN_TCG_J2_call(SHORTCODE) \
+gen_call(ctx, riV)
+
+#define fGEN_TCG_J2_callt(SHORTCODE) \
+gen_cond_call(ctx, PuV, TCG_COND_EQ, riV)
+#define fGEN_TCG_J2_callf(SHORTCODE) \
+gen_cond_call(ctx, PuV, TCG_COND_NE, riV)
+
 #define fGEN_TCG_J2_pause(SHORTCODE) \
 do { \
 uiV = uiV; \
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index ccfed9d643..ffaea5a639 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -456,6 +456,61 @@ static TCGv gen_8bitsof(TCGv result, TCGv value)
 return result;
 }
 
+static void gen_write_new_pc_addr(DisasContext *ctx, TCGv addr,
+  TCGCond cond, TCGv pred)
+{
+TCGLabel *pred_false = NULL;
+if (cond != TCG_COND_ALWAYS) {
+pred_false = gen_new_label();
+tcg_gen_brcondi_tl(cond, pred, 0, pred_false);
+}
+
+if (ctx->pkt->pkt_has_multi_cof) {
+/* If there are multiple branches in a packet, ignore the second one */
+tcg_gen_movcond_tl(TCG_COND_NE, hex_gpr[HEX_REG_PC],
+   hex_branch_taken, tcg_constant_tl(0),
+   hex_gpr[HEX_REG_PC], addr);
+tcg_gen_movi_tl(hex_branch_taken, 1);
+} else {
+tcg_gen_mov_tl(hex_gpr[HEX_REG_PC], addr);
+}
+
+if (cond != TCG_COND_ALWAYS) {
+gen_set_label(pred_false);
+}
+}
+
+static void gen_write_new_pc_pcrel(DisasContext *ctx, int pc_off,
+   TCGCond cond, TCGv pred)
+{
+target_ulong dest = ctx->pkt->pc + pc_off;
+gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), cond, pred);
+}
+
+static void gen_call(DisasContext *ctx, int pc_off)
+{
+TCGv next_PC =
+tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes);
+gen_log_reg_write(HEX_REG_LR, next_PC);
+gen_write_new_pc_pcrel(ctx, pc_off, TCG_COND_ALWAYS, NULL);
+}
+
+static void gen_cond_call(DisasContext *ctx, TCGv pred,
+  TCGCond cond, int pc_off)
+{
+TCGv next_PC;
+TCGv lsb = tcg_temp_local_new();
+TCGLabel *skip = gen_new_label();
+tcg_gen_andi_tl(lsb, pred, 1);
+gen_write_new_pc_pcrel(ctx, pc_off, cond, lsb);
+tcg_gen_brcondi_tl(cond, lsb, 0, skip);
+tcg_temp_free(lsb);
+next_PC =
+tcg_constant_tl(ctx->pkt->pc + ctx->pkt->encod_pkt_size_in_bytes);
+gen_log_reg_write(HEX_REG_LR, next_PC);
+gen_set_label(skip);
+}
+
 /* Shift left with saturation */
 static void gen_shl_sat(TCGv dst, TCGv src, TCGv shift_amt)
 {
-- 
2.17.1



[PATCH v4 10/11] Hexagon (target/hexagon) Use direct block chaining for direct jump/branch

2022-11-07 Thread Taylor Simpson
Direct block chaining is documented here
https://qemu.readthedocs.io/en/latest/devel/tcg.html#direct-block-chaining

Recall that Hexagon allows packets with multiple jumps where only the
first one with a true predicate will actually jump.  We can  use
tcg_gen_goto_tb/tcg_gen_exit_tb when the packet contains a single
PC-relative branch or jump.  If not, we use tcg_gen_lookup_and_goto_ptr.

We add the following to DisasContext in order to delay the branching
until the end of packet commit (in gen_end_tb)
branch_cond
The TCGCond condition under which the branch is taken
When branch_cond == TCG_COND_NEVER, there isn't a single
direct branch in this packet.
When branch_cond != TCG_COND_ALWAYS, the value is in
hex_branch_taken
branch_dest
The destination of the branch

Reviewed-by: Richard Henderson 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/translate.h |  2 ++
 target/hexagon/genptr.c| 12 +++-
 target/hexagon/translate.c | 35 ++-
 3 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 96509a4da7..aacf0b0921 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -57,6 +57,8 @@ typedef struct DisasContext {
 bool qreg_is_predicated[NUM_QREGS];
 int qreg_log_idx;
 bool pre_commit;
+TCGCond branch_cond;
+target_ulong branch_dest;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index b8808ae17a..584e6415c0 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -484,7 +484,17 @@ static void gen_write_new_pc_pcrel(DisasContext *ctx, int 
pc_off,
TCGCond cond, TCGv pred)
 {
 target_ulong dest = ctx->pkt->pc + pc_off;
-gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), cond, pred);
+if (ctx->pkt->pkt_has_multi_cof) {
+gen_write_new_pc_addr(ctx, tcg_constant_tl(dest), cond, pred);
+} else {
+/* Defer this jump to the end of the TB */
+ctx->branch_cond = TCG_COND_ALWAYS;
+if (pred != NULL) {
+ctx->branch_cond = cond;
+tcg_gen_mov_tl(hex_branch_taken, pred);
+}
+ctx->branch_dest = dest;
+}
 }
 
 static void gen_compare(TCGCond cond, TCGv res, TCGv arg1, TCGv arg2)
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index fa6415936c..8e5814a3ea 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -116,10 +116,41 @@ static void gen_exec_counters(DisasContext *ctx)
 hex_gpr[HEX_REG_QEMU_HVX_CNT], ctx->num_hvx_insns);
 }
 
+static bool use_goto_tb(DisasContext *ctx, target_ulong dest)
+{
+return translator_use_goto_tb(>base, dest);
+}
+
+static void gen_goto_tb(DisasContext *ctx, int idx, target_ulong dest)
+{
+if (use_goto_tb(ctx, dest)) {
+tcg_gen_goto_tb(idx);
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], dest);
+tcg_gen_exit_tb(ctx->base.tb, idx);
+} else {
+tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], dest);
+tcg_gen_lookup_and_goto_ptr();
+}
+}
+
 static void gen_end_tb(DisasContext *ctx)
 {
 gen_exec_counters(ctx);
-tcg_gen_exit_tb(NULL, 0);
+
+if (ctx->branch_cond != TCG_COND_NEVER) {
+if (ctx->branch_cond != TCG_COND_ALWAYS) {
+TCGLabel *skip = gen_new_label();
+tcg_gen_brcondi_tl(ctx->branch_cond, hex_branch_taken, 0, skip);
+gen_goto_tb(ctx, 0, ctx->branch_dest);
+gen_set_label(skip);
+gen_goto_tb(ctx, 1, ctx->next_PC);
+} else {
+gen_goto_tb(ctx, 0, ctx->branch_dest);
+}
+} else {
+tcg_gen_lookup_and_goto_ptr();
+}
+
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
@@ -811,6 +842,8 @@ static void hexagon_tr_init_disas_context(DisasContextBase 
*dcbase,
 
 static void hexagon_tr_tb_start(DisasContextBase *db, CPUState *cpu)
 {
+DisasContext *ctx = container_of(db, DisasContext, base);
+ctx->branch_cond = TCG_COND_NEVER;
 }
 
 static void hexagon_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
-- 
2.17.1



[PATCH v4 08/11] Hexagon (target/hexagon) Add overrides for compound compare and jump

2022-11-07 Thread Taylor Simpson
Acked-by: Richard Henderson 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h | 177 +++
 target/hexagon/genptr.c  |  90 
 2 files changed, 267 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 1bdc787a02..506b454e4e 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -620,6 +620,183 @@
 #define fGEN_TCG_J2_callf(SHORTCODE) \
 gen_cond_call(ctx, PuV, TCG_COND_NE, riV)
 
+/*
+ * Compound compare and jump instructions
+ * Here is a primer to understand the tag names
+ *
+ * Comparison
+ *  cmpeqi   compare equal to an immediate
+ *  cmpgti   compare greater than an immediate
+ *  cmpgtiu  compare greater than an unsigned immediate
+ *  cmpeqn1  compare equal to negative 1
+ *  cmpgtn1  compare greater than negative 1
+ *  cmpeqcompare equal (two registers)
+ *  cmpgtu   compare greater than unsigned (two registers)
+ *  tstbit0  test bit zero
+ *
+ * Condition
+ *  tp0  p0 is true p0 = cmp.eq(r0,#5); if (p0.new) jump:nt address
+ *  fp0  p0 is falsep0 = cmp.eq(r0,#5); if (!p0.new) jump:nt 
address
+ *  tp1  p1 is true p1 = cmp.eq(r0,#5); if (p1.new) jump:nt address
+ *  fp1  p1 is falsep1 = cmp.eq(r0,#5); if (!p1.new) jump:nt 
address
+ *
+ * Prediction (not modelled in qemu)
+ *  _nt  not taken
+ *  _t   taken
+ */
+#define fGEN_TCG_J4_cmpeq_tp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_EQ, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_tp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_EQ, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_fp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_EQ, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_fp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_EQ, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_tp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_EQ, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_tp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_EQ, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_fp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_EQ, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_fp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_EQ, RsV, RtV, riV)
+
+#define fGEN_TCG_J4_cmpgt_tp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_GT, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_tp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_GT, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_fp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_GT, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_fp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_GT, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_tp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_GT, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_tp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_GT, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_fp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_GT, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_fp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_GT, RsV, RtV, riV)
+
+#define fGEN_TCG_J4_cmpgtu_tp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_GTU, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_tp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 0, TCG_COND_GTU, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_fp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_GTU, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_fp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 0, TCG_COND_GTU, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_tp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_GTU, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_tp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_t(ctx, 1, TCG_COND_GTU, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_fp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_GTU, RsV, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_fp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmp_jmp_f(ctx, 1, TCG_COND_GTU, RsV, RtV, riV)
+
+#define fGEN_TCG_J4_cmpeqi_tp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmpi_jmp_t(ctx, 0, TCG_COND_EQ, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_tp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmpi_jmp_t(ctx, 0, TCG_COND_EQ, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_fp0_jump_t(SHORTCODE) \
+gen_cmpnd_cmpi_jmp_f(ctx, 0, TCG_COND_EQ, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_fp0_jump_nt(SHORTCODE) \
+gen_cmpnd_cmpi_jmp_f(ctx, 0, TCG_COND_EQ, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_tp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmpi_jmp_t(ctx, 1, TCG_COND_EQ, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_tp1_jump_nt(SHORTCODE) \
+gen_cmpnd_cmpi_jmp_t(ctx, 1, TCG_COND_EQ, RsV, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_fp1_jump_t(SHORTCODE) \
+gen_cmpnd_cmpi_jmp_f(ctx, 1, TCG_COND_EQ, RsV, UiV, riV)
+#define 

[PATCH v4 09/11] Hexagon (target/hexagon) Add overrides for various forms of jump

2022-11-07 Thread Taylor Simpson
Reviewed-by: Richard Henderson 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h | 203 +++
 target/hexagon/genptr.c  |  43 +
 2 files changed, 246 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 506b454e4e..17431403a9 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -797,6 +797,209 @@
 #define fGEN_TCG_J4_tstbit0_fp1_jump_t(SHORTCODE) \
 gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_NE, riV)
 
+#define fGEN_TCG_J2_jump(SHORTCODE) \
+gen_jump(ctx, riV)
+#define fGEN_TCG_J2_jumpr(SHORTCODE) \
+gen_jumpr(ctx, RsV)
+#define fGEN_TCG_J4_jumpseti(SHORTCODE) \
+do { \
+tcg_gen_movi_tl(RdV, UiV); \
+gen_jump(ctx, riV); \
+} while (0)
+
+#define fGEN_TCG_cond_jumpt(COND) \
+do { \
+TCGv LSB = tcg_temp_new(); \
+COND; \
+gen_cond_jump(ctx, TCG_COND_EQ, LSB, riV); \
+tcg_temp_free(LSB); \
+} while (0)
+#define fGEN_TCG_cond_jumpf(COND) \
+do { \
+TCGv LSB = tcg_temp_new(); \
+COND; \
+gen_cond_jump(ctx, TCG_COND_NE, LSB, riV); \
+tcg_temp_free(LSB); \
+} while (0)
+
+#define fGEN_TCG_J2_jumpt(SHORTCODE) \
+fGEN_TCG_cond_jumpt(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumptpt(SHORTCODE) \
+fGEN_TCG_cond_jumpt(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumpf(SHORTCODE) \
+fGEN_TCG_cond_jumpf(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumpfpt(SHORTCODE) \
+fGEN_TCG_cond_jumpf(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumptnew(SHORTCODE) \
+gen_cond_jump(ctx, TCG_COND_EQ, PuN, riV)
+#define fGEN_TCG_J2_jumptnewpt(SHORTCODE) \
+gen_cond_jump(ctx, TCG_COND_EQ, PuN, riV)
+#define fGEN_TCG_J2_jumpfnewpt(SHORTCODE) \
+fGEN_TCG_cond_jumpf(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumpfnew(SHORTCODE) \
+fGEN_TCG_cond_jumpf(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprz(SHORTCODE) \
+fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_NE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprzpt(SHORTCODE) \
+fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_NE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprnz(SHORTCODE) \
+fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_EQ, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprnzpt(SHORTCODE) \
+fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_EQ, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprgtez(SHORTCODE) \
+fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_GE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprgtezpt(SHORTCODE) \
+fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_GE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprltez(SHORTCODE) \
+fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_LE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprltezpt(SHORTCODE) \
+fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_LE, LSB, RsV, 0))
+
+#define fGEN_TCG_cond_jumprt(COND) \
+do { \
+TCGv LSB = tcg_temp_new(); \
+COND; \
+gen_cond_jumpr(ctx, RsV, TCG_COND_EQ, LSB); \
+tcg_temp_free(LSB); \
+} while (0)
+#define fGEN_TCG_cond_jumprf(COND) \
+do { \
+TCGv LSB = tcg_temp_new(); \
+COND; \
+gen_cond_jumpr(ctx, RsV, TCG_COND_NE, LSB); \
+tcg_temp_free(LSB); \
+} while (0)
+
+#define fGEN_TCG_J2_jumprt(SHORTCODE) \
+fGEN_TCG_cond_jumprt(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprtpt(SHORTCODE) \
+fGEN_TCG_cond_jumprt(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprf(SHORTCODE) \
+fGEN_TCG_cond_jumprf(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprfpt(SHORTCODE) \
+fGEN_TCG_cond_jumprf(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprtnew(SHORTCODE) \
+fGEN_TCG_cond_jumprt(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprtnewpt(SHORTCODE) \
+fGEN_TCG_cond_jumprt(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprfnew(SHORTCODE) \
+fGEN_TCG_cond_jumprf(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprfnewpt(SHORTCODE) \
+fGEN_TCG_cond_jumprf(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprfnewpt(SHORTCODE) \
+fGEN_TCG_cond_jumprf(fLSBNEW(PuN))
+
+/*
+ * New value compare & jump instructions
+ * if ([!]COND(r0.new, r1) jump:t address
+ * if ([!]COND(r0.new, #7) jump:t address
+ */
+#define fGEN_TCG_J4_cmpgt_t_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_GT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_t_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_GT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_f_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_LE, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_f_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_LE, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmpeq_t_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_EQ, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_t_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_EQ, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_f_jumpnv_t(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_NE, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_f_jumpnv_nt(SHORTCODE) \
+gen_cmp_jumpnv(ctx, TCG_COND_NE, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmplt_t_jumpnv_t(SHORTCODE) \

[PATCH v4 11/11] Hexagon (target/hexagon) Use direct block chaining for tight loops

2022-11-07 Thread Taylor Simpson
Direct block chaining is documented here
https://qemu.readthedocs.io/en/latest/devel/tcg.html#direct-block-chaining

Hexagon inner loops end with the endloop0 instruction
To go back to the beginning of the loop, this instructions writes to PC
from register SA0 (start address 0).  To use direct block chaining, we
have to assign PC with a constant value.  So, we specialize the code
generation when the start of the translation block is equal to SA0.

When this is the case, we defer the compare/branch from endloop0 to
gen_end_tb.  When this is done, we can assign the start address of the TB
to PC.

Reviewed-by: Richard Henderson 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/cpu.h   | 13 +++---
 target/hexagon/gen_tcg.h   |  3 ++
 target/hexagon/translate.h |  1 +
 target/hexagon/genptr.c| 84 ++
 target/hexagon/translate.c | 34 +++
 5 files changed, 130 insertions(+), 5 deletions(-)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index ff8c26272d..1d89e11a1a 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -25,6 +25,7 @@
 #include "mmvec/mmvec.h"
 #include "qom/object.h"
 #include "hw/core/cpu.h"
+#include "hw/registerfields.h"
 
 #define NUM_PREGS 4
 #define TOTAL_PER_THREAD_REGS 64
@@ -152,16 +153,18 @@ struct ArchCPU {
 
 #include "cpu_bits.h"
 
+FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1)
+
 static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, target_ulong *pc,
 target_ulong *cs_base, uint32_t *flags)
 {
+uint32_t hex_flags = 0;
 *pc = env->gpr[HEX_REG_PC];
 *cs_base = 0;
-#ifdef CONFIG_USER_ONLY
-*flags = 0;
-#else
-#error System mode not supported on Hexagon yet
-#endif
+if (*pc == env->gpr[HEX_REG_SA0]) {
+hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, IS_TIGHT_LOOP, 1);
+}
+*flags = hex_flags;
 }
 
 static inline int cpu_mmu_index(CPUHexagonState *env, bool ifetch)
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 17431403a9..3a12c12ef1 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -620,6 +620,9 @@
 #define fGEN_TCG_J2_callf(SHORTCODE) \
 gen_cond_call(ctx, PuV, TCG_COND_NE, riV)
 
+#define fGEN_TCG_J2_endloop0(SHORTCODE) \
+gen_endloop0(ctx)
+
 /*
  * Compound compare and jump instructions
  * Here is a primer to understand the tag names
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index aacf0b0921..d971f4f095 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -59,6 +59,7 @@ typedef struct DisasContext {
 bool pre_commit;
 TCGCond branch_cond;
 target_ulong branch_dest;
+bool is_tight_loop;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 584e6415c0..34b2a52bb0 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -497,6 +497,33 @@ static void gen_write_new_pc_pcrel(DisasContext *ctx, int 
pc_off,
 }
 }
 
+static void gen_set_usr_field(int field, TCGv val)
+{
+tcg_gen_deposit_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_USR],
+   val,
+   reg_field_info[field].offset,
+   reg_field_info[field].width);
+}
+
+static void gen_set_usr_fieldi(int field, int x)
+{
+if (reg_field_info[field].width == 1) {
+target_ulong bit = 1 << reg_field_info[field].offset;
+if ((x & 1) == 1) {
+tcg_gen_ori_tl(hex_new_value[HEX_REG_USR],
+   hex_new_value[HEX_REG_USR],
+   bit);
+} else {
+tcg_gen_andi_tl(hex_new_value[HEX_REG_USR],
+hex_new_value[HEX_REG_USR],
+~bit);
+}
+} else {
+TCGv val = tcg_constant_tl(x);
+gen_set_usr_field(field, val);
+}
+}
+
 static void gen_compare(TCGCond cond, TCGv res, TCGv arg1, TCGv arg2)
 {
 TCGv one = tcg_constant_tl(0xff);
@@ -636,6 +663,63 @@ static void gen_cond_call(DisasContext *ctx, TCGv pred,
 gen_set_label(skip);
 }
 
+static void gen_endloop0(DisasContext *ctx)
+{
+TCGv lpcfg = tcg_temp_local_new();
+
+GET_USR_FIELD(USR_LPCFG, lpcfg);
+
+/*
+ *if (lpcfg == 1) {
+ *hex_new_pred_value[3] = 0xff;
+ *hex_pred_written |= 1 << 3;
+ *}
+ */
+TCGLabel *label1 = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_NE, lpcfg, 1, label1);
+{
+tcg_gen_movi_tl(hex_new_pred_value[3], 0xff);
+tcg_gen_ori_tl(hex_pred_written, hex_pred_written, 1 << 3);
+}
+gen_set_label(label1);
+
+/*
+ *if (lpcfg) {
+ *SET_USR_FIELD(USR_LPCFG, lpcfg - 1);
+ *}
+ */
+TCGLabel *label2 = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, lpcfg, 0, label2);
+{
+tcg_gen_subi_tl(lpcfg, lpcfg, 1);
+

[PATCH v4 00/11] Hexagon (target/hexagon) performance and bug fixes

2022-11-07 Thread Taylor Simpson
1)
Performance improvement
Add pkt and insn to DisasContext
Many functions need information from all 3 structures, so merge
them together.

2)
Bug fix
Fix predicated assignment to .tmp and .cur


3)
Performance improvement
Add overrides for S2_asr_r_r_sat/S2_asl_r_r_sat
These functions will not be handled by idef-parser

4-11)
The final 8 patches improve change-of-flow handling.

Currently, we set the PC to a new address before exiting a TB.  The
ultimate goal is to use direct block chaining.  However, several steps
are needed along the way.

4)
When a packet has more than one change-of-flow (COF) instruction, only
the first one taken is considered.  The runtime bookkeeping is only
needed when there is more than one COF instruction in a packet.

5, 6)
Remove PC and next_PC from the runtime state and always use a
translation-time constant.  Note that next_PC is used by call instructions
to set LR and by conditional COF instructions to set the fall-through
address.

7, 8, 9)
Add helper overrides for COF instructions.  In particular, we must
distinguish those that use a PC-relative address for the destination.
These are candidates for direct block chaining later.

10)
Use direct block chaining for packets that have a single PC-relative
COF instruction.  Instead of generating the code while processing the
instruction, we record the effect in DisasContext and generate the code
during gen_end_tb.

11)
Use direct block chaining for tight loops.  We look for TBs that end
with an endloop0 that will branch back to the TB start address.


 Changes in V4 
Address feedback from Richard Henderson 
Rewrite gen_sat_i64 to be branchless
Rewrite gen_sar to be branchless
Rewrite gen_shl_sat to be branchless
Pass branch condition instead of doing xor when false
Use hex_branch_taken to hold the predicate for direct branches
Remove HexStateFlags and use "hw/registerfields.h" macros instead

 Changes in V3 
Merge previously emailed patches into single series
Merge functions that check if vreg is preloaded

 Changes in V2 
Update test case to use both true and false predicates
Add fix for .cur
Simplify test in need_pkt_has_multi_cof
Address feedback from Matheus Tavares Bernardino 
Rearrange new-value-jump overrides
Simplify gen_write_new_pc_addr


Taylor Simpson (11):
  Hexagon (target/hexagon) Add pkt and insn to DisasContext
  Hexagon (target/hexagon) Fix predicated assignment to .tmp and .cur
  Hexagon (target/hexagon) Add overrides for
S2_asr_r_r_sat/S2_asl_r_r_sat
  Hexagon (target/hexagon) Only use branch_taken when packet has multi
cof
  Hexagon (target/hexagon) Remove PC from the runtime state
  Hexagon (target/hexagon) Remove next_PC from runtime state
  Hexagon (target/hexagon) Add overrides for direct call instructions
  Hexagon (target/hexagon) Add overrides for compound compare and jump
  Hexagon (target/hexagon) Add overrides for various forms of jump
  Hexagon (target/hexagon) Use direct block chaining for direct
jump/branch
  Hexagon (target/hexagon) Use direct block chaining for tight loops

 target/hexagon/cpu.h|  14 +-
 target/hexagon/gen_tcg.h| 414 +++-
 target/hexagon/gen_tcg_hvx.h|   6 +-
 target/hexagon/insn.h   |   9 +-
 target/hexagon/macros.h |  16 +-
 target/hexagon/mmvec/macros.h   |   4 +-
 target/hexagon/translate.h  |  20 +-
 target/hexagon/decode.c |  15 +-
 target/hexagon/genptr.c | 392 +-
 target/hexagon/op_helper.c  |  28 +-
 target/hexagon/translate.c  | 231 +++-
 tests/tcg/hexagon/hvx_misc.c|  72 +
 tests/tcg/hexagon/usr.c |  30 +-
 target/hexagon/gen_helper_funcs.py  |  13 +-
 target/hexagon/gen_helper_protos.py |  14 +-
 target/hexagon/gen_tcg_funcs.py |  38 ++-
 target/hexagon/hex_common.py|  29 +-
 17 files changed, 1207 insertions(+), 138 deletions(-)

-- 
2.17.1



[PATCH v4 03/11] Hexagon (target/hexagon) Add overrides for S2_asr_r_r_sat/S2_asl_r_r_sat

2022-11-07 Thread Taylor Simpson
These instructions will not be generated by idef-parser, so we override
them manually.

Test cases added to tests/tcg/hexagon/usr.c

Co-authored-by: Matheus Tavares Bernardino 
Signed-off-by: Matheus Tavares Bernardino 
Signed-off-by: Taylor Simpson 
---
 target/hexagon/gen_tcg.h |  10 +++-
 target/hexagon/genptr.c  | 104 +++
 tests/tcg/hexagon/usr.c  |  30 ---
 3 files changed, 137 insertions(+), 7 deletions(-)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 50634ac459..b5fe22a07a 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  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
@@ -612,6 +612,14 @@
 tcg_temp_free(tmp); \
 } while (0)
 
+/* r0 = asr(r1, r2):sat */
+#define fGEN_TCG_S2_asr_r_r_sat(SHORTCODE) \
+gen_asr_r_r_sat(RdV, RsV, RtV)
+
+/* r0 = asl(r1, r2):sat */
+#define fGEN_TCG_S2_asl_r_r_sat(SHORTCODE) \
+gen_asl_r_r_sat(RdV, RsV, RtV)
+
 /* Floating point */
 #define fGEN_TCG_F2_conv_sf2df(SHORTCODE) \
 gen_helper_conv_sf2df(RddV, cpu_env, RsV)
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index 85416dd530..ccfed9d643 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -456,6 +456,110 @@ static TCGv gen_8bitsof(TCGv result, TCGv value)
 return result;
 }
 
+/* Shift left with saturation */
+static void gen_shl_sat(TCGv dst, TCGv src, TCGv shift_amt)
+{
+TCGv_i64 src64 = tcg_temp_local_new_i64();
+TCGv_i64 shift64 = tcg_temp_new_i64();
+TCGv_i64 dst64 = tcg_temp_new_i64();
+TCGv dst_sar = tcg_temp_new();
+TCGv ovf = tcg_temp_new();
+TCGv satval = tcg_temp_new();
+TCGv min = tcg_constant_tl(0x8000);
+TCGv max = tcg_constant_tl(0x7fff);
+
+/*
+ * dst64 = (int64_t)src << (int64_t)shift_amt
+ * dst = (int32_t)dst64
+ * dst_sar = dst >> shift_amt
+ * if (dst_sar != src) {
+ * usr.OVF = 1
+ * dst = src < 0 ? min : max
+ * }
+ */
+tcg_gen_ext_i32_i64(src64, src);
+tcg_gen_ext_i32_i64(shift64, shift_amt);
+tcg_gen_shl_i64(dst64, src64, shift64);
+
+tcg_gen_extrl_i64_i32(dst, dst64);
+tcg_gen_sar_tl(dst_sar, dst, shift_amt);
+
+tcg_gen_setcond_tl(TCG_COND_NE, ovf, dst_sar, src);
+tcg_gen_shli_tl(ovf, ovf, reg_field_info[USR_OVF].offset);
+tcg_gen_or_tl(hex_new_value[HEX_REG_USR], hex_new_value[HEX_REG_USR], ovf);
+
+tcg_gen_movcond_tl(TCG_COND_LT, satval, src, tcg_constant_tl(0),
+   min, max);
+tcg_gen_movcond_tl(TCG_COND_EQ, dst, dst_sar, src, dst, satval);
+
+tcg_temp_free_i64(src64);
+tcg_temp_free_i64(shift64);
+tcg_temp_free_i64(dst64);
+tcg_temp_free(dst_sar);
+tcg_temp_free(ovf);
+tcg_temp_free(satval);
+}
+
+static void gen_sar(TCGv dst, TCGv src, TCGv shift_amt)
+{
+/*
+ *  Shift arithmetic right
+ *  Robust when shift_amt is >31 bits
+ */
+TCGv tmp = tcg_temp_new();
+tcg_gen_umin_tl(tmp, shift_amt, tcg_constant_tl(31));
+tcg_gen_sar_tl(dst, src, tmp);
+tcg_temp_free(tmp);
+}
+
+/* Bidirectional shift right with saturation */
+static void gen_asr_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV)
+{
+TCGv shift_amt = tcg_temp_local_new();
+TCGLabel *positive = gen_new_label();
+TCGLabel *done = gen_new_label();
+
+tcg_gen_sextract_i32(shift_amt, RtV, 0, 7);
+tcg_gen_brcondi_tl(TCG_COND_GE, shift_amt, 0, positive);
+
+/* Negative shift amount => shift left */
+tcg_gen_neg_tl(shift_amt, shift_amt);
+gen_shl_sat(RdV, RsV, shift_amt);
+tcg_gen_br(done);
+
+gen_set_label(positive);
+/* Positive shift amount => shift right */
+gen_sar(RdV, RsV, shift_amt);
+
+gen_set_label(done);
+
+tcg_temp_free(shift_amt);
+}
+
+/* Bidirectional shift left with saturation */
+static void gen_asl_r_r_sat(TCGv RdV, TCGv RsV, TCGv RtV)
+{
+TCGv shift_amt = tcg_temp_local_new();
+TCGLabel *positive = gen_new_label();
+TCGLabel *done = gen_new_label();
+
+tcg_gen_sextract_i32(shift_amt, RtV, 0, 7);
+tcg_gen_brcondi_tl(TCG_COND_GE, shift_amt, 0, positive);
+
+/* Negative shift amount => shift right */
+tcg_gen_neg_tl(shift_amt, shift_amt);
+gen_sar(RdV, RsV, shift_amt);
+tcg_gen_br(done);
+
+gen_set_label(positive);
+/* Positive shift amount => shift left */
+gen_shl_sat(RdV, RsV, shift_amt);
+
+gen_set_label(done);
+
+tcg_temp_free(shift_amt);
+}
+
 static intptr_t vreg_src_off(DisasContext *ctx, int num)
 {
 intptr_t offset = offsetof(CPUHexagonState, VRegs[num]);
diff --git a/tests/tcg/hexagon/usr.c b/tests/tcg/hexagon/usr.c
index fb4514989c..63c7d2700f 100644

Re: [PATCH v8 5/5] docs: Add generic vhost-vdpa device documentation

2022-11-07 Thread longpeng2--- via




在 2022/11/8 10:42, Jason Wang 写道:

On Tue, Nov 8, 2022 at 8:42 AM Longpeng(Mike)  wrote:


From: Longpeng 

Signed-off-by: Longpeng 
---
  docs/system/devices/vhost-vdpa-device.rst | 43 +++
  1 file changed, 43 insertions(+)
  create mode 100644 docs/system/devices/vhost-vdpa-device.rst

diff --git a/docs/system/devices/vhost-vdpa-device.rst 
b/docs/system/devices/vhost-vdpa-device.rst
new file mode 100644
index 00..b758c4fce6
--- /dev/null
+++ b/docs/system/devices/vhost-vdpa-device.rst


If the doc is for a general vhost-vDPA device, we'd better have a better name?



How about general-vhost-vdpa-device.rst?

On the other hand, this series focuses on the general vhost-vDPA device, 
so the doc is for it. It's ok if you want one doc includes both, then I 
think it should move out of this series.




@@ -0,0 +1,43 @@
+
+=
+generic vhost-vdpa device
+=
+
+This document explains the usage of the generic vhost vdpa device.
+
+Description
+---
+
+vDPA(virtio data path acceleration) device is a device that uses a datapath
+which complies with the virtio specifications with vendor specific control
+path.
+
+QEMU provides two types of vhost-vdpa devices to enable the vDPA device, one
+is type sensitive which means QEMU needs to know the actual device type
+(e.g. net, blk, scsi) and another is called "generic vdpa device" which is
+type insensitive (likes vfio-pci).


Same as above, if this document is focused on the general vhost-vDPA
device, we'd better emphasize it. And I don't think mention vfio-pci
is good idea here since those two are different from a lot of places,
(e.g the general vhost-vdpa is not transport specific, as demonstrated
below).



Ok, got it.


Thanks


+
+Examples
+
+
+Prepare the vhost-vdpa backends first:
+
+::
+  host# ls -l /dev/vhost-vdpa-*
+  crw--- 1 root root 236, 0 Nov  2 00:49 /dev/vhost-vdpa-0
+
+Start QEMU with virtio-mmio bus:
+
+::
+  host# qemu-system  \
+  -M microvm -m 512 -smp 2 -kernel ... -initrd ...   \
+  -device vhost-vdpa-device,vhostdev=/dev/vhost-vdpa-0   \
+  ...
+
+Start QEMU with virtio-pci bus:
+
+::
+  host# qemu-system  \
+  -M pc -m 512 -smp 2\
+  -device vhost-vdpa-device-pci,vhostdev=/dev/vhost-vdpa-0   \
+  ...
--
2.23.0



.




Re: [PATCH v8 5/5] docs: Add generic vhost-vdpa device documentation

2022-11-07 Thread Jason Wang
On Tue, Nov 8, 2022 at 8:42 AM Longpeng(Mike)  wrote:
>
> From: Longpeng 
>
> Signed-off-by: Longpeng 
> ---
>  docs/system/devices/vhost-vdpa-device.rst | 43 +++
>  1 file changed, 43 insertions(+)
>  create mode 100644 docs/system/devices/vhost-vdpa-device.rst
>
> diff --git a/docs/system/devices/vhost-vdpa-device.rst 
> b/docs/system/devices/vhost-vdpa-device.rst
> new file mode 100644
> index 00..b758c4fce6
> --- /dev/null
> +++ b/docs/system/devices/vhost-vdpa-device.rst

If the doc is for a general vhost-vDPA device, we'd better have a better name?

> @@ -0,0 +1,43 @@
> +
> +=
> +generic vhost-vdpa device
> +=
> +
> +This document explains the usage of the generic vhost vdpa device.
> +
> +Description
> +---
> +
> +vDPA(virtio data path acceleration) device is a device that uses a datapath
> +which complies with the virtio specifications with vendor specific control
> +path.
> +
> +QEMU provides two types of vhost-vdpa devices to enable the vDPA device, one
> +is type sensitive which means QEMU needs to know the actual device type
> +(e.g. net, blk, scsi) and another is called "generic vdpa device" which is
> +type insensitive (likes vfio-pci).

Same as above, if this document is focused on the general vhost-vDPA
device, we'd better emphasize it. And I don't think mention vfio-pci
is good idea here since those two are different from a lot of places,
(e.g the general vhost-vdpa is not transport specific, as demonstrated
below).

Thanks

> +
> +Examples
> +
> +
> +Prepare the vhost-vdpa backends first:
> +
> +::
> +  host# ls -l /dev/vhost-vdpa-*
> +  crw--- 1 root root 236, 0 Nov  2 00:49 /dev/vhost-vdpa-0
> +
> +Start QEMU with virtio-mmio bus:
> +
> +::
> +  host# qemu-system  \
> +  -M microvm -m 512 -smp 2 -kernel ... -initrd ...   \
> +  -device vhost-vdpa-device,vhostdev=/dev/vhost-vdpa-0   \
> +  ...
> +
> +Start QEMU with virtio-pci bus:
> +
> +::
> +  host# qemu-system  \
> +  -M pc -m 512 -smp 2\
> +  -device vhost-vdpa-device-pci,vhostdev=/dev/vhost-vdpa-0   \
> +  ...
> --
> 2.23.0
>




Re: [PATCH v8 4/5] vdpa-dev: mark the device as unmigratable

2022-11-07 Thread Jason Wang
On Tue, Nov 8, 2022 at 8:42 AM Longpeng(Mike)  wrote:
>
> From: Longpeng 
>
> The generic vDPA device doesn't support migration currently, so
> mark it as unmigratable temporarily.
>
> Signed-off-by: Longpeng 

Acked-by: Jason Wang 

> ---
>  hw/virtio/vdpa-dev.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
> index 2885d06cbe..62d83d3423 100644
> --- a/hw/virtio/vdpa-dev.c
> +++ b/hw/virtio/vdpa-dev.c
> @@ -327,6 +327,7 @@ static Property vhost_vdpa_device_properties[] = {
>
>  static const VMStateDescription vmstate_vhost_vdpa_device = {
>  .name = "vhost-vdpa-device",
> +.unmigratable = 1,
>  .minimum_version_id = 1,
>  .version_id = 1,
>  .fields = (VMStateField[]) {
> --
> 2.23.0
>




[PATCH] hw/arm/boot: set initrd parameters to 64bit in fdt

2022-11-07 Thread Schspa Shi
We use 32bit value for linux,initrd-[start/end], when we have
loader_start > 4GB, there will be a wrong initrd_start passed
to the kernel, and the kernel will report the following warning.

[0.00] [ cut here ]
[0.00] initrd not fully accessible via the linear mapping -- please 
check your bootloader ...
[0.00] WARNING: CPU: 0 PID: 0 at arch/arm64/mm/init.c:355 
arm64_memblock_init+0x158/0x244
[0.00] Modules linked in:
[0.00] CPU: 0 PID: 0 Comm: swapper Tainted: GW  
6.1.0-rc3-13250-g30a0b95b1335-dirty #28
[0.00] Hardware name: Horizon Sigi Virtual development board (DT)
[0.00] pstate: 60c5 (nZCv daIF -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[0.00] pc : arm64_memblock_init+0x158/0x244
[0.00] lr : arm64_memblock_init+0x158/0x244
[0.00] sp : 89273df0
[0.00] x29: 89273df0 x28: 001000cc0010 x27: 8000
[0.00] x26: 0050a3e2 x25: 88b46000 x24: 88b46000
[0.00] x23: 88a53000 x22: 8942 x21: 88a53000
[0.00] x20: 0400 x19: 0400 x18: 1020
[0.00] x17: 6568632065736165 x16: 6c70202d2d20676e x15: 697070616d207261
[0.00] x14: 656e696c20656874 x13: 0a2e2e2e20726564 x12: 
[0.00] x11:  x10:  x9 : 
[0.00] x8 :  x7 : 796c6c756620746f x6 : 6e20647274696e69
[0.00] x5 : 893c7c47 x4 : 88a2102f x3 : 89273a88
[0.00] x2 : 8000f038 x1 : 00c0 x0 : 0056
[0.00] Call trace:
[0.00]  arm64_memblock_init+0x158/0x244
[0.00]  setup_arch+0x164/0x1cc
[0.00]  start_kernel+0x94/0x4ac
[0.00]  __primary_switched+0xb4/0xbc
[0.00] ---[ end trace  ]---
[0.00] Zone ranges:
[0.00]   DMA  [mem 0x0010-0x001007ff]

To fix it, we can change it to u64 type.

Signed-off-by: Schspa Shi 
---
 hw/arm/boot.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 57efb61ee419..da719a4f8874 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -638,14 +638,14 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info 
*binfo,
 }
 
 if (binfo->initrd_size) {
-rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
+rc = qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start",
binfo->initrd_start);
 if (rc < 0) {
 fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");
 goto fail;
 }
 
-rc = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+rc = qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end",
binfo->initrd_start + binfo->initrd_size);
 if (rc < 0) {
 fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");
-- 
2.37.3




Re: [PATCH v1 1/4] target/riscv: Add itrigger support when icount is not enabled

2022-11-07 Thread LIU Zhiwei


On 2022/11/7 23:58, Alex Bennée wrote:

LIU Zhiwei  writes:


On 2022/11/7 9:37, Alistair Francis wrote:

On Thu, Oct 13, 2022 at 4:32 PM LIU Zhiwei  wrote:

When icount is not enabled, there is no API in QEMU that can get the
guest instruction number.

Translate the guest code in a way that each TB only has one instruction.

I don't think this is a great idea.

Why can't we just require icount be enabled if a user wants this? Or singlestep?

This feature will only be used by users who want to  run the native
gdb on Linux. If we run QEMU as a service,  after booting the kernel,
we can't predicate whether the users will use native gdb.

Besides, icount can't be enabled on MTTCG currently (I am working on
this problem)

I'm curious as to what your approach is going to be to solve this one?


Yes, I am interested in this problem.  But actually, I don't find a 
clear way.


For RR or MTTCG, timers using QEMU_CLOCK_VIRTUAL will set the total 
icount_budget.


 * For RR smp, every cpu has configured the total icount_budget.

 * For MTTCG smp, every cpu can't be configured the total
   icount_budget.  But we can split the icount_budget, such as divide
   by smp.cpus, to each core. If one core consumed its budget, it will
   wait for other cores.  Another way is to kick other cores and split
   the remaining icount_budget.

I am not sure if there are many other problems related.  It a difficult 
problem. Looking forward to your advice.


Thanks,
Zhiwei



Re: [PATCH v9 5/8] KVM: Register/unregister the guest private memory regions

2022-11-07 Thread Yuan Yao
On Tue, Oct 25, 2022 at 11:13:41PM +0800, Chao Peng wrote:
> Introduce generic private memory register/unregister by reusing existing
> SEV ioctls KVM_MEMORY_ENCRYPT_{UN,}REG_REGION. It differs from SEV case
> by treating address in the region as gpa instead of hva. Which cases
> should these ioctls go is determined by the kvm_arch_has_private_mem().
> Architecture which supports KVM_PRIVATE_MEM should override this function.
>
> KVM internally defaults all guest memory as private memory and maintain
> the shared memory in 'mem_attr_array'. The above ioctls operate on this
> field and unmap existing mappings if any.
>
> Signed-off-by: Chao Peng 
> ---
>  Documentation/virt/kvm/api.rst |  17 ++-
>  arch/x86/kvm/Kconfig   |   1 +
>  include/linux/kvm_host.h   |  10 +-
>  virt/kvm/Kconfig   |   4 +
>  virt/kvm/kvm_main.c| 227 +
>  5 files changed, 198 insertions(+), 61 deletions(-)
>
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index 975688912b8c..08253cf498d1 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -4717,10 +4717,19 @@ Documentation/virt/kvm/x86/amd-memory-encryption.rst.
>  This ioctl can be used to register a guest memory region which may
>  contain encrypted data (e.g. guest RAM, SMRAM etc).
>
> -It is used in the SEV-enabled guest. When encryption is enabled, a guest
> -memory region may contain encrypted data. The SEV memory encryption
> -engine uses a tweak such that two identical plaintext pages, each at
> -different locations will have differing ciphertexts. So swapping or
> +Currently this ioctl supports registering memory regions for two usages:
> +private memory and SEV-encrypted memory.
> +
> +When private memory is enabled, this ioctl is used to register guest private
> +memory region and the addr/size of kvm_enc_region represents guest physical
> +address (GPA). In this usage, this ioctl zaps the existing guest memory
> +mappings in KVM that fallen into the region.
> +
> +When SEV-encrypted memory is enabled, this ioctl is used to register guest
> +memory region which may contain encrypted data for a SEV-enabled guest. The
> +addr/size of kvm_enc_region represents userspace address (HVA). The SEV
> +memory encryption engine uses a tweak such that two identical plaintext 
> pages,
> +each at different locations will have differing ciphertexts. So swapping or
>  moving ciphertext of those pages will not result in plaintext being
>  swapped. So relocating (or migrating) physical backing pages for the SEV
>  guest will require some additional steps.
> diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig
> index 8d2bd455c0cd..73fdfa429b20 100644
> --- a/arch/x86/kvm/Kconfig
> +++ b/arch/x86/kvm/Kconfig
> @@ -51,6 +51,7 @@ config KVM
>   select HAVE_KVM_PM_NOTIFIER if PM
>   select HAVE_KVM_RESTRICTED_MEM if X86_64
>   select RESTRICTEDMEM if HAVE_KVM_RESTRICTED_MEM
> + select KVM_GENERIC_PRIVATE_MEM if HAVE_KVM_RESTRICTED_MEM
>   help
> Support hosting fully virtualized guest machines using hardware
> virtualization extensions.  You will need a fairly recent
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 79e5cbc35fcf..4ce98fa0153c 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -245,7 +245,8 @@ bool kvm_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t 
> cr2_or_gpa,
>  int kvm_async_pf_wakeup_all(struct kvm_vcpu *vcpu);
>  #endif
>
> -#ifdef KVM_ARCH_WANT_MMU_NOTIFIER
> +
> +#if defined(KVM_ARCH_WANT_MMU_NOTIFIER) || 
> defined(CONFIG_KVM_GENERIC_PRIVATE_MEM)
>  struct kvm_gfn_range {
>   struct kvm_memory_slot *slot;
>   gfn_t start;
> @@ -254,6 +255,9 @@ struct kvm_gfn_range {
>   bool may_block;
>  };
>  bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range);
> +#endif
> +
> +#ifdef KVM_ARCH_WANT_MMU_NOTIFIER
>  bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
>  bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
>  bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range);
> @@ -794,6 +798,9 @@ struct kvm {
>   struct notifier_block pm_notifier;
>  #endif
>   char stats_id[KVM_STATS_NAME_SIZE];
> +#ifdef CONFIG_KVM_GENERIC_PRIVATE_MEM
> + struct xarray mem_attr_array;
> +#endif
>  };
>
>  #define kvm_err(fmt, ...) \
> @@ -1453,6 +1460,7 @@ bool kvm_arch_dy_has_pending_interrupt(struct kvm_vcpu 
> *vcpu);
>  int kvm_arch_post_init_vm(struct kvm *kvm);
>  void kvm_arch_pre_destroy_vm(struct kvm *kvm);
>  int kvm_arch_create_vm_debugfs(struct kvm *kvm);
> +bool kvm_arch_has_private_mem(struct kvm *kvm);
>
>  #ifndef __KVM_HAVE_ARCH_VM_ALLOC
>  /*
> diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
> index 9ff164c7e0cc..69ca59e82149 100644
> --- a/virt/kvm/Kconfig
> +++ b/virt/kvm/Kconfig
> @@ -89,3 +89,7 @@ config HAVE_KVM_PM_NOTIFIER
>
>  config HAVE_KVM_RESTRICTED_MEM
>

[PATCH v8 1/5] virtio: get class_id and pci device id by the virtio id

2022-11-07 Thread Longpeng(Mike)
From: Longpeng 

Add helpers to get the "Transitional PCI Device ID" and "class_id"
of the device specified by the "Virtio Device ID".

These helpers will be used to build the generic vDPA device later.

Acked-by: Jason Wang 
Signed-off-by: Longpeng 
---
 hw/virtio/virtio-pci.c | 88 ++
 include/hw/virtio/virtio-pci.h |  5 ++
 2 files changed, 93 insertions(+)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 34db51e241..3469b88d43 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -19,6 +19,7 @@
 
 #include "exec/memop.h"
 #include "standard-headers/linux/virtio_pci.h"
+#include "standard-headers/linux/virtio_ids.h"
 #include "hw/boards.h"
 #include "hw/virtio/virtio.h"
 #include "migration/qemu-file-types.h"
@@ -213,6 +214,90 @@ static int virtio_pci_load_queue(DeviceState *d, int n, 
QEMUFile *f)
 return 0;
 }
 
+typedef struct VirtIOPCIIDInfo {
+/* virtio id */
+uint16_t vdev_id;
+/* pci device id for the transitional device */
+uint16_t trans_devid;
+uint16_t class_id;
+} VirtIOPCIIDInfo;
+
+static const VirtIOPCIIDInfo virtio_pci_id_info[] = {
+{
+.vdev_id = VIRTIO_ID_CRYPTO,
+.class_id = PCI_CLASS_OTHERS,
+}, {
+.vdev_id = VIRTIO_ID_FS,
+.class_id = PCI_CLASS_STORAGE_OTHER,
+}, {
+.vdev_id = VIRTIO_ID_NET,
+.trans_devid = PCI_DEVICE_ID_VIRTIO_NET,
+.class_id = PCI_CLASS_NETWORK_ETHERNET,
+}, {
+.vdev_id = VIRTIO_ID_BLOCK,
+.trans_devid = PCI_DEVICE_ID_VIRTIO_BLOCK,
+.class_id = PCI_CLASS_STORAGE_SCSI,
+}, {
+.vdev_id = VIRTIO_ID_CONSOLE,
+.trans_devid = PCI_DEVICE_ID_VIRTIO_CONSOLE,
+.class_id = PCI_CLASS_COMMUNICATION_OTHER,
+}, {
+.vdev_id = VIRTIO_ID_SCSI,
+.trans_devid = PCI_DEVICE_ID_VIRTIO_SCSI,
+.class_id = PCI_CLASS_STORAGE_SCSI
+}, {
+.vdev_id = VIRTIO_ID_9P,
+.trans_devid = PCI_DEVICE_ID_VIRTIO_9P,
+.class_id = PCI_BASE_CLASS_NETWORK,
+}, {
+.vdev_id = VIRTIO_ID_BALLOON,
+.trans_devid = PCI_DEVICE_ID_VIRTIO_BALLOON,
+.class_id = PCI_CLASS_OTHERS,
+}, {
+.vdev_id = VIRTIO_ID_RNG,
+.trans_devid = PCI_DEVICE_ID_VIRTIO_RNG,
+.class_id = PCI_CLASS_OTHERS,
+},
+};
+
+static const VirtIOPCIIDInfo *virtio_pci_get_id_info(uint16_t vdev_id)
+{
+const VirtIOPCIIDInfo *info = NULL;
+int i;
+
+for (i = 0; i < ARRAY_SIZE(virtio_pci_id_info); i++) {
+if (virtio_pci_id_info[i].vdev_id == vdev_id) {
+info = _pci_id_info[i];
+break;
+}
+}
+
+if (!info) {
+/* The device id is invalid or not added to the id_info yet. */
+error_report("Invalid virtio device(id %u)", vdev_id);
+abort();
+}
+
+return info;
+}
+
+/*
+ * Get the Transitional Device ID for the specific device, return
+ * zero if the device is non-transitional.
+ */
+uint16_t virtio_pci_get_trans_devid(uint16_t device_id)
+{
+return virtio_pci_get_id_info(device_id)->trans_devid;
+}
+
+/*
+ * Get the Class ID for the specific device.
+ */
+uint16_t virtio_pci_get_class_id(uint16_t device_id)
+{
+return virtio_pci_get_id_info(device_id)->class_id;
+}
+
 static bool virtio_pci_ioeventfd_enabled(DeviceState *d)
 {
 VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
@@ -1683,6 +1768,9 @@ static void virtio_pci_device_plugged(DeviceState *d, 
Error **errp)
  * is set to PCI_SUBVENDOR_ID_REDHAT_QUMRANET by default.
  */
 pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
+if (proxy->trans_devid) {
+pci_config_set_device_id(config, proxy->trans_devid);
+}
 } else {
 /* pure virtio-1.0 */
 pci_set_word(config + PCI_VENDOR_ID,
diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h
index 2446dcd9ae..d95b1a13a5 100644
--- a/include/hw/virtio/virtio-pci.h
+++ b/include/hw/virtio/virtio-pci.h
@@ -146,6 +146,8 @@ struct VirtIOPCIProxy {
 bool disable_modern;
 bool ignore_backend_features;
 OnOffAuto disable_legacy;
+/* Transitional device id */
+uint16_t trans_devid;
 uint32_t class_code;
 uint32_t nvectors;
 uint32_t dfselect;
@@ -179,6 +181,9 @@ static inline void virtio_pci_disable_modern(VirtIOPCIProxy 
*proxy)
 proxy->disable_modern = true;
 }
 
+uint16_t virtio_pci_get_trans_devid(uint16_t device_id);
+uint16_t virtio_pci_get_class_id(uint16_t device_id);
+
 /*
  * virtio-input-pci: This extends VirtioPCIProxy.
  */
-- 
2.23.0




[PATCH v8 4/5] vdpa-dev: mark the device as unmigratable

2022-11-07 Thread Longpeng(Mike)
From: Longpeng 

The generic vDPA device doesn't support migration currently, so
mark it as unmigratable temporarily.

Signed-off-by: Longpeng 
---
 hw/virtio/vdpa-dev.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index 2885d06cbe..62d83d3423 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -327,6 +327,7 @@ static Property vhost_vdpa_device_properties[] = {
 
 static const VMStateDescription vmstate_vhost_vdpa_device = {
 .name = "vhost-vdpa-device",
+.unmigratable = 1,
 .minimum_version_id = 1,
 .version_id = 1,
 .fields = (VMStateField[]) {
-- 
2.23.0




[PATCH v8 5/5] docs: Add generic vhost-vdpa device documentation

2022-11-07 Thread Longpeng(Mike)
From: Longpeng 

Signed-off-by: Longpeng 
---
 docs/system/devices/vhost-vdpa-device.rst | 43 +++
 1 file changed, 43 insertions(+)
 create mode 100644 docs/system/devices/vhost-vdpa-device.rst

diff --git a/docs/system/devices/vhost-vdpa-device.rst 
b/docs/system/devices/vhost-vdpa-device.rst
new file mode 100644
index 00..b758c4fce6
--- /dev/null
+++ b/docs/system/devices/vhost-vdpa-device.rst
@@ -0,0 +1,43 @@
+
+=
+generic vhost-vdpa device
+=
+
+This document explains the usage of the generic vhost vdpa device.
+
+Description
+---
+
+vDPA(virtio data path acceleration) device is a device that uses a datapath
+which complies with the virtio specifications with vendor specific control
+path.
+
+QEMU provides two types of vhost-vdpa devices to enable the vDPA device, one
+is type sensitive which means QEMU needs to know the actual device type
+(e.g. net, blk, scsi) and another is called "generic vdpa device" which is
+type insensitive (likes vfio-pci).
+
+Examples
+
+
+Prepare the vhost-vdpa backends first:
+
+::
+  host# ls -l /dev/vhost-vdpa-*
+  crw--- 1 root root 236, 0 Nov  2 00:49 /dev/vhost-vdpa-0
+
+Start QEMU with virtio-mmio bus:
+
+::
+  host# qemu-system  \
+  -M microvm -m 512 -smp 2 -kernel ... -initrd ...   \
+  -device vhost-vdpa-device,vhostdev=/dev/vhost-vdpa-0   \
+  ...
+
+Start QEMU with virtio-pci bus:
+
+::
+  host# qemu-system  \
+  -M pc -m 512 -smp 2\
+  -device vhost-vdpa-device-pci,vhostdev=/dev/vhost-vdpa-0   \
+  ...
-- 
2.23.0




[PATCH v8 3/5] vdpa: add vdpa-dev-pci support

2022-11-07 Thread Longpeng(Mike)
From: Longpeng 

Supports vdpa-dev-pci, we can use the device as follow:

-device vhost-vdpa-device-pci,vhostdev=/dev/vhost-vdpa-X

Reviewed-by: Stefano Garzarella 
Acked-by: Jason Wang 
Signed-off-by: Longpeng 
---
 hw/virtio/meson.build|   1 +
 hw/virtio/vdpa-dev-pci.c | 102 +++
 2 files changed, 103 insertions(+)
 create mode 100644 hw/virtio/vdpa-dev-pci.c

diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 54d6d29af7..559b80cb28 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -57,6 +57,7 @@ virtio_pci_ss.add(when: 'CONFIG_VIRTIO_SERIAL', if_true: 
files('virtio-serial-pc
 virtio_pci_ss.add(when: 'CONFIG_VIRTIO_PMEM', if_true: 
files('virtio-pmem-pci.c'))
 virtio_pci_ss.add(when: 'CONFIG_VIRTIO_IOMMU', if_true: 
files('virtio-iommu-pci.c'))
 virtio_pci_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: 
files('virtio-mem-pci.c'))
+virtio_pci_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: 
files('vdpa-dev-pci.c'))
 
 virtio_ss.add_all(when: 'CONFIG_VIRTIO_PCI', if_true: virtio_pci_ss)
 
diff --git a/hw/virtio/vdpa-dev-pci.c b/hw/virtio/vdpa-dev-pci.c
new file mode 100644
index 00..5446e6b393
--- /dev/null
+++ b/hw/virtio/vdpa-dev-pci.c
@@ -0,0 +1,102 @@
+/*
+ * Vhost Vdpa Device PCI Bindings
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights Reserved.
+ *
+ * Authors:
+ *   Longpeng 
+ *
+ * Largely based on the "vhost-user-blk-pci.c" and "vhost-user-blk.c"
+ * implemented by:
+ *   Changpeng Liu 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include 
+#include 
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/vdpa-dev.h"
+#include "hw/pci/pci.h"
+#include "hw/qdev-properties.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/module.h"
+#include "hw/virtio/virtio-pci.h"
+#include "qom/object.h"
+
+
+typedef struct VhostVdpaDevicePCI VhostVdpaDevicePCI;
+
+#define TYPE_VHOST_VDPA_DEVICE_PCI "vhost-vdpa-device-pci-base"
+DECLARE_INSTANCE_CHECKER(VhostVdpaDevicePCI, VHOST_VDPA_DEVICE_PCI,
+ TYPE_VHOST_VDPA_DEVICE_PCI)
+
+struct VhostVdpaDevicePCI {
+VirtIOPCIProxy parent_obj;
+VhostVdpaDevice vdev;
+};
+
+static void vhost_vdpa_device_pci_instance_init(Object *obj)
+{
+VhostVdpaDevicePCI *dev = VHOST_VDPA_DEVICE_PCI(obj);
+
+virtio_instance_init_common(obj, >vdev, sizeof(dev->vdev),
+TYPE_VHOST_VDPA_DEVICE);
+object_property_add_alias(obj, "bootindex", OBJECT(>vdev),
+  "bootindex");
+}
+
+static Property vhost_vdpa_device_pci_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static int vhost_vdpa_device_pci_post_init(VhostVdpaDevice *v, Error **errp)
+{
+VhostVdpaDevicePCI *dev = container_of(v, VhostVdpaDevicePCI, vdev);
+VirtIOPCIProxy *vpci_dev = >parent_obj;
+
+vpci_dev->class_code = virtio_pci_get_class_id(v->vdev_id);
+vpci_dev->trans_devid = virtio_pci_get_trans_devid(v->vdev_id);
+/* one for config vector */
+vpci_dev->nvectors = v->num_queues + 1;
+
+return 0;
+}
+
+static void
+vhost_vdpa_device_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+VhostVdpaDevicePCI *dev = VHOST_VDPA_DEVICE_PCI(vpci_dev);
+
+dev->vdev.post_init = vhost_vdpa_device_pci_post_init;
+qdev_realize(DEVICE(>vdev), BUS(_dev->bus), errp);
+}
+
+static void vhost_vdpa_device_pci_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+device_class_set_props(dc, vhost_vdpa_device_pci_properties);
+k->realize = vhost_vdpa_device_pci_realize;
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_vdpa_device_pci_info = {
+.base_name   = TYPE_VHOST_VDPA_DEVICE_PCI,
+.generic_name= "vhost-vdpa-device-pci",
+.transitional_name   = "vhost-vdpa-device-pci-transitional",
+.non_transitional_name   = "vhost-vdpa-device-pci-non-transitional",
+.instance_size  = sizeof(VhostVdpaDevicePCI),
+.instance_init  = vhost_vdpa_device_pci_instance_init,
+.class_init = vhost_vdpa_device_pci_class_init,
+};
+
+static void vhost_vdpa_device_pci_register(void)
+{
+virtio_pci_types_register(_vdpa_device_pci_info);
+}
+
+type_init(vhost_vdpa_device_pci_register);
-- 
2.23.0




[PATCH v8 0/5] add generic vDPA device support

2022-11-07 Thread Longpeng(Mike)
From: Longpeng 

Hi guys,

With the generic vDPA device, QEMU won't need to touch the device
types any more, such like vfio.

We can use the generic vDPA device as follow:
  -device vhost-vdpa-device-pci,vhostdev=/dev/vhost-vdpa-X
  Or
  -M microvm -m 512m -smp 2 -kernel ... -initrd ... -device \
  vhost-vdpa-device,vhostdev=/dev/vhost-vdpa-x

Changes v8 -> v7:
- add migration blocker. [Michael]

Changes v6 -> v7:
(v6: https://mail.gnu.org/archive/html/qemu-devel/2022-05/msg02821.html)
- rebase. [Jason]
- add documentation . [Stefan]

Changes v5 -> v6:
  Patch 2:
- Turn to the original approach in the RFC to initialize the
  virtio_pci_id_info array. [Michael]
  https://lore.kernel.org/all/20220105005900.860-2-longpe...@huawei.com/
  Patch 3:
- Fix logical error of exception handler around the post_init.
  [Stefano]
- Fix some coding style warnings. [Stefano]
  Patch 4:
- Fix some coding style warnings. [Stefano]

Changes v4 -> v5:
  Patch 3:
- remove vhostfd [Jason]
- support virtio-mmio [Jason]

Changes v3 -> v4:
  v3: https://www.mail-archive.com/qemu-devel@nongnu.org/msg877015.html
  - reorganize the series [Stefano]
  - fix some typos [Stefano]
  - fix logical error in vhost_vdpa_device_realize [Stefano]

Changes v2 -> v3
  Patch 4 & 5:
- only call vdpa ioctls in vdpa-dev.c [Stefano, Longpeng]
- s/VQS_NUM/VQS_COUNT  [Stefano]
- check both vdpa_dev_fd and vdpa_dev [Stefano]
  Patch 6:
- move all steps into vhost_vdpa_device_unrealize. [Stefano]

Changes RFC -> v2
  Patch 1:
- rename 'pdev_id' to 'trans_devid'  [Michael]
- only use transitional device id for the devices
  listed in the spec  [Michael]
- use macros to make the id_info table clearer  [Longpeng]
- add some modern devices in the id_info table  [Longpeng]
  Patch 2:
- remove the GET_VECTORS_NUM command  [Jason]
  Patch 4:
- expose vdpa_dev_fd as a QOM preperty  [Stefan]
- introduce vhost_vdpa_device_get_u32 as a common
  function to make the code clearer  [Stefan]
- fix the misleading description of 'dc->desc'  [Stefano]
  Patch 5:
- check returned number of virtqueues  [Stefan]
  Patch 6:
- init s->num_queues  [Stefano]
- free s->dev.vqs  [Stefano]

Longpeng (Mike) (5):
  virtio: get class_id and pci device id by the virtio id
  vdpa: add vdpa-dev support
  vdpa: add vdpa-dev-pci support
  vdpa-dev: mark the device as unmigratable
  docs: Add generic vhost-vdpa device documentation

 docs/system/devices/vhost-vdpa-device.rst |  43 +++
 hw/virtio/Kconfig |   5 +
 hw/virtio/meson.build |   2 +
 hw/virtio/vdpa-dev-pci.c  | 102 ++
 hw/virtio/vdpa-dev.c  | 377 ++
 hw/virtio/virtio-pci.c|  88 +
 include/hw/virtio/vdpa-dev.h  |  43 +++
 include/hw/virtio/virtio-pci.h|   5 +
 8 files changed, 665 insertions(+)
 create mode 100644 docs/system/devices/vhost-vdpa-device.rst
 create mode 100644 hw/virtio/vdpa-dev-pci.c
 create mode 100644 hw/virtio/vdpa-dev.c
 create mode 100644 include/hw/virtio/vdpa-dev.h

-- 
2.23.0




Re: [PATCH v9 0/8] KVM: mm: fd-based approach for supporting KVM

2022-11-07 Thread Isaku Yamahata
On Thu, Nov 03, 2022 at 05:43:52PM +0530,
Vishal Annapurve  wrote:

> On Tue, Oct 25, 2022 at 8:48 PM Chao Peng  wrote:
> >
> > This patch series implements KVM guest private memory for confidential
> > computing scenarios like Intel TDX[1]. If a TDX host accesses
> > TDX-protected guest memory, machine check can happen which can further
> > crash the running host system, this is terrible for multi-tenant
> > configurations. The host accesses include those from KVM userspace like
> > QEMU. This series addresses KVM userspace induced crash by introducing
> > new mm and KVM interfaces so KVM userspace can still manage guest memory
> > via a fd-based approach, but it can never access the guest memory
> > content.
> >
> > The patch series touches both core mm and KVM code. I appreciate
> > Andrew/Hugh and Paolo/Sean can review and pick these patches. Any other
> > reviews are always welcome.
> >   - 01: mm change, target for mm tree
> >   - 02-08: KVM change, target for KVM tree
> >
> > Given KVM is the only current user for the mm part, I have chatted with
> > Paolo and he is OK to merge the mm change through KVM tree, but
> > reviewed-by/acked-by is still expected from the mm people.
> >
> > The patches have been verified in Intel TDX environment, but Vishal has
> > done an excellent work on the selftests[4] which are dedicated for this
> > series, making it possible to test this series without innovative
> > hardware and fancy steps of building a VM environment. See Test section
> > below for more info.
> >
> >
> > Introduction
> > 
> > KVM userspace being able to crash the host is horrible. Under current
> > KVM architecture, all guest memory is inherently accessible from KVM
> > userspace and is exposed to the mentioned crash issue. The goal of this
> > series is to provide a solution to align mm and KVM, on a userspace
> > inaccessible approach of exposing guest memory.
> >
> > Normally, KVM populates secondary page table (e.g. EPT) by using a host
> > virtual address (hva) from core mm page table (e.g. x86 userspace page
> > table). This requires guest memory being mmaped into KVM userspace, but
> > this is also the source where the mentioned crash issue can happen. In
> > theory, apart from those 'shared' memory for device emulation etc, guest
> > memory doesn't have to be mmaped into KVM userspace.
> >
> > This series introduces fd-based guest memory which will not be mmaped
> > into KVM userspace. KVM populates secondary page table by using a
> 
> With no mappings in place for userspace VMM, IIUC, looks like the host
> kernel will not be able to find the culprit userspace process in case
> of Machine check error on guest private memory. As implemented in
> hwpoison_user_mappings, host kernel tries to look at the processes
> which have mapped the pfns with hardware error.
> 
> Is there a modification needed in mce handling logic of the host
> kernel to immediately send a signal to the vcpu thread accessing
> faulting pfn backing guest private memory?

mce_register_decode_chain() can be used.  MCE physical address(p->mce_addr)
includes host key id in addition to real physical address.  By searching used
hkid by KVM, we can determine if the page is assigned to guest TD or not. If
yes, send SIGBUS.

kvm_machine_check() can be enhanced for KVM specific use.  This is before
memory_failure() is called, though.

any other ideas?
-- 
Isaku Yamahata 



[PATCH v8 2/5] vdpa: add vdpa-dev support

2022-11-07 Thread Longpeng(Mike)
From: Longpeng 

Supports vdpa-dev, we can use the deivce directly:

-M microvm -m 512m -smp 2 -kernel ... -initrd ... -device \
vhost-vdpa-device,vhostdev=/dev/vhost-vdpa-x

Reviewed-by: Stefano Garzarella 
Acked-by: Jason Wang 
Signed-off-by: Longpeng 
---
 hw/virtio/Kconfig|   5 +
 hw/virtio/meson.build|   1 +
 hw/virtio/vdpa-dev.c | 376 +++
 include/hw/virtio/vdpa-dev.h |  43 
 4 files changed, 425 insertions(+)
 create mode 100644 hw/virtio/vdpa-dev.c
 create mode 100644 include/hw/virtio/vdpa-dev.h

diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index cbfd8c7173..89e9e426d8 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -85,3 +85,8 @@ config VHOST_USER_GPIO
 bool
 default y
 depends on VIRTIO && VHOST_USER
+
+config VHOST_VDPA_DEV
+bool
+default y
+depends on VIRTIO && VHOST_VDPA && LINUX
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index dfed1e7af5..54d6d29af7 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -31,6 +31,7 @@ virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: 
files('vhost-user-i2c.c'))
 virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: 
files('vhost-user-rng.c'))
 virtio_ss.add(when: 'CONFIG_VHOST_USER_GPIO', if_true: 
files('vhost-user-gpio.c'))
 virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_GPIO'], if_true: 
files('vhost-user-gpio-pci.c'))
+virtio_ss.add(when: 'CONFIG_VHOST_VDPA_DEV', if_true: files('vdpa-dev.c'))
 
 virtio_pci_ss = ss.source_set()
 virtio_pci_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: 
files('vhost-vsock-pci.c'))
diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
new file mode 100644
index 00..2885d06cbe
--- /dev/null
+++ b/hw/virtio/vdpa-dev.c
@@ -0,0 +1,376 @@
+/*
+ * Vhost Vdpa Device
+ *
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022. All Rights Reserved.
+ *
+ * Authors:
+ *   Longpeng 
+ *
+ * Largely based on the "vhost-user-blk-pci.c" and "vhost-user-blk.c"
+ * implemented by:
+ *   Changpeng Liu 
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include 
+#include 
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/cutils.h"
+#include "hw/qdev-core.h"
+#include "hw/qdev-properties.h"
+#include "hw/qdev-properties-system.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/virtio-access.h"
+#include "hw/virtio/vdpa-dev.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/runstate.h"
+
+static void
+vhost_vdpa_device_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+/* Nothing to do */
+}
+
+static uint32_t
+vhost_vdpa_device_get_u32(int fd, unsigned long int cmd, Error **errp)
+{
+uint32_t val = (uint32_t)-1;
+
+if (ioctl(fd, cmd, ) < 0) {
+error_setg(errp, "vhost-vdpa-device: cmd 0x%lx failed: %s",
+   cmd, strerror(errno));
+}
+
+return val;
+}
+
+static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp)
+{
+VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+VhostVdpaDevice *v = VHOST_VDPA_DEVICE(vdev);
+uint16_t max_queue_size;
+struct vhost_virtqueue *vqs;
+int i, ret;
+
+if (!v->vhostdev) {
+error_setg(errp, "vhost-vdpa-device: vhostdev are missing");
+return;
+}
+
+v->vhostfd = qemu_open(v->vhostdev, O_RDWR, errp);
+if (*errp) {
+return;
+}
+v->vdpa.device_fd = v->vhostfd;
+
+v->vdev_id = vhost_vdpa_device_get_u32(v->vhostfd,
+   VHOST_VDPA_GET_DEVICE_ID, errp);
+if (*errp) {
+goto out;
+}
+
+max_queue_size = vhost_vdpa_device_get_u32(v->vhostfd,
+   VHOST_VDPA_GET_VRING_NUM, errp);
+if (*errp) {
+goto out;
+}
+
+if (v->queue_size > max_queue_size) {
+error_setg(errp, "vhost-vdpa-device: invalid queue_size: %u (max:%u)",
+   v->queue_size, max_queue_size);
+goto out;
+} else if (!v->queue_size) {
+v->queue_size = max_queue_size;
+}
+
+v->num_queues = vhost_vdpa_device_get_u32(v->vhostfd,
+  VHOST_VDPA_GET_VQS_COUNT, errp);
+if (*errp) {
+goto out;
+}
+
+if (!v->num_queues || v->num_queues > VIRTIO_QUEUE_MAX) {
+error_setg(errp, "invalid number of virtqueues: %u (max:%u)",
+   v->num_queues, VIRTIO_QUEUE_MAX);
+goto out;
+}
+
+v->dev.nvqs = v->num_queues;
+vqs = g_new0(struct vhost_virtqueue, v->dev.nvqs);
+v->dev.vqs = vqs;
+v->dev.vq_index = 0;
+v->dev.vq_index_end = v->dev.nvqs;
+v->dev.backend_features = 0;
+v->started = false;
+
+ret = vhost_dev_init(>dev, >vdpa, VHOST_BACKEND_TYPE_VDPA, 0, NULL);
+if (ret < 0) {
+error_setg(errp, 

[PULL 11/14] disas/nanomips: Merge insn{1,2,3} into words[3]

2022-11-07 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

Since Disassemble wants the data in this format, collect
it that way.  This allows using a loop to print the bytes.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20221106212852.152384-3-richard.hender...@linaro.org>
---
 disas/nanomips.c | 44 +---
 1 file changed, 21 insertions(+), 23 deletions(-)

diff --git a/disas/nanomips.c b/disas/nanomips.c
index 83a39a878c..e462256760 100644
--- a/disas/nanomips.c
+++ b/disas/nanomips.c
@@ -21907,26 +21907,22 @@ static const Pool MAJOR[2] = {
0x0 },/* P16 */
 };
 
-static bool nanomips_dis(char **buf, Dis_info *info,
- unsigned short one,
- unsigned short two,
- unsigned short three)
+static bool nanomips_dis(const uint16_t *data, char **buf, Dis_info *info)
 {
-uint16 bits[3] = {one, two, three};
 TABLE_ENTRY_TYPE type;
 
 /* Handle runtime errors. */
 if (unlikely(sigsetjmp(info->buf, 0) != 0)) {
 return false;
 }
-return Disassemble(bits, buf, , MAJOR, ARRAY_SIZE(MAJOR), info) >= 0;
+return Disassemble(data, buf, , MAJOR, ARRAY_SIZE(MAJOR), info) >= 0;
 }
 
 int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info)
 {
 int status, length;
 bfd_byte buffer[2];
-uint16_t insn1 = 0, insn2 = 0, insn3 = 0;
+uint16_t words[3] = { };
 g_autofree char *buf = NULL;
 
 info->bytes_per_chunk = 2;
@@ -21950,15 +21946,14 @@ int print_insn_nanomips(bfd_vma memaddr, struct 
disassemble_info *info)
 }
 
 if (info->endian == BFD_ENDIAN_BIG) {
-insn1 = bfd_getb16(buffer);
+words[0] = bfd_getb16(buffer);
 } else {
-insn1 = bfd_getl16(buffer);
+words[0] = bfd_getl16(buffer);
 }
 length = 2;
-(*info->fprintf_func)(info->stream, "%04x ", insn1);
 
 /* Handle 32-bit opcodes.  */
-if ((insn1 & 0x1000) == 0) {
+if ((words[0] & 0x1000) == 0) {
 status = (*info->read_memory_func)(memaddr + 2, buffer, 2, info);
 if (status != 0) {
 (*info->memory_error_func)(status, memaddr + 2, info);
@@ -21966,17 +21961,15 @@ int print_insn_nanomips(bfd_vma memaddr, struct 
disassemble_info *info)
 }
 
 if (info->endian == BFD_ENDIAN_BIG) {
-insn2 = bfd_getb16(buffer);
+words[1] = bfd_getb16(buffer);
 } else {
-insn2 = bfd_getl16(buffer);
+words[1] = bfd_getl16(buffer);
 }
 length = 4;
-(*info->fprintf_func)(info->stream, "%04x ", insn2);
-} else {
-(*info->fprintf_func)(info->stream, " ");
 }
+
 /* Handle 48-bit opcodes.  */
-if ((insn1 >> 10) == 0x18) {
+if ((words[0] >> 10) == 0x18) {
 status = (*info->read_memory_func)(memaddr + 4, buffer, 2, info);
 if (status != 0) {
 (*info->memory_error_func)(status, memaddr + 4, info);
@@ -21984,17 +21977,22 @@ int print_insn_nanomips(bfd_vma memaddr, struct 
disassemble_info *info)
 }
 
 if (info->endian == BFD_ENDIAN_BIG) {
-insn3 = bfd_getb16(buffer);
+words[2] = bfd_getb16(buffer);
 } else {
-insn3 = bfd_getl16(buffer);
+words[2] = bfd_getl16(buffer);
 }
 length = 6;
-(*info->fprintf_func)(info->stream, "%04x ", insn3);
-} else {
-(*info->fprintf_func)(info->stream, " ");
 }
 
-if (nanomips_dis(, _info, insn1, insn2, insn3)) {
+for (int i = 0; i < ARRAY_SIZE(words); i++) {
+if (i * 2 < length) {
+(*info->fprintf_func)(info->stream, "%04x ", words[i]);
+} else {
+(*info->fprintf_func)(info->stream, " ");
+}
+}
+
+if (nanomips_dis(words, , _info)) {
 (*info->fprintf_func) (info->stream, "%s", buf);
 }
 
-- 
2.38.1




[PULL 04/14] target/mips: Disable DSP ASE for Octeon68XX

2022-11-07 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

I don't have access to Octeon68XX hardware but according
to my investigation Octeon never had DSP ASE support.

As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference
Manual" CP0C3_DSPP is reserved bit and read as 0. Also I do have
access to a Ubiquiti Edgerouter 4 which has Octeon CN7130 processor
and I can confirm CP0C3_DSPP is read as 0 on that processor.

Further more, in linux kernel:
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
cpu_has_dsp is overridden as 0.

So I believe we shouldn't emulate DSP in QEMU as well.

Signed-off-by: Jiaxun Yang 
Acked-by: Richard Henderson 
Reviewed-by: Pavel Dovgalyuk 
Message-Id: <20221031132531.18122-4-jiaxun.y...@flygoat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/cpu-defs.c.inc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/mips/cpu-defs.c.inc b/target/mips/cpu-defs.c.inc
index 7f53c94ec8..480e60aeec 100644
--- a/target/mips/cpu-defs.c.inc
+++ b/target/mips/cpu-defs.c.inc
@@ -934,7 +934,7 @@ const mips_def_t mips_defs[] =
(1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
(1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
 .CP0_Config2 = MIPS_CONFIG2,
-.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA) | (1 << CP0C3_DSPP) ,
+.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
 .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) |
(0x3c << CP0C4_KScrExist) | (1U << CP0C4_MMUExtDef) |
(3U << CP0C4_MMUSizeExt),
@@ -946,7 +946,7 @@ const mips_def_t mips_defs[] =
 .CP0_Status_rw_bitmask = 0x12F8,
 .SEGBITS = 42,
 .PABITS = 49,
-.insn_flags = CPU_MIPS64R2 | INSN_OCTEON | ASE_DSP,
+.insn_flags = CPU_MIPS64R2 | INSN_OCTEON,
 .mmu_type = MMU_TYPE_R4000,
 },
 
-- 
2.38.1




[PULL 13/14] disas/nanomips: Tidy read for 48-bit opcodes

2022-11-07 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

There is no point in looking for a 48-bit opcode if we've
not read the second word for a 32-bit opcode.

Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221106023735.5277-5-richard.hender...@linaro.org>
---
 disas/nanomips.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/disas/nanomips.c b/disas/nanomips.c
index 3b998118e3..a0253598dd 100644
--- a/disas/nanomips.c
+++ b/disas/nanomips.c
@@ -21964,14 +21964,14 @@ int print_insn_nanomips(bfd_vma memaddr, struct 
disassemble_info *info)
 return -1;
 }
 length = 4;
-}
 
-/* Handle 48-bit opcodes.  */
-if ((words[0] >> 10) == 0x18) {
-if (!read_u16([1], memaddr + 4, info)) {
-return -1;
+/* Handle 48-bit opcodes.  */
+if ((words[0] >> 10) == 0x18) {
+if (!read_u16([1], memaddr + 4, info)) {
+return -1;
+}
+length = 6;
 }
-length = 6;
 }
 
 for (int i = 0; i < ARRAY_SIZE(words); i++) {
-- 
2.38.1




[PULL 10/14] disas/nanomips: Move setjmp into nanomips_dis

2022-11-07 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

Reduce the number of local variables within the scope of the
setjmp by moving it to the existing helper.  The actual length
returned from Disassemble is not used, because we have already
determined the length while reading bytes.  Fixes:

nanomips.c: In function ‘print_insn_nanomips’:
nanomips.c:21925:14: error: variable ‘insn1’ might be clobbered by ‘longjmp’ or 
‘vfork’ [-Werror=clobbered]
nanomips.c:21925:25: error: variable ‘insn2’ might be clobbered by ‘longjmp’ or 
‘vfork’ [-Werror=clobbered]
nanomips.c:21925:36: error: variable ‘insn3’ might be clobbered by ‘longjmp’ or 
‘vfork’ [-Werror=clobbered]
nanomips.c:21926:22: error: variable ‘buf’ might be clobbered by ‘longjmp’ or 
‘vfork’ [-Werror=clobbered]

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20221106212852.152384-2-richard.hender...@linaro.org>
---
 disas/nanomips.c | 42 +-
 1 file changed, 17 insertions(+), 25 deletions(-)

diff --git a/disas/nanomips.c b/disas/nanomips.c
index 821d4f8832..83a39a878c 100644
--- a/disas/nanomips.c
+++ b/disas/nanomips.c
@@ -21907,22 +21907,24 @@ static const Pool MAJOR[2] = {
0x0 },/* P16 */
 };
 
-static int nanomips_dis(char **buf,
- Dis_info *info,
- unsigned short one,
- unsigned short two,
- unsigned short three)
+static bool nanomips_dis(char **buf, Dis_info *info,
+ unsigned short one,
+ unsigned short two,
+ unsigned short three)
 {
 uint16 bits[3] = {one, two, three};
-
 TABLE_ENTRY_TYPE type;
-int size = Disassemble(bits, buf, , MAJOR, 2, info);
-return size;
+
+/* Handle runtime errors. */
+if (unlikely(sigsetjmp(info->buf, 0) != 0)) {
+return false;
+}
+return Disassemble(bits, buf, , MAJOR, ARRAY_SIZE(MAJOR), info) >= 0;
 }
 
 int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info)
 {
-int status;
+int status, length;
 bfd_byte buffer[2];
 uint16_t insn1 = 0, insn2 = 0, insn3 = 0;
 g_autofree char *buf = NULL;
@@ -21952,6 +21954,7 @@ int print_insn_nanomips(bfd_vma memaddr, struct 
disassemble_info *info)
 } else {
 insn1 = bfd_getl16(buffer);
 }
+length = 2;
 (*info->fprintf_func)(info->stream, "%04x ", insn1);
 
 /* Handle 32-bit opcodes.  */
@@ -21967,6 +21970,7 @@ int print_insn_nanomips(bfd_vma memaddr, struct 
disassemble_info *info)
 } else {
 insn2 = bfd_getl16(buffer);
 }
+length = 4;
 (*info->fprintf_func)(info->stream, "%04x ", insn2);
 } else {
 (*info->fprintf_func)(info->stream, " ");
@@ -21984,27 +21988,15 @@ int print_insn_nanomips(bfd_vma memaddr, struct 
disassemble_info *info)
 } else {
 insn3 = bfd_getl16(buffer);
 }
+length = 6;
 (*info->fprintf_func)(info->stream, "%04x ", insn3);
 } else {
 (*info->fprintf_func)(info->stream, " ");
 }
 
-/* Handle runtime errors. */
-if (sigsetjmp(disassm_info.buf, 0) != 0) {
-info->insn_type = dis_noninsn;
-return insn3 ? 6 : insn2 ? 4 : 2;
+if (nanomips_dis(, _info, insn1, insn2, insn3)) {
+(*info->fprintf_func) (info->stream, "%s", buf);
 }
 
-int length = nanomips_dis(, _info, insn1, insn2, insn3);
-
-/* FIXME: Should probably use a hash table on the major opcode here.  */
-
-(*info->fprintf_func) (info->stream, "%s", buf);
-if (length > 0) {
-return length / 8;
-}
-
-info->insn_type = dis_noninsn;
-
-return insn3 ? 6 : insn2 ? 4 : 2;
+return length;
 }
-- 
2.38.1




[PULL 03/14] target/mips: Enable LBX/LWX/* instructions for Octeon

2022-11-07 Thread Philippe Mathieu-Daudé
From: Pavel Dovgalyuk 

This patch changes condition and function name for enabling
indexed load instructions for Octeon vCPUs. Octeons do not
have DSP extension, but implement LBX-and-others.

Signed-off-by: Pavel Dovgalyuk 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <166728058455.229236.13834649461181619195.stgit@pasha-ThinkPad-X280>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/translate.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 2f2d707a12..4c4bd0823d 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -12173,12 +12173,16 @@ enum {
 #include "nanomips_translate.c.inc"
 
 /* MIPSDSP functions. */
-static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
-   int rd, int base, int offset)
+
+/* Indexed load is not for DSP only */
+static void gen_mips_lx(DisasContext *ctx, uint32_t opc,
+int rd, int base, int offset)
 {
 TCGv t0;
 
-check_dsp(ctx);
+if (!(ctx->insn_flags & INSN_OCTEON)) {
+check_dsp(ctx);
+}
 t0 = tcg_temp_new();
 
 if (base == 0) {
@@ -14523,7 +14527,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
*env, DisasContext *ctx)
 case OPC_LBUX:
 case OPC_LHX:
 case OPC_LWX:
-gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
+gen_mips_lx(ctx, op2, rd, rs, rt);
 break;
 default:/* Invalid */
 MIPS_INVAL("MASK LX");
-- 
2.38.1




[PULL 12/14] disas/nanomips: Split out read_u16

2022-11-07 Thread Philippe Mathieu-Daudé
From: Richard Henderson 

Split out a helper function for reading a uint16_t
with the correct endianness.

Signed-off-by: Richard Henderson 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221106023735.5277-4-richard.hender...@linaro.org>
---
 disas/nanomips.c | 48 +++-
 1 file changed, 19 insertions(+), 29 deletions(-)

diff --git a/disas/nanomips.c b/disas/nanomips.c
index e462256760..3b998118e3 100644
--- a/disas/nanomips.c
+++ b/disas/nanomips.c
@@ -21918,10 +21918,24 @@ static bool nanomips_dis(const uint16_t *data, char 
**buf, Dis_info *info)
 return Disassemble(data, buf, , MAJOR, ARRAY_SIZE(MAJOR), info) >= 0;
 }
 
+static bool read_u16(uint16_t *ret, bfd_vma memaddr,
+ struct disassemble_info *info)
+{
+int status = (*info->read_memory_func)(memaddr, (bfd_byte *)ret, 2, info);
+if (status != 0) {
+(*info->memory_error_func)(status, memaddr, info);
+return false;
+}
+
+if ((info->endian == BFD_ENDIAN_BIG) != HOST_BIG_ENDIAN) {
+bswap16s(ret);
+}
+return true;
+}
+
 int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info)
 {
-int status, length;
-bfd_byte buffer[2];
+int length;
 uint16_t words[3] = { };
 g_autofree char *buf = NULL;
 
@@ -21939,48 +21953,24 @@ int print_insn_nanomips(bfd_vma memaddr, struct 
disassemble_info *info)
 disassm_info.fprintf_func = info->fprintf_func;
 disassm_info.stream = info->stream;
 
-status = (*info->read_memory_func)(memaddr, buffer, 2, info);
-if (status != 0) {
-(*info->memory_error_func)(status, memaddr, info);
+if (!read_u16([0], memaddr, info)) {
 return -1;
 }
-
-if (info->endian == BFD_ENDIAN_BIG) {
-words[0] = bfd_getb16(buffer);
-} else {
-words[0] = bfd_getl16(buffer);
-}
 length = 2;
 
 /* Handle 32-bit opcodes.  */
 if ((words[0] & 0x1000) == 0) {
-status = (*info->read_memory_func)(memaddr + 2, buffer, 2, info);
-if (status != 0) {
-(*info->memory_error_func)(status, memaddr + 2, info);
+if (!read_u16([1], memaddr + 2, info)) {
 return -1;
 }
-
-if (info->endian == BFD_ENDIAN_BIG) {
-words[1] = bfd_getb16(buffer);
-} else {
-words[1] = bfd_getl16(buffer);
-}
 length = 4;
 }
 
 /* Handle 48-bit opcodes.  */
 if ((words[0] >> 10) == 0x18) {
-status = (*info->read_memory_func)(memaddr + 4, buffer, 2, info);
-if (status != 0) {
-(*info->memory_error_func)(status, memaddr + 4, info);
+if (!read_u16([1], memaddr + 4, info)) {
 return -1;
 }
-
-if (info->endian == BFD_ENDIAN_BIG) {
-words[2] = bfd_getb16(buffer);
-} else {
-words[2] = bfd_getl16(buffer);
-}
 length = 6;
 }
 
-- 
2.38.1




[PULL 14/14] MAINTAINERS: Inherit from nanoMIPS

2022-11-07 Thread Philippe Mathieu-Daudé
6 months ago Stefan Pejic stepped in as nanoMIPS maintainer
(see commit a 8e0e23445a "target/mips: Undeprecate nanoMIPS
ISA support in QEMU"), however today his email is bouncing:

  ** Message blocked **

  Your message to stefan.pe...@syrmia.com has been blocked. See technical 
details below for more information.

  The response from the remote server was:
  550 5.4.1 Recipient address rejected: Access denied. AS(201806281) 
[DBAEUR03FT030.eop-EUR03.prod.protection.outlook.com]

To avoid unmaintained code, I feel forced to merge this code
back with the generic MIPS section.

Historical references:
- 
https://lore.kernel.org/qemu-devel/ty0pr03mb679726901bd6c6be40114a2fe2...@ty0pr03mb6797.apcprd03.prod.outlook.com/
- 
https://lore.kernel.org/qemu-devel/b858a20e97b74e7b90a94948314d0...@mtkmbs62n2.mediatek.inc/

Cc: Vince Del Vecchio 
Reviewed-by: Richard Henderson 
Message-Id: <49f41916-687f-b9e5-2de7-9c658fe0d...@linaro.org>
Tested-by: Thomas Huth 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20221101114458.25756-6-phi...@linaro.org>
---
 MAINTAINERS | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4adf8c65db..86bcd07a31 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -237,16 +237,10 @@ R: Jiaxun Yang 
 R: Aleksandar Rikalo 
 S: Odd Fixes
 F: target/mips/
-F: disas/mips.c
+F: disas/*mips.c
 F: docs/system/cpu-models-mips.rst.inc
 F: tests/tcg/mips/
 
-MIPS TCG CPUs (nanoMIPS ISA)
-M: Stefan Pejic 
-S: Maintained
-F: disas/nanomips.*
-F: target/mips/tcg/*nanomips*
-
 NiosII TCG CPUs
 M: Chris Wulff 
 M: Marek Vasut 
-- 
2.38.1




[PULL 01/14] target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F

2022-11-07 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

As per an unpublished document, in later reversion of chips
CP0St_{KX, SX, UX} is not writeable and hardcoded to 1.

Without those bits set, kernel is unable to access XKPHYS address
segment. So just set them up on CPU reset.

Signed-off-by: Jiaxun Yang 
Acked-by: Richard Henderson 
Message-Id: <20221031132531.18122-2-jiaxun.y...@flygoat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/cpu.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index e997c1b9cb..7a565466cb 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -302,6 +302,12 @@ static void mips_cpu_reset(DeviceState *dev)
 env->CP0_EntryHi_ASID_mask = (env->CP0_Config5 & (1 << CP0C5_MI)) ?
 0x0 : (env->CP0_Config4 & (1 << CP0C4_AE)) ? 0x3ff : 0xff;
 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
+if (env->insn_flags & INSN_LOONGSON2F) {
+/* Loongson-2F has those bits hardcoded to 1 */
+env->CP0_Status |= (1 << CP0St_KX) | (1 << CP0St_SX) |
+(1 << CP0St_UX);
+}
+
 /*
  * Vectored interrupts not implemented, timer on int 7,
  * no performance counters.
-- 
2.38.1




[PULL 08/14] disas/nanomips: Use G_GNUC_PRINTF to avoid invalid string formats

2022-11-07 Thread Philippe Mathieu-Daudé
Suggested-by: Stefan Weil 
Reviewed-by: Stefan Weil 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20221101114458.25756-4-phi...@linaro.org>
---
 disas/nanomips.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/disas/nanomips.c b/disas/nanomips.c
index e4b21e7c45..3f45447292 100644
--- a/disas/nanomips.c
+++ b/disas/nanomips.c
@@ -95,7 +95,7 @@ typedef struct Pool {
 #define IMGASSERTONCE(test)
 
 
-static char *img_format(const char *format, ...)
+static char * G_GNUC_PRINTF(1, 2) img_format(const char *format, ...)
 {
 char *buffer;
 va_list args;
-- 
2.38.1




[PULL 05/14] target/mips: Don't check COP1X for 64 bit FP mode

2022-11-07 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

Some implementations (i.e. Loongson-2F) may decide to implement
a 64 bit FPU without implementing COP1X instructions.

As the eligibility of 64 bit FP instructions is already determined
by CP0St_FR, there is no need to check for COP1X again.

Signed-off-by: Jiaxun Yang 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221102165719.190378-1-jiaxun.y...@flygoat.com>
[PMD: Add missing trailing parenthesis (buildfix)]
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/translate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 4c4bd0823d..624e6b7786 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1545,7 +1545,7 @@ void check_cop1x(DisasContext *ctx)
  */
 void check_cp1_64bitmode(DisasContext *ctx)
 {
-if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
+if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) {
 gen_reserved_instruction(ctx);
 }
 }
-- 
2.38.1




[PULL 07/14] disas/nanomips: Fix invalid PRIx64 format calling img_format()

2022-11-07 Thread Philippe Mathieu-Daudé
Fix:

  disas/nanomips.c:12231:62: warning: format specifies type 'char *' but the 
argument has type 'uint64' (aka 'unsigned long long') [-Wformat]
return img_format("RESTOREF 0x%" PRIx64 ", %s", u_value, count_value);
   ~~^~~
   %llu

Fixes: 4066c152b3 ("disas/nanomips: Remove IMMEDIATE functions")
Reported-by: Stefan Weil 
Reviewed-by: Stefan Weil 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20221101114458.25756-3-phi...@linaro.org>
---
 disas/nanomips.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/disas/nanomips.c b/disas/nanomips.c
index 6466c80dc5..e4b21e7c45 100644
--- a/disas/nanomips.c
+++ b/disas/nanomips.c
@@ -12235,7 +12235,8 @@ static char *RESTOREF(uint64 instruction, Dis_info 
*info)
 uint64 u_value = extract_u_11_10_9_8_7_6_5_4_3__s3(instruction);
 
 
-return img_format("RESTOREF 0x%" PRIx64 ", %s", u_value, count_value);
+return img_format("RESTOREF 0x%" PRIx64 ", 0x%" PRIx64,
+  u_value, count_value);
 }
 
 
-- 
2.38.1




[PULL 06/14] disas/nanomips: Fix invalid PRId64 format calling img_format()

2022-11-07 Thread Philippe Mathieu-Daudé
Fix warnings such:

  disas/nanomips.c:3251:64: warning: format specifies type 'char *' but the 
argument has type 'int64' (aka 'long long') [-Wformat]
return img_format("CACHE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs);
~~ ^~~
%lld

To avoid crashes such (kernel from commit f375ad6a0d):

  $ qemu-system-mipsel -cpu I7200 -d in_asm -kernel generic_nano32r6el_page4k
  ...
  
  IN: __bzero
  0x805c6084:  20c4 6950  ADDU r13, a0, a2
  0x805c6088:  9089   ADDIU a0, 1
  Process 70261 stopped
  * thread #6, stop reason = EXC_BAD_ACCESS (code=1, address=0xfff0)
  frame #0: 0x0001bfe38864 libsystem_platform.dylib`_platform_strlen + 4
  libsystem_platform.dylib`:
  ->  0x1bfe38864 <+4>:  ldrq0, [x1]
  0x1bfe38868 <+8>:  adrx3, #-0xc8; 
___lldb_unnamed_symbol314
  0x1bfe3886c <+12>: ldrq2, [x3], #0x10
  0x1bfe38870 <+16>: andx2, x0, #0xf
  Target 0: (qemu-system-mipsel) stopped.
  (lldb) bt
  * thread #6, stop reason = EXC_BAD_ACCESS (code=1, address=0xfff0)
* frame #0: 0x0001bfe38864 libsystem_platform.dylib`_platform_strlen + 4
  frame #1: 0x0001bfce76a0 libsystem_c.dylib`__vfprintf + 4544
  frame #2: 0x0001bfd158b4 libsystem_c.dylib`_vasprintf + 280
  frame #3: 0x000101c22fb0 libglib-2.0.0.dylib`g_vasprintf + 28
  frame #4: 0x000101bfb7d8 libglib-2.0.0.dylib`g_strdup_vprintf + 32
  frame #5: 0x0001fb70 
qemu-system-mipsel`img_format(format=) at nanomips.c:103:14 [opt]
  frame #6: 0x000100018868 
qemu-system-mipsel`SB_S9_(instruction=, info=) at 
nanomips.c:12616:12 [opt]
  frame #7: 0x0001f90c qemu-system-mipsel`print_insn_nanomips at 
nanomips.c:589:28 [opt]

Fixes: 4066c152b3 ("disas/nanomips: Remove IMMEDIATE functions")
Reported-by: Stefan Weil 
Reviewed-by: Stefan Weil 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20221101114458.25756-2-phi...@linaro.org>
---
 disas/nanomips.c | 35 ---
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/disas/nanomips.c b/disas/nanomips.c
index 9647f1a8e3..6466c80dc5 100644
--- a/disas/nanomips.c
+++ b/disas/nanomips.c
@@ -3252,7 +3252,8 @@ static char *CACHE(uint64 instruction, Dis_info *info)
 
 const char *rs = GPR(rs_value, info);
 
-return img_format("CACHE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs);
+return img_format("CACHE 0x%" PRIx64 ", %" PRId64 "(%s)",
+  op_value, s_value, rs);
 }
 
 
@@ -3274,7 +3275,8 @@ static char *CACHEE(uint64 instruction, Dis_info *info)
 
 const char *rs = GPR(rs_value, info);
 
-return img_format("CACHEE 0x%" PRIx64 ", %s(%s)", op_value, s_value, rs);
+return img_format("CACHEE 0x%" PRIx64 ", %" PRId64 "(%s)",
+  op_value, s_value, rs);
 }
 
 
@@ -5173,7 +5175,7 @@ static char *DADDIU_48_(uint64 instruction, Dis_info 
*info)
 
 const char *rt = GPR(rt_value, info);
 
-return img_format("DADDIU %s, %s", rt, s_value);
+return img_format("DADDIU %s, %" PRId64, rt, s_value);
 }
 
 
@@ -11859,7 +11861,7 @@ static char *PREF_S9_(uint64 instruction, Dis_info 
*info)
 
 const char *rs = GPR(rs_value, info);
 
-return img_format("PREF 0x%" PRIx64 ", %s(%s)",
+return img_format("PREF 0x%" PRIx64 ", %" PRId64 "(%s)",
   hint_value, s_value, rs);
 }
 
@@ -11905,7 +11907,8 @@ static char *PREFE(uint64 instruction, Dis_info *info)
 
 const char *rs = GPR(rs_value, info);
 
-return img_format("PREFE 0x%" PRIx64 ", %s(%s)", hint_value, s_value, rs);
+return img_format("PREFE 0x%" PRIx64 ", %" PRId64 "(%s)",
+  hint_value, s_value, rs);
 }
 
 
@@ -12079,7 +12082,7 @@ static char *REPL_PH(uint64 instruction, Dis_info *info)
 
 const char *rt = GPR(rt_value, info);
 
-return img_format("REPL.PH %s, %s", rt, s_value);
+return img_format("REPL.PH %s, %" PRId64, rt, s_value);
 }
 
 
@@ -12613,7 +12616,7 @@ static char *SB_S9_(uint64 instruction, Dis_info *info)
 const char *rt = GPR(rt_value, info);
 const char *rs = GPR(rs_value, info);
 
-return img_format("SB %s, %s(%s)", rt, s_value, rs);
+return img_format("SB %s, %" PRId64 "(%s)", rt, s_value, rs);
 }
 
 
@@ -12659,7 +12662,7 @@ static char *SBE(uint64 instruction, Dis_info *info)
 const char *rt = GPR(rt_value, info);
 const char *rs = GPR(rs_value, info);
 
-return img_format("SBE %s, %s(%s)", rt, s_value, rs);
+return img_format("SBE %s, %" PRId64 "(%s)", rt, s_value, rs);
 }
 
 
@@ -12706,7 +12709,7 @@ static char *SC(uint64 instruction, Dis_info *info)
 const char *rt = GPR(rt_value, info);
 const char *rs = GPR(rs_value, info);
 
-return img_format("SC %s, %s(%s)", rt, s_value, rs);
+return img_format("SC %s, %" PRId64 "(%s)", rt, s_value, rs);
 }
 
 
@@ 

[PULL 09/14] disas/nanomips: Remove headers already included by "qemu/osdep.h"

2022-11-07 Thread Philippe Mathieu-Daudé
Reviewed-by: Stefan Weil 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20221101114458.25756-5-phi...@linaro.org>
---
 disas/nanomips.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/disas/nanomips.c b/disas/nanomips.c
index 3f45447292..821d4f8832 100644
--- a/disas/nanomips.c
+++ b/disas/nanomips.c
@@ -30,10 +30,6 @@
 #include "qemu/osdep.h"
 #include "disas/dis-asm.h"
 
-#include 
-#include 
-#include 
-
 typedef int64_t int64;
 typedef uint64_t uint64;
 typedef uint32_t uint32;
-- 
2.38.1




[PULL 02/14] target/mips: Cast offset field of Octeon BBIT to int16_t

2022-11-07 Thread Philippe Mathieu-Daudé
From: Jiaxun Yang 

As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference
Manual" offset field is signed 16 bit value. However arg_BBIT.offset
is unsigned. We need to cast it as signed to do address calculation.

Signed-off-by: Jiaxun Yang 
Acked-by: Richard Henderson 
Acked-by: Pavel Dovgalyuk 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221031132531.18122-3-jiaxun.y...@flygoat.com>
Signed-off-by: Philippe Mathieu-Daudé 
---
 target/mips/tcg/octeon.decode | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode
index 8929ad088e..0c787cb498 100644
--- a/target/mips/tcg/octeon.decode
+++ b/target/mips/tcg/octeon.decode
@@ -12,7 +12,7 @@
 # BBIT13210 . . 
 
 %bbit_p  28:1 16:5
-BBIT 11 set:1 . 10 rs:5 . offset:16 p=%bbit_p
+BBIT 11 set:1 . 10 rs:5 . offset:s16 p=%bbit_p
 
 # Arithmetic
 # BADDU rd, rs, rt
-- 
2.38.1




[PULL 00/14] MIPS patches for 2022-11-08

2022-11-07 Thread Philippe Mathieu-Daudé
The following changes since commit cd706454c6cd239a477cb227caf3e3dfbb742d1a:

  Merge tag 'pull-request-2022-11-06' of https://gitlab.com/thuth/qemu into 
staging (2022-11-07 05:44:44 -0500)

are available in the Git repository at:

  https://github.com/philmd/qemu.git tags/mips-20221108

for you to fetch changes up to 617fbc31a25e699c4f7cdf0b5d172322516afb20:

  MAINTAINERS: Inherit from nanoMIPS (2022-11-08 00:39:03 +0100)


MIPS patches queue

- Remove -Wclobbered in nanoMIPS disassembler (Richard Henderson)
- Fix invalid string formats in nanoMIPS disassembler (myself)
- Allow Loongson-2F to access XKPHYS in kernel mode (Jiaxun Yang)
- Octeon opcode fixes (Jiaxun Yang, Pavel Dovgalyuk)
- MAINTAINERS nanoMIPS update



Jiaxun Yang (4):
  target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F
  target/mips: Cast offset field of Octeon BBIT to int16_t
  target/mips: Disable DSP ASE for Octeon68XX
  target/mips: Don't check COP1X for 64 bit FP mode

Pavel Dovgalyuk (1):
  target/mips: Enable LBX/LWX/* instructions for Octeon

Philippe Mathieu-Daudé (5):
  disas/nanomips: Fix invalid PRId64 format calling img_format()
  disas/nanomips: Fix invalid PRIx64 format calling img_format()
  disas/nanomips: Use G_GNUC_PRINTF to avoid invalid string formats
  disas/nanomips: Remove headers already included by "qemu/osdep.h"
  MAINTAINERS: Inherit from nanoMIPS

Richard Henderson (4):
  disas/nanomips: Move setjmp into nanomips_dis
  disas/nanomips: Merge insn{1,2,3} into words[3]
  disas/nanomips: Split out read_u16
  disas/nanomips: Tidy read for 48-bit opcodes

 MAINTAINERS   |   8 +-
 disas/nanomips.c  | 154 +++---
 target/mips/cpu-defs.c.inc|   4 +-
 target/mips/cpu.c |   6 ++
 target/mips/tcg/octeon.decode |   2 +-
 target/mips/tcg/translate.c   |  14 ++--
 6 files changed, 87 insertions(+), 101 deletions(-)

-- 
2.38.1




Re: [PATCH 0/2] util/log: Make the per-thread flag immutable

2022-11-07 Thread Stefan Hajnoczi
Merged, thanks!

Stefan



Re: [PULL 0/2] loongarch for 7.2 patches

2022-11-07 Thread Stefan Hajnoczi
Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/7.2 for any 
user-visible changes.


signature.asc
Description: PGP signature


[PULL v4 71/83] intel-iommu: don't warn guest errors when getting rid2pasid entry

2022-11-07 Thread Michael S. Tsirkin
From: Jason Wang 

We use to warn on wrong rid2pasid entry. But this error could be
triggered by the guest and could happens during initialization. So
let's don't warn in this case.

Reviewed-by: Peter Xu 
Signed-off-by: Jason Wang 
Message-Id: <20221028061436.30093-2-jasow...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Yi Liu 
---
 hw/i386/intel_iommu.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 6524c2ee32..271de995be 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1554,8 +1554,10 @@ static bool vtd_dev_pt_enabled(IntelIOMMUState *s, 
VTDContextEntry *ce)
 if (s->root_scalable) {
 ret = vtd_ce_get_rid2pasid_entry(s, ce, );
 if (ret) {
-error_report_once("%s: vtd_ce_get_rid2pasid_entry error: %"PRId32,
-  __func__, ret);
+/*
+ * This error is guest triggerable. We should assumt PT
+ * not enabled for safety.
+ */
 return false;
 }
 return (VTD_PE_GET_TYPE() == VTD_SM_PASID_ENTRY_PT);
@@ -1569,14 +1571,12 @@ static bool vtd_as_pt_enabled(VTDAddressSpace *as)
 {
 IntelIOMMUState *s;
 VTDContextEntry ce;
-int ret;
 
 assert(as);
 
 s = as->iommu_state;
-ret = vtd_dev_to_context_entry(s, pci_bus_num(as->bus),
-   as->devfn, );
-if (ret) {
+if (vtd_dev_to_context_entry(s, pci_bus_num(as->bus), as->devfn,
+ )) {
 /*
  * Possibly failed to parse the context entry for some reason
  * (e.g., during init, or any guest configuration errors on
-- 
MST




[PULL v4 70/83] vfio: move implement of vfio_get_xlat_addr() to memory.c

2022-11-07 Thread Michael S. Tsirkin
From: Cindy Lu 

- Move the implement vfio_get_xlat_addr to softmmu/memory.c, and
  change the name to memory_get_xlat_addr(). So we can use this
  function on other devices, such as vDPA device.
- Add a new function vfio_get_xlat_addr in vfio/common.c, and it will check
  whether the memory is backed by a discard manager. then device can
  have its own warning.

Signed-off-by: Cindy Lu 
Message-Id: <20221031031020.1405111-2-l...@redhat.com>
Acked-by: Alex Williamson 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/exec/memory.h |  4 +++
 hw/vfio/common.c  | 66 +++
 softmmu/memory.c  | 72 +++
 3 files changed, 81 insertions(+), 61 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index bfb1de8eea..d1e79c39dc 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -713,6 +713,10 @@ void 
ram_discard_manager_register_listener(RamDiscardManager *rdm,
 void ram_discard_manager_unregister_listener(RamDiscardManager *rdm,
  RamDiscardListener *rdl);
 
+bool memory_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
+  ram_addr_t *ram_addr, bool *read_only,
+  bool *mr_has_discard_manager);
+
 typedef struct CoalescedMemoryRange CoalescedMemoryRange;
 typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
 
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 6b5d8c0bf6..130e5d1dc7 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -578,45 +578,11 @@ static bool 
vfio_listener_skipped_section(MemoryRegionSection *section)
 static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr,
ram_addr_t *ram_addr, bool *read_only)
 {
-MemoryRegion *mr;
-hwaddr xlat;
-hwaddr len = iotlb->addr_mask + 1;
-bool writable = iotlb->perm & IOMMU_WO;
-
-/*
- * The IOMMU TLB entry we have just covers translation through
- * this IOMMU to its immediate target.  We need to translate
- * it the rest of the way through to memory.
- */
-mr = address_space_translate(_space_memory,
- iotlb->translated_addr,
- , , writable,
- MEMTXATTRS_UNSPECIFIED);
-if (!memory_region_is_ram(mr)) {
-error_report("iommu map to non memory area %"HWADDR_PRIx"",
- xlat);
-return false;
-} else if (memory_region_has_ram_discard_manager(mr)) {
-RamDiscardManager *rdm = memory_region_get_ram_discard_manager(mr);
-MemoryRegionSection tmp = {
-.mr = mr,
-.offset_within_region = xlat,
-.size = int128_make64(len),
-};
-
-/*
- * Malicious VMs can map memory into the IOMMU, which is expected
- * to remain discarded. vfio will pin all pages, populating memory.
- * Disallow that. vmstate priorities make sure any RamDiscardManager
- * were already restored before IOMMUs are restored.
- */
-if (!ram_discard_manager_is_populated(rdm, )) {
-error_report("iommu map to discarded memory (e.g., unplugged via"
- " virtio-mem): %"HWADDR_PRIx"",
- iotlb->translated_addr);
-return false;
-}
+bool ret, mr_has_discard_manager;
 
+ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only,
+   _has_discard_manager);
+if (ret && mr_has_discard_manager) {
 /*
  * Malicious VMs might trigger discarding of IOMMU-mapped memory. The
  * pages will remain pinned inside vfio until unmapped, resulting in a
@@ -635,29 +601,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void 
**vaddr,
  " intended via an IOMMU. It's possible to mitigate "
  " by setting/adjusting RLIMIT_MEMLOCK.");
 }
-
-/*
- * Translation truncates length to the IOMMU page size,
- * check that it did not truncate too much.
- */
-if (len & iotlb->addr_mask) {
-error_report("iommu has granularity incompatible with target AS");
-return false;
-}
-
-if (vaddr) {
-*vaddr = memory_region_get_ram_ptr(mr) + xlat;
-}
-
-if (ram_addr) {
-*ram_addr = memory_region_get_ram_addr(mr) + xlat;
-}
-
-if (read_only) {
-*read_only = !writable || mr->readonly;
-}
-
-return true;
+return ret;
 }
 
 static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb)
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 7ba2048836..bc0be3f62c 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -33,6 +33,7 @@
 #include "qemu/accel.h"
 #include "hw/boards.h"
 #include "migration/vmstate.h"
+#include "exec/address-spaces.h"
 
 //#define DEBUG_UNASSIGNED
 
@@ -2121,6 

Re: [PATCH 1/2] target/mips: Don't check COP1X for 64 bit FP mode

2022-11-07 Thread Philippe Mathieu-Daudé

On 7/11/22 23:47, Philippe Mathieu-Daudé wrote:

On 2/11/22 17:57, Jiaxun Yang wrote:

Some implementations (i.e. Loongson-2F) may decide to implement a 64 bit
FPU without implmenting COP1X instructions.

As the eligibility of 64 bit FP instructions is already determined by
CP0St_FR, there is no need to check for COP1X again.

Signed-off-by: Jiaxun Yang 
---
  target/mips/tcg/translate.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index 2f2d707a12..e49d2a25a8 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -1545,7 +1545,7 @@ void check_cop1x(DisasContext *ctx)
   */
  void check_cp1_64bitmode(DisasContext *ctx)
  {
-    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
+    if (unlikely(~ctx->hflags & MIPS_HFLAG_F64) {
  gen_reserved_instruction(ctx);
  }
  }


Did you test your patch? I'm getting:

../../target/mips/tcg/translate.c:1548:49: error: expected ')'
if (unlikely(~ctx->hflags & MIPS_HFLAG_F64) {
^
../../target/mips/tcg/translate.c:1548:8: note: to match this '('
if (unlikely(~ctx->hflags & MIPS_HFLAG_F64) {
   ^
../../target/mips/tcg/translate.c:1551:1: error: expected statement
}
^




[PULL v4 29/83] virtio: introduce virtio_queue_enable()

2022-11-07 Thread Michael S. Tsirkin
From: Kangjie Xu 

Introduce the interface queue_enable() in VirtioDeviceClass and the
fucntion virtio_queue_enable() in virtio, it can be called when
VIRTIO_PCI_COMMON_Q_ENABLE is written and related virtqueue can be
started. It only supports the devices of virtio 1 or later. The
not-supported devices can only start the virtqueue when DRIVER_OK.

Signed-off-by: Kangjie Xu 
Signed-off-by: Xuan Zhuo 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-4-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/hw/virtio/virtio.h |  2 ++
 hw/virtio/virtio.c | 14 ++
 2 files changed, 16 insertions(+)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index 74d76c1dbc..b00b3fcf31 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -149,6 +149,7 @@ struct VirtioDeviceClass {
 void (*reset)(VirtIODevice *vdev);
 void (*set_status)(VirtIODevice *vdev, uint8_t val);
 void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index);
+void (*queue_enable)(VirtIODevice *vdev, uint32_t queue_index);
 /* For transitional devices, this is a bitmap of features
  * that are only exposed on the legacy interface but not
  * the modern one.
@@ -288,6 +289,7 @@ int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, 
int n,
 int virtio_set_status(VirtIODevice *vdev, uint8_t val);
 void virtio_reset(void *opaque);
 void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index);
+void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index);
 void virtio_update_irq(VirtIODevice *vdev);
 int virtio_set_features(VirtIODevice *vdev, uint64_t val);
 
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index cf5f9ca387..9683b2e158 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2495,6 +2495,20 @@ void virtio_queue_reset(VirtIODevice *vdev, uint32_t 
queue_index)
 __virtio_queue_reset(vdev, queue_index);
 }
 
+void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index)
+{
+VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+
+if (!virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) {
+error_report("queue_enable is only suppported in devices of virtio "
+ "1.0 or later.");
+}
+
+if (k->queue_enable) {
+k->queue_enable(vdev, queue_index);
+}
+}
+
 void virtio_reset(void *opaque)
 {
 VirtIODevice *vdev = opaque;
-- 
MST




[PULL v4 83/83] checkpatch: better pattern for inline comments

2022-11-07 Thread Michael S. Tsirkin
checkpatch is unhappy about this line:

WARNING: Block comments use a leading /* on a separate line
#50: FILE: hw/acpi/nvdimm.c:1074:
+   aml_equal(aml_sizeof(pckg), aml_int(1)) /* 1 element? 
*/));

but there's nothing wrong with it - the check is just too simplistic. It
will also miss lines which mix inline and block comments.

Instead, let's strip all inline comments from a line and then check for block
comments.

Signed-off-by: Michael S. Tsirkin 
---
 scripts/checkpatch.pl | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index e3e3b43076..bc7d4780ec 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1681,8 +1681,10 @@ sub process {
 # Block comment styles
 
# Block comments use /* on a line of its own
-   if ($rawline !~ m@^\+.*/\*.*\*/[ \t)}]*$@ &&#inline /*...*/
-   $rawline =~ m@^\+.*/\*\*?+[ \t]*[^ \t]@) { # /* or /** 
non-blank
+   my $commentline = $rawline;
+   while ($commentline =~ s@^(\+.*)/\*.*\*/@$1@o) { # remove 
inline #inline /*...*/
+   }
+   if ($commentline =~ m@^\+.*/\*\*?+[ \t]*[^ \t]@) { # /* or /** 
non-blank
WARN("Block comments use a leading /* on a separate 
line\n" . $herecurr);
}
 
-- 
MST




[PULL v4 78/83] bios-tables-test: teach test to use smbios 3.0 tables

2022-11-07 Thread Michael S. Tsirkin
From: Julia Suvorova 

Introduce the 64-bit entry point. Since we no longer have a total
number of structures, stop checking for the new ones at the EOF
structure (type 127).

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
Message-Id: <20220731162141.178443-3-jus...@redhat.com>
Message-Id: <2022101731.101412-3-jus...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/qtest/bios-tables-test.c | 100 +
 1 file changed, 76 insertions(+), 24 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index e805b3efec..aa91b0fca5 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -88,8 +88,8 @@ typedef struct {
 uint64_t rsdp_addr;
 uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */];
 GArray *tables;
-uint32_t smbios_ep_addr;
-struct smbios_21_entry_point smbios_ep_table;
+uint64_t smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE__MAX];
+SmbiosEntryPoint smbios_ep_table;
 uint16_t smbios_cpu_max_speed;
 uint16_t smbios_cpu_curr_speed;
 uint8_t *required_struct_types;
@@ -533,10 +533,9 @@ static void test_acpi_asl(test_data *data)
 free_test_data(_data);
 }
 
-static bool smbios_ep_table_ok(test_data *data)
+static bool smbios_ep2_table_ok(test_data *data, uint32_t addr)
 {
-struct smbios_21_entry_point *ep_table = >smbios_ep_table;
-uint32_t addr = data->smbios_ep_addr;
+struct smbios_21_entry_point *ep_table = >smbios_ep_table.ep21;
 
 qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
 if (memcmp(ep_table->anchor_string, "_SM_", 4)) {
@@ -559,13 +558,29 @@ static bool smbios_ep_table_ok(test_data *data)
 return true;
 }
 
-static void test_smbios_entry_point(test_data *data)
+static bool smbios_ep3_table_ok(test_data *data, uint64_t addr)
+{
+struct smbios_30_entry_point *ep_table = >smbios_ep_table.ep30;
+
+qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
+if (memcmp(ep_table->anchor_string, "_SM3_", 5)) {
+return false;
+}
+
+if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) {
+return false;
+}
+
+return true;
+}
+
+static SmbiosEntryPointType test_smbios_entry_point(test_data *data)
 {
 uint32_t off;
 
 /* find smbios entry point structure */
 for (off = 0xf; off < 0x10; off += 0x10) {
-uint8_t sig[] = "_SM_";
+uint8_t sig[] = "_SM_", sig3[] = "_SM3_";
 int i;
 
 for (i = 0; i < sizeof sig - 1; ++i) {
@@ -574,14 +589,30 @@ static void test_smbios_entry_point(test_data *data)
 
 if (!memcmp(sig, "_SM_", sizeof sig)) {
 /* signature match, but is this a valid entry point? */
-data->smbios_ep_addr = off;
-if (smbios_ep_table_ok(data)) {
+if (smbios_ep2_table_ok(data, off)) {
+data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] = off;
+}
+}
+
+for (i = 0; i < sizeof sig3 - 1; ++i) {
+sig3[i] = qtest_readb(data->qts, off + i);
+}
+
+if (!memcmp(sig3, "_SM3_", sizeof sig3)) {
+if (smbios_ep3_table_ok(data, off)) {
+data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] = off;
+/* found 64-bit entry point, no need to look for 32-bit one */
 break;
 }
 }
 }
 
-g_assert_cmphex(off, <, 0x10);
+/* found at least one entry point */
+g_assert_true(data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] ||
+  data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64]);
+
+return data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] ?
+   SMBIOS_ENTRY_POINT_TYPE_64 : SMBIOS_ENTRY_POINT_TYPE_32;
 }
 
 static inline bool smbios_single_instance(uint8_t type)
@@ -625,16 +656,23 @@ static bool smbios_cpu_test(test_data *data, uint32_t 
addr)
 return true;
 }
 
-static void test_smbios_structs(test_data *data)
+static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type)
 {
 DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
-struct smbios_21_entry_point *ep_table = >smbios_ep_table;
-uint32_t addr = le32_to_cpu(ep_table->structure_table_address);
-int i, len, max_len = 0;
+
+SmbiosEntryPoint *ep_table = >smbios_ep_table;
+int i = 0, len, max_len = 0;
 uint8_t type, prv, crt;
+uint64_t addr;
+
+if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) {
+addr = le32_to_cpu(ep_table->ep21.structure_table_address);
+} else {
+addr = le64_to_cpu(ep_table->ep30.structure_table_address);
+}
 
 /* walk the smbios tables */
-for (i = 0; i < le16_to_cpu(ep_table->number_of_structures); i++) {
+do {
 
 /* grab type and formatted area length from struct header */
 type = qtest_readb(data->qts, addr);
@@ -660,19 +698,33 @@ static void test_smbios_structs(test_data *data)
 }
 
 

[PULL v4 17/83] tests/acpi: virt: allow acpi MADT and FADT changes

2022-11-07 Thread Michael S. Tsirkin
From: Miguel Luis 

Step 3 from bios-tables-test.c documented procedure.

Signed-off-by: Miguel Luis 
Message-Id: <20221011181730.10885-2-miguel.l...@oracle.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Acked-by: Ani Sinha 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..8dc50f7a8a 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,7 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/virt/FACP",
+"tests/data/acpi/virt/FACP.numamem",
+"tests/data/acpi/virt/FACP.memhp",
+"tests/data/acpi/virt/APIC",
+"tests/data/acpi/virt/APIC.memhp",
+"tests/data/acpi/virt/APIC.numamem",
-- 
MST




[PULL v4 49/83] acpi: add get_dev_aml_func() helper

2022-11-07 Thread Michael S. Tsirkin
From: Igor Mammedov 

It will be used in followup commits to figure out if
device has it's own, device specific AML block.

Signed-off-by: Igor Mammedov 
Message-Id: <20221017102146.2254096-7-imamm...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Ani Sinha 
---
 include/hw/acpi/acpi_aml_interface.h | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/include/hw/acpi/acpi_aml_interface.h 
b/include/hw/acpi/acpi_aml_interface.h
index ab76f0e55d..436da069d6 100644
--- a/include/hw/acpi/acpi_aml_interface.h
+++ b/include/hw/acpi/acpi_aml_interface.h
@@ -29,11 +29,20 @@ struct AcpiDevAmlIfClass {
 dev_aml_fn build_dev_aml;
 };
 
-static inline void call_dev_aml_func(DeviceState *dev, Aml *scope)
+static inline dev_aml_fn get_dev_aml_func(DeviceState *dev)
 {
 if (object_dynamic_cast(OBJECT(dev), TYPE_ACPI_DEV_AML_IF)) {
 AcpiDevAmlIfClass *klass = ACPI_DEV_AML_IF_GET_CLASS(dev);
-klass->build_dev_aml(ACPI_DEV_AML_IF(dev), scope);
+return klass->build_dev_aml;
+}
+return NULL;
+}
+
+static inline void call_dev_aml_func(DeviceState *dev, Aml *scope)
+{
+dev_aml_fn fn = get_dev_aml_func(dev);
+if (fn) {
+fn(ACPI_DEV_AML_IF(dev), scope);
 }
 }
 
-- 
MST




Re: [PATCH 1/2] target/mips: Don't check COP1X for 64 bit FP mode

2022-11-07 Thread Philippe Mathieu-Daudé

On 2/11/22 17:57, Jiaxun Yang wrote:

Some implementations (i.e. Loongson-2F) may decide to implement a 64 bit
FPU without implmenting COP1X instructions.

As the eligibility of 64 bit FP instructions is already determined by
CP0St_FR, there is no need to check for COP1X again.

Signed-off-by: Jiaxun Yang 
---
  target/mips/tcg/translate.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)


Queued to mips-fixes, thanks.



[PULL v4 28/83] virtio: introduce virtio_queue_reset()

2022-11-07 Thread Michael S. Tsirkin
From: Xuan Zhuo 

Introduce a new interface function virtio_queue_reset() to implement
reset for vq.

Add a new callback to VirtioDeviceClass for queue reset operation for
each child device.

Signed-off-by: Xuan Zhuo 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-3-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/hw/virtio/virtio.h |  2 ++
 hw/virtio/virtio.c | 11 +++
 2 files changed, 13 insertions(+)

diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index f41b4a7e64..74d76c1dbc 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -148,6 +148,7 @@ struct VirtioDeviceClass {
 void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
 void (*reset)(VirtIODevice *vdev);
 void (*set_status)(VirtIODevice *vdev, uint8_t val);
+void (*queue_reset)(VirtIODevice *vdev, uint32_t queue_index);
 /* For transitional devices, this is a bitmap of features
  * that are only exposed on the legacy interface but not
  * the modern one.
@@ -286,6 +287,7 @@ int virtio_queue_set_host_notifier_mr(VirtIODevice *vdev, 
int n,
   MemoryRegion *mr, bool assign);
 int virtio_set_status(VirtIODevice *vdev, uint8_t val);
 void virtio_reset(void *opaque);
+void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index);
 void virtio_update_irq(VirtIODevice *vdev);
 int virtio_set_features(VirtIODevice *vdev, uint64_t val);
 
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 6f42fcadd7..cf5f9ca387 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2484,6 +2484,17 @@ static void __virtio_queue_reset(VirtIODevice *vdev, 
uint32_t i)
 virtio_virtqueue_reset_region_cache(>vq[i]);
 }
 
+void virtio_queue_reset(VirtIODevice *vdev, uint32_t queue_index)
+{
+VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
+
+if (k->queue_reset) {
+k->queue_reset(vdev, queue_index);
+}
+
+__virtio_queue_reset(vdev, queue_index);
+}
+
 void virtio_reset(void *opaque)
 {
 VirtIODevice *vdev = opaque;
-- 
MST




Re: [PATCH v2 2/3] target/mips: Cast offset field of Octeon BBIT to int16_t

2022-11-07 Thread Philippe Mathieu-Daudé

On 31/10/22 14:25, Jiaxun Yang wrote:

As per "Cavium Networks OCTEON Plus CN50XX Hardware Reference
Manual" offset field is signed 16 bit value. However arg_BBIT.offset
is unsigned. We need to cast it as signed to do address calculation.

Signed-off-by: Jiaxun Yang 
---
v2:
Do casting in decodetree. (philmd)
---
  target/mips/tcg/octeon.decode | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/mips/tcg/octeon.decode b/target/mips/tcg/octeon.decode
index 8929ad088e..0c787cb498 100644
--- a/target/mips/tcg/octeon.decode
+++ b/target/mips/tcg/octeon.decode
@@ -12,7 +12,7 @@
  # BBIT13210 . . 
  
  %bbit_p  28:1 16:5

-BBIT 11 set:1 . 10 rs:5 . offset:16 p=%bbit_p
+BBIT 11 set:1 . 10 rs:5 . offset:s16 p=%bbit_p
  
  # Arithmetic

  # BADDU rd, rs, rt


Reviewed-by: Philippe Mathieu-Daudé 




[PULL v4 35/83] vhost-net: vhost-kernel: introduce vhost_net_virtqueue_reset()

2022-11-07 Thread Michael S. Tsirkin
From: Kangjie Xu 

Introduce vhost_virtqueue_reset(), which can reset the specific
virtqueue in the device. Then it will unmap vrings and the desc
of the virtqueue.

Here we do not reuse the vhost_net_stop_one() or vhost_dev_stop(),
because they work at queue pair level. We do not use
vhost_virtqueue_stop() because it may stop the device in the
backend.

This patch only considers the case of vhost-kernel, when
NetClientDriver is NET_CLIENT_DRIVER_TAP.

Furthermore, we do not need net->nc->info->poll() because
it enables userspace datapath and we want to stop all
datapaths for this reset virtqueue here.

Signed-off-by: Kangjie Xu 
Signed-off-by: Xuan Zhuo 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-10-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/net/vhost_net.h |  2 ++
 hw/net/vhost_net-stub.c |  6 ++
 hw/net/vhost_net.c  | 25 +
 3 files changed, 33 insertions(+)

diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 387e913e4e..85d85a4957 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -48,4 +48,6 @@ uint64_t vhost_net_get_acked_features(VHostNetState *net);
 
 int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu);
 
+void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc,
+   int vq_index);
 #endif
diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c
index 89d71cfb8e..2d745e359c 100644
--- a/hw/net/vhost_net-stub.c
+++ b/hw/net/vhost_net-stub.c
@@ -101,3 +101,9 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu)
 {
 return 0;
 }
+
+void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc,
+   int vq_index)
+{
+
+}
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index d28f8b974b..8beecb4d22 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -531,3 +531,28 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu)
 
 return vhost_ops->vhost_net_set_mtu(>dev, mtu);
 }
+
+void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc,
+   int vq_index)
+{
+VHostNetState *net = get_vhost_net(nc->peer);
+const VhostOps *vhost_ops = net->dev.vhost_ops;
+struct vhost_vring_file file = { .fd = -1 };
+int idx;
+
+/* should only be called after backend is connected */
+assert(vhost_ops);
+
+idx = vhost_ops->vhost_get_vq_index(>dev, vq_index);
+
+if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
+file.index = idx;
+int r = vhost_net_set_backend(>dev, );
+assert(r >= 0);
+}
+
+vhost_virtqueue_stop(>dev,
+ vdev,
+ net->dev.vqs + idx,
+ net->dev.vq_index + idx);
+}
-- 
MST




[PULL v4 41/83] virtio-net: enable vq reset feature

2022-11-07 Thread Michael S. Tsirkin
From: Xuan Zhuo 

Add virtqueue reset feature for virtio-net

Signed-off-by: Xuan Zhuo 
Message-Id: <20221017092558.111082-16-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/net/virtio-net.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index e68daf51bb..8b32339b76 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -788,6 +788,7 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, 
uint64_t features,
 }
 
 if (!get_vhost_net(nc->peer)) {
+virtio_add_feature(, VIRTIO_F_RING_RESET);
 return features;
 }
 
-- 
MST




[PULL v4 40/83] vhost: vhost-kernel: enable vq reset feature

2022-11-07 Thread Michael S. Tsirkin
From: Kangjie Xu 

Add virtqueue reset feature for vhost-kernel.

Signed-off-by: Kangjie Xu 
Signed-off-by: Xuan Zhuo 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-15-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/net/vhost_net.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index d2926e2ed6..53b2fac4f6 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -47,6 +47,7 @@ static const int kernel_feature_bits[] = {
 VIRTIO_NET_F_MTU,
 VIRTIO_F_IOMMU_PLATFORM,
 VIRTIO_F_RING_PACKED,
+VIRTIO_F_RING_RESET,
 VIRTIO_NET_F_HASH_REPORT,
 VHOST_INVALID_FEATURE_BIT
 };
-- 
MST




[PULL v4 80/83] bios-tables-test: add test for number of cores > 255

2022-11-07 Thread Michael S. Tsirkin
From: Julia Suvorova 

The new test is run with a large number of cpus and checks if the
core_count field in smbios_cpu_test (structure type 4) is correct.

Choose q35 as it allows to run with -smp > 255.

Signed-off-by: Julia Suvorova 
Message-Id: <20220731162141.178443-5-jus...@redhat.com>
Message-Id: <2022101731.101412-5-jus...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Igor Mammedov 
---
 tests/qtest/bios-tables-test.c | 58 ++
 1 file changed, 45 insertions(+), 13 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index aa91b0fca5..395d441212 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -92,6 +92,8 @@ typedef struct {
 SmbiosEntryPoint smbios_ep_table;
 uint16_t smbios_cpu_max_speed;
 uint16_t smbios_cpu_curr_speed;
+uint8_t smbios_core_count;
+uint16_t smbios_core_count2;
 uint8_t *required_struct_types;
 int required_struct_types_len;
 QTestState *qts;
@@ -631,29 +633,42 @@ static inline bool smbios_single_instance(uint8_t type)
 }
 }
 
-static bool smbios_cpu_test(test_data *data, uint32_t addr)
+static void smbios_cpu_test(test_data *data, uint32_t addr,
+SmbiosEntryPointType ep_type)
 {
-uint16_t expect_speed[2];
-uint16_t real;
+uint8_t core_count, expected_core_count = data->smbios_core_count;
+uint16_t speed, expected_speed[2];
+uint16_t core_count2, expected_core_count2 = data->smbios_core_count2;
 int offset[2];
 int i;
 
 /* Check CPU speed for backward compatibility */
 offset[0] = offsetof(struct smbios_type_4, max_speed);
 offset[1] = offsetof(struct smbios_type_4, current_speed);
-expect_speed[0] = data->smbios_cpu_max_speed ? : 2000;
-expect_speed[1] = data->smbios_cpu_curr_speed ? : 2000;
+expected_speed[0] = data->smbios_cpu_max_speed ? : 2000;
+expected_speed[1] = data->smbios_cpu_curr_speed ? : 2000;
 
 for (i = 0; i < 2; i++) {
-real = qtest_readw(data->qts, addr + offset[i]);
-if (real != expect_speed[i]) {
-fprintf(stderr, "Unexpected SMBIOS CPU speed: real %u expect %u\n",
-real, expect_speed[i]);
-return false;
-}
+speed = qtest_readw(data->qts, addr + offset[i]);
+g_assert_cmpuint(speed, ==, expected_speed[i]);
 }
 
-return true;
+core_count = qtest_readb(data->qts,
+addr + offsetof(struct smbios_type_4, core_count));
+
+if (expected_core_count) {
+g_assert_cmpuint(core_count, ==, expected_core_count);
+}
+
+if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
+core_count2 = qtest_readw(data->qts,
+  addr + offsetof(struct smbios_type_4, core_count2));
+
+/* Core Count has reached its limit, checking Core Count 2 */
+if (expected_core_count == 0xFF && expected_core_count2) {
+g_assert_cmpuint(core_count2, ==, expected_core_count2);
+}
+}
 }
 
 static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type)
@@ -686,7 +701,7 @@ static void test_smbios_structs(test_data *data, 
SmbiosEntryPointType ep_type)
 set_bit(type, struct_bitmap);
 
 if (type == 4) {
-g_assert(smbios_cpu_test(data, addr));
+smbios_cpu_test(data, addr, ep_type);
 }
 
 /* seek to end of unformatted string area of this struct ("\0\0") */
@@ -908,6 +923,21 @@ static void test_acpi_q35_tcg(void)
 free_test_data();
 }
 
+static void test_acpi_q35_tcg_core_count2(void)
+{
+test_data data = {
+.machine = MACHINE_Q35,
+.variant = ".core-count2",
+.required_struct_types = base_required_struct_types,
+.required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
+.smbios_core_count = 0xFF,
+.smbios_core_count2 = 275,
+};
+
+test_acpi_one("-machine smbios-entry-point-type=64 -smp 275", );
+free_test_data();
+}
+
 static void test_acpi_q35_tcg_bridge(void)
 {
 test_data data;
@@ -1994,6 +2024,8 @@ int main(int argc, char *argv[])
 if (has_kvm) {
 qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic);
 qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
+qtest_add_func("acpi/q35/core-count2",
+   test_acpi_q35_tcg_core_count2);
 }
 qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
 #ifdef CONFIG_POSIX
-- 
MST




[PULL v4 79/83] tests/acpi: allow changes for core_count2 test

2022-11-07 Thread Michael S. Tsirkin
From: Julia Suvorova 

Signed-off-by: Julia Suvorova 
Message-Id: <20220731162141.178443-4-jus...@redhat.com>
Message-Id: <2022101731.101412-4-jus...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Acked-by: Igor Mammedov 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 tests/data/acpi/q35/APIC.core-count2| 0
 tests/data/acpi/q35/DSDT.core-count2| 0
 tests/data/acpi/q35/FACP.core-count2| 0
 4 files changed, 3 insertions(+)
 create mode 100644 tests/data/acpi/q35/APIC.core-count2
 create mode 100644 tests/data/acpi/q35/DSDT.core-count2
 create mode 100644 tests/data/acpi/q35/FACP.core-count2

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..e81dc67a2e 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/APIC.core-count2",
+"tests/data/acpi/q35/DSDT.core-count2",
+"tests/data/acpi/q35/FACP.core-count2",
diff --git a/tests/data/acpi/q35/APIC.core-count2 
b/tests/data/acpi/q35/APIC.core-count2
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/q35/DSDT.core-count2 
b/tests/data/acpi/q35/DSDT.core-count2
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/q35/FACP.core-count2 
b/tests/data/acpi/q35/FACP.core-count2
new file mode 100644
index 00..e69de29bb2
-- 
MST




Re: [PATCH] target/mips: enable LBX/LWX/* instructions for Octeon

2022-11-07 Thread Philippe Mathieu-Daudé

On 1/11/22 06:29, Pavel Dovgalyuk wrote:

This patch changes condition and function name for enabling
indexed load instructions for Octeon vCPUs. Octeons do not
have DSP extension, but implement LBX-and-others.

Signed-off-by: Pavel Dovgalyuk 
---
  target/mips/tcg/translate.c |   10 +++---
  1 file changed, 7 insertions(+), 3 deletions(-)


Queued to mips-fixes, thanks.



[PULL v4 69/83] tests: virt: Update expected *.acpihmatvirt tables

2022-11-07 Thread Michael S. Tsirkin
From: Hesham Almatary 

* Expected ACPI Data Table [HMAT]
[000h    4]Signature : "HMAT"[Heterogeneous
Memory Attributes Table]
[004h 0004   4] Table Length : 0120
[008h 0008   1] Revision : 02
[009h 0009   1] Checksum : 4F
[00Ah 0010   6]   Oem ID : "BOCHS "
[010h 0016   8] Oem Table ID : "BXPC"
[018h 0024   4] Oem Revision : 0001
[01Ch 0028   4]  Asl Compiler ID : "BXPC"
[020h 0032   4]Asl Compiler Revision : 0001

[024h 0036   4] Reserved : 

[028h 0040   2]   Structure Type :  [Memory Proximity
Domain Attributes]
[02Ah 0042   2] Reserved : 
[02Ch 0044   4]   Length : 0028
[030h 0048   2]Flags (decoded below) : 0001
Processor Proximity Domain Valid : 1
[032h 0050   2]Reserved1 : 
[034h 0052   4]   Processor Proximity Domain : 
[038h 0056   4]  Memory Proximity Domain : 
[03Ch 0060   4]Reserved2 : 
[040h 0064   8]Reserved3 : 
[048h 0072   8]Reserved4 : 

[050h 0080   2]   Structure Type :  [Memory Proximity
Domain Attributes]
[052h 0082   2] Reserved : 
[054h 0084   4]   Length : 0028
[058h 0088   2]Flags (decoded below) : 0001
Processor Proximity Domain Valid : 1
[05Ah 0090   2]Reserved1 : 
[05Ch 0092   4]   Processor Proximity Domain : 0001
[060h 0096   4]  Memory Proximity Domain : 0001
[064h 0100   4]Reserved2 : 
[068h 0104   8]Reserved3 : 
[070h 0112   8]Reserved4 : 

[078h 0120   2]   Structure Type :  [Memory Proximity
Domain Attributes]
[07Ah 0122   2] Reserved : 
[07Ch 0124   4]   Length : 0028
[080h 0128   2]Flags (decoded below) : 
Processor Proximity Domain Valid : 0
[082h 0130   2]Reserved1 : 
[084h 0132   4]   Processor Proximity Domain : 0080
[088h 0136   4]  Memory Proximity Domain : 0002
[08Ch 0140   4]Reserved2 : 
[040h 0064   8]Reserved3 : 
[048h 0072   8]Reserved4 : 

[050h 0080   2]   Structure Type :  [Memory Proximity
Domain Attributes]
[052h 0082   2] Reserved : 
[054h 0084   4]   Length : 0028
[058h 0088   2]Flags (decoded below) : 0001
Processor Proximity Domain Valid : 1
[05Ah 0090   2]Reserved1 : 
[05Ch 0092   4]   Processor Proximity Domain : 0001
[060h 0096   4]  Memory Proximity Domain : 0001
[064h 0100   4]Reserved2 : 
[068h 0104   8]Reserved3 : 
[070h 0112   8]Reserved4 : 

[078h 0120   2]   Structure Type :  [Memory Proximity
Domain Attributes]
[07Ah 0122   2] Reserved : 
[07Ch 0124   4]   Length : 0028
[080h 0128   2]Flags (decoded below) : 
Processor Proximity Domain Valid : 0
[082h 0130   2]Reserved1 : 
[084h 0132   4]   Processor Proximity Domain : 0080
[088h 0136   4]  Memory Proximity Domain : 0002
[08Ch 0140   4]Reserved2 : 
[090h 0144   8]Reserved3 : 
[098h 0152   8]Reserved4 : 

[0A0h 0160   2]   Structure Type : 0001 [System Locality
Latency and Bandwidth Information]
[0A2h 0162   2] Reserved : 
[0A4h 0164   4]   Length : 0040
[0A8h 0168   1]Flags (decoded below) : 00
Memory Hierarchy : 0
[0A9h 0169   1]Data Type : 00
[0AAh 0170   2]Reserved1 : 
[0ACh 0172   4] Initiator Proximity Domains # : 0002
[0B0h 0176   4]   Target Proximity Domains # : 0003
[0B4h 0180   4]Reserved2 : 
[0B8h 0184   8]  Entry Base Unit : 2710
[0C0h 0192   4] Initiator Proximity Domain List : 
[0C4h 0196   4] Initiator Proximity Domain List : 0001
[0C8h 0200   4] Target Proximity Domain List : 
[0CCh 0204   4] Target Proximity Domain List : 0001
[0D0h 0208   4] Target Proximity Domain List : 0002
[0D4h 0212   2]Entry : 0001
[0D6h 0214   2]Entry : 0002
[0D8h 0216   2]Entry : 0003
[0DAh 0218   2]

Re: [PATCH 0/5] disas/nanomips: Format string fixes

2022-11-07 Thread Philippe Mathieu-Daudé

On 1/11/22 12:44, Philippe Mathieu-Daudé wrote:

Fix invalid string formats reported by Stefan:
https://lore.kernel.org/qemu-devel/78553699-00c1-ad69-1d58-02f75a1f4...@weilnetz.de/

Philippe Mathieu-Daudé (5):
   disas/nanomips: Fix invalid PRId64 format calling img_format()
   disas/nanomips: Fix invalid PRIx64 format calling img_format()
   disas/nanomips: Use G_GNUC_PRINTF to avoid invalid string formats
   disas/nanomips: Remove headers already included by "qemu/osdep.h"
   MAINTAINERS: Inherit from nanoMIPS


Queued to mips-fixes.



[PULL v4 74/83] intel-iommu: PASID support

2022-11-07 Thread Michael S. Tsirkin
From: Jason Wang 

This patch introduce ECAP_PASID via "x-pasid-mode". Based on the
existing support for scalable mode, we need to implement the following
missing parts:

1) tag VTDAddressSpace with PASID and support IOMMU/DMA translation
   with PASID
2) tag IOTLB with PASID
3) PASID cache and its flush
4) PASID based IOTLB invalidation

For simplicity PASID cache is not implemented so we can simply
implement the PASID cache flush as a no and leave it to be implemented
in the future. For PASID based IOTLB invalidation, since we haven't
had L1 stage support, the PASID based IOTLB invalidation is not
implemented yet. For PASID based device IOTLB invalidation, it
requires the support for vhost so we forbid enabling device IOTLB when
PASID is enabled now. Those work could be done in the future.

Note that though PASID based IOMMU translation is ready but no device
can issue PASID DMA right now. In this case, PCI_NO_PASID is used as
PASID to identify the address without PASID. vtd_find_add_as() has
been extended to provision address space with PASID which could be
utilized by the future extension of PCI core to allow device model to
use PASID based DMA translation.

This feature would be useful for:

1) prototyping PASID support for devices like virtio
2) future vPASID work
3) future PRS and vSVA work

Reviewed-by: Peter Xu 
Signed-off-by: Jason Wang 
Message-Id: <20221028061436.30093-5-jasow...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/i386/intel_iommu_internal.h |  16 +-
 include/hw/i386/intel_iommu.h  |   7 +-
 include/hw/pci/pci_bus.h   |   2 +
 hw/i386/intel_iommu.c  | 418 +
 hw/i386/trace-events   |   2 +
 5 files changed, 341 insertions(+), 104 deletions(-)

diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 930ce61feb..f090e61e11 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -114,8 +114,9 @@
  VTD_INTERRUPT_ADDR_FIRST + 1)
 
 /* The shift of source_id in the key of IOTLB hash table */
-#define VTD_IOTLB_SID_SHIFT 36
-#define VTD_IOTLB_LVL_SHIFT 52
+#define VTD_IOTLB_SID_SHIFT 20
+#define VTD_IOTLB_LVL_SHIFT 28
+#define VTD_IOTLB_PASID_SHIFT   30
 #define VTD_IOTLB_MAX_SIZE  1024/* Max size of the hash table */
 
 /* IOTLB_REG */
@@ -191,6 +192,7 @@
 #define VTD_ECAP_SC (1ULL << 7)
 #define VTD_ECAP_MHMV   (15ULL << 20)
 #define VTD_ECAP_SRS(1ULL << 31)
+#define VTD_ECAP_PASID  (1ULL << 40)
 #define VTD_ECAP_SMTS   (1ULL << 43)
 #define VTD_ECAP_SLTS   (1ULL << 46)
 
@@ -211,6 +213,8 @@
 #define VTD_CAP_DRAIN_READ  (1ULL << 55)
 #define VTD_CAP_DRAIN   (VTD_CAP_DRAIN_READ | VTD_CAP_DRAIN_WRITE)
 #define VTD_CAP_CM  (1ULL << 7)
+#define VTD_PASID_ID_SHIFT  20
+#define VTD_PASID_ID_MASK   ((1ULL << VTD_PASID_ID_SHIFT) - 1)
 
 /* Supported Adjusted Guest Address Widths */
 #define VTD_CAP_SAGAW_SHIFT 8
@@ -262,6 +266,8 @@
 #define VTD_FRCD_SID(val)   ((val) & VTD_FRCD_SID_MASK)
 /* For the low 64-bit of 128-bit */
 #define VTD_FRCD_FI(val)((val) & ~0xfffULL)
+#define VTD_FRCD_PV(val)(((val) & 0xULL) << 40)
+#define VTD_FRCD_PP(val)(((val) & 0x1) << 31)
 
 /* DMA Remapping Fault Conditions */
 typedef enum VTDFaultReason {
@@ -379,6 +385,11 @@ typedef union VTDInvDesc VTDInvDesc;
 #define VTD_INV_DESC_IOTLB_AM(val)  ((val) & 0x3fULL)
 #define VTD_INV_DESC_IOTLB_RSVD_LO  0xff00ULL
 #define VTD_INV_DESC_IOTLB_RSVD_HI  0xf80ULL
+#define VTD_INV_DESC_IOTLB_PASID_PASID  (2ULL << 4)
+#define VTD_INV_DESC_IOTLB_PASID_PAGE   (3ULL << 4)
+#define VTD_INV_DESC_IOTLB_PASID(val)   (((val) >> 32) & VTD_PASID_ID_MASK)
+#define VTD_INV_DESC_IOTLB_PASID_RSVD_LO  0xfff001c0ULL
+#define VTD_INV_DESC_IOTLB_PASID_RSVD_HI  0xf80ULL
 
 /* Mask for Device IOTLB Invalidate Descriptor */
 #define VTD_INV_DESC_DEVICE_IOTLB_ADDR(val) ((val) & 0xf000ULL)
@@ -413,6 +424,7 @@ typedef union VTDInvDesc VTDInvDesc;
 /* Information about page-selective IOTLB invalidate */
 struct VTDIOTLBPageInvInfo {
 uint16_t domain_id;
+uint32_t pasid;
 uint64_t addr;
 uint8_t mask;
 };
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index e49fff2a6c..46d973e629 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -97,11 +97,13 @@ struct VTDPASIDEntry {
 struct VTDAddressSpace {
 PCIBus *bus;
 uint8_t devfn;
+uint32_t pasid;
 AddressSpace as;
 IOMMUMemoryRegion iommu;
 MemoryRegion root;  /* The root container of the device */
 MemoryRegion nodmar;/* The alias of shared nodmar MR */
 MemoryRegion iommu_ir;  /* Interrupt region: 0xfeeX */
+MemoryRegion 

[PULL v4 36/83] vhost-net: vhost-kernel: introduce vhost_net_virtqueue_restart()

2022-11-07 Thread Michael S. Tsirkin
From: Kangjie Xu 

Introduce vhost_net_virtqueue_restart(), which can restart the
specific virtqueue when the vhost net started running before.
If it fails to restart the virtqueue, the device will be stopped.

Here we do not reuse vhost_net_start_one() or vhost_dev_start()
because they work at queue pair level. The mem table and features
do not change, so we can call the vhost_virtqueue_start() to
restart a specific queue.

This patch only considers the case of vhost-kernel, when
NetClientDriver is NET_CLIENT_DRIVER_TAP.

Signed-off-by: Kangjie Xu 
Signed-off-by: Xuan Zhuo 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-11-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/net/vhost_net.h |  2 ++
 hw/net/vhost_net-stub.c |  6 +
 hw/net/vhost_net.c  | 53 +
 3 files changed, 61 insertions(+)

diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 85d85a4957..40b9a40074 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -50,4 +50,6 @@ int vhost_net_set_mtu(struct vhost_net *net, uint16_t mtu);
 
 void vhost_net_virtqueue_reset(VirtIODevice *vdev, NetClientState *nc,
int vq_index);
+int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc,
+int vq_index);
 #endif
diff --git a/hw/net/vhost_net-stub.c b/hw/net/vhost_net-stub.c
index 2d745e359c..9f7daae99c 100644
--- a/hw/net/vhost_net-stub.c
+++ b/hw/net/vhost_net-stub.c
@@ -107,3 +107,9 @@ void vhost_net_virtqueue_reset(VirtIODevice *vdev, 
NetClientState *nc,
 {
 
 }
+
+int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc,
+int vq_index)
+{
+return 0;
+}
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 8beecb4d22..d2926e2ed6 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -34,6 +34,7 @@
 #include "standard-headers/linux/virtio_ring.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/virtio-bus.h"
+#include "linux-headers/linux/vhost.h"
 
 
 /* Features supported by host kernel. */
@@ -556,3 +557,55 @@ void vhost_net_virtqueue_reset(VirtIODevice *vdev, 
NetClientState *nc,
  net->dev.vqs + idx,
  net->dev.vq_index + idx);
 }
+
+int vhost_net_virtqueue_restart(VirtIODevice *vdev, NetClientState *nc,
+int vq_index)
+{
+VHostNetState *net = get_vhost_net(nc->peer);
+const VhostOps *vhost_ops = net->dev.vhost_ops;
+struct vhost_vring_file file = { };
+int idx, r;
+
+if (!net->dev.started) {
+return -EBUSY;
+}
+
+/* should only be called after backend is connected */
+assert(vhost_ops);
+
+idx = vhost_ops->vhost_get_vq_index(>dev, vq_index);
+
+r = vhost_virtqueue_start(>dev,
+  vdev,
+  net->dev.vqs + idx,
+  net->dev.vq_index + idx);
+if (r < 0) {
+goto err_start;
+}
+
+if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
+file.index = idx;
+file.fd = net->backend;
+r = vhost_net_set_backend(>dev, );
+if (r < 0) {
+r = -errno;
+goto err_start;
+}
+}
+
+return 0;
+
+err_start:
+error_report("Error when restarting the queue.");
+
+if (net->nc->info->type == NET_CLIENT_DRIVER_TAP) {
+file.fd = VHOST_FILE_UNBIND;
+file.index = idx;
+int r = vhost_net_set_backend(>dev, );
+assert(r >= 0);
+}
+
+vhost_dev_stop(>dev, vdev);
+
+return r;
+}
-- 
MST




[PULL v4 13/83] acpi/tests/avocado/bits: add biosbits config file for running bios tests

2022-11-07 Thread Michael S. Tsirkin
From: Ani Sinha 

This change adds initial biosbits config file that instructs biosbits to run
bios test suits in batch mode. Additionally acpi and smbios structures are also
dumped.

Cc: Daniel P. Berrangé 
Cc: Paolo Bonzini 
Cc: Maydell Peter 
Cc: John Snow 
Cc: Thomas Huth 
Cc: Alex Bennée 
Cc: Igor Mammedov 
Cc: Michael Tsirkin 
Signed-off-by: Ani Sinha 
Reviewed-by: Alex Bennée 
Message-Id: <20221021095108.104843-5-...@anisinha.ca>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 .../avocado/acpi-bits/bits-config/bits-cfg.txt | 18 ++
 1 file changed, 18 insertions(+)
 create mode 100644 tests/avocado/acpi-bits/bits-config/bits-cfg.txt

diff --git a/tests/avocado/acpi-bits/bits-config/bits-cfg.txt 
b/tests/avocado/acpi-bits/bits-config/bits-cfg.txt
new file mode 100644
index 00..8010804453
--- /dev/null
+++ b/tests/avocado/acpi-bits/bits-config/bits-cfg.txt
@@ -0,0 +1,18 @@
+# BITS configuration file
+[bits]
+
+# To run BITS in batch mode, set batch to a list of one or more of the
+# following keywords; BITS will then run all of the requested operations, then
+# save the log file to disk.
+#
+# test: Run the full BITS testsuite.
+# acpi: Dump all ACPI structures.
+# smbios: Dump all SMBIOS structures.
+#
+# Leave batch set to an empty string to disable batch mode.
+# batch =
+
+# Uncomment the following to run all available batch operations
+# please take a look at boot/python/init.py in bits zip file
+# to see how these options are parsed and used.
+batch = test acpi smbios
-- 
MST




[PULL v4 75/83] vhost: Change the sequence of device start

2022-11-07 Thread Michael S. Tsirkin
From: Yajun Wu 

This patch is part of adding vhost-user vhost_dev_start support. The
motivation is to improve backend configuration speed and reduce live
migration VM downtime.

Moving the device start routines after finishing all the necessary device
and VQ configuration, further aligning to the virtio specification for
"device initialization sequence".

Following patch will add vhost-user vhost_dev_start support.

Signed-off-by: Yajun Wu 
Acked-by: Parav Pandit 

Message-Id: <20221017064452.1226514-2-yaj...@nvidia.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/block/vhost-user-blk.c | 18 +++---
 hw/net/vhost_net.c| 11 +--
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 13bf5cc47a..28409c90f7 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -168,13 +168,6 @@ static int vhost_user_blk_start(VirtIODevice *vdev, Error 
**errp)
 goto err_guest_notifiers;
 }
 
-ret = vhost_dev_start(>dev, vdev);
-if (ret < 0) {
-error_setg_errno(errp, -ret, "Error starting vhost");
-goto err_guest_notifiers;
-}
-s->started_vu = true;
-
 /* guest_notifier_mask/pending not used yet, so just unmask
  * everything here. virtio-pci will do the right thing by
  * enabling/disabling irqfd.
@@ -183,9 +176,20 @@ static int vhost_user_blk_start(VirtIODevice *vdev, Error 
**errp)
 vhost_virtqueue_mask(>dev, vdev, i, false);
 }
 
+s->dev.vq_index_end = s->dev.nvqs;
+ret = vhost_dev_start(>dev, vdev);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Error starting vhost");
+goto err_guest_notifiers;
+}
+s->started_vu = true;
+
 return ret;
 
 err_guest_notifiers:
+for (i = 0; i < s->dev.nvqs; i++) {
+vhost_virtqueue_mask(>dev, vdev, i, true);
+}
 k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
 err_host_notifiers:
 vhost_dev_disable_notifiers(>dev, vdev);
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index 53b2fac4f6..feda448878 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -389,21 +389,20 @@ int vhost_net_start(VirtIODevice *dev, NetClientState 
*ncs,
 } else {
 peer = qemu_get_peer(ncs, n->max_queue_pairs);
 }
-r = vhost_net_start_one(get_vhost_net(peer), dev);
-
-if (r < 0) {
-goto err_start;
-}
 
 if (peer->vring_enable) {
 /* restore vring enable state */
 r = vhost_set_vring_enable(peer, peer->vring_enable);
 
 if (r < 0) {
-vhost_net_stop_one(get_vhost_net(peer), dev);
 goto err_start;
 }
 }
+
+r = vhost_net_start_one(get_vhost_net(peer), dev);
+if (r < 0) {
+goto err_start;
+}
 }
 
 return 0;
-- 
MST




[PULL v4 27/83] virtio: introduce __virtio_queue_reset()

2022-11-07 Thread Michael S. Tsirkin
From: Xuan Zhuo 

Separate the logic of vq reset. This logic will be called directly
later.

Signed-off-by: Xuan Zhuo 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-2-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio.c | 37 +
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 808446b4c9..6f42fcadd7 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -2464,6 +2464,26 @@ static enum virtio_device_endian 
virtio_current_cpu_endian(void)
 }
 }
 
+static void __virtio_queue_reset(VirtIODevice *vdev, uint32_t i)
+{
+vdev->vq[i].vring.desc = 0;
+vdev->vq[i].vring.avail = 0;
+vdev->vq[i].vring.used = 0;
+vdev->vq[i].last_avail_idx = 0;
+vdev->vq[i].shadow_avail_idx = 0;
+vdev->vq[i].used_idx = 0;
+vdev->vq[i].last_avail_wrap_counter = true;
+vdev->vq[i].shadow_avail_wrap_counter = true;
+vdev->vq[i].used_wrap_counter = true;
+virtio_queue_set_vector(vdev, i, VIRTIO_NO_VECTOR);
+vdev->vq[i].signalled_used = 0;
+vdev->vq[i].signalled_used_valid = false;
+vdev->vq[i].notification = true;
+vdev->vq[i].vring.num = vdev->vq[i].vring.num_default;
+vdev->vq[i].inuse = 0;
+virtio_virtqueue_reset_region_cache(>vq[i]);
+}
+
 void virtio_reset(void *opaque)
 {
 VirtIODevice *vdev = opaque;
@@ -2495,22 +2515,7 @@ void virtio_reset(void *opaque)
 virtio_notify_vector(vdev, vdev->config_vector);
 
 for(i = 0; i < VIRTIO_QUEUE_MAX; i++) {
-vdev->vq[i].vring.desc = 0;
-vdev->vq[i].vring.avail = 0;
-vdev->vq[i].vring.used = 0;
-vdev->vq[i].last_avail_idx = 0;
-vdev->vq[i].shadow_avail_idx = 0;
-vdev->vq[i].used_idx = 0;
-vdev->vq[i].last_avail_wrap_counter = true;
-vdev->vq[i].shadow_avail_wrap_counter = true;
-vdev->vq[i].used_wrap_counter = true;
-virtio_queue_set_vector(vdev, i, VIRTIO_NO_VECTOR);
-vdev->vq[i].signalled_used = 0;
-vdev->vq[i].signalled_used_valid = false;
-vdev->vq[i].notification = true;
-vdev->vq[i].vring.num = vdev->vq[i].vring.num_default;
-vdev->vq[i].inuse = 0;
-virtio_virtqueue_reset_region_cache(>vq[i]);
+__virtio_queue_reset(vdev, i);
 }
 }
 
-- 
MST




[PULL v4 58/83] hw/i386/pc.c: CXL Fixed Memory Window should not reserve e820 in bios

2022-11-07 Thread Michael S. Tsirkin
From: Gregory Price 

Early-boot e820 records will be inserted by the bios/efi/early boot
software and be reported to the kernel via insert_resource.  Later, when
CXL drivers iterate through the regions again, they will insert another
resource and make the RESERVED memory area a child.

This RESERVED memory area causes the memory region to become unusable,
and as a result attempting to create memory regions with

`cxl create-region ...`

Will fail due to the RESERVED area intersecting with the CXL window.

During boot the following traceback is observed:

0x81101650 in insert_resource_expand_to_fit ()
0x83d964c5 in e820__reserve_resources_late ()
0x83e03210 in pcibios_resource_survey ()
0x83e04f4a in pcibios_init ()

Which produces a call to reserve the CFMWS area:

(gdb) p *new
$54 = {start = 0x29000, end = 0x2cfff, name = "Reserved",
   flags = 0x200, desc = 0x7, parent = 0x0, sibling = 0x0,
   child = 0x0}

Later the Kernel parses ACPI tables and reserves the exact same area as
the CXL Fixed Memory Window:

0x811016a4 in insert_resource_conflict ()
  insert_resource ()
0x81a81389 in cxl_parse_cfmws ()
0x818c4a81 in call_handler ()
  acpi_parse_entries_array ()

(gdb) p/x *new
$59 = {start = 0x29000, end = 0x2cfff, name = "CXL Window 0",
   flags = 0x200, desc = 0x0, parent = 0x0, sibling = 0x0,
   child = 0x0}

This produces the following output in /proc/iomem:

59000-68fff : CXL Window 0
  59000-68fff : Reserved

This reserved area causes `get_free_mem_region()` to fail due to a check
against `__region_intersects()`.  Due to this reserved area, the
intersect check will only ever return REGION_INTERSECTS, which causes
`cxl create-region` to always fail.

Signed-off-by: Gregory Price 
Message-Id: <20221026205912.8579-1-gregory.pr...@memverge.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Acked-by: Jonathan Cameron 
---
 hw/i386/pc.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ef14da5094..546b703cb4 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1061,7 +1061,6 @@ void pc_memory_init(PCMachineState *pcms,
 hwaddr cxl_size = MiB;
 
 cxl_base = pc_get_cxl_range_start(pcms);
-e820_add_entry(cxl_base, cxl_size, E820_RESERVED);
 memory_region_init(mr, OBJECT(machine), "cxl_host_reg", cxl_size);
 memory_region_add_subregion(system_memory, cxl_base, mr);
 cxl_resv_end = cxl_base + cxl_size;
@@ -1077,7 +1076,6 @@ void pc_memory_init(PCMachineState *pcms,
 memory_region_init_io(>mr, OBJECT(machine), _ops, fw,
   "cxl-fixed-memory-region", fw->size);
 memory_region_add_subregion(system_memory, fw->base, >mr);
-e820_add_entry(fw->base, fw->size, E820_RESERVED);
 cxl_fmw_base += fw->size;
 cxl_resv_end = cxl_fmw_base;
 }
-- 
MST




Re: [PATCH v2 0/3] MIPS system emulation miscellaneous fixes

2022-11-07 Thread Philippe Mathieu-Daudé

On 31/10/22 14:25, Jiaxun Yang wrote:

Hi all,

I was trying to build a MIPS VirtIO board[1] for QEMU that is able
to work with all processors we support.

When I was bring up varoius CPUs on that board I noticed some issues
with the system emulation code that I'm fixing in this series.

Thanks.

- Jiaxun
[1]: https://gitlab.com/FlyGoat/qemu/-/tree/mips-virt

v2: Address review comments

Jiaxun Yang (3):
   target/mips: Set CP0St_{KX, SX, UX} for Loongson-2F
   target/mips: Cast offset field of Octeon BBIT to int16_t
   target/mips: Disable DSP ASE for Octeon68XX


Queued to mips-fixes, thanks.



[PULL v4 20/83] tests/acpi: virt: update ACPI MADT and FADT binaries

2022-11-07 Thread Michael S. Tsirkin
From: Miguel Luis 

Step 6 & 7 of the bios-tables-test.c documented procedure.

Differences between disassembled ASL files for MADT:

@@ -11,9 +11,9 @@
  */

 [000h    4]Signature : "APIC"[Multiple APIC 
Description Table (MADT)]
-[004h 0004   4] Table Length : 00A8
-[008h 0008   1] Revision : 03
-[009h 0009   1] Checksum : 50
+[004h 0004   4] Table Length : 00AC
+[008h 0008   1] Revision : 04
+[009h 0009   1] Checksum : 47
 [00Ah 0010   6]   Oem ID : "BOCHS "
 [010h 0016   8] Oem Table ID : "BXPC"
 [018h 0024   4] Oem Revision : 0001
@@ -34,7 +34,7 @@
 [041h 0065   3] Reserved : 00

 [044h 0068   1]Subtable Type : 0B [Generic Interrupt 
Controller]
-[045h 0069   1]   Length : 4C
+[045h 0069   1]   Length : 50
 [046h 0070   2] Reserved : 
 [048h 0072   4] CPU Interface Number : 
 [04Ch 0076   4]Processor UID : 
@@ -51,28 +51,29 @@
 [07Ch 0124   4]Virtual GIC Interrupt : 
 [080h 0128   8]   Redistributor Base Address : 
 [088h 0136   8]ARM MPIDR : 
-/ ACPI subtable terminates early - may be older version (dump table) */
+[090h 0144   1] Efficiency Class : 00
+[091h 0145   3] Reserved : 00

-[090h 0144   1]Subtable Type : 0D [Generic MSI Frame]
-[091h 0145   1]   Length : 18
-[092h 0146   2] Reserved : 
-[094h 0148   4] MSI Frame ID : 
-[098h 0152   8] Base Address : 0802
-[0A0h 0160   4]Flags (decoded below) : 0001
+[094h 0148   1]Subtable Type : 0D [Generic MSI Frame]
+[095h 0149   1]   Length : 18
+[096h 0150   2] Reserved : 
+[098h 0152   4] MSI Frame ID : 
+[09Ch 0156   8] Base Address : 0802
+[0A4h 0164   4]Flags (decoded below) : 0001
   Select SPI : 1
-[0A4h 0164   2]SPI Count : 0040
-[0A6h 0166   2] SPI Base : 0050
+[0A8h 0168   2]SPI Count : 0040
+[0AAh 0170   2] SPI Base : 0050

-Raw Table Data: Length 168 (0xA8)
+Raw Table Data: Length 172 (0xAC)

-: 41 50 49 43 A8 00 00 00 03 50 42 4F 43 48 53 20  // APIC.PBOCHS
+: 41 50 49 43 AC 00 00 00 04 47 42 4F 43 48 53 20  // APIC.GBOCHS
 0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43  // BXPCBXPC
 0020: 01 00 00 00 00 00 00 00 00 00 00 00 0C 18 00 00  // 
 0030: 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00  // 
-0040: 02 00 00 00 0B 4C 00 00 00 00 00 00 00 00 00 00  // .L..
+0040: 02 00 00 00 0B 50 00 00 00 00 00 00 00 00 00 00  // .P..
 0050: 01 00 00 00 00 00 00 00 17 00 00 00 00 00 00 00  // 
 0060: 00 00 00 00 00 00 01 08 00 00 00 00 00 00 04 08  // 
 0070: 00 00 00 00 00 00 03 08 00 00 00 00 00 00 00 00  // 
 0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  // 
-0090: 0D 18 00 00 00 00 00 00 00 00 02 08 00 00 00 00  // 
-00A0: 01 00 00 00 40 00 50 00  // @.P.
+0090: 00 00 00 00 0D 18 00 00 00 00 00 00 00 00 02 08  // 
+00A0: 00 00 00 00 01 00 00 00 40 00 50 00  // @.P.

Differences between disassembled ASL files for FADT:

@@ -11,9 +11,9 @@
  */

 [000h    4]Signature : "FACP"[Fixed ACPI 
Description Table (FADT)]
-[004h 0004   4] Table Length : 010C
-[008h 0008   1] Revision : 05
-[009h 0009   1] Checksum : 55
+[004h 0004   4] Table Length : 0114
+[008h 0008   1] Revision : 06
+[009h 0009   1] Checksum : 15
 [00Ah 0010   6]   Oem ID : "BOCHS "
 [010h 0016   8] Oem Table ID : "BXPC"
 [018h 0024   4] Oem Revision : 0001
@@ -99,7 +99,7 @@
   PSCI Compliant : 1
Must use HVC for PSCI : 1

-[083h 0131   1]  FADT Minor Revision : 01
+[083h 0131   1]  FADT Minor Revision : 00
 [084h 0132   8] FACS Address : 
 [08Ch 0140   8] DSDT Address : 
 [094h 0148  12] PM1A Event Block : [Generic Address Structure]
@@ -173,11 +173,11 @@
 [103h 0259   1] Encoded Access Width : 00 [Undefined/Legacy]
 [104h 0260   8]   

[PULL v4 14/83] acpi/tests/avocado/bits: add acpi and smbios avocado tests that uses biosbits

2022-11-07 Thread Michael S. Tsirkin
From: Ani Sinha 

This introduces QEMU acpi/smbios biosbits avocado test which is run
from within the python virtual environment. When the bits tests are run, bits
binaries are downloaded from an external repo/location, bios bits iso is
regenerated containing the acpi/smbios bits tests that are maintained as a part
of the QEMU source under tests/avocado/acpi-bits/bits-test . When the VM is
spawned with the iso, it runs the tests in batch mode and the results are pushed
out from the VM to the test machine where they are analyzed by this script and
pass/fail results are reported.

Cc: Daniel P. Berrangé 
Cc: Paolo Bonzini 
Cc: Maydell Peter 
Cc: John Snow 
Cc: Thomas Huth 
Cc: Alex Bennée 
Cc: Igor Mammedov 
Cc: Michael Tsirkin 
Signed-off-by: Ani Sinha 
Message-Id: <20221021095108.104843-6-...@anisinha.ca>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/avocado/acpi-bits.py | 396 +
 1 file changed, 396 insertions(+)
 create mode 100644 tests/avocado/acpi-bits.py

diff --git a/tests/avocado/acpi-bits.py b/tests/avocado/acpi-bits.py
new file mode 100644
index 00..8745a58a76
--- /dev/null
+++ b/tests/avocado/acpi-bits.py
@@ -0,0 +1,396 @@
+#!/usr/bin/env python3
+# group: rw quick
+# Exercize QEMU generated ACPI/SMBIOS tables using biosbits,
+# https://biosbits.org/
+#
+# 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see .
+#
+#
+# Author:
+#  Ani Sinha 
+
+# pylint: disable=invalid-name
+# pylint: disable=consider-using-f-string
+
+"""
+This is QEMU ACPI/SMBIOS avocado tests using biosbits.
+Biosbits is available originally at https://biosbits.org/.
+This test uses a fork of the upstream bits and has numerous fixes
+including an upgraded acpica. The fork is located here:
+https://gitlab.com/qemu-project/biosbits-bits .
+"""
+
+import logging
+import os
+import platform
+import re
+import shutil
+import subprocess
+import tarfile
+import tempfile
+import time
+import zipfile
+from typing import (
+List,
+Optional,
+Sequence,
+)
+from qemu.machine import QEMUMachine
+from avocado import skipIf
+from avocado_qemu import QemuBaseTest
+
+deps = ["xorriso"] # dependent tools needed in the test setup/box.
+supported_platforms = ['x86_64'] # supported test platforms.
+
+
+def which(tool):
+""" looks up the full path for @tool, returns None if not found
+or if @tool does not have executable permissions.
+"""
+paths=os.getenv('PATH')
+for p in paths.split(os.path.pathsep):
+p = os.path.join(p, tool)
+if os.path.exists(p) and os.access(p, os.X_OK):
+return p
+return None
+
+def missing_deps():
+""" returns True if any of the test dependent tools are absent.
+"""
+for dep in deps:
+if which(dep) is None:
+return True
+return False
+
+def supported_platform():
+""" checks if the test is running on a supported platform.
+"""
+return platform.machine() in supported_platforms
+
+class QEMUBitsMachine(QEMUMachine): # pylint: disable=too-few-public-methods
+"""
+A QEMU VM, with isa-debugcon enabled and bits iso passed
+using -cdrom to QEMU commandline.
+
+"""
+def __init__(self,
+ binary: str,
+ args: Sequence[str] = (),
+ wrapper: Sequence[str] = (),
+ name: Optional[str] = None,
+ base_temp_dir: str = "/var/tmp",
+ debugcon_log: str = "debugcon-log.txt",
+ debugcon_addr: str = "0x403",
+ sock_dir: Optional[str] = None,
+ qmp_timer: Optional[float] = None):
+# pylint: disable=too-many-arguments
+
+if name is None:
+name = "qemu-bits-%d" % os.getpid()
+if sock_dir is None:
+sock_dir = base_temp_dir
+super().__init__(binary, args, wrapper=wrapper, name=name,
+ base_temp_dir=base_temp_dir,
+ sock_dir=sock_dir, qmp_timer=qmp_timer)
+self.debugcon_log = debugcon_log
+self.debugcon_addr = debugcon_addr
+self.base_temp_dir = base_temp_dir
+
+@property
+def _base_args(self) -> List[str]:
+args = super()._base_args
+args.extend([
+'-chardev',
+'file,path=%s,id=debugcon' %os.path.join(self.base_temp_dir,
+  

[PULL v4 39/83] virtio-net: support queue_enable

2022-11-07 Thread Michael S. Tsirkin
From: Kangjie Xu 

Support queue_enable in vhost-kernel scenario. It can be called when
a vq reset operation has been performed and the vq is restared.

It should be noted that we can restart the vq when the vhost has
already started. When launching a new vhost device, the vhost is not
started and all vqs are not initalized until VIRTIO_PCI_COMMON_STATUS
is written. Thus, we should use vhost_started to differentiate the
two cases: vq reset and device start.

Currently it only supports vhost-kernel.

Signed-off-by: Kangjie Xu 
Signed-off-by: Xuan Zhuo 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-14-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/net/virtio-net.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 34fb4b1423..e68daf51bb 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -563,6 +563,26 @@ static void virtio_net_queue_reset(VirtIODevice *vdev, 
uint32_t queue_index)
 flush_or_purge_queued_packets(nc);
 }
 
+static void virtio_net_queue_enable(VirtIODevice *vdev, uint32_t queue_index)
+{
+VirtIONet *n = VIRTIO_NET(vdev);
+NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(queue_index));
+int r;
+
+if (!nc->peer || !vdev->vhost_started) {
+return;
+}
+
+if (get_vhost_net(nc->peer) &&
+nc->peer->info->type == NET_CLIENT_DRIVER_TAP) {
+r = vhost_net_virtqueue_restart(vdev, nc, queue_index);
+if (r < 0) {
+error_report("unable to restart vhost net virtqueue: %d, "
+"when resetting the queue", queue_index);
+}
+}
+}
+
 static void virtio_net_reset(VirtIODevice *vdev)
 {
 VirtIONet *n = VIRTIO_NET(vdev);
@@ -3845,6 +3865,7 @@ static void virtio_net_class_init(ObjectClass *klass, 
void *data)
 vdc->bad_features = virtio_net_bad_features;
 vdc->reset = virtio_net_reset;
 vdc->queue_reset = virtio_net_queue_reset;
+vdc->queue_enable = virtio_net_queue_enable;
 vdc->set_status = virtio_net_set_status;
 vdc->guest_notifier_mask = virtio_net_guest_notifier_mask;
 vdc->guest_notifier_pending = virtio_net_guest_notifier_pending;
-- 
MST




[PULL v4 53/83] acpi: pc/35: sanitize _GPE declaration order

2022-11-07 Thread Michael S. Tsirkin
From: Igor Mammedov 

Move _GPE block declaration before it gets referenced by other
hotplug handlers. While at it move PCI hotplug (_E01) handler
after PCI tree description to avoid forward reference to
to not yet declared methods/devices.

PS:
Forward 'usage' usualy is fine as long as it's hidden within
method, however 'iasl' may print warnings. So be nice
to iasl/guest OS and do things in proper order.

PS2: Also follow up patches will move some of hotplug code
from PCI tree to _E01 and that also requires PCI Device
nodes build first, before Scope can reuse that from
global context.

Signed-off-by: Igor Mammedov 
Message-Id: <20221017102146.2254096-11-imamm...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/i386/acpi-build.c | 47 +++-
 1 file changed, 25 insertions(+), 22 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 916343d8d6..960305462c 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1434,6 +1434,18 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 aml_append(dsdt, sb_scope);
 }
 
+scope =  aml_scope("_GPE");
+{
+aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006")));
+if (machine->nvdimms_state->is_enabled) {
+method = aml_method("_E04", 0, AML_NOTSERIALIZED);
+aml_append(method, aml_notify(aml_name("\\_SB.NVDR"),
+  aml_int(0x80)));
+aml_append(scope, method);
+}
+}
+aml_append(dsdt, scope);
+
 if (pcmc->legacy_cpu_hotplug) {
 build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base);
 } else {
@@ -1452,28 +1464,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
  pcms->memhp_io_base);
 }
 
-scope =  aml_scope("_GPE");
-{
-aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006")));
-
-if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
-method = aml_method("_E01", 0, AML_NOTSERIALIZED);
-aml_append(method,
-aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0x));
-aml_append(method, aml_call0("\\_SB.PCI0.PCNT"));
-aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK")));
-aml_append(scope, method);
-}
-
-if (machine->nvdimms_state->is_enabled) {
-method = aml_method("_E04", 0, AML_NOTSERIALIZED);
-aml_append(method, aml_notify(aml_name("\\_SB.NVDR"),
-  aml_int(0x80)));
-aml_append(scope, method);
-}
-}
-aml_append(dsdt, scope);
-
 crs_range_set_init(_range_set);
 bus = PC_MACHINE(machine)->bus;
 if (bus) {
@@ -1752,6 +1742,19 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 }
 aml_append(dsdt, sb_scope);
 
+if (pm->pcihp_bridge_en || pm->pcihp_root_en) {
+scope =  aml_scope("_GPE");
+{
+method = aml_method("_E01", 0, AML_NOTSERIALIZED);
+aml_append(method,
+aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0x));
+aml_append(method, aml_call0("\\_SB.PCI0.PCNT"));
+aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK")));
+aml_append(scope, method);
+}
+aml_append(dsdt, scope);
+}
+
 /* copy AML table into ACPI tables blob and patch header there */
 g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
 acpi_table_end(linker, );
-- 
MST




[PULL v4 65/83] tests: acpi: q35: update expected blobs *.hmat-noinitiators expected HMAT:

2022-11-07 Thread Michael S. Tsirkin
From: Brice Goglin 

[000h    4]Signature : "HMAT"[Heterogeneous Memory 
Attributes Table]
[004h 0004   4] Table Length : 0120
[008h 0008   1] Revision : 02
[009h 0009   1] Checksum : 4F
[00Ah 0010   6]   Oem ID : "BOCHS "
[010h 0016   8] Oem Table ID : "BXPC"
[018h 0024   4] Oem Revision : 0001
[01Ch 0028   4]  Asl Compiler ID : "BXPC"
[020h 0032   4]Asl Compiler Revision : 0001

[024h 0036   4] Reserved : 

[028h 0040   2]   Structure Type :  [Memory Proximity Domain 
Attributes]
[02Ah 0042   2] Reserved : 
[02Ch 0044   4]   Length : 0028
[030h 0048   2]Flags (decoded below) : 0001
Processor Proximity Domain Valid : 1
[032h 0050   2]Reserved1 : 
[034h 0052   4] Attached Initiator Proximity Domain : 
[038h 0056   4]  Memory Proximity Domain : 
[03Ch 0060   4]Reserved2 : 
[040h 0064   8]Reserved3 : 
[048h 0072   8]Reserved4 : 

[050h 0080   2]   Structure Type :  [Memory Proximity Domain 
Attributes]
[052h 0082   2] Reserved : 
[054h 0084   4]   Length : 0028
[058h 0088   2]Flags (decoded below) : 0001
Processor Proximity Domain Valid : 1
[05Ah 0090   2]Reserved1 : 
[05Ch 0092   4] Attached Initiator Proximity Domain : 0001
[060h 0096   4]  Memory Proximity Domain : 0001
[064h 0100   4]Reserved2 : 
[068h 0104   8]Reserved3 : 
[070h 0112   8]Reserved4 : 

[078h 0120   2]   Structure Type :  [Memory Proximity Domain 
Attributes]
[07Ah 0122   2] Reserved : 
[07Ch 0124   4]   Length : 0028
[080h 0128   2]Flags (decoded below) : 
Processor Proximity Domain Valid : 0
[082h 0130   2]Reserved1 : 
[084h 0132   4] Attached Initiator Proximity Domain : 0080
[088h 0136   4]  Memory Proximity Domain : 0002
[08Ch 0140   4]Reserved2 : 
[090h 0144   8]Reserved3 : 
[098h 0152   8]Reserved4 : 

[0A0h 0160   2]   Structure Type : 0001 [System Locality Latency 
and Bandwidth Information]
[0A2h 0162   2] Reserved : 
[0A4h 0164   4]   Length : 0040
[0A8h 0168   1]Flags (decoded below) : 00
Memory Hierarchy : 0
[0A9h 0169   1]Data Type : 00
[0AAh 0170   2]Reserved1 : 
[0ACh 0172   4] Initiator Proximity Domains # : 0002
[0B0h 0176   4]   Target Proximity Domains # : 0003
[0B4h 0180   4]Reserved2 : 
[0B8h 0184   8]  Entry Base Unit : 2710
[0C0h 0192   4] Initiator Proximity Domain List : 
[0C4h 0196   4] Initiator Proximity Domain List : 0001
[0C8h 0200   4] Target Proximity Domain List : 
[0CCh 0204   4] Target Proximity Domain List : 0001
[0D0h 0208   4] Target Proximity Domain List : 0002
[0D4h 0212   2]Entry : 0001
[0D6h 0214   2]Entry : 0002
[0D8h 0216   2]Entry : 0003
[0DAh 0218   2]Entry : 0002
[0DCh 0220   2]Entry : 0001
[0DEh 0222   2]Entry : 0003

[0E0h 0224   2]   Structure Type : 0001 [System Locality Latency 
and Bandwidth Information]
[0E2h 0226   2] Reserved : 
[0E4h 0228   4]   Length : 0040
[0E8h 0232   1]Flags (decoded below) : 00
Memory Hierarchy : 0
[0E9h 0233   1]Data Type : 03
[0EAh 0234   2]Reserved1 : 
[0ECh 0236   4] Initiator Proximity Domains # : 0002
[0F0h 0240   4]   Target Proximity Domains # : 0003
[0F4h 0244   4]Reserved2 : 
[0F8h 0248   8]  Entry Base Unit : 0001
[100h 0256   4] Initiator Proximity Domain List : 
[104h 0260   4] Initiator Proximity Domain List : 0001
[108h 0264   4] Target Proximity Domain List : 
[10Ch 0268   4] Target Proximity Domain List : 0001
[110h 0272   4] Target Proximity Domain List : 0002
[114h 0276   2]Entry : 000A
[116h 0278   2]Entry : 0005
[118h 0280   2]Entry : 0001
[11Ah 0282   2]Entry : 0005
[11Ch 0284   2]   

[PULL v4 64/83] tests: acpi: q35: add test for hmat nodes without initiators

2022-11-07 Thread Michael S. Tsirkin
From: Brice Goglin 

expected HMAT:

[000h    4]Signature : "HMAT"[Heterogeneous Memory 
Attributes Table]
[004h 0004   4] Table Length : 0120
[008h 0008   1] Revision : 02
[009h 0009   1] Checksum : 4F
[00Ah 0010   6]   Oem ID : "BOCHS "
[010h 0016   8] Oem Table ID : "BXPC"
[018h 0024   4] Oem Revision : 0001
[01Ch 0028   4]  Asl Compiler ID : "BXPC"
[020h 0032   4]Asl Compiler Revision : 0001

[024h 0036   4] Reserved : 

[028h 0040   2]   Structure Type :  [Memory Proximity Domain 
Attributes]
[02Ah 0042   2] Reserved : 
[02Ch 0044   4]   Length : 0028
[030h 0048   2]Flags (decoded below) : 0001
Processor Proximity Domain Valid : 1
[032h 0050   2]Reserved1 : 
[034h 0052   4] Attached Initiator Proximity Domain : 
[038h 0056   4]  Memory Proximity Domain : 
[03Ch 0060   4]Reserved2 : 
[040h 0064   8]Reserved3 : 
[048h 0072   8]Reserved4 : 

[050h 0080   2]   Structure Type :  [Memory Proximity Domain 
Attributes]
[052h 0082   2] Reserved : 
[054h 0084   4]   Length : 0028
[058h 0088   2]Flags (decoded below) : 0001
Processor Proximity Domain Valid : 1
[05Ah 0090   2]Reserved1 : 
[05Ch 0092   4] Attached Initiator Proximity Domain : 0001
[060h 0096   4]  Memory Proximity Domain : 0001
[064h 0100   4]Reserved2 : 
[068h 0104   8]Reserved3 : 
[070h 0112   8]Reserved4 : 

[078h 0120   2]   Structure Type :  [Memory Proximity Domain 
Attributes]
[07Ah 0122   2] Reserved : 
[07Ch 0124   4]   Length : 0028
[080h 0128   2]Flags (decoded below) : 
Processor Proximity Domain Valid : 0
[082h 0130   2]Reserved1 : 
[084h 0132   4] Attached Initiator Proximity Domain : 0080
[088h 0136   4]  Memory Proximity Domain : 0002
[08Ch 0140   4]Reserved2 : 
[090h 0144   8]Reserved3 : 
[098h 0152   8]Reserved4 : 

[0A0h 0160   2]   Structure Type : 0001 [System Locality Latency 
and Bandwidth Information]
[0A2h 0162   2] Reserved : 
[0A4h 0164   4]   Length : 0040
[0A8h 0168   1]Flags (decoded below) : 00
Memory Hierarchy : 0
[0A9h 0169   1]Data Type : 00
[0AAh 0170   2]Reserved1 : 
[0ACh 0172   4] Initiator Proximity Domains # : 0002
[0B0h 0176   4]   Target Proximity Domains # : 0003
[0B4h 0180   4]Reserved2 : 
[0B8h 0184   8]  Entry Base Unit : 2710
[0C0h 0192   4] Initiator Proximity Domain List : 
[0C4h 0196   4] Initiator Proximity Domain List : 0001
[0C8h 0200   4] Target Proximity Domain List : 
[0CCh 0204   4] Target Proximity Domain List : 0001
[0D0h 0208   4] Target Proximity Domain List : 0002
[0D4h 0212   2]Entry : 0001
[0D6h 0214   2]Entry : 0002
[0D8h 0216   2]Entry : 0003
[0DAh 0218   2]Entry : 0002
[0DCh 0220   2]Entry : 0001
[0DEh 0222   2]Entry : 0003

[0E0h 0224   2]   Structure Type : 0001 [System Locality Latency 
and Bandwidth Information]
[0E2h 0226   2] Reserved : 
[0E4h 0228   4]   Length : 0040
[0E8h 0232   1]Flags (decoded below) : 00
Memory Hierarchy : 0
[0E9h 0233   1]Data Type : 03
[0EAh 0234   2]Reserved1 : 
[0ECh 0236   4] Initiator Proximity Domains # : 0002
[0F0h 0240   4]   Target Proximity Domains # : 0003
[0F4h 0244   4]Reserved2 : 
[0F8h 0248   8]  Entry Base Unit : 0001
[100h 0256   4] Initiator Proximity Domain List : 
[104h 0260   4] Initiator Proximity Domain List : 0001
[108h 0264   4] Target Proximity Domain List : 
[10Ch 0268   4] Target Proximity Domain List : 0001
[110h 0272   4] Target Proximity Domain List : 0002
[114h 0276   2]Entry : 000A
[116h 0278   2]Entry : 0005
[118h 0280   2]Entry : 0001
[11Ah 0282   2]Entry : 0005
[11Ch 0284   2]   

[PULL v4 76/83] vhost-user: Support vhost_dev_start

2022-11-07 Thread Michael S. Tsirkin
From: Yajun Wu 

The motivation of adding vhost-user vhost_dev_start support is to
improve backend configuration speed and reduce live migration VM
downtime.

Today VQ configuration is issued one by one. For virtio net with
multi-queue support, backend needs to update RSS (Receive side
scaling) on every rx queue enable. Updating RSS is time-consuming
(typical time like 7ms).

Implement already defined vhost status and message in the vhost
specification [1].
(a) VHOST_USER_PROTOCOL_F_STATUS
(b) VHOST_USER_SET_STATUS
(c) VHOST_USER_GET_STATUS

Send message VHOST_USER_SET_STATUS with VIRTIO_CONFIG_S_DRIVER_OK for
device start and reset(0) for device stop.

On reception of the DRIVER_OK message, backend can apply the needed setting
only once (instead of incremental) and also utilize parallelism on enabling
queues.

This improves QEMU's live migration downtime with vhost user backend
implementation by great margin, specially for the large number of VQs of 64
from 800 msec to 250 msec.

[1] https://qemu-project.gitlab.io/qemu/interop/vhost-user.html

Signed-off-by: Yajun Wu 
Acked-by: Parav Pandit 
Message-Id: <20221017064452.1226514-3-yaj...@nvidia.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/vhost-user.c | 74 +-
 1 file changed, 73 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index d256ce589b..abe23d4ebe 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -81,6 +81,7 @@ enum VhostUserProtocolFeature {
 VHOST_USER_PROTOCOL_F_RESET_DEVICE = 13,
 /* Feature 14 reserved for VHOST_USER_PROTOCOL_F_INBAND_NOTIFICATIONS. */
 VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS = 15,
+VHOST_USER_PROTOCOL_F_STATUS = 16,
 VHOST_USER_PROTOCOL_F_MAX
 };
 
@@ -126,6 +127,8 @@ typedef enum VhostUserRequest {
 VHOST_USER_GET_MAX_MEM_SLOTS = 36,
 VHOST_USER_ADD_MEM_REG = 37,
 VHOST_USER_REM_MEM_REG = 38,
+VHOST_USER_SET_STATUS = 39,
+VHOST_USER_GET_STATUS = 40,
 VHOST_USER_MAX
 } VhostUserRequest;
 
@@ -1452,6 +1455,43 @@ static int vhost_user_set_u64(struct vhost_dev *dev, int 
request, uint64_t u64,
 return 0;
 }
 
+static int vhost_user_set_status(struct vhost_dev *dev, uint8_t status)
+{
+return vhost_user_set_u64(dev, VHOST_USER_SET_STATUS, status, false);
+}
+
+static int vhost_user_get_status(struct vhost_dev *dev, uint8_t *status)
+{
+uint64_t value;
+int ret;
+
+ret = vhost_user_get_u64(dev, VHOST_USER_GET_STATUS, );
+if (ret < 0) {
+return ret;
+}
+*status = value;
+
+return 0;
+}
+
+static int vhost_user_add_status(struct vhost_dev *dev, uint8_t status)
+{
+uint8_t s;
+int ret;
+
+ret = vhost_user_get_status(dev, );
+if (ret < 0) {
+return ret;
+}
+
+if ((s & status) == status) {
+return 0;
+}
+s |= status;
+
+return vhost_user_set_status(dev, s);
+}
+
 static int vhost_user_set_features(struct vhost_dev *dev,
uint64_t features)
 {
@@ -1460,6 +1500,7 @@ static int vhost_user_set_features(struct vhost_dev *dev,
  * backend is actually logging changes
  */
 bool log_enabled = features & (0x1ULL << VHOST_F_LOG_ALL);
+int ret;
 
 /*
  * We need to include any extra backend only feature bits that
@@ -1467,9 +1508,18 @@ static int vhost_user_set_features(struct vhost_dev *dev,
  * VHOST_USER_F_PROTOCOL_FEATURES bit for enabling protocol
  * features.
  */
-return vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES,
+ret = vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES,
   features | dev->backend_features,
   log_enabled);
+
+if (virtio_has_feature(dev->protocol_features,
+   VHOST_USER_PROTOCOL_F_STATUS)) {
+if (!ret) {
+return vhost_user_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK);
+}
+}
+
+return ret;
 }
 
 static int vhost_user_set_protocol_features(struct vhost_dev *dev,
@@ -2620,6 +2670,27 @@ void vhost_user_cleanup(VhostUserState *user)
 user->chr = NULL;
 }
 
+static int vhost_user_dev_start(struct vhost_dev *dev, bool started)
+{
+if (!virtio_has_feature(dev->protocol_features,
+VHOST_USER_PROTOCOL_F_STATUS)) {
+return 0;
+}
+
+/* Set device status only for last queue pair */
+if (dev->vq_index + dev->nvqs != dev->vq_index_end) {
+return 0;
+}
+
+if (started) {
+return vhost_user_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE |
+  VIRTIO_CONFIG_S_DRIVER |
+  VIRTIO_CONFIG_S_DRIVER_OK);
+} else {
+return vhost_user_set_status(dev, 0);
+}
+}
+
 const VhostOps user_ops = {
 .backend_type = VHOST_BACKEND_TYPE_USER,
 .vhost_backend_init = vhost_user_backend_init,
@@ 

[PULL v4 56/83] MAINTAINERS: Add qapi/virtio.json to section "virtio"

2022-11-07 Thread Michael S. Tsirkin
From: Markus Armbruster 

Cc: Michael S. Tsirkin 
Signed-off-by: Markus Armbruster 
Message-Id: <20221020120458.80709-1-arm...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Philippe Mathieu-Daudé 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 8b7d49b089..28cc70c25f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2017,6 +2017,7 @@ S: Supported
 F: hw/*/virtio*
 F: hw/virtio/Makefile.objs
 F: hw/virtio/trace-events
+F: qapi/virtio.json
 F: net/vhost-user.c
 F: include/hw/virtio/
 
-- 
MST




[PULL v4 38/83] virtio-net: support queue reset

2022-11-07 Thread Michael S. Tsirkin
From: Xuan Zhuo 

virtio-net and vhost-kernel implement queue reset.
Queued packets in the corresponding queue pair are flushed
or purged.

For virtio-net, userspace datapath will be disabled later in
__virtio_queue_reset(). It will set addr of vring to 0 and idx to 0.
Thus, virtio_net_receive() and virtio_net_flush_tx() will not receive
or send packets.

For vhost-net, the datapath will be disabled in vhost_net_virtqueue_reset().

Signed-off-by: Xuan Zhuo 
Signed-off-by: Kangjie Xu 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-13-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/net/virtio-net.c | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 038a6fba7c..34fb4b1423 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -546,6 +546,23 @@ static RxFilterInfo 
*virtio_net_query_rxfilter(NetClientState *nc)
 return info;
 }
 
+static void virtio_net_queue_reset(VirtIODevice *vdev, uint32_t queue_index)
+{
+VirtIONet *n = VIRTIO_NET(vdev);
+NetClientState *nc = qemu_get_subqueue(n->nic, vq2q(queue_index));
+
+if (!nc->peer) {
+return;
+}
+
+if (get_vhost_net(nc->peer) &&
+nc->peer->info->type == NET_CLIENT_DRIVER_TAP) {
+vhost_net_virtqueue_reset(vdev, nc, queue_index);
+}
+
+flush_or_purge_queued_packets(nc);
+}
+
 static void virtio_net_reset(VirtIODevice *vdev)
 {
 VirtIONet *n = VIRTIO_NET(vdev);
@@ -3827,6 +3844,7 @@ static void virtio_net_class_init(ObjectClass *klass, 
void *data)
 vdc->set_features = virtio_net_set_features;
 vdc->bad_features = virtio_net_bad_features;
 vdc->reset = virtio_net_reset;
+vdc->queue_reset = virtio_net_queue_reset;
 vdc->set_status = virtio_net_set_status;
 vdc->guest_notifier_mask = virtio_net_guest_notifier_mask;
 vdc->guest_notifier_pending = virtio_net_guest_notifier_pending;
-- 
MST




[PULL v4 59/83] hw/i386/acpi-build: Remove unused struct

2022-11-07 Thread Michael S. Tsirkin
From: Bernhard Beschow 

Ammends commit b23046abe78f48498a423b802d6d86ba0172d57f 'pc: acpi-build:
simplify PCI bus tree generation'.

Signed-off-by: Bernhard Beschow 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20221026133110.91828-2-shen...@gmail.com>
Message-Id: <20221028103419.93398-2-shen...@gmail.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/i386/acpi-build.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 960305462c..1ebf14b899 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -121,13 +121,6 @@ typedef struct AcpiMiscInfo {
 unsigned dsdt_size;
 } AcpiMiscInfo;
 
-typedef struct AcpiBuildPciBusHotplugState {
-GArray *device_table;
-GArray *notify_table;
-struct AcpiBuildPciBusHotplugState *parent;
-bool pcihp_bridge_en;
-} AcpiBuildPciBusHotplugState;
-
 typedef struct FwCfgTPMConfig {
 uint32_t tpmppi_address;
 uint8_t tpm_version;
-- 
MST




Re: [PATCH] target/mips: enable LBX/LWX/* instructions for Octeon

2022-11-07 Thread Philippe Mathieu-Daudé

On 1/11/22 06:29, Pavel Dovgalyuk wrote:

This patch changes condition and function name for enabling
indexed load instructions for Octeon vCPUs. Octeons do not
have DSP extension, but implement LBX-and-others.

Signed-off-by: Pavel Dovgalyuk 
---
  target/mips/tcg/translate.c |   10 +++---
  1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c
index c3f92ea652..6248143c62 100644
--- a/target/mips/tcg/translate.c
+++ b/target/mips/tcg/translate.c
@@ -12173,12 +12173,16 @@ enum {
  #include "nanomips_translate.c.inc"
  
  /* MIPSDSP functions. */

-static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
+
+/* Indexed load is not for DSP only */
+static void gen_mips_lx(DisasContext *ctx, uint32_t opc,
 int rd, int base, int offset)
  {
  TCGv t0;
  
-check_dsp(ctx);

+if (!(ctx->insn_flags & INSN_OCTEON)) {


Ideally we'd need to check CP0 reg 9 select 7 bit 12 (USEUN in
Cavium Control) is set, otherwise these instrs are a NOP.

I presume QEMU Octeon emulation expects CvmCtl[USEUN] to be set
to be more useful; therefore:

Reviewed-by: Philippe Mathieu-Daudé 


+check_dsp(ctx);
+}
  t0 = tcg_temp_new();
  
  if (base == 0) {

@@ -14523,7 +14527,7 @@ static void decode_opc_special3_legacy(CPUMIPSState 
*env, DisasContext *ctx)
  case OPC_LBUX:
  case OPC_LHX:
  case OPC_LWX:
-gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
+gen_mips_lx(ctx, op2, rd, rs, rt);
  break;
  default:/* Invalid */
  MIPS_INVAL("MASK LX");






[PULL v4 67/83] hw/arm/virt: Enable HMAT on arm virt machine

2022-11-07 Thread Michael S. Tsirkin
From: Xiang Chen 

Since the patchset ("Build ACPI Heterogeneous Memory Attribute Table (HMAT)"),
HMAT is supported, but only x86 is enabled. Enable HMAT on arm virt machine.

Signed-off-by: Xiang Chen 
Signed-off-by: Hesham Almatary 
Reviewed-by: Igor Mammedov 
Message-Id: <20221027100037.251-7-hesham.almat...@huawei.com>
Tested-by: Yicong Yang 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/arm/virt-acpi-build.c | 7 +++
 hw/arm/Kconfig   | 1 +
 2 files changed, 8 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index da9e41e72b..4156111d49 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -42,6 +42,7 @@
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/acpi/tpm.h"
+#include "hw/acpi/hmat.h"
 #include "hw/pci/pcie_host.h"
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bus.h"
@@ -987,6 +988,12 @@ void virt_acpi_build(VirtMachineState *vms, 
AcpiBuildTables *tables)
 build_slit(tables_blob, tables->linker, ms, vms->oem_id,
vms->oem_table_id);
 }
+
+if (ms->numa_state->hmat_enabled) {
+acpi_add_table(table_offsets, tables_blob);
+build_hmat(tables_blob, tables->linker, ms->numa_state,
+   vms->oem_id, vms->oem_table_id);
+}
 }
 
 if (ms->nvdimms_state->is_enabled) {
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 15fa79afd3..17fcde8e1c 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -30,6 +30,7 @@ config ARM_VIRT
 select ACPI_VIOT
 select VIRTIO_MEM_SUPPORTED
 select ACPI_CXL
+select ACPI_HMAT
 
 config CHEETAH
 bool
-- 
MST




[PULL v4 33/83] vhost: expose vhost_virtqueue_start()

2022-11-07 Thread Michael S. Tsirkin
From: Kangjie Xu 

Expose vhost_virtqueue_start(), we need to use it when restarting a
virtqueue.

Signed-off-by: Kangjie Xu 
Signed-off-by: Xuan Zhuo 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-8-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 include/hw/virtio/vhost.h | 3 +++
 hw/virtio/vhost.c | 8 
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index d7eb557885..0054a695dc 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -297,6 +297,9 @@ int vhost_net_set_backend(struct vhost_dev *hdev,
 
 int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write);
 
+int vhost_virtqueue_start(struct vhost_dev *dev, struct VirtIODevice *vdev,
+  struct vhost_virtqueue *vq, unsigned idx);
+
 void vhost_dev_reset_inflight(struct vhost_inflight *inflight);
 void vhost_dev_free_inflight(struct vhost_inflight *inflight);
 void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f);
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 5185c15295..788d0a0679 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1081,10 +1081,10 @@ out:
 return ret;
 }
 
-static int vhost_virtqueue_start(struct vhost_dev *dev,
-struct VirtIODevice *vdev,
-struct vhost_virtqueue *vq,
-unsigned idx)
+int vhost_virtqueue_start(struct vhost_dev *dev,
+  struct VirtIODevice *vdev,
+  struct vhost_virtqueue *vq,
+  unsigned idx)
 {
 BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
 VirtioBusState *vbus = VIRTIO_BUS(qbus);
-- 
MST




[PULL v4 37/83] virtio-net: introduce flush_or_purge_queued_packets()

2022-11-07 Thread Michael S. Tsirkin
From: Kangjie Xu 

Introduce the fucntion flush_or_purge_queued_packets(), it will be
used in device reset and virtqueue reset. Therefore, we extract the
common logic as a new function.

Signed-off-by: Kangjie Xu 
Signed-off-by: Xuan Zhuo 
Acked-by: Jason Wang 
Message-Id: <20221017092558.111082-12-xuanz...@linux.alibaba.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/net/virtio-net.c | 17 +++--
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index b6903aea54..038a6fba7c 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -124,6 +124,16 @@ static int vq2q(int queue_index)
 return queue_index / 2;
 }
 
+static void flush_or_purge_queued_packets(NetClientState *nc)
+{
+if (!nc->peer) {
+return;
+}
+
+qemu_flush_or_purge_queued_packets(nc->peer, true);
+assert(!virtio_net_get_subqueue(nc)->async_tx.elem);
+}
+
 /* TODO
  * - we could suppress RX interrupt if we were so inclined.
  */
@@ -566,12 +576,7 @@ static void virtio_net_reset(VirtIODevice *vdev)
 
 /* Flush any async TX */
 for (i = 0;  i < n->max_queue_pairs; i++) {
-NetClientState *nc = qemu_get_subqueue(n->nic, i);
-
-if (nc->peer) {
-qemu_flush_or_purge_queued_packets(nc->peer, true);
-assert(!virtio_net_get_subqueue(nc)->async_tx.elem);
-}
+flush_or_purge_queued_packets(qemu_get_subqueue(n->nic, i));
 }
 }
 
-- 
MST




[PULL v4 48/83] tests: acpi: whitelist DSDT before generating ICH9_SMB AML automatically

2022-11-07 Thread Michael S. Tsirkin
From: Igor Mammedov 

Signed-off-by: Igor Mammedov 
Message-Id: <20221017102146.2254096-6-imamm...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 21 +
 1 file changed, 21 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..fd5852776c 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,22 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/DSDT",
+"tests/data/acpi/q35/DSDT.acpierst",
+"tests/data/acpi/q35/DSDT.acpihmat",
+"tests/data/acpi/q35/DSDT.applesmc",
+"tests/data/acpi/q35/DSDT.bridge",
+"tests/data/acpi/q35/DSDT.cphp",
+"tests/data/acpi/q35/DSDT.cxl",
+"tests/data/acpi/q35/DSDT.dimmpxm",
+"tests/data/acpi/q35/DSDT.ipmibt",
+"tests/data/acpi/q35/DSDT.ipmismbus",
+"tests/data/acpi/q35/DSDT.ivrs",
+"tests/data/acpi/q35/DSDT.memhp",
+"tests/data/acpi/q35/DSDT.mmio64",
+"tests/data/acpi/q35/DSDT.multi-bridge",
+"tests/data/acpi/q35/DSDT.nohpet",
+"tests/data/acpi/q35/DSDT.numamem",
+"tests/data/acpi/q35/DSDT.pvpanic-isa",
+"tests/data/acpi/q35/DSDT.tis.tpm12",
+"tests/data/acpi/q35/DSDT.tis.tpm2",
+"tests/data/acpi/q35/DSDT.viot",
+"tests/data/acpi/q35/DSDT.xapic",
-- 
MST




[PULL v4 57/83] msix: Assert that specified vector is in range

2022-11-07 Thread Michael S. Tsirkin
From: Akihiko Odaki 

There were several different ways to deal with the situation where the
vector specified for a msix function is out of bound:
- early return a function and keep progresssing
- propagate the error to the caller
- mark msix unusable
- assert it is in bound
- just ignore

An out-of-bound vector should not be specified if the device
implementation is correct so let msix functions always assert that the
specified vector is in range.

An exceptional case is virtio-pci, which allows the guest to configure
vectors. For virtio-pci, it is more appropriate to introduce its own
checks because it is sometimes too late to check the vector range in
msix functions.

Signed-off-by: Akihiko Odaki 
Message-Id: <20220829083524.143640-1-akihiko.od...@daynix.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Yuval Shaia 
Signed-off-by: Akihiko Odaki mailto:akihiko.od...@daynix.com; 
target="_blank">akihiko.od...@daynix.com
---
 include/hw/pci/msix.h |  4 +--
 hw/net/e1000e.c   | 15 ++---
 hw/net/rocker/rocker.c| 23 ++
 hw/net/vmxnet3.c  | 27 +++-
 hw/nvme/ctrl.c|  5 +--
 hw/pci/msix.c | 24 ++
 hw/rdma/vmw/pvrdma_main.c |  7 +---
 hw/remote/vfio-user-obj.c |  9 +-
 hw/virtio/virtio-pci.c| 67 ---
 9 files changed, 74 insertions(+), 107 deletions(-)

diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h
index 4f1cda0ebe..0e6f257e45 100644
--- a/include/hw/pci/msix.h
+++ b/include/hw/pci/msix.h
@@ -33,10 +33,10 @@ bool msix_is_masked(PCIDevice *dev, unsigned vector);
 void msix_set_pending(PCIDevice *dev, unsigned vector);
 void msix_clr_pending(PCIDevice *dev, int vector);
 
-int msix_vector_use(PCIDevice *dev, unsigned vector);
+void msix_vector_use(PCIDevice *dev, unsigned vector);
 void msix_vector_unuse(PCIDevice *dev, unsigned vector);
 void msix_unuse_all_vectors(PCIDevice *dev);
-void msix_set_mask(PCIDevice *dev, int vector, bool mask, Error **errp);
+void msix_set_mask(PCIDevice *dev, int vector, bool mask);
 
 void msix_notify(PCIDevice *dev, unsigned vector);
 
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index ac96f7665a..7523e9f5d2 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -276,25 +276,18 @@ e1000e_unuse_msix_vectors(E1000EState *s, int num_vectors)
 }
 }
 
-static bool
+static void
 e1000e_use_msix_vectors(E1000EState *s, int num_vectors)
 {
 int i;
 for (i = 0; i < num_vectors; i++) {
-int res = msix_vector_use(PCI_DEVICE(s), i);
-if (res < 0) {
-trace_e1000e_msix_use_vector_fail(i, res);
-e1000e_unuse_msix_vectors(s, i);
-return false;
-}
+msix_vector_use(PCI_DEVICE(s), i);
 }
-return true;
 }
 
 static void
 e1000e_init_msix(E1000EState *s)
 {
-PCIDevice *d = PCI_DEVICE(s);
 int res = msix_init(PCI_DEVICE(s), E1000E_MSIX_VEC_NUM,
 >msix,
 E1000E_MSIX_IDX, E1000E_MSIX_TABLE,
@@ -305,9 +298,7 @@ e1000e_init_msix(E1000EState *s)
 if (res < 0) {
 trace_e1000e_msix_init_fail(res);
 } else {
-if (!e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM)) {
-msix_uninit(d, >msix, >msix);
-}
+e1000e_use_msix_vectors(s, E1000E_MSIX_VEC_NUM);
 }
 }
 
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index d8f3f16fe8..281d43e6cf 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -1212,24 +1212,14 @@ static void rocker_msix_vectors_unuse(Rocker *r,
 }
 }
 
-static int rocker_msix_vectors_use(Rocker *r,
-   unsigned int num_vectors)
+static void rocker_msix_vectors_use(Rocker *r, unsigned int num_vectors)
 {
 PCIDevice *dev = PCI_DEVICE(r);
-int err;
 int i;
 
 for (i = 0; i < num_vectors; i++) {
-err = msix_vector_use(dev, i);
-if (err) {
-goto rollback;
-}
+msix_vector_use(dev, i);
 }
-return 0;
-
-rollback:
-rocker_msix_vectors_unuse(r, i);
-return err;
 }
 
 static int rocker_msix_init(Rocker *r, Error **errp)
@@ -1247,16 +1237,9 @@ static int rocker_msix_init(Rocker *r, Error **errp)
 return err;
 }
 
-err = rocker_msix_vectors_use(r, ROCKER_MSIX_VEC_COUNT(r->fp_ports));
-if (err) {
-goto err_msix_vectors_use;
-}
+rocker_msix_vectors_use(r, ROCKER_MSIX_VEC_COUNT(r->fp_ports));
 
 return 0;
-
-err_msix_vectors_use:
-msix_uninit(dev, >msix_bar, >msix_bar);
-return err;
 }
 
 static void rocker_msix_uninit(Rocker *r)
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 0b7acf7f89..d2ab527ef4 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2110,20 +2110,14 @@ vmxnet3_unuse_msix_vectors(VMXNET3State *s, int 
num_vectors)
 }
 }
 
-static bool
+static void
 vmxnet3_use_msix_vectors(VMXNET3State *s, int num_vectors)
 {
 PCIDevice *d = 

[PULL v4 47/83] tests: acpi: update expected DSDT after ISA bridge is moved directly under PCI host bridge

2022-11-07 Thread Michael S. Tsirkin
From: Igor Mammedov 

example of the change for PC machine with hotplug disabled on root buss (no 
BSEL case):

 -Field (PCI0.ISA.P40C, ByteAcc, NoLock, Preserve)
 +Field (S08.P40C, ByteAcc, NoLock, Preserve)

 ===
 -Scope (_SB.PCI0)
 -{
 -Device (ISA)
 -{
 -Name (_ADR, 0x0001)  // _ADR: Address
 -OperationRegion (P40C, PCI_Config, 0x60, 0x04)
 ...
 -}
 -}
 -
  Scope (_SB)
 ===
 +Device (S08)
 +{
 +Name (_ADR, 0x0001)  // _ADR: Address
 +OperationRegion (P40C, PCI_Config, 0x60, 0x04)
 ...
 +}
 +
  Device (S10)
  {
  Name (_ADR, 0x0002)  // _ADR: Address

with hotplug enabled on root bus (i.e. bus has BSEL configured),
a following addtional entries will be seen:

 +Name (ASUN, One)
 +Method (_DSM, 4, Serialized)  // _DSM: Device-Specific Method
 +{
 +Local0 = Package (0x02)
 +{
 +BSEL,
 +ASUN
 +}
 +Return (PDSM (Arg0, Arg1, Arg2, Arg3, Local0))
 +}

similar changes are expected for Q35 modulo:

 -Field (PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve)
 +Field (SF8.PIRQ, ByteAcc, NoLock, Preserve)

and bridge address

Signed-off-by: Igor Mammedov 
Message-Id: <20221017102146.2254096-5-imamm...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 tests/qtest/bios-tables-test-allowed-diff.h |  34 
 tests/data/acpi/pc/DSDT | Bin 6422 -> 6496 bytes
 tests/data/acpi/pc/DSDT.acpierst| Bin 6382 -> 6456 bytes
 tests/data/acpi/pc/DSDT.acpihmat| Bin 7747 -> 7821 bytes
 tests/data/acpi/pc/DSDT.bridge  | Bin 9496 -> 9570 bytes
 tests/data/acpi/pc/DSDT.cphp| Bin 6886 -> 6960 bytes
 tests/data/acpi/pc/DSDT.dimmpxm | Bin 8076 -> 8150 bytes
 tests/data/acpi/pc/DSDT.hpbridge| Bin 6382 -> 6456 bytes
 tests/data/acpi/pc/DSDT.hpbrroot| Bin 3069 -> 3107 bytes
 tests/data/acpi/pc/DSDT.ipmikcs | Bin 6494 -> 6568 bytes
 tests/data/acpi/pc/DSDT.memhp   | Bin 7781 -> 7855 bytes
 tests/data/acpi/pc/DSDT.nohpet  | Bin 6280 -> 6354 bytes
 tests/data/acpi/pc/DSDT.numamem | Bin 6428 -> 6502 bytes
 tests/data/acpi/pc/DSDT.roothp  | Bin 6656 -> 6694 bytes
 tests/data/acpi/q35/DSDT| Bin 8320 -> 8418 bytes
 tests/data/acpi/q35/DSDT.acpierst   | Bin 8337 -> 8435 bytes
 tests/data/acpi/q35/DSDT.acpihmat   | Bin 9645 -> 9743 bytes
 tests/data/acpi/q35/DSDT.applesmc   | Bin 8366 -> 8464 bytes
 tests/data/acpi/q35/DSDT.bridge | Bin 11449 -> 11547 bytes
 tests/data/acpi/q35/DSDT.cphp   | Bin 8784 -> 8882 bytes
 tests/data/acpi/q35/DSDT.cxl| Bin 9646 -> 9744 bytes
 tests/data/acpi/q35/DSDT.dimmpxm| Bin 9974 -> 10072 bytes
 tests/data/acpi/q35/DSDT.ipmibt | Bin 8395 -> 8493 bytes
 tests/data/acpi/q35/DSDT.ipmismbus  | Bin 8409 -> 8507 bytes
 tests/data/acpi/q35/DSDT.ivrs   | Bin 8337 -> 8435 bytes
 tests/data/acpi/q35/DSDT.memhp  | Bin 9679 -> 9777 bytes
 tests/data/acpi/q35/DSDT.mmio64 | Bin 9450 -> 9548 bytes
 tests/data/acpi/q35/DSDT.multi-bridge   | Bin 8640 -> 8738 bytes
 tests/data/acpi/q35/DSDT.nohpet | Bin 8178 -> 8276 bytes
 tests/data/acpi/q35/DSDT.numamem| Bin 8326 -> 8424 bytes
 tests/data/acpi/q35/DSDT.pvpanic-isa| Bin 8421 -> 8519 bytes
 tests/data/acpi/q35/DSDT.tis.tpm12  | Bin 8926 -> 9024 bytes
 tests/data/acpi/q35/DSDT.tis.tpm2   | Bin 8952 -> 9050 bytes
 tests/data/acpi/q35/DSDT.viot   | Bin 9429 -> 9527 bytes
 tests/data/acpi/q35/DSDT.xapic  | Bin 35683 -> 35781 bytes
 35 files changed, 34 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index 570b17478e..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,35 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/pc/DSDT",
-"tests/data/acpi/pc/DSDT.acpierst",
-"tests/data/acpi/pc/DSDT.acpihmat",
-"tests/data/acpi/pc/DSDT.bridge",
-"tests/data/acpi/pc/DSDT.cphp",
-"tests/data/acpi/pc/DSDT.dimmpxm",
-"tests/data/acpi/pc/DSDT.hpbridge",
-"tests/data/acpi/pc/DSDT.hpbrroot",
-"tests/data/acpi/pc/DSDT.ipmikcs",
-"tests/data/acpi/pc/DSDT.memhp",
-"tests/data/acpi/pc/DSDT.nohpet",
-"tests/data/acpi/pc/DSDT.numamem",
-"tests/data/acpi/pc/DSDT.roothp",
-"tests/data/acpi/q35/DSDT",
-"tests/data/acpi/q35/DSDT.acpierst",
-"tests/data/acpi/q35/DSDT.acpihmat",

[PULL v4 42/83] virtio-rng-pci: Allow setting nvectors, so we can use MSI-X

2022-11-07 Thread Michael S. Tsirkin
From: David Daney 

Most other virtio-pci devices allow MSI-X, let's have it for rng too.

Signed-off-by: David Daney 
Reviewed-by: Marcin Nowakowski 
Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20221014160947.66105-1-phi...@fungible.com>
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
---
 hw/virtio/virtio-rng-pci.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/hw/virtio/virtio-rng-pci.c b/hw/virtio/virtio-rng-pci.c
index 151ece6f94..6e76f8b57b 100644
--- a/hw/virtio/virtio-rng-pci.c
+++ b/hw/virtio/virtio-rng-pci.c
@@ -13,6 +13,7 @@
 
 #include "hw/virtio/virtio-pci.h"
 #include "hw/virtio/virtio-rng.h"
+#include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qemu/module.h"
 #include "qom/object.h"
@@ -31,11 +32,23 @@ struct VirtIORngPCI {
 VirtIORNG vdev;
 };
 
+static Property virtio_rng_properties[] = {
+DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
+VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
+   DEV_NVECTORS_UNSPECIFIED),
+DEFINE_PROP_END_OF_LIST(),
+};
+
 static void virtio_rng_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
 {
 VirtIORngPCI *vrng = VIRTIO_RNG_PCI(vpci_dev);
 DeviceState *vdev = DEVICE(>vdev);
 
+if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
+vpci_dev->nvectors = 2;
+}
+
 if (!qdev_realize(vdev, BUS(_dev->bus), errp)) {
 return;
 }
@@ -54,6 +67,7 @@ static void virtio_rng_pci_class_init(ObjectClass *klass, 
void *data)
 pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_RNG;
 pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
 pcidev_k->class_id = PCI_CLASS_OTHERS;
+device_class_set_props(dc, virtio_rng_properties);
 }
 
 static void virtio_rng_initfn(Object *obj)
-- 
MST




[PULL v4 54/83] tests: acpi: update expected blobs

2022-11-07 Thread Michael S. Tsirkin
From: Igor Mammedov 

Expected changes are:
 1) Moving _GPE scope declaration achec of all _E0x methods
   +Scope (_GPE)
   +{
   +Name (_HID, "ACPI0006" /* GPE Block Device */)  // _HID: Hardware ID
   +}
   +
Scope (_SB)
{
Device (\_SB.PCI0.PRES)

\_SB.CPUS.CSCN ()
}

   -Scope (_GPE)
   -{
   -Name (_HID, "ACPI0006" /* GPE Block Device */)  // _HID: Hardware ID
   -}

 2) Moving _E01 handler after PCI0 scope is defined
-Scope (_GPE)
-{
-Name (_HID, "ACPI0006" /* GPE Block Device */)  // _HID: Hardware 
ID
-Method (_E01, 0, NotSerialized)  // _Exx: Edge-Triggered GPE
-{
-Acquire (\_SB.PCI0.BLCK, 0x)
-\_SB.PCI0.PCNT ()
-Release (\_SB.PCI0.BLCK)
-}
-}
-
 Scope (\_SB.PCI0)
 {
 Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
=
 }
 }
 }
+
+Scope (_GPE)
+{
+Method (_E01, 0, NotSerialized)  // _Exx: Edge-Triggered GPE
+{
+Acquire (\_SB.PCI0.BLCK, 0x)
+\_SB.PCI0.PCNT ()
+Release (\_SB.PCI0.BLCK)
+}
+}
 }

Signed-off-by: Igor Mammedov 
Message-Id: <20221017102146.2254096-12-imamm...@redhat.com>
---
 tests/qtest/bios-tables-test-allowed-diff.h |  34 
 tests/data/acpi/pc/DSDT | Bin 6496 -> 6501 bytes
 tests/data/acpi/pc/DSDT.acpierst| Bin 6456 -> 6461 bytes
 tests/data/acpi/pc/DSDT.acpihmat| Bin 7821 -> 7826 bytes
 tests/data/acpi/pc/DSDT.bridge  | Bin 9570 -> 9575 bytes
 tests/data/acpi/pc/DSDT.cphp| Bin 6960 -> 6965 bytes
 tests/data/acpi/pc/DSDT.dimmpxm | Bin 8150 -> 8155 bytes
 tests/data/acpi/pc/DSDT.hpbridge| Bin 6456 -> 6461 bytes
 tests/data/acpi/pc/DSDT.hpbrroot| Bin 3107 -> 3107 bytes
 tests/data/acpi/pc/DSDT.ipmikcs | Bin 6568 -> 6573 bytes
 tests/data/acpi/pc/DSDT.memhp   | Bin 7855 -> 7860 bytes
 tests/data/acpi/pc/DSDT.nohpet  | Bin 6354 -> 6359 bytes
 tests/data/acpi/pc/DSDT.numamem | Bin 6502 -> 6507 bytes
 tests/data/acpi/pc/DSDT.roothp  | Bin 6694 -> 6699 bytes
 tests/data/acpi/q35/DSDT| Bin 8407 -> 8412 bytes
 tests/data/acpi/q35/DSDT.acpierst   | Bin 8424 -> 8429 bytes
 tests/data/acpi/q35/DSDT.acpihmat   | Bin 9732 -> 9737 bytes
 tests/data/acpi/q35/DSDT.applesmc   | Bin 8453 -> 8458 bytes
 tests/data/acpi/q35/DSDT.bridge | Bin 11536 -> 11541 bytes
 tests/data/acpi/q35/DSDT.cphp   | Bin 8871 -> 8876 bytes
 tests/data/acpi/q35/DSDT.cxl| Bin 9733 -> 9738 bytes
 tests/data/acpi/q35/DSDT.dimmpxm| Bin 10061 -> 10066 bytes
 tests/data/acpi/q35/DSDT.ipmibt | Bin 8482 -> 8487 bytes
 tests/data/acpi/q35/DSDT.ipmismbus  | Bin 8495 -> 8500 bytes
 tests/data/acpi/q35/DSDT.ivrs   | Bin 8424 -> 8429 bytes
 tests/data/acpi/q35/DSDT.memhp  | Bin 9766 -> 9771 bytes
 tests/data/acpi/q35/DSDT.mmio64 | Bin 9537 -> 9542 bytes
 tests/data/acpi/q35/DSDT.multi-bridge   | Bin 8727 -> 8732 bytes
 tests/data/acpi/q35/DSDT.nohpet | Bin 8265 -> 8270 bytes
 tests/data/acpi/q35/DSDT.numamem| Bin 8413 -> 8418 bytes
 tests/data/acpi/q35/DSDT.pvpanic-isa| Bin 8508 -> 8513 bytes
 tests/data/acpi/q35/DSDT.tis.tpm12  | Bin 9013 -> 9018 bytes
 tests/data/acpi/q35/DSDT.tis.tpm2   | Bin 9039 -> 9044 bytes
 tests/data/acpi/q35/DSDT.viot   | Bin 9516 -> 9521 bytes
 tests/data/acpi/q35/DSDT.xapic  | Bin 35770 -> 35775 bytes
 35 files changed, 34 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index 725a1dc798..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,35 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/pc/DSDT",
-"tests/data/acpi/pc/DSDT.bridge",
-"tests/data/acpi/pc/DSDT.ipmikcs",
-"tests/data/acpi/pc/DSDT.cphp",
-"tests/data/acpi/pc/DSDT.memhp",
-"tests/data/acpi/pc/DSDT.numamem",
-"tests/data/acpi/pc/DSDT.nohpet",
-"tests/data/acpi/pc/DSDT.dimmpxm",
-"tests/data/acpi/pc/DSDT.acpihmat",
-"tests/data/acpi/pc/DSDT.acpierst",
-"tests/data/acpi/pc/DSDT.roothp",
-"tests/data/acpi/pc/DSDT.hpbridge",
-"tests/data/acpi/pc/DSDT.hpbrroot",
-"tests/data/acpi/q35/DSDT",
-"tests/data/acpi/q35/DSDT.tis.tpm2",
-"tests/data/acpi/q35/DSDT.tis.tpm12",
-"tests/data/acpi/q35/DSDT.bridge",
-"tests/data/acpi/q35/DSDT.multi-bridge",
-"tests/data/acpi/q35/DSDT.mmio64",
-"tests/data/acpi/q35/DSDT.ipmibt",

[PULL v4 72/83] intel-iommu: drop VTDBus

2022-11-07 Thread Michael S. Tsirkin
From: Jason Wang 

We introduce VTDBus structure as an intermediate step for searching
the address space. This works well with SID based matching/lookup. But
when we want to support SID plus PASID based address space lookup,
this intermediate steps turns out to be a burden. So the patch simply
drops the VTDBus structure and use the PCIBus and devfn as the key for
the g_hash_table(). This simplifies the codes and the future PASID
extension.

To prevent being slower for past vtd_find_as_from_bus_num() callers, a
vtd_as cache indexed by the bus number is introduced to store the last
recent search result of a vtd_as belongs to a specific bus.

Reviewed-by: Peter Xu 
Signed-off-by: Jason Wang 
Message-Id: <20221028061436.30093-3-jasow...@redhat.com>
Reviewed-by: Michael S. Tsirkin 
Signed-off-by: Michael S. Tsirkin 
Reviewed-by: Yi Liu 
---
 include/hw/i386/intel_iommu.h |  11 +-
 hw/i386/intel_iommu.c | 234 +-
 2 files changed, 118 insertions(+), 127 deletions(-)

diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 67653b0f9b..e49fff2a6c 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -58,7 +58,6 @@ typedef struct VTDContextEntry VTDContextEntry;
 typedef struct VTDContextCacheEntry VTDContextCacheEntry;
 typedef struct VTDAddressSpace VTDAddressSpace;
 typedef struct VTDIOTLBEntry VTDIOTLBEntry;
-typedef struct VTDBus VTDBus;
 typedef union VTD_IR_TableEntry VTD_IR_TableEntry;
 typedef union VTD_IR_MSIAddress VTD_IR_MSIAddress;
 typedef struct VTDPASIDDirEntry VTDPASIDDirEntry;
@@ -111,12 +110,6 @@ struct VTDAddressSpace {
 IOVATree *iova_tree;  /* Traces mapped IOVA ranges */
 };
 
-struct VTDBus {
-PCIBus* bus;   /* A reference to the bus to provide 
translation for */
-/* A table of VTDAddressSpace objects indexed by devfn */
-VTDAddressSpace *dev_as[];
-};
-
 struct VTDIOTLBEntry {
 uint64_t gfn;
 uint16_t domain_id;
@@ -253,8 +246,8 @@ struct IntelIOMMUState {
 uint32_t context_cache_gen; /* Should be in [1,MAX] */
 GHashTable *iotlb;  /* IOTLB */
 
-GHashTable *vtd_as_by_busptr;   /* VTDBus objects indexed by PCIBus* 
reference */
-VTDBus *vtd_as_by_bus_num[VTD_PCI_BUS_MAX]; /* VTDBus objects indexed by 
bus number */
+GHashTable *vtd_address_spaces; /* VTD address spaces */
+VTDAddressSpace *vtd_as_cache[VTD_PCI_BUS_MAX]; /* VTD address space cache 
*/
 /* list of registered notifiers */
 QLIST_HEAD(, VTDAddressSpace) vtd_as_with_notifiers;
 
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 271de995be..3d426bb326 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -61,6 +61,16 @@
 } \
 }
 
+/*
+ * PCI bus number (or SID) is not reliable since the device is usaully
+ * initalized before guest can configure the PCI bridge
+ * (SECONDARY_BUS_NUMBER).
+ */
+struct vtd_as_key {
+PCIBus *bus;
+uint8_t devfn;
+};
+
 static void vtd_address_space_refresh_all(IntelIOMMUState *s);
 static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n);
 
@@ -210,6 +220,27 @@ static guint vtd_uint64_hash(gconstpointer v)
 return (guint)*(const uint64_t *)v;
 }
 
+static gboolean vtd_as_equal(gconstpointer v1, gconstpointer v2)
+{
+const struct vtd_as_key *key1 = v1;
+const struct vtd_as_key *key2 = v2;
+
+return (key1->bus == key2->bus) && (key1->devfn == key2->devfn);
+}
+
+/*
+ * Note that we use pointer to PCIBus as the key, so hashing/shifting
+ * based on the pointer value is intended. Note that we deal with
+ * collisions through vtd_as_equal().
+ */
+static guint vtd_as_hash(gconstpointer v)
+{
+const struct vtd_as_key *key = v;
+guint value = (guint)(uintptr_t)key->bus;
+
+return (guint)(value << 8 | key->devfn);
+}
+
 static gboolean vtd_hash_remove_by_domain(gpointer key, gpointer value,
   gpointer user_data)
 {
@@ -248,22 +279,14 @@ static gboolean vtd_hash_remove_by_page(gpointer key, 
gpointer value,
 static void vtd_reset_context_cache_locked(IntelIOMMUState *s)
 {
 VTDAddressSpace *vtd_as;
-VTDBus *vtd_bus;
-GHashTableIter bus_it;
-uint32_t devfn_it;
+GHashTableIter as_it;
 
 trace_vtd_context_cache_reset();
 
-g_hash_table_iter_init(_it, s->vtd_as_by_busptr);
+g_hash_table_iter_init(_it, s->vtd_address_spaces);
 
-while (g_hash_table_iter_next (_it, NULL, (void**)_bus)) {
-for (devfn_it = 0; devfn_it < PCI_DEVFN_MAX; ++devfn_it) {
-vtd_as = vtd_bus->dev_as[devfn_it];
-if (!vtd_as) {
-continue;
-}
-vtd_as->context_cache_entry.context_cache_gen = 0;
-}
+while (g_hash_table_iter_next(_it, NULL, (void **)_as)) {
+vtd_as->context_cache_entry.context_cache_gen = 0;
 }
 

  1   2   3   >