Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

2022-01-04 Thread Jason Wang
On Wed, Jan 5, 2022 at 3:02 PM Michael S. Tsirkin  wrote:
>
> On Wed, Jan 05, 2022 at 12:35:53PM +0800, Jason Wang wrote:
> > On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)  wrote:
> > >
> > > From: Longpeng 
> > >
> > > To support generic vdpa deivce, we need add the following ioctls:
> > > - GET_VECTORS_NUM: the count of vectors that supported
> >
> > Does this mean MSI vectors? If yes, it looks like a layer violation:
> > vhost is transport independent.
>
> Well *guest* needs to know how many vectors device supports.
> I don't think there's a way around that. Do you?

We have VHOST_SET_VRING/CONFIG_CALL which is per vq. I think we can
simply assume #vqs + 1?

> Otherwise guests will at best be suboptimal.
>
> >  And it reveals device implementation
> > details which block (cross vendor) migration.
> >
> > Thanks
>
> Not necessarily, userspace can hide this from guest if it
> wants to, just validate.

If we can hide it at vhost/uAPI level, it would be even better?

Thanks

>
>
> > > - GET_CONFIG_SIZE: the size of the virtio config space
> > > - GET_VQS_NUM: the count of virtqueues that exported
> > >
> > > Signed-off-by: Longpeng 
> > > ---
> > >  linux-headers/linux/vhost.h | 10 ++
> > >  1 file changed, 10 insertions(+)
> > >
> > > diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
> > > index c998860d7b..c5edd75d15 100644
> > > --- a/linux-headers/linux/vhost.h
> > > +++ b/linux-headers/linux/vhost.h
> > > @@ -150,4 +150,14 @@
> > >  /* Get the valid iova range */
> > >  #define VHOST_VDPA_GET_IOVA_RANGE  _IOR(VHOST_VIRTIO, 0x78, \
> > >  struct vhost_vdpa_iova_range)
> > > +
> > > +/* Get the number of vectors */
> > > +#define VHOST_VDPA_GET_VECTORS_NUM _IOR(VHOST_VIRTIO, 0x79, int)
> > > +
> > > +/* Get the virtio config size */
> > > +#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x80, int)
> > > +
> > > +/* Get the number of virtqueues */
> > > +#define VHOST_VDPA_GET_VQS_NUM _IOR(VHOST_VIRTIO, 0x81, int)
> > > +
> > >  #endif
> > > --
> > > 2.23.0
> > >
>




Re: Re: [PATCH 4/5] usb: allow max 8192 bytes for desc

2022-01-04 Thread zhenwei pi



On 1/4/22 11:22 PM, Philippe Mathieu-Daudé wrote:

On 27/12/21 15:27, zhenwei pi wrote:

A device of USB video class usually uses larger desc structure, so
use larger buffer to avoid failure.

Signed-off-by: zhenwei pi 
---
  hw/usb/desc.c | 15 ---
  hw/usb/desc.h |  1 +
  2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index 8b6eaea407..7f6cc2f99b 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -632,7 +632,8 @@ int usb_desc_get_descriptor(USBDevice *dev, 
USBPacket *p,

  bool msos = (dev->flags & (1 << USB_DEV_FLAG_MSOS_DESC_IN_USE));
  const USBDesc *desc = usb_device_get_usb_desc(dev);
  const USBDescDevice *other_dev;
-    uint8_t buf[256];
+    size_t buflen = USB_DESC_MAX_LEN;
+    g_autofree uint8_t *buf = g_malloc(buflen);


Do we want to have a per-device desc_size (in USBDevice, default to
256, video devices set it to 8K)?

How "hot" is this path? Could we keep 8K on the stack?


It's an unlikely code path:
1, During guest startup, guest tries to probe device.
2, run 'lsusb' command in guest

Keeping 8K on the stack also seems OK.


diff --git a/hw/usb/desc.h b/hw/usb/desc.h
index 3ac604ecfa..35babdeff6 100644
--- a/hw/usb/desc.h
+++ b/hw/usb/desc.h
@@ -199,6 +199,7 @@ struct USBDesc {
  const USBDescMSOS *msos;
  };
+#define USB_DESC_MAX_LEN    8192
  #define USB_DESC_FLAG_SUPER (1 << 1)
  /* little helpers */




--
zhenwei pi



Re: Re: [PATCH 0/5] Introduce camera subsystem and USB video device

2022-01-04 Thread zhenwei pi



On 1/4/22 9:39 PM, Daniel P. Berrangé wrote:

On Mon, Dec 27, 2021 at 10:27:29PM +0800, zhenwei pi wrote:

1, The full picture of this patch set:
+-+   ++ +---+
|UVC(done)|   |virtio(TODO)| |other HW device|
+-+   ++ +---+
  | | |
  |++ |
 ++camera(done)+-+
   ++---+
|
  +-+-+
  | | |
   +--+--+ ++-++--+--+
   |builtin(done)| |v4l2(done)||other drivers|
   +-+ +--++-+

With this patch set, We can run a desktop VM (Ex Ubuntu-2004), several camera
APPs(cheese, kamoso, guvcview and qcam) work fine.

Some works still in working:
   1, hot-plug
   2, compat with live migration
   3, several actions defined in UVC SPEC

Zhenwei Pi (5):
   camera: Introduce camera subsystem and builtin driver
   camera: v4l2: Introduce v4l2 camera driver
   usb: Introduce video&mescellaneous
   usb: allow max 8192 bytes for desc
   usb-video: Introduce USB video class

  camera/builtin.c|  717 
  camera/camera-int.h |   19 +
  camera/camera.c |  522 +++
  camera/meson.build  |   20 +
  camera/trace-events |   28 +
  camera/trace.h  |1 +
  camera/v4l2.c   |  637 ++
  hw/usb/Kconfig  |5 +
  hw/usb/desc.c   |   15 +-
  hw/usb/desc.h   |1 +
  hw/usb/dev-video.c  | 1395 +++
  hw/usb/meson.build  |1 +
  hw/usb/trace-events |   11 +
  include/camera/camera.h |  238 +++
  include/hw/usb.h|2 +
  include/hw/usb/video.h  |  303 +
  meson.build |   20 +-
  meson_options.txt   |3 +
  qapi/camera.json|  101 +++
  qapi/meson.build|1 +
  qapi/qapi-schema.json   |1 +
  qemu-options.hx |   13 +
  softmmu/vl.c|4 +


There's no MAINTAINERS file update here.

As a general rule, if you are introducing an entire new subsystem
into the QEMU codebase, it is expected someone will be nominated
as the maintainer for the new subsystem. Usually the person adding
it will themselves volunteer to be the maintainer.

Regards,
Daniel


OK, thanks. I have a plan to add two parts in next version:
1, camera subsystem, include folder qemu/camera and qemu/include/camera/
2, UVC, include qemu/hw/usb/dev-video.c and qemu/include/hw/usb/video.h


--
zhenwei pi



Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

2022-01-04 Thread Michael S. Tsirkin
On Wed, Jan 05, 2022 at 12:35:53PM +0800, Jason Wang wrote:
> On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)  wrote:
> >
> > From: Longpeng 
> >
> > To support generic vdpa deivce, we need add the following ioctls:
> > - GET_VECTORS_NUM: the count of vectors that supported
> 
> Does this mean MSI vectors? If yes, it looks like a layer violation:
> vhost is transport independent.

Well *guest* needs to know how many vectors device supports.
I don't think there's a way around that. Do you?
Otherwise guests will at best be suboptimal.

>  And it reveals device implementation
> details which block (cross vendor) migration.
> 
> Thanks

Not necessarily, userspace can hide this from guest if it
wants to, just validate.


> > - GET_CONFIG_SIZE: the size of the virtio config space
> > - GET_VQS_NUM: the count of virtqueues that exported
> >
> > Signed-off-by: Longpeng 
> > ---
> >  linux-headers/linux/vhost.h | 10 ++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
> > index c998860d7b..c5edd75d15 100644
> > --- a/linux-headers/linux/vhost.h
> > +++ b/linux-headers/linux/vhost.h
> > @@ -150,4 +150,14 @@
> >  /* Get the valid iova range */
> >  #define VHOST_VDPA_GET_IOVA_RANGE  _IOR(VHOST_VIRTIO, 0x78, \
> >  struct vhost_vdpa_iova_range)
> > +
> > +/* Get the number of vectors */
> > +#define VHOST_VDPA_GET_VECTORS_NUM _IOR(VHOST_VIRTIO, 0x79, int)
> > +
> > +/* Get the virtio config size */
> > +#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x80, int)
> > +
> > +/* Get the number of virtqueues */
> > +#define VHOST_VDPA_GET_VQS_NUM _IOR(VHOST_VIRTIO, 0x81, int)
> > +
> >  #endif
> > --
> > 2.23.0
> >




Re: [PATCH v2 1/2] linux-user/ppc: deliver SIGTRAP on POWERPC_EXCP_TRAP

2022-01-04 Thread Cédric Le Goater

On 1/4/22 22:00, matheus.fe...@eldorado.org.br wrote:

From: Matheus Ferst 

Handle POWERPC_EXCP_TRAP in cpu_loop to deliver SIGTRAP on tw[i]/td[i].
The si_code comes from do_program_check in the kernel source file
arch/powerpc/kernel/traps.c

Signed-off-by: Matheus Ferst 
---
  linux-user/ppc/cpu_loop.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index 46e6ffd6d3..6c99feb19b 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -188,7 +188,8 @@ void cpu_loop(CPUPPCState *env)
  }
  break;
  case POWERPC_EXCP_TRAP:
-cpu_abort(cs, "Tried to call a TRAP\n");
+si_signo = TARGET_SIGTRAP;
+si_code = TARGET_TRAP_BRKPT;


These lack 'info.'

Thanks,

C.


  break;
  default:
  /* Should not happen ! */






Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

2022-01-04 Thread Jason Wang



在 2022/1/5 下午2:40, Longpeng (Mike, Cloud Infrastructure Service Product 
Dept.) 写道:



-Original Message-
From: Jason Wang [mailto:jasow...@redhat.com]
Sent: Wednesday, January 5, 2022 12:36 PM
To: Longpeng (Mike, Cloud Infrastructure Service Product Dept.)

Cc: Stefan Hajnoczi ; mst ; Stefano
Garzarella ; Cornelia Huck ; pbonzini
; Gonglei (Arei) ; Yechuan
; Huangzhichao ; qemu-devel

Subject: Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)  wrote:

From: Longpeng 

To support generic vdpa deivce, we need add the following ioctls:
- GET_VECTORS_NUM: the count of vectors that supported

Does this mean MSI vectors? If yes, it looks like a layer violation:
vhost is transport independent.  And it reveals device implementation
details which block (cross vendor) migration.


Can we set the VirtIOPCIProxy.nvectors to "the count of virtqueues + 1 
(config)" ?



That should work.

Thanks





Thanks


- GET_CONFIG_SIZE: the size of the virtio config space
- GET_VQS_NUM: the count of virtqueues that exported

Signed-off-by: Longpeng 
---
  linux-headers/linux/vhost.h | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
index c998860d7b..c5edd75d15 100644
--- a/linux-headers/linux/vhost.h
+++ b/linux-headers/linux/vhost.h
@@ -150,4 +150,14 @@
  /* Get the valid iova range */
  #define VHOST_VDPA_GET_IOVA_RANGE  _IOR(VHOST_VIRTIO, 0x78, \
  struct vhost_vdpa_iova_range)
+
+/* Get the number of vectors */
+#define VHOST_VDPA_GET_VECTORS_NUM _IOR(VHOST_VIRTIO, 0x79, int)
+
+/* Get the virtio config size */
+#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x80, int)
+
+/* Get the number of virtqueues */
+#define VHOST_VDPA_GET_VQS_NUM _IOR(VHOST_VIRTIO, 0x81, int)
+
  #endif
--
2.23.0






RE: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

2022-01-04 Thread longpeng2--- via


> -Original Message-
> From: Jason Wang [mailto:jasow...@redhat.com]
> Sent: Wednesday, January 5, 2022 12:36 PM
> To: Longpeng (Mike, Cloud Infrastructure Service Product Dept.)
> 
> Cc: Stefan Hajnoczi ; mst ; Stefano
> Garzarella ; Cornelia Huck ; pbonzini
> ; Gonglei (Arei) ; Yechuan
> ; Huangzhichao ; qemu-devel
> 
> Subject: Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa
> 
> On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)  wrote:
> >
> > From: Longpeng 
> >
> > To support generic vdpa deivce, we need add the following ioctls:
> > - GET_VECTORS_NUM: the count of vectors that supported
> 
> Does this mean MSI vectors? If yes, it looks like a layer violation:
> vhost is transport independent.  And it reveals device implementation
> details which block (cross vendor) migration.
> 

Can we set the VirtIOPCIProxy.nvectors to "the count of virtqueues + 1 
(config)" ?

> Thanks
> 
> > - GET_CONFIG_SIZE: the size of the virtio config space
> > - GET_VQS_NUM: the count of virtqueues that exported
> >
> > Signed-off-by: Longpeng 
> > ---
> >  linux-headers/linux/vhost.h | 10 ++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
> > index c998860d7b..c5edd75d15 100644
> > --- a/linux-headers/linux/vhost.h
> > +++ b/linux-headers/linux/vhost.h
> > @@ -150,4 +150,14 @@
> >  /* Get the valid iova range */
> >  #define VHOST_VDPA_GET_IOVA_RANGE  _IOR(VHOST_VIRTIO, 0x78, \
> >  struct vhost_vdpa_iova_range)
> > +
> > +/* Get the number of vectors */
> > +#define VHOST_VDPA_GET_VECTORS_NUM _IOR(VHOST_VIRTIO, 0x79, int)
> > +
> > +/* Get the virtio config size */
> > +#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x80, int)
> > +
> > +/* Get the number of virtqueues */
> > +#define VHOST_VDPA_GET_VQS_NUM _IOR(VHOST_VIRTIO, 0x81, int)
> > +
> >  #endif
> > --
> > 2.23.0
> >



Re: [PATCH v3 kvm/queue 14/16] KVM: Handle page fault for private memory

2022-01-04 Thread Chao Peng
On Tue, Jan 04, 2022 at 06:06:12PM +0800, Yan Zhao wrote:
> On Tue, Jan 04, 2022 at 05:10:08PM +0800, Chao Peng wrote:
> > On Tue, Jan 04, 2022 at 09:46:35AM +0800, Yan Zhao wrote:
> > > On Thu, Dec 23, 2021 at 08:30:09PM +0800, Chao Peng wrote:
> > > > When a page fault from the secondary page table while the guest is
> > > > running happens in a memslot with KVM_MEM_PRIVATE, we need go
> > > > different paths for private access and shared access.
> > > > 
> > > >   - For private access, KVM checks if the page is already allocated in
> > > > the memory backend, if yes KVM establishes the mapping, otherwise
> > > > exits to userspace to convert a shared page to private one.
> > > >
> > > will this conversion be atomical or not?
> > > For example, after punching a hole in a private memory slot, will KVM
> > > see two notifications: one for invalidation of the whole private memory
> > > slot, and one for fallocate of the rest ranges besides the hole?
> > > Or, KVM only sees one invalidation notification for the hole?
> > 
> > Punching hole doesn't need to invalidate the whole memory slot. It only
> > send one invalidation notification to KVM for the 'hole' part.
> good :)
> 
> > 
> > Taking shared-to-private conversion as example it only invalidates the
> > 'hole' part (that usually only the portion of the whole memory) on the
> > shared fd,, and then fallocate the private memory in the private fd at
> > the 'hole'. The KVM invalidation notification happens when the shared
> > hole gets invalidated. The establishment of the private mapping happens
> > at subsequent KVM page fault handlers.
> > 
> > > Could you please show QEMU code about this conversion?
> > 
> > See below for the QEMU side conversion code. The above described
> > invalidation and fallocation will be two steps in this conversion. If
> > error happens in the middle then this error will be propagated to
> > kvm_run to do the proper action (e.g. may kill the guest?).
> > 
> > int ram_block_convert_range(RAMBlock *rb, uint64_t start, size_t length,
> > bool shared_to_private)
> > {
> > int ret; 
> > int fd_from, fd_to;
> > 
> > if (!rb || rb->private_fd <= 0) { 
> > return -1;
> > }
> > 
> > if (!QEMU_PTR_IS_ALIGNED(start, rb->page_size) ||
> > !QEMU_PTR_IS_ALIGNED(length, rb->page_size)) {
> > return -1;
> > }
> > 
> > if (length > rb->max_length) {
> > return -1;
> > }
> > 
> > if (shared_to_private) {
> > fd_from = rb->fd;
> > fd_to = rb->private_fd;
> > } else {
> > fd_from = rb->private_fd;
> > fd_to = rb->fd;
> > }
> > 
> > ret = ram_block_discard_range_fd(rb, start, length, fd_from);
> > if (ret) {
> > return ret; 
> > }
> > 
> > if (fd_to > 0) { 
> > return fallocate(fd_to, 0, start, length);
> > }
> > 
> > return 0;
> > }
> > 
> Thanks. So QEMU will re-generate memslots and set KVM_MEM_PRIVATE
> accordingly? Will it involve slot deletion and create?

KVM will not re-generate memslots when do the conversion, instead, it
does unmap/map a range on the same memslot. For memslot with tag
KVM_MEM_PRIVATE, it always have two mappings (private/shared) but at a
time only one is effective. What conversion does is to turn off the
existing mapping and turn on the other mapping for specified range in
that slot.

> 
> > > 
> > > 
> > > >   - For shared access, KVM also checks if the page is already allocated
> > > > in the memory backend, if yes then exit to userspace to convert a
> > > > private page to shared one, otherwise it's treated as a traditional
> > > > hva-based shared memory, KVM lets existing code to obtain a pfn with
> > > > get_user_pages() and establish the mapping.
> > > > 
> > > > The above code assume private memory is persistent and pre-allocated in
> > > > the memory backend so KVM can use this information as an indicator for
> > > > a page is private or shared. The above check is then performed by
> > > > calling kvm_memfd_get_pfn() which currently is implemented as a
> > > > pagecache search but in theory that can be implemented differently
> > > > (i.e. when the page is even not mapped into host pagecache there should
> > > > be some different implementation).
> > > > 
> > > > Signed-off-by: Yu Zhang 
> > > > Signed-off-by: Chao Peng 
> > > > ---
> > > >  arch/x86/kvm/mmu/mmu.c | 73 --
> > > >  arch/x86/kvm/mmu/paging_tmpl.h | 11 +++--
> > > >  2 files changed, 77 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> > > > index 2856eb662a21..fbcdf62f8281 100644
> > > > --- a/arch/x86/kvm/mmu/mmu.c
> > > > +++ b/arch/x86/kvm/mmu/mmu.c
> > > > @@ -2920,6 +2920,9 @@ int kvm_mmu_max_mapping_level(struct kvm *kvm,
> > > > if (max_level == PG_LEVEL_4K)
> > > > return PG_LEVEL_4K;
> > > >  
> > 

Re: [RFC 01/10] virtio: get class_id and pci device id by the virtio id

2022-01-04 Thread Jason Wang
On Wed, Jan 5, 2022 at 1:48 PM Longpeng (Mike, Cloud Infrastructure
Service Product Dept.)  wrote:
>
>
>
> > -Original Message-
> > From: Jason Wang [mailto:jasow...@redhat.com]
> > Sent: Wednesday, January 5, 2022 12:38 PM
> > To: Longpeng (Mike, Cloud Infrastructure Service Product Dept.)
> > 
> > Cc: Stefan Hajnoczi ; mst ; Stefano
> > Garzarella ; Cornelia Huck ; 
> > pbonzini
> > ; Gonglei (Arei) ; Yechuan
> > ; Huangzhichao ; qemu-devel
> > 
> > Subject: Re: [RFC 01/10] virtio: get class_id and pci device id by the 
> > virtio
> > id
> >
> > On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)  wrote:
> > >
> > > From: Longpeng 
> > >
> > > Add helpers to get the "Transitional PCI Device ID" and "class_id" of the
> > > deivce which is specificed by the "Virtio Device ID".
> > >
> > > These helpers will be used to build the generic vDPA device later.
> > >
> > > Signed-off-by: Longpeng 
> > > ---
> > >  hw/virtio/virtio-pci.c | 93 ++
> > >  hw/virtio/virtio-pci.h |  4 ++
> > >  2 files changed, 97 insertions(+)
> > >
> > > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > > index 750aa47ec1..843085c4ea 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,95 @@ static int virtio_pci_load_queue(DeviceState *d, int 
> > > n,
> > QEMUFile *f)
> > >  return 0;
> > >  }
> > >
> > > +typedef struct VirtIOPCIIDInfo {
> > > +uint16_t vdev_id; /* virtio id */
> > > +uint16_t pdev_id; /* pci device id */
> > > +uint16_t class_id;
> > > +} VirtIOPCIIDInfo;
> > > +
> > > +static const VirtIOPCIIDInfo virtio_pci_id_info[] = {
> > > +{
> >
> > Any way to get rid of this array? E.g using the algorithm that is used
> > by the kernel virtio driver.
> >
>
> For device id, we can use the algorithm if we no need to support
> Transitional id. But how to get the class id ?

Right, I miss this. So the current code should be fine.

Thanks

>
> > Thanks
> >
> > > +.vdev_id = VIRTIO_ID_NET,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_NET,
> > > +.class_id = PCI_CLASS_NETWORK_ETHERNET,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_BLOCK,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
> > > +.class_id = PCI_CLASS_STORAGE_SCSI,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_CONSOLE,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
> > > +.class_id = PCI_CLASS_COMMUNICATION_OTHER,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_SCSI,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_SCSI,
> > > +.class_id = PCI_CLASS_STORAGE_SCSI,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_9P,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_9P,
> > > +.class_id = PCI_BASE_CLASS_NETWORK,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_VSOCK,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_VSOCK,
> > > +.class_id = PCI_CLASS_COMMUNICATION_OTHER,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_IOMMU,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_IOMMU,
> > > +.class_id = PCI_CLASS_OTHERS,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_MEM,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_MEM,
> > > +.class_id = PCI_CLASS_OTHERS,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_PMEM,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_PMEM,
> > > +.class_id = PCI_CLASS_OTHERS,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_RNG,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_RNG,
> > > +.class_id = PCI_CLASS_OTHERS,
> > > +},
> > > +{
> > > +.vdev_id = VIRTIO_ID_BALLOON,
> > > +.pdev_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
> > > +.class_id = PCI_CLASS_OTHERS,
> > > +},
> > > +};
> > > +
> > > +static VirtIOPCIIDInfo virtio_pci_get_id_info(uint16_t vdev_id)
> > > +{
> > > +VirtIOPCIIDInfo info = {};
> > > +int i;
> > > +
> > > +for (i = 0; i < ARRAY_SIZE(virtio_pci_id_info); i++) {
> > > +if (virtio_pci_id_info[i].vdev_id == vdev_id) {
> > > +info = virtio_pci_id_info[i];
> > > +break;
> > > +}
> > > +}
> > > +
> > > +return info;
> > > +}
> > > +
> > > +uint16_t virtio_pci_get_pci_devid(uint16_t device_id)
> > > +{
> > > +return virtio_pci_get_id_info(device_id).pdev_id;
> > > +}
> > > +
> > > +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 *

Re: [PATCH v3 kvm/queue 11/16] KVM: Add kvm_map_gfn_range

2022-01-04 Thread Chao Peng
On Tue, Jan 04, 2022 at 05:31:30PM +, Sean Christopherson wrote:
> On Fri, Dec 31, 2021, Chao Peng wrote:
> > On Fri, Dec 24, 2021 at 12:13:51PM +0800, Chao Peng wrote:
> > > On Thu, Dec 23, 2021 at 06:06:19PM +, Sean Christopherson wrote:
> > > > On Thu, Dec 23, 2021, Chao Peng wrote:
> > > > > This new function establishes the mapping in KVM page tables for a
> > > > > given gfn range. It can be used in the memory fallocate callback for
> > > > > memfd based memory to establish the mapping for KVM secondary MMU when
> > > > > the pages are allocated in the memory backend.
> > > > 
> > > > NAK, under no circumstance should KVM install SPTEs in response to 
> > > > allocating
> > > > memory in a file.   The correct thing to do is to invalidate the gfn 
> > > > range
> > > > associated with the newly mapped range, i.e. wipe out any shared SPTEs 
> > > > associated
> > > > with the memslot.
> > > 
> > > Right, thanks.
> > 
> > BTW, I think the current fallocate() callback is just useless as long as
> > we don't want to install KVM SPTEs in response to allocating memory in a
> > file. The invalidation of the shared SPTEs should be notified through 
> > mmu_notifier of the shared memory backend, not memfd_notifier of the
> > private memory backend.
> 
> No, because the private fd is the final source of truth as to whether or not a
> GPA is private, e.g. userspace may choose to not unmap the shared backing.
> KVM's rule per Paolo's/this proposoal is that a GPA is private if it has a 
> private
> memslot and is present in the private backing store.  And the other core rule 
> is
> that KVM must never map both the private and shared variants of a GPA into the
> guest.

That's true, but I'm wondering if zapping the shared variant can be
handled at the time when the private one gets mapped in the KVM page
fault. No bothering the backing store to dedicate a callback to tell
KVM.

Chao



Re: [PATCH v3 kvm/queue 05/16] KVM: Maintain ofs_tree for fast memslot lookup by file offset

2022-01-04 Thread Chao Peng
On Tue, Jan 04, 2022 at 05:43:50PM +, Sean Christopherson wrote:
> On Fri, Dec 31, 2021, Chao Peng wrote:
> > On Tue, Dec 28, 2021 at 09:48:08PM +, Sean Christopherson wrote:
> > >KVM handles
> > > reverse engineering the memslot to get the offset and whatever else it 
> > > needs.
> > > notify_fallocate() and other callbacks are unchanged, though they 
> > > probably can
> > > drop the inode.
> > > 
> > > E.g. likely with bad math and handwaving on the overlap detection:
> > > 
> > > int kvm_private_fd_fallocate_range(void *owner, pgoff_t start, pgoff_t 
> > > end)
> > > {
> > >   struct kvm_memory_slot *slot = owner;
> > >   struct kvm_gfn_range gfn_range = {
> > >   .slot  = slot,
> > >   .start = (start - slot->private_offset) >> PAGE_SHIFT,
> > >   .end   = (end - slot->private_offset) >> PAGE_SHIFT,
> > >   .may_block = true,
> > >   };
> > > 
> > >   if (!has_overlap(slot, start, end))
> > >   return 0;
> > > 
> > >   gfn_range.end = min(gfn_range.end, slot->base_gfn + slot->npages);
> > > 
> > >   kvm_unmap_gfn_range(slot->kvm, &gfn_range);
> > >   return 0;
> > > }
> > 
> > I understand this KVM side handling, but again one fd can have multiple
> > memslots. How shmem decides to notify which memslot from a list of
> > memslots when it invokes the notify_fallocate()? Or just notify all
> > the possible memslots then let KVM to check? 
> 
> Heh, yeah, those are the two choices.  :-)
> 
> Either the backing store needs to support registering callbacks for specific,
> arbitrary ranges, or it needs to invoke all registered callbacks.  Invoking 
> all
> callbacks has my vote; it's much simpler to implement and is unlikely to incur
> meaningful overhead.  _Something_ has to find the overlapping ranges, that 
> cost
> doesn't magically go away if it's pushed into the backing store.
> 
> Note, invoking all notifiers is also aligned with the mmu_notifier behavior.

Sounds a good reason. Then shmem side only needs to maintain a list of
users.

Chao



Re: [PATCH v3 kvm/queue 03/16] mm/memfd: Introduce MEMFD_OPS

2022-01-04 Thread Chao Peng
On Tue, Jan 04, 2022 at 05:38:38PM +, Sean Christopherson wrote:
> On Fri, Dec 31, 2021, Chao Peng wrote:
> > On Fri, Dec 24, 2021 at 11:53:15AM +0800, Robert Hoo wrote:
> > > On Thu, 2021-12-23 at 20:29 +0800, Chao Peng wrote:
> > > > From: "Kirill A. Shutemov" 
> > > >  
> > > > +static void notify_fallocate(struct inode *inode, pgoff_t start,
> > > > pgoff_t end)
> > > > +{
> > > > +#ifdef CONFIG_MEMFD_OPS
> > > > +   struct shmem_inode_info *info = SHMEM_I(inode);
> > > > +   const struct memfd_falloc_notifier *notifier;
> > > > +   void *owner;
> > > > +   bool ret;
> > > > +
> > > > +   if (!info->falloc_notifier)
> > > > +   return;
> > > > +
> > > > +   spin_lock(&info->lock);
> > > > +   notifier = info->falloc_notifier;
> > > > +   if (!notifier) {
> > > > +   spin_unlock(&info->lock);
> > > > +   return;
> > > > +   }
> > > > +
> > > > +   owner = info->owner;
> > > > +   ret = notifier->get_owner(owner);
> > > > +   spin_unlock(&info->lock);
> > > > +   if (!ret)
> > > > +   return;
> > > > +
> > > > +   notifier->fallocate(inode, owner, start, end);
> > > 
> > > I see notifier->fallocate(), i.e. memfd_fallocate(), discards
> > > kvm_memfd_fallocate_range()'s return value. Should it be checked?
> > 
> > I think we can ignore it, just like how current mmu_notifier does,
> > the return value of __kvm_handle_hva_range is discarded in
> > kvm_mmu_notifier_invalidate_range_start(). Even when KVM side failed,
> > it's not fatal, it should not block the operation in the primary MMU.
> 
> If the return value is ignored, it'd be better to have no return value at all 
> so
> that it's clear fallocate() will continue on regardless of whether or not the
> secondary MMU callback succeeds.  E.g. if KVM can't handle the fallocate() for
> whatever reason, then knowing that fallocate() will continue on means KVM 
> should
> mark the VM as dead so that the broken setup cannot be abused by userspace.

After a close look, kvm_unmap_gfn_range() actually does not return a
error code, so it's safe to not return in kvm_memfd_handle_range().

Chao



RE: [RFC 01/10] virtio: get class_id and pci device id by the virtio id

2022-01-04 Thread longpeng2--- via


> -Original Message-
> From: Jason Wang [mailto:jasow...@redhat.com]
> Sent: Wednesday, January 5, 2022 12:38 PM
> To: Longpeng (Mike, Cloud Infrastructure Service Product Dept.)
> 
> Cc: Stefan Hajnoczi ; mst ; Stefano
> Garzarella ; Cornelia Huck ; pbonzini
> ; Gonglei (Arei) ; Yechuan
> ; Huangzhichao ; qemu-devel
> 
> Subject: Re: [RFC 01/10] virtio: get class_id and pci device id by the virtio
> id
> 
> On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)  wrote:
> >
> > From: Longpeng 
> >
> > Add helpers to get the "Transitional PCI Device ID" and "class_id" of the
> > deivce which is specificed by the "Virtio Device ID".
> >
> > These helpers will be used to build the generic vDPA device later.
> >
> > Signed-off-by: Longpeng 
> > ---
> >  hw/virtio/virtio-pci.c | 93 ++
> >  hw/virtio/virtio-pci.h |  4 ++
> >  2 files changed, 97 insertions(+)
> >
> > diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> > index 750aa47ec1..843085c4ea 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,95 @@ static int virtio_pci_load_queue(DeviceState *d, int n,
> QEMUFile *f)
> >  return 0;
> >  }
> >
> > +typedef struct VirtIOPCIIDInfo {
> > +uint16_t vdev_id; /* virtio id */
> > +uint16_t pdev_id; /* pci device id */
> > +uint16_t class_id;
> > +} VirtIOPCIIDInfo;
> > +
> > +static const VirtIOPCIIDInfo virtio_pci_id_info[] = {
> > +{
> 
> Any way to get rid of this array? E.g using the algorithm that is used
> by the kernel virtio driver.
> 

For device id, we can use the algorithm if we no need to support
Transitional id. But how to get the class id ?

> Thanks
> 
> > +.vdev_id = VIRTIO_ID_NET,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_NET,
> > +.class_id = PCI_CLASS_NETWORK_ETHERNET,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_BLOCK,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
> > +.class_id = PCI_CLASS_STORAGE_SCSI,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_CONSOLE,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
> > +.class_id = PCI_CLASS_COMMUNICATION_OTHER,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_SCSI,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_SCSI,
> > +.class_id = PCI_CLASS_STORAGE_SCSI,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_9P,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_9P,
> > +.class_id = PCI_BASE_CLASS_NETWORK,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_VSOCK,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_VSOCK,
> > +.class_id = PCI_CLASS_COMMUNICATION_OTHER,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_IOMMU,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_IOMMU,
> > +.class_id = PCI_CLASS_OTHERS,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_MEM,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_MEM,
> > +.class_id = PCI_CLASS_OTHERS,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_PMEM,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_PMEM,
> > +.class_id = PCI_CLASS_OTHERS,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_RNG,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_RNG,
> > +.class_id = PCI_CLASS_OTHERS,
> > +},
> > +{
> > +.vdev_id = VIRTIO_ID_BALLOON,
> > +.pdev_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
> > +.class_id = PCI_CLASS_OTHERS,
> > +},
> > +};
> > +
> > +static VirtIOPCIIDInfo virtio_pci_get_id_info(uint16_t vdev_id)
> > +{
> > +VirtIOPCIIDInfo info = {};
> > +int i;
> > +
> > +for (i = 0; i < ARRAY_SIZE(virtio_pci_id_info); i++) {
> > +if (virtio_pci_id_info[i].vdev_id == vdev_id) {
> > +info = virtio_pci_id_info[i];
> > +break;
> > +}
> > +}
> > +
> > +return info;
> > +}
> > +
> > +uint16_t virtio_pci_get_pci_devid(uint16_t device_id)
> > +{
> > +return virtio_pci_get_id_info(device_id).pdev_id;
> > +}
> > +
> > +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);
> > @@ -1674,6 +1764,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->pdev_id) {
> > +pci_config_set_device_id(config, proxy->pdev_id);
> > +}
> >  } else {
> >  /* pure virtio-1.0 */
> >

[PATCH] common-user: Really fix i386 calls to safe_syscall_set_errno_tail

2022-01-04 Thread Richard Henderson
Brown bag time: offset 0 from esp is the return address,
offset 4 is the first argument.

Fixes: d7478d4229f0 ("common-user: Fix tail calls to 
safe_syscall_set_errno_tail")
Signed-off-by: Richard Henderson 
---

Ho hum.  I'm disappointed that our CI didn't catch this,
despite cross-i386-user.  And I'm disappointed that I
didn't run a full manual build on an i386 vm to catch
it myself.  I plan on committing this directly.

---
 common-user/host/i386/safe-syscall.inc.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/common-user/host/i386/safe-syscall.inc.S 
b/common-user/host/i386/safe-syscall.inc.S
index 9c45e56e480..db2ed098394 100644
--- a/common-user/host/i386/safe-syscall.inc.S
+++ b/common-user/host/i386/safe-syscall.inc.S
@@ -120,7 +120,7 @@ safe_syscall_end:
 pop %ebp
 .cfi_adjust_cfa_offset -4
 .cfi_restore ebp
-mov %eax, (%esp)
+mov %eax, 4(%esp)
 jmp safe_syscall_set_errno_tail
 
 .cfi_endproc
-- 
2.25.1




Re: [RFC 01/10] virtio: get class_id and pci device id by the virtio id

2022-01-04 Thread Jason Wang
On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)  wrote:
>
> From: Longpeng 
>
> Add helpers to get the "Transitional PCI Device ID" and "class_id" of the
> deivce which is specificed by the "Virtio Device ID".
>
> These helpers will be used to build the generic vDPA device later.
>
> Signed-off-by: Longpeng 
> ---
>  hw/virtio/virtio-pci.c | 93 ++
>  hw/virtio/virtio-pci.h |  4 ++
>  2 files changed, 97 insertions(+)
>
> diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
> index 750aa47ec1..843085c4ea 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,95 @@ static int virtio_pci_load_queue(DeviceState *d, int n, 
> QEMUFile *f)
>  return 0;
>  }
>
> +typedef struct VirtIOPCIIDInfo {
> +uint16_t vdev_id; /* virtio id */
> +uint16_t pdev_id; /* pci device id */
> +uint16_t class_id;
> +} VirtIOPCIIDInfo;
> +
> +static const VirtIOPCIIDInfo virtio_pci_id_info[] = {
> +{

Any way to get rid of this array? E.g using the algorithm that is used
by the kernel virtio driver.

Thanks

> +.vdev_id = VIRTIO_ID_NET,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_NET,
> +.class_id = PCI_CLASS_NETWORK_ETHERNET,
> +},
> +{
> +.vdev_id = VIRTIO_ID_BLOCK,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
> +.class_id = PCI_CLASS_STORAGE_SCSI,
> +},
> +{
> +.vdev_id = VIRTIO_ID_CONSOLE,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
> +.class_id = PCI_CLASS_COMMUNICATION_OTHER,
> +},
> +{
> +.vdev_id = VIRTIO_ID_SCSI,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_SCSI,
> +.class_id = PCI_CLASS_STORAGE_SCSI,
> +},
> +{
> +.vdev_id = VIRTIO_ID_9P,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_9P,
> +.class_id = PCI_BASE_CLASS_NETWORK,
> +},
> +{
> +.vdev_id = VIRTIO_ID_VSOCK,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_VSOCK,
> +.class_id = PCI_CLASS_COMMUNICATION_OTHER,
> +},
> +{
> +.vdev_id = VIRTIO_ID_IOMMU,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_IOMMU,
> +.class_id = PCI_CLASS_OTHERS,
> +},
> +{
> +.vdev_id = VIRTIO_ID_MEM,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_MEM,
> +.class_id = PCI_CLASS_OTHERS,
> +},
> +{
> +.vdev_id = VIRTIO_ID_PMEM,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_PMEM,
> +.class_id = PCI_CLASS_OTHERS,
> +},
> +{
> +.vdev_id = VIRTIO_ID_RNG,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_RNG,
> +.class_id = PCI_CLASS_OTHERS,
> +},
> +{
> +.vdev_id = VIRTIO_ID_BALLOON,
> +.pdev_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
> +.class_id = PCI_CLASS_OTHERS,
> +},
> +};
> +
> +static VirtIOPCIIDInfo virtio_pci_get_id_info(uint16_t vdev_id)
> +{
> +VirtIOPCIIDInfo info = {};
> +int i;
> +
> +for (i = 0; i < ARRAY_SIZE(virtio_pci_id_info); i++) {
> +if (virtio_pci_id_info[i].vdev_id == vdev_id) {
> +info = virtio_pci_id_info[i];
> +break;
> +}
> +}
> +
> +return info;
> +}
> +
> +uint16_t virtio_pci_get_pci_devid(uint16_t device_id)
> +{
> +return virtio_pci_get_id_info(device_id).pdev_id;
> +}
> +
> +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);
> @@ -1674,6 +1764,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->pdev_id) {
> +pci_config_set_device_id(config, proxy->pdev_id);
> +}
>  } else {
>  /* pure virtio-1.0 */
>  pci_set_word(config + PCI_VENDOR_ID,
> diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
> index 2446dcd9ae..06aa59436e 100644
> --- a/hw/virtio/virtio-pci.h
> +++ b/hw/virtio/virtio-pci.h
> @@ -146,6 +146,7 @@ struct VirtIOPCIProxy {
>  bool disable_modern;
>  bool ignore_backend_features;
>  OnOffAuto disable_legacy;
> +uint16_t pdev_id;
>  uint32_t class_code;
>  uint32_t nvectors;
>  uint32_t dfselect;
> @@ -158,6 +159,9 @@ struct VirtIOPCIProxy {
>  VirtioBusState bus;
>  };
>
> +uint16_t virtio_pci_get_pci_devid(uint16_t device_id);
> +uint16_t virtio_pci_get_class_id(uint16_t device_id);
> +
>  static inline bool virtio_pci_modern(VirtIOPCIProxy *proxy)
>  {
>  return !proxy->disable_modern;
> --
> 2.23.0
>




Re: [RFC 02/10] vhost: add 3 commands for vhost-vdpa

2022-01-04 Thread Jason Wang
On Wed, Jan 5, 2022 at 8:59 AM Longpeng(Mike)  wrote:
>
> From: Longpeng 
>
> To support generic vdpa deivce, we need add the following ioctls:
> - GET_VECTORS_NUM: the count of vectors that supported

Does this mean MSI vectors? If yes, it looks like a layer violation:
vhost is transport independent.  And it reveals device implementation
details which block (cross vendor) migration.

Thanks

> - GET_CONFIG_SIZE: the size of the virtio config space
> - GET_VQS_NUM: the count of virtqueues that exported
>
> Signed-off-by: Longpeng 
> ---
>  linux-headers/linux/vhost.h | 10 ++
>  1 file changed, 10 insertions(+)
>
> diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
> index c998860d7b..c5edd75d15 100644
> --- a/linux-headers/linux/vhost.h
> +++ b/linux-headers/linux/vhost.h
> @@ -150,4 +150,14 @@
>  /* Get the valid iova range */
>  #define VHOST_VDPA_GET_IOVA_RANGE  _IOR(VHOST_VIRTIO, 0x78, \
>  struct vhost_vdpa_iova_range)
> +
> +/* Get the number of vectors */
> +#define VHOST_VDPA_GET_VECTORS_NUM _IOR(VHOST_VIRTIO, 0x79, int)
> +
> +/* Get the virtio config size */
> +#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x80, int)
> +
> +/* Get the number of virtqueues */
> +#define VHOST_VDPA_GET_VQS_NUM _IOR(VHOST_VIRTIO, 0x81, int)
> +
>  #endif
> --
> 2.23.0
>




[PATCH 3/3] intel-iommu: PASID support

2022-01-04 Thread 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

For simplicity, PASID cache is not implemented so we can simply
implement the PASID cache flush as a nop. This could be added 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 w/ 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

Signed-off-by: Jason Wang 
---
 hw/i386/intel_iommu.c  | 355 +
 hw/i386/intel_iommu_internal.h |  14 +-
 hw/i386/trace-events   |   2 +
 include/hw/i386/intel_iommu.h  |   6 +-
 include/hw/pci/pci_bus.h   |   2 +
 5 files changed, 289 insertions(+), 90 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 58c682097b..04ae604ea1 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -64,6 +64,14 @@
 struct vtd_as_key {
 PCIBus *bus;
 uint8_t devfn;
+uint32_t pasid;
+};
+
+struct vtd_iotlb_key {
+uint16_t sid;
+uint32_t pasid;
+uint64_t gfn;
+uint32_t level;
 };
 
 static void vtd_address_space_refresh_all(IntelIOMMUState *s);
@@ -193,15 +201,36 @@ static inline gboolean 
vtd_as_has_map_notifier(VTDAddressSpace *as)
 }
 
 /* GHashTable functions */
-static gboolean vtd_uint64_equal(gconstpointer v1, gconstpointer v2)
+static gboolean vtd_iotlb_equal(gconstpointer v1, gconstpointer v2)
+{
+const struct vtd_iotlb_key *key1 = v1;
+const struct vtd_iotlb_key *key2 = v2;
+
+return key1->sid == key2->sid &&
+   key1->pasid == key2->pasid &&
+   key1->level == key2->level &&
+   key1->gfn == key2->gfn;
+}
+
+static guint vtd_iotlb_hash(gconstpointer v)
+{
+const struct vtd_iotlb_key *key = v;
+
+return key->gfn | ((key->sid) << VTD_IOTLB_SID_SHIFT) |
+   (key->level) << VTD_IOTLB_LVL_SHIFT |
+   (key->pasid) << VTD_IOTLB_PASID_SHIFT;
+}
+
+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);
+return (key1->bus == key2->bus) && (key1->devfn == key2->devfn) &&
+   (key1->pasid == key2->pasid);
 }
 
-static guint vtd_uint64_hash(gconstpointer v)
+static guint vtd_as_hash(gconstpointer v)
 {
 const struct vtd_as_key *key = v;
 guint value = (guint)(uintptr_t)key->bus;
@@ -241,6 +270,29 @@ static gboolean vtd_hash_remove_by_page(gpointer key, 
gpointer value,
  (entry->gfn == gfn_tlb));
 }
 
+static gboolean vtd_hash_remove_by_page_pasid(gpointer key, gpointer value,
+  gpointer user_data)
+{
+VTDIOTLBEntry *entry = (VTDIOTLBEntry *)value;
+VTDIOTLBPageInvInfo *info = (VTDIOTLBPageInvInfo *)user_data;
+uint64_t gfn = (info->addr >> VTD_PAGE_SHIFT_4K) & info->mask;
+uint64_t gfn_tlb = (info->addr & entry->mask) >> VTD_PAGE_SHIFT_4K;
+return (entry->domain_id == info->domain_id) &&
+   (entry->pasid == info->pasid) &&
+(((entry->gfn & info->mask) == gfn) ||
+ (entry->gfn == gfn_tlb));
+}
+
+static gboolean vtd_hash_remove_by_pasid(gpointer key, gpointer value,
+ gpointer user_data)
+{
+VTDIOTLBEntry *entry = (VTDIOTLBEntry *)value;
+VTDIOTLBPageInvInfo *info = (VTDIOTLBPageInvInfo *)user_data;
+
+return (entry->domain_id == info->domain_id) &&
+   (entry->pasid == info->pasid);
+}
+
 /* Reset all the gen of VTDAddressSpace to zero and set the gen of
  * IntelIOMMUState to 1.  Must be called with IOMMU lock held.
  */
@@ -281,13 +333,6 @@ static void vtd_reset_caches(IntelIOMMUState *s)
 vtd_iommu_unlock(s);
 }
 
-static uint64_t vtd_get_iotlb_key(uint64_t gfn, uint16_t source_id,
-  uint32_t level)
-{
-return gfn | ((uint64_t)(source_id) << VTD_IOTLB_SID_SHIFT) |
-   ((uint64_t)(level) << VTD_IOTLB_LVL_SHIFT);
-}
-
 static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32_t level)
 {
 return (addr & vtd_slpt_level_page_mask(level)) >> VTD_PAGE_SHIFT_4K;
@@ -295,15 +340,17 @@ static uint64_t vtd_get_iotlb_gfn(hwaddr addr, uint32_t 
level)
 
 /* Must be called with IOMMU lock held */
 static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,
-   hwaddr addr)
+   hwad

[PATCH 2/3] intel-iommu: drop VTDBus

2022-01-04 Thread 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.

This may case slight slower for the vtd_find_as_from_bus_num() callers
but since they are all called from the control path, we can afford it.

Signed-off-by: Jason Wang 
---
 hw/i386/intel_iommu.c | 183 +-
 include/hw/i386/intel_iommu.h |  10 +-
 2 files changed, 69 insertions(+), 124 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index f2c7a23712..58c682097b 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -61,6 +61,11 @@
 } \
 }
 
+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);
 
@@ -190,12 +195,18 @@ static inline gboolean 
vtd_as_has_map_notifier(VTDAddressSpace *as)
 /* GHashTable functions */
 static gboolean vtd_uint64_equal(gconstpointer v1, gconstpointer v2)
 {
-return *((const uint64_t *)v1) == *((const uint64_t *)v2);
+const struct vtd_as_key *key1 = v1;
+const struct vtd_as_key *key2 = v2;
+
+return (key1->bus == key2->bus) && (key1->devfn == key2->devfn);
 }
 
 static guint vtd_uint64_hash(gconstpointer v)
 {
-return (guint)*(const uint64_t *)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,
@@ -236,22 +247,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(&bus_it, s->vtd_as_by_busptr);
+g_hash_table_iter_init(&as_it, s->vtd_as);
 
-while (g_hash_table_iter_next (&bus_it, NULL, (void**)&vtd_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 (&as_it, NULL, (void**)&vtd_as)) {
+vtd_as->context_cache_entry.context_cache_gen = 0;
 }
 s->context_cache_gen = 1;
 }
@@ -986,32 +989,6 @@ static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, 
uint32_t level)
 return slpte & rsvd_mask;
 }
 
-/* Find the VTD address space associated with a given bus number */
-static VTDBus *vtd_find_as_from_bus_num(IntelIOMMUState *s, uint8_t bus_num)
-{
-VTDBus *vtd_bus = s->vtd_as_by_bus_num[bus_num];
-GHashTableIter iter;
-
-if (vtd_bus) {
-return vtd_bus;
-}
-
-/*
- * Iterate over the registered buses to find the one which
- * currently holds this bus number and update the bus_num
- * lookup table.
- */
-g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
-while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
-if (pci_bus_num(vtd_bus->bus) == bus_num) {
-s->vtd_as_by_bus_num[bus_num] = vtd_bus;
-return vtd_bus;
-}
-}
-
-return NULL;
-}
-
 /* Given the @iova, get relevant @slptep. @slpte_level will be the last level
  * of the translation, can be used for deciding the size of large page.
  */
@@ -1604,18 +1581,12 @@ static bool vtd_switch_address_space(VTDAddressSpace 
*as)
 
 static void vtd_switch_address_space_all(IntelIOMMUState *s)
 {
+VTDAddressSpace *vtd_as;
 GHashTableIter iter;
-VTDBus *vtd_bus;
-int i;
-
-g_hash_table_iter_init(&iter, s->vtd_as_by_busptr);
-while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_bus)) {
-for (i = 0; i < PCI_DEVFN_MAX; i++) {
-if (!vtd_bus->dev_as[i]) {
-continue;
-}
-vtd_switch_address_space(vtd_bus->dev_as[i]);
-}
+
+g_hash_table_iter_init(&iter, s->vtd_as);
+while (g_hash_table_iter_next(&iter, NULL, (void **)&vtd_as)) {
+vtd_switch_address_space(vtd_as);
 }
 }
 
@@ -1659,16 +1630,11 @@ static inline bool vtd_is_interrupt_addr(hwaddr addr)
 
 static void vtd_pt_enable_fast_path(IntelIOMMUState *s, uint16_t source_id)
 {
-VTDBus *vtd_bus;
 VTDAddressSpace *vtd_as;
 bool success = false;
+uintptr_t key = (uintptr_t)source_id;
 
-vtd_bus = vtd_find_as_from_bus_num

[PATCH 0/3] PASID support for Intel IOMMU

2022-01-04 Thread Jason Wang
Hi All:

This series tries to introduce PASID support for Intel IOMMU. The work
is based on the previous scalabe mode support by implement the
ECAP_PASID. A new "x-pasid-mode" is introduced to enable this
mode. All internal vIOMMU codes were extended to support PASID instead
of the current RID2PASID method. The code is also capable of
provisiong address space with PASID. Note that no devices can issue
PASID DMA right now, this needs future work.

This will be used for prototying PASID based device like virito or
future vPASID support for Intel IOMMU.

Test has been done with the Linux guest with scalalbe mode enabled and
disabled. A virtio prototype[1][2] that can issue PAISD based DMA
request were also tested.

This series depends on the fix of passthrough mode:

https://lore.kernel.org/all/20211222063956.2871-1-jasow...@redhat.com/T/

Please review.

[1] https://github.com/jasowang/qemu.git virtio-pasid
[2] https://github.com/jasowang/linux.git virtio-pasid

Jason Wang (3):
  intel-iommu: don't warn guest errors when getting rid2pasid entry
  intel-iommu: drop VTDBus
  intel-iommu: PASID support

 hw/i386/intel_iommu.c  | 538 +
 hw/i386/intel_iommu_internal.h |  14 +-
 hw/i386/trace-events   |   2 +
 include/hw/i386/intel_iommu.h  |  16 +-
 include/hw/pci/pci_bus.h   |   2 +
 5 files changed, 359 insertions(+), 213 deletions(-)

-- 
2.25.1




[PATCH 1/3] intel-iommu: don't warn guest errors when getting rid2pasid entry

2022-01-04 Thread 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.

Signed-off-by: Jason Wang 
---
 hw/i386/intel_iommu.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 4c6c016388..f2c7a23712 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1524,8 +1524,10 @@ static bool vtd_dev_pt_enabled(IntelIOMMUState *s, 
VTDContextEntry *ce)
 if (s->root_scalable) {
 ret = vtd_ce_get_rid2pasid_entry(s, ce, &pe);
 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(&pe) == VTD_SM_PASID_ENTRY_PT);
-- 
2.25.1




[PATCH v4 2/2] linux-user: call set/getscheduler set/getparam directly

2022-01-04 Thread Tonis Tiigi
There seems to be difference in syscall and libc definition of these
methods and therefore musl does not implement them (1e21e78bf7). Call
syscall directly to ensure the behavior of the libc of user application,
not the libc that was used to build QEMU.

Signed-off-by: Tonis Tiigi 
---
 linux-user/syscall.c  | 34 --
 linux-user/syscall_defs.h |  4 
 2 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1b8415c8a3..30962155a6 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -359,6 +359,17 @@ _syscall4(int, sys_sched_getattr, pid_t, pid, struct 
sched_attr *, attr,
 #define __NR_sys_sched_setattr __NR_sched_setattr
 _syscall3(int, sys_sched_setattr, pid_t, pid, struct sched_attr *, attr,
   unsigned int, flags);
+#define __NR_sys_sched_getscheduler __NR_sched_getscheduler
+_syscall1(int, sys_sched_getscheduler, pid_t, pid);
+#define __NR_sys_sched_setscheduler __NR_sched_setscheduler
+_syscall3(int, sys_sched_setscheduler, pid_t, pid, int, policy,
+  const struct sched_param *, param);
+#define __NR_sys_sched_getparam __NR_sched_getparam
+_syscall2(int, sys_sched_getparam, pid_t, pid,
+  struct sched_param *, param);
+#define __NR_sys_sched_setparam __NR_sched_setparam
+_syscall2(int, sys_sched_setparam, pid_t, pid,
+  const struct sched_param *, param);
 #define __NR_sys_getcpu __NR_getcpu
 _syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
 _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
@@ -10587,30 +10598,32 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 return ret;
 case TARGET_NR_sched_setparam:
 {
-struct sched_param *target_schp;
+struct target_sched_param *target_schp;
 struct sched_param schp;
 
 if (arg2 == 0) {
 return -TARGET_EINVAL;
 }
-if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1))
+if (!lock_user_struct(VERIFY_READ, target_schp, arg2, 1)) {
 return -TARGET_EFAULT;
+}
 schp.sched_priority = tswap32(target_schp->sched_priority);
 unlock_user_struct(target_schp, arg2, 0);
-return get_errno(sched_setparam(arg1, &schp));
+return get_errno(sys_sched_setparam(arg1, &schp));
 }
 case TARGET_NR_sched_getparam:
 {
-struct sched_param *target_schp;
+struct target_sched_param *target_schp;
 struct sched_param schp;
 
 if (arg2 == 0) {
 return -TARGET_EINVAL;
 }
-ret = get_errno(sched_getparam(arg1, &schp));
+ret = get_errno(sys_sched_getparam(arg1, &schp));
 if (!is_error(ret)) {
-if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0))
+if (!lock_user_struct(VERIFY_WRITE, target_schp, arg2, 0)) {
 return -TARGET_EFAULT;
+}
 target_schp->sched_priority = tswap32(schp.sched_priority);
 unlock_user_struct(target_schp, arg2, 1);
 }
@@ -10618,19 +10631,20 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 return ret;
 case TARGET_NR_sched_setscheduler:
 {
-struct sched_param *target_schp;
+struct target_sched_param *target_schp;
 struct sched_param schp;
 if (arg3 == 0) {
 return -TARGET_EINVAL;
 }
-if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1))
+if (!lock_user_struct(VERIFY_READ, target_schp, arg3, 1)) {
 return -TARGET_EFAULT;
+}
 schp.sched_priority = tswap32(target_schp->sched_priority);
 unlock_user_struct(target_schp, arg3, 0);
-return get_errno(sched_setscheduler(arg1, arg2, &schp));
+return get_errno(sys_sched_setscheduler(arg1, arg2, &schp));
 }
 case TARGET_NR_sched_getscheduler:
-return get_errno(sched_getscheduler(arg1));
+return get_errno(sys_sched_getscheduler(arg1));
 case TARGET_NR_sched_getattr:
 {
 struct target_sched_attr *target_scha;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 310d6ce8ad..28b9fe9a47 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -2928,4 +2928,8 @@ struct target_sched_attr {
 abi_uint sched_util_max;
 };
 
+struct target_sched_param {
+abi_int sched_priority;
+};
+
 #endif
-- 
2.32.0 (Apple Git-132)




[PATCH] intel-iommu: correctly check passthrough during translation

2022-01-04 Thread Jason Wang
When scsalable mode is enabled, the passthrough more is not determined
by the context entry but PASID entry, so switch to use the logic of
vtd_dev_pt_enabled() to determine the passthrough mode in
vtd_do_iommu_translate().

Signed-off-by: Jason Wang 
---
 hw/i386/intel_iommu.c | 38 +++---
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index f584449d8d..f346a82652 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -1512,11 +1512,29 @@ static int vtd_sync_shadow_page_table(VTDAddressSpace 
*vtd_as)
  * 1st-level translation or 2nd-level translation, it depends
  * on PGTT setting.
  */
-static bool vtd_dev_pt_enabled(VTDAddressSpace *as)
+static bool vtd_dev_pt_enabled(IntelIOMMUState *s, VTDContextEntry *ce)
+{
+VTDPASIDEntry pe;
+int ret;
+
+if (s->root_scalable) {
+ret = vtd_ce_get_rid2pasid_entry(s, ce, &pe);
+if (ret) {
+error_report_once("%s: vtd_ce_get_rid2pasid_entry error: %"PRId32,
+  __func__, ret);
+return false;
+}
+return (VTD_PE_GET_TYPE(&pe) == VTD_SM_PASID_ENTRY_PT);
+}
+
+return (vtd_ce_get_type(ce) == VTD_CONTEXT_TT_PASS_THROUGH);
+
+}
+
+static bool vtd_as_pt_enabled(VTDAddressSpace *as)
 {
 IntelIOMMUState *s;
 VTDContextEntry ce;
-VTDPASIDEntry pe;
 int ret;
 
 assert(as);
@@ -1534,17 +1552,7 @@ static bool vtd_dev_pt_enabled(VTDAddressSpace *as)
 return false;
 }
 
-if (s->root_scalable) {
-ret = vtd_ce_get_rid2pasid_entry(s, &ce, &pe);
-if (ret) {
-error_report_once("%s: vtd_ce_get_rid2pasid_entry error: %"PRId32,
-  __func__, ret);
-return false;
-}
-return (VTD_PE_GET_TYPE(&pe) == VTD_SM_PASID_ENTRY_PT);
-}
-
-return (vtd_ce_get_type(&ce) == VTD_CONTEXT_TT_PASS_THROUGH);
+return vtd_dev_pt_enabled(s, &ce);
 }
 
 /* Return whether the device is using IOMMU translation. */
@@ -1556,7 +1564,7 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
 
 assert(as);
 
-use_iommu = as->iommu_state->dmar_enabled && !vtd_dev_pt_enabled(as);
+use_iommu = as->iommu_state->dmar_enabled && !vtd_as_pt_enabled(as);
 
 trace_vtd_switch_address_space(pci_bus_num(as->bus),
VTD_PCI_SLOT(as->devfn),
@@ -1749,7 +1757,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace 
*vtd_as, PCIBus *bus,
  * We don't need to translate for pass-through context entries.
  * Also, let's ignore IOTLB caching as well for PT devices.
  */
-if (vtd_ce_get_type(&ce) == VTD_CONTEXT_TT_PASS_THROUGH) {
+if (vtd_dev_pt_enabled(s, &ce)) {
 entry->iova = addr & VTD_PAGE_MASK_4K;
 entry->translated_addr = entry->iova;
 entry->addr_mask = ~VTD_PAGE_MASK_4K;
-- 
2.25.1




[PATCH v4 1/2] linux-user: add sched_getattr support

2022-01-04 Thread Tonis Tiigi
These syscalls are not exposed by glibc. The struct type need to be
redefined as it can't be included directly before
https://lkml.org/lkml/2020/5/28/810 .

sched_attr type can grow in future kernel versions. When client sends
values that QEMU does not understand it will return E2BIG with same
semantics as old kernel would so client can retry with smaller inputs.

Signed-off-by: Tonis Tiigi 
---
 linux-user/syscall.c  | 123 ++
 linux-user/syscall_defs.h |  14 +
 2 files changed, 137 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 56a3e17183..1b8415c8a3 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -340,6 +340,25 @@ _syscall3(int, sys_sched_getaffinity, pid_t, pid, unsigned 
int, len,
 #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
 _syscall3(int, sys_sched_setaffinity, pid_t, pid, unsigned int, len,
   unsigned long *, user_mask_ptr);
+/* sched_attr is not defined in glibc */
+struct sched_attr {
+uint32_t size;
+uint32_t sched_policy;
+uint64_t sched_flags;
+int32_t sched_nice;
+uint32_t sched_priority;
+uint64_t sched_runtime;
+uint64_t sched_deadline;
+uint64_t sched_period;
+uint32_t sched_util_min;
+uint32_t sched_util_max;
+};
+#define __NR_sys_sched_getattr __NR_sched_getattr
+_syscall4(int, sys_sched_getattr, pid_t, pid, struct sched_attr *, attr,
+  unsigned int, size, unsigned int, flags);
+#define __NR_sys_sched_setattr __NR_sched_setattr
+_syscall3(int, sys_sched_setattr, pid_t, pid, struct sched_attr *, attr,
+  unsigned int, flags);
 #define __NR_sys_getcpu __NR_getcpu
 _syscall3(int, sys_getcpu, unsigned *, cpu, unsigned *, node, void *, tcache);
 _syscall4(int, reboot, int, magic1, int, magic2, unsigned int, cmd,
@@ -558,6 +577,24 @@ const char *target_strerror(int err)
 return strerror(target_to_host_errno(err));
 }
 
+static int check_zeroed_user(abi_long addr, size_t ksize, size_t usize)
+{
+int i;
+uint8_t b;
+if (usize <= ksize) {
+return 1;
+}
+for (i = ksize; i < usize; i++) {
+if (get_user_u8(b, addr + i)) {
+return -TARGET_EFAULT;
+}
+if (b != 0) {
+return 0;
+}
+}
+return 1;
+}
+
 #define safe_syscall0(type, name) \
 static type safe_##name(void) \
 { \
@@ -10594,6 +10631,92 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 }
 case TARGET_NR_sched_getscheduler:
 return get_errno(sched_getscheduler(arg1));
+case TARGET_NR_sched_getattr:
+{
+struct target_sched_attr *target_scha;
+struct sched_attr scha;
+if (arg2 == 0) {
+return -TARGET_EINVAL;
+}
+if (arg3 > sizeof(scha)) {
+arg3 = sizeof(scha);
+}
+ret = get_errno(sys_sched_getattr(arg1, &scha, arg3, arg4));
+if (!is_error(ret)) {
+target_scha = lock_user(VERIFY_WRITE, arg2, arg3, 0);
+if (!target_scha) {
+return -TARGET_EFAULT;
+}
+target_scha->size = tswap32(scha.size);
+target_scha->sched_policy = tswap32(scha.sched_policy);
+target_scha->sched_flags = tswap64(scha.sched_flags);
+target_scha->sched_nice = tswap32(scha.sched_nice);
+target_scha->sched_priority = tswap32(scha.sched_priority);
+target_scha->sched_runtime = tswap64(scha.sched_runtime);
+target_scha->sched_deadline = tswap64(scha.sched_deadline);
+target_scha->sched_period = tswap64(scha.sched_period);
+if (scha.size > offsetof(struct sched_attr, sched_util_min)) {
+target_scha->sched_util_min = tswap32(scha.sched_util_min);
+target_scha->sched_util_max = tswap32(scha.sched_util_max);
+}
+unlock_user(target_scha, arg2, arg3);
+}
+return ret;
+}
+case TARGET_NR_sched_setattr:
+{
+struct target_sched_attr *target_scha;
+struct sched_attr scha;
+uint32_t size;
+int zeroed;
+if (arg2 == 0) {
+return -TARGET_EINVAL;
+}
+if (get_user_u32(size, arg2)) {
+return -TARGET_EFAULT;
+}
+if (!size) {
+size = offsetof(struct target_sched_attr, sched_util_min);
+}
+if (size < offsetof(struct target_sched_attr, sched_util_min)) {
+if (put_user_u32(sizeof(struct target_sched_attr), arg2)) {
+return -TARGET_EFAULT;
+}
+return -TARGET_E2BIG;
+}
+
+zeroed = check_zeroed_user(arg2, sizeof(struct target_sched_attr), 
size);
+if (zeroed < 0) {
+   

[PATCH v4 0/2] linux-user: fixes for sched_ syscalls

2022-01-04 Thread Tonis Tiigi
This patchset improves support for sched_* syscalls under user emulation.

The first commit adds support for sched_g/setattr that was previously not 
implemented. These syscalls are not exposed by glibc. The struct type needs
to be redefined as it can't be included directly before
https://lkml.org/lkml/2020/5/28/810 .

sched_attr type can grow in future kernel versions. When client sends
values that QEMU does not understand it will return E2BIG with same
semantics as old kernel would so client can retry with smaller inputs.

The second commit fixes sched_g/setscheduler and sched_g/setparam, when QEMU is 
built with musl. Musl does not implement these due to conflict between what 
these functions should do in syscalls and libc 
https://git.musl-libc.org/cgit/musl/commit/?id=1e21e78bf7a5c24c217446d8760be7b7188711c2
 . I've changed it to call syscall directly what should always be the expected 
behavior for the user.

Via https://github.com/tonistiigi/binfmt/pull/70
https://github.com/tonistiigi/binfmt/pull/73 with additional tests.


Changes v4->v3:
- host `sched_param` type is used for local syscalls
- Added check_zeroed_user() helper. This function takes kernel and userspace 
size
and checks if the extra padding is empty with same rules as kernel does. I also
tried with only one size parameter but doing all the `size-sizeof()` 
calculations
on caller side made the function quite useless.
- Defined local host version for `sched_param` so target and host types are 
defined
separately.
- Moved size type declaration to the beginning of the function.

Changes v3->v2:
- Fix wrong property name for sched_flags
- Validate size parameter and handle E2BIG errors same way as kernel does. There
is one case where it can't be done completely correctly but clients should still
be able to handle it: when client sends a bigger non-zero structure than current
kernel definition we will send E2BIG with the struct size known to qemu. If now
the client sends structure with this size it may still get another E2BIG error
from the kernel if kernel is old and doesn't implement util_min/util_max. I 
don't
think this can be handled without making additional syscalls to kernel.

Changes v1->v2:
- Locking guest addresses for sched_attr is now based on size inputs, not local 
struct size. Also did the same for setter where I now read only the size field 
of the struct first.
- Use offsetof() when checking if optional fields are supported.
- `target_sched_attr` now uses aligned types as requested. I didn't quite 
understand why this is needed as I don't see same in kernel headers, but as 
this type uses only constant width fields and is already aligned by default it 
can't break anything.
- Fixed formatting.
- Defined own `target_sched_param` struct as requested.

Tonis Tiigi (2):
  linux-user: add sched_getattr support
  linux-user: call set/getscheduler set/getparam directly

 linux-user/syscall.c  | 157 +++---
 linux-user/syscall_defs.h |  18 +
 2 files changed, 165 insertions(+), 10 deletions(-)

-- 
2.32.0 (Apple Git-132)




Re: [PATCH v6 15/23] target/riscv: Implement AIA IMSIC interface CSRs

2022-01-04 Thread Frank Chang
Anup Patel  於 2021年12月30日 週四 下午8:53寫道:

> From: Anup Patel 
>
> The AIA specification defines IMSIC interface CSRs for easy access
> to the per-HART IMSIC registers without using indirect xiselect and
> xireg CSRs. This patch implements the AIA IMSIC interface CSRs.
>
> Signed-off-by: Anup Patel 
> Signed-off-by: Anup Patel 
> ---
>  target/riscv/csr.c | 202 +
>  1 file changed, 202 insertions(+)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 488877e89c..89e74f848d 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -906,6 +906,16 @@ static int aia_xlate_vs_csrno(CPURISCVState *env, int
> csrno)
>  return CSR_VSISELECT;
>  case CSR_SIREG:
>  return CSR_VSIREG;
> +case CSR_SSETEIPNUM:
> +return CSR_VSSETEIPNUM;
> +case CSR_SCLREIPNUM:
> +return CSR_VSCLREIPNUM;
> +case CSR_SSETEIENUM:
> +return CSR_VSSETEIENUM;
> +case CSR_SCLREIENUM:
> +return CSR_VSCLREIENUM;
> +case CSR_STOPEI:
> +return CSR_VSTOPEI;
>  default:
>  return csrno;
>  };
> @@ -1058,6 +1068,177 @@ done:
>  return RISCV_EXCP_NONE;
>  }
>
> +static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong
> *val,
> +target_ulong new_val, target_ulong wr_mask)
> +{
> +int ret = -EINVAL;
> +bool set, pend, virt;
> +target_ulong priv, isel, vgein, xlen, nval, wmask;
> +
> +/* Translate CSR number for VS-mode */
> +csrno = aia_xlate_vs_csrno(env, csrno);
> +
> +/* Decode register details from CSR number */
> +virt = set = pend = false;
> +switch (csrno) {
> +case CSR_MSETEIPNUM:
> +priv = PRV_M;
> +set = true;
>

Missing: *pend = true;* here?

Frank Chang


> +break;
> +case CSR_MCLREIPNUM:
> +priv = PRV_M;
> +pend = true;
> +break;
> +case CSR_MSETEIENUM:
> +priv = PRV_M;
> +set = true;
> +break;
> +case CSR_MCLREIENUM:
> +priv = PRV_M;
> +break;
> +case CSR_SSETEIPNUM:
> +priv = PRV_S;
> +set = true;
> +pend = true;
> +break;
> +case CSR_SCLREIPNUM:
> +priv = PRV_S;
> +pend = true;
> +break;
> +case CSR_SSETEIENUM:
> +priv = PRV_S;
> +set = true;
> +break;
> +case CSR_SCLREIENUM:
> +priv = PRV_S;
> +break;
> +case CSR_VSSETEIPNUM:
> +priv = PRV_S;
> +virt = true;
> +set = true;
> +pend = true;
> +break;
> +case CSR_VSCLREIPNUM:
> +priv = PRV_S;
> +virt = true;
> +pend = true;
> +break;
> +case CSR_VSSETEIENUM:
> +priv = PRV_S;
> +virt = true;
> +set = true;
> +break;
> +case CSR_VSCLREIENUM:
> +priv = PRV_S;
> +virt = true;
> +break;
> +default:
> + goto done;
> +};
> +
> +/* IMSIC CSRs only available when machine implements IMSIC. */
> +if (!env->aia_ireg_rmw_fn[priv]) {
> +goto done;
> +}
> +
> +/* Find the selected guest interrupt file */
> +vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
> +
> +/* Selected guest interrupt file should be valid */
> +if (virt && (!vgein || env->geilen < vgein)) {
> +goto done;
> +}
> +
> +/* Set/Clear CSRs always read zero */
> +if (val) {
> +*val = 0;
> +}
> +
> +if (wr_mask) {
> +/* Get interrupt number */
> +new_val &= wr_mask;
> +
> +/* Find target interrupt pending/enable register */
> +xlen = riscv_cpu_mxl_bits(env);
> +isel = (new_val / xlen);
> +isel *= (xlen / IMSIC_EIPx_BITS);
> +isel += (pend) ? ISELECT_IMSIC_EIP0 : ISELECT_IMSIC_EIE0;
> +
> +/* Find the interrupt bit to be set/clear */
> +wmask = ((target_ulong)1) << (new_val % xlen);
> +nval = (set) ? wmask : 0;
> +
> +/* Call machine specific IMSIC register emulation */
> +ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
> + AIA_MAKE_IREG(isel, priv, virt,
> +   vgein, xlen),
> + NULL, nval, wmask);
> +} else {
> +ret = 0;
> +}
> +
> +done:
> +if (ret) {
> +return (riscv_cpu_virt_enabled(env) && virt) ?
> +   RISCV_EXCP_VIRT_INSTRUCTION_FAULT :
> RISCV_EXCP_ILLEGAL_INST;
> +}
> +return RISCV_EXCP_NONE;
> +}
> +
> +static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
> +  target_ulong new_val, target_ulong wr_mask)
> +{
> +bool virt;
> +int ret = -EINVAL;
> +target_ulong priv, vgein;
> +
> +/* Translate CSR number for VS-mode */
> +csrno = aia_xlate_vs_csrno(env, csrno);
> +
> +/* Decode register details from

[RESEND PATCH v3 7/7] hw/core: tcg-cpu-ops.h: Update comments of debug_check_watchpoint()

2022-01-04 Thread Bin Meng
From: Bin Meng 

This is now used by RISC-V as well. Update the comments.

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

(no changes since v1)

 include/hw/core/tcg-cpu-ops.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index e13898553a..f98671ff32 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -90,6 +90,7 @@ struct TCGCPUOps {
 /**
  * @debug_check_watchpoint: return true if the architectural
  * watchpoint whose address has matched should really fire, used by ARM
+ * and RISC-V
  */
 bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);
 
-- 
2.25.1




[RESEND PATCH v3 6/7] target/riscv: cpu: Enable native debug feature

2022-01-04 Thread Bin Meng
From: Bin Meng 

Turn on native debug feature by default for all CPUs.

Signed-off-by: Bin Meng 
---

Changes in v3:
- enable debug feature by default for all CPUs

 target/riscv/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 17dcc3c14f..17444b458f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -644,7 +644,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
-DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false),
+DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
 
 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
 DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
-- 
2.25.1




[RESEND PATCH v3 4/7] target/riscv: cpu: Add a config option for native debug

2022-01-04 Thread Bin Meng
From: Bin Meng 

Add a config option to enable support for native M-mode debug.
This is disabled by default and can be enabled with 'debug=true'.

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

(no changes since v2)

Changes in v2:
- change the config option to 'disabled' by default

 target/riscv/cpu.h | 2 ++
 target/riscv/cpu.c | 5 +
 2 files changed, 7 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0f3b3a4219..35445bbc86 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -75,6 +75,7 @@ enum {
 RISCV_FEATURE_MMU,
 RISCV_FEATURE_PMP,
 RISCV_FEATURE_EPMP,
+RISCV_FEATURE_DEBUG,
 RISCV_FEATURE_MISA
 };
 
@@ -332,6 +333,7 @@ struct RISCVCPU {
 bool mmu;
 bool pmp;
 bool epmp;
+bool debug;
 uint64_t resetvec;
 } cfg;
 };
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3aa07bc019..d36c31ce9a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -448,6 +448,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+if (cpu->cfg.debug) {
+set_feature(env, RISCV_FEATURE_DEBUG);
+}
+
 set_resetvec(env, cpu->cfg.resetvec);
 
 /* Validate that MISA_MXL is set properly. */
@@ -634,6 +638,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false),
 
 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
 DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
-- 
2.25.1




Re: [PATCH] Set return code on failure

2022-01-04 Thread Jason Wang
On Wed, Jan 5, 2022 at 5:32 AM Patrick Venture  wrote:
>
>
>
> On Tue, Jan 4, 2022 at 1:18 PM Patrick Venture  wrote:
>>
>> From: Peter Foley 
>>
>> Match the other error handling in this function.
>
>
> Just noticed I didn't fix up the commit title here to match style.  Should I 
> do a PATCH RESEND or a new patch, or can you add the "net/tap: " to the title 
> before applying (should it be accepted).

Please resend.

Thanks

>
>>
>>
>> Signed-off-by: Peter Foley 
>
> Reviewed-by: Patrick Venture 
>>
>> ---
>>  net/tap.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/net/tap.c b/net/tap.c
>> index f716be3e3f..c5cbeaa7a2 100644
>> --- a/net/tap.c
>> +++ b/net/tap.c
>> @@ -900,6 +900,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
>>  if (i == 0) {
>>  vnet_hdr = tap_probe_vnet_hdr(fd, errp);
>>  if (vnet_hdr < 0) {
>> +ret = -1;
>>  goto free_fail;
>>  }
>>  } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
>> --
>> 2.34.1.448.ga2b2bfdf31-goog
>>




[PATCH v3 1/7] target/riscv: Add initial support for native debug

2022-01-04 Thread Bin Meng
This adds initial support for the native debug via the Trigger Module,
as defined in the RISC-V Debug Specification [1].

Only "Address / Data Match" trigger (type 2) is implemented as of now,
which is mainly used for hardware breakpoint and watchpoint. The number
of type 2 triggers implemented is 2, which is the number that we can
find in the SiFive U54/U74 cores.

[1] https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf

Signed-off-by: Bin Meng 

---

Changes in v3:
- drop riscv_trigger_init(), which will be moved to patch #5

 target/riscv/cpu.h   |   5 +
 target/riscv/debug.h | 108 +
 target/riscv/debug.c | 339 +++
 target/riscv/meson.build |   1 +
 4 files changed, 453 insertions(+)
 create mode 100644 target/riscv/debug.h
 create mode 100644 target/riscv/debug.c

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index dc10f27093..0f3b3a4219 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -98,6 +98,7 @@ typedef struct CPURISCVState CPURISCVState;
 
 #if !defined(CONFIG_USER_ONLY)
 #include "pmp.h"
+#include "debug.h"
 #endif
 
 #define RV_VLEN_MAX 1024
@@ -234,6 +235,10 @@ struct CPURISCVState {
 pmp_table_t pmp_state;
 target_ulong mseccfg;
 
+/* trigger module */
+target_ulong trigger_cur;
+trigger_type2_t trigger_type2[TRIGGER_TYPE2_NUM];
+
 /* machine specific rdtime callback */
 uint64_t (*rdtime_fn)(uint32_t);
 uint32_t rdtime_fn_arg;
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
new file mode 100644
index 00..0a3fda6c72
--- /dev/null
+++ b/target/riscv/debug.h
@@ -0,0 +1,108 @@
+/*
+ * QEMU RISC-V Native Debug Support
+ *
+ * Copyright (c) 2022 Wind River Systems, Inc.
+ *
+ * Author:
+ *   Bin Meng 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 .
+ */
+
+#ifndef RISCV_DEBUG_H
+#define RISCV_DEBUG_H
+
+/* trigger indexes implemented */
+enum {
+TRIGGER_TYPE2_IDX_0 = 0,
+TRIGGER_TYPE2_IDX_1,
+TRIGGER_TYPE2_NUM,
+TRIGGER_NUM = TRIGGER_TYPE2_NUM
+};
+
+/* register index of tdata CSRs */
+enum {
+TDATA1 = 0,
+TDATA2,
+TDATA3,
+TDATA_NUM
+};
+
+typedef enum {
+TRIGGER_TYPE_NO_EXIST = 0,  /* trigger does not exist */
+TRIGGER_TYPE_AD_MATCH = 2,  /* address/data match trigger */
+TRIGGER_TYPE_INST_CNT = 3,  /* instruction count trigger */
+TRIGGER_TYPE_INT = 4,   /* interrupt trigger */
+TRIGGER_TYPE_EXCP = 5,  /* exception trigger */
+TRIGGER_TYPE_AD_MATCH6 = 6, /* new address/data match trigger */
+TRIGGER_TYPE_EXT_SRC = 7,   /* external source trigger */
+TRIGGER_TYPE_UNAVAIL = 15   /* trigger exists, but unavailable */
+} trigger_type_t;
+
+typedef struct {
+target_ulong mcontrol;
+target_ulong maddress;
+struct CPUBreakpoint *bp;
+struct CPUWatchpoint *wp;
+} trigger_type2_t;
+
+/* tdata field masks */
+
+#define RV32_TYPE(t)((uint32_t)(t) << 28)
+#define RV32_TYPE_MASK  (0xf << 28)
+#define RV32_DMODE  BIT(27)
+#define RV64_TYPE(t)((uint64_t)(t) << 60)
+#define RV64_TYPE_MASK  (0xfULL << 60)
+#define RV64_DMODE  BIT_ULL(59)
+
+/* mcontrol field masks */
+
+#define TYPE2_LOAD  BIT(0)
+#define TYPE2_STORE BIT(1)
+#define TYPE2_EXEC  BIT(2)
+#define TYPE2_U BIT(3)
+#define TYPE2_S BIT(4)
+#define TYPE2_M BIT(6)
+#define TYPE2_MATCH (0xf << 7)
+#define TYPE2_CHAIN BIT(11)
+#define TYPE2_ACTION(0xf << 12)
+#define TYPE2_SIZELO(0x3 << 16)
+#define TYPE2_TIMINGBIT(18)
+#define TYPE2_SELECTBIT(19)
+#define TYPE2_HIT   BIT(20)
+#define TYPE2_SIZEHI(0x3 << 21) /* RV64 only */
+
+/* access size */
+enum {
+SIZE_ANY = 0,
+SIZE_1B,
+SIZE_2B,
+SIZE_4B,
+SIZE_6B,
+SIZE_8B,
+SIZE_10B,
+SIZE_12B,
+SIZE_14B,
+SIZE_16B,
+SIZE_NUM = 16
+};
+
+bool tdata_available(CPURISCVState *env, int tdata_index);
+
+target_ulong tselect_csr_read(CPURISCVState *env);
+void tselect_csr_write(CPURISCVState *env, target_ulong val);
+
+target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index);
+void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val);
+
+#endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
new file mode 100644
index 00..530e030007
--- /dev/null
+++ b/target/riscv/debug.c
@@ -0,0 +1,339 @@
+/*
+ * QEMU RIS

[RESEND PATCH v3 0/7] target/riscv: Initial support for native debug feature via M-mode CSRs

2022-01-04 Thread Bin Meng


This adds initial support for the native debug via the Trigger Module,
as defined in the RISC-V Debug Specification [1].

Only "Address / Data Match" trigger (type 2) is implemented as of now,
which is mainly used for hardware breakpoint and watchpoint. The number
of type 2 triggers implemented is 2, which is the number that we can
find in the SiFive U54/U74 cores.

[1] https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf

- RESEND to correct the email address


Changes in v3:
- drop riscv_trigger_init(), which will be moved to patch #5
- add riscv_trigger_init(), moved from patch #1 to this patch
- enable debug feature by default for all CPUs

Changes in v2:
- new patch: add debug state description
- use 0 instead of GETPC()
- change the config option to 'disabled' by default

Bin Meng (7):
  target/riscv: Add initial support for native debug
  target/riscv: machine: Add debug state description
  target/riscv: debug: Implement debug related TCGCPUOps
  target/riscv: cpu: Add a config option for native debug
  target/riscv: csr: Hook debug CSR read/write
  target/riscv: cpu: Enable native debug feature
  hw/core: tcg-cpu-ops.h: Update comments of debug_check_watchpoint()

 include/hw/core/tcg-cpu-ops.h |   1 +
 target/riscv/cpu.h|   7 +
 target/riscv/debug.h  | 114 +
 target/riscv/cpu.c|  14 ++
 target/riscv/csr.c|  57 +
 target/riscv/debug.c  | 441 ++
 target/riscv/machine.c|  33 +++
 target/riscv/meson.build  |   1 +
 8 files changed, 668 insertions(+)
 create mode 100644 target/riscv/debug.h
 create mode 100644 target/riscv/debug.c

-- 
2.25.1




[RESEND PATCH v3 3/7] target/riscv: debug: Implement debug related TCGCPUOps

2022-01-04 Thread Bin Meng
From: Bin Meng 

Implement .debug_excp_handler, .debug_check_{breakpoint, watchpoint}
TCGCPUOps and hook them into riscv_tcg_ops.

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

(no changes since v2)

Changes in v2:
- use 0 instead of GETPC()

 target/riscv/debug.h |  4 +++
 target/riscv/cpu.c   |  3 ++
 target/riscv/debug.c | 75 
 3 files changed, 82 insertions(+)

diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index 0a3fda6c72..d0f63e2414 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -105,4 +105,8 @@ void tselect_csr_write(CPURISCVState *env, target_ulong 
val);
 target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index);
 void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val);
 
+void riscv_cpu_debug_excp_handler(CPUState *cs);
+bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
+bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
+
 #endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6ef3314bce..3aa07bc019 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -705,6 +705,9 @@ static const struct TCGCPUOps riscv_tcg_ops = {
 .do_interrupt = riscv_cpu_do_interrupt,
 .do_transaction_failed = riscv_cpu_do_transaction_failed,
 .do_unaligned_access = riscv_cpu_do_unaligned_access,
+.debug_excp_handler = riscv_cpu_debug_excp_handler,
+.debug_check_breakpoint = riscv_cpu_debug_check_breakpoint,
+.debug_check_watchpoint = riscv_cpu_debug_check_watchpoint,
 #endif /* !CONFIG_USER_ONLY */
 };
 
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 530e030007..7760c4611f 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -337,3 +337,78 @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, 
target_ulong val)
 
 return write_func(env, env->trigger_cur, tdata_index, val);
 }
+
+void riscv_cpu_debug_excp_handler(CPUState *cs)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = &cpu->env;
+
+if (cs->watchpoint_hit) {
+if (cs->watchpoint_hit->flags & BP_CPU) {
+cs->watchpoint_hit = NULL;
+riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
+}
+} else {
+if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
+riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
+}
+}
+}
+
+bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = &cpu->env;
+CPUBreakpoint *bp;
+target_ulong ctrl;
+target_ulong pc;
+int i;
+
+QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
+for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
+ctrl = env->trigger_type2[i].mcontrol;
+pc = env->trigger_type2[i].maddress;
+
+if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
+/* check U/S/M bit against current privilege level */
+if ((ctrl >> 3) & BIT(env->priv)) {
+return true;
+}
+}
+}
+}
+
+return false;
+}
+
+bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = &cpu->env;
+target_ulong ctrl;
+target_ulong addr;
+int flags;
+int i;
+
+for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
+ctrl = env->trigger_type2[i].mcontrol;
+addr = env->trigger_type2[i].maddress;
+flags = 0;
+
+if (ctrl & TYPE2_LOAD) {
+flags |= BP_MEM_READ;
+}
+if (ctrl & TYPE2_STORE) {
+flags |= BP_MEM_WRITE;
+}
+
+if ((wp->flags & flags) && (wp->vaddr == addr)) {
+/* check U/S/M bit against current privilege level */
+if ((ctrl >> 3) & BIT(env->priv)) {
+return true;
+}
+}
+}
+
+return false;
+}
-- 
2.25.1




[PATCH v3 7/7] hw/core: tcg-cpu-ops.h: Update comments of debug_check_watchpoint()

2022-01-04 Thread Bin Meng
This is now used by RISC-V as well. Update the comments.

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

---

(no changes since v1)

 include/hw/core/tcg-cpu-ops.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index e13898553a..f98671ff32 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -90,6 +90,7 @@ struct TCGCPUOps {
 /**
  * @debug_check_watchpoint: return true if the architectural
  * watchpoint whose address has matched should really fire, used by ARM
+ * and RISC-V
  */
 bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);
 
-- 
2.25.1




[RESEND PATCH v3 5/7] target/riscv: csr: Hook debug CSR read/write

2022-01-04 Thread Bin Meng
From: Bin Meng 

This adds debug CSR read/write support to the RISC-V CSR RW table.

Signed-off-by: Bin Meng 
---

Changes in v3:
- add riscv_trigger_init(), moved from patch #1 to this patch

 target/riscv/debug.h |  2 ++
 target/riscv/cpu.c   |  6 +
 target/riscv/csr.c   | 57 
 target/riscv/debug.c | 27 +
 4 files changed, 92 insertions(+)

diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index d0f63e2414..f4da2db35d 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -109,4 +109,6 @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
 bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
 bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
 
+void riscv_trigger_init(CPURISCVState *env);
+
 #endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d36c31ce9a..17dcc3c14f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -575,6 +575,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 
 riscv_cpu_register_gdb_regs_for_features(cs);
 
+#ifndef CONFIG_USER_ONLY
+if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
+riscv_trigger_init(env);
+}
+#endif
+
 qemu_init_vcpu(cs);
 cpu_reset(cs);
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 146447eac5..189b9cc8c6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -220,6 +220,15 @@ static RISCVException epmp(CPURISCVState *env, int csrno)
 
 return RISCV_EXCP_ILLEGAL_INST;
 }
+
+static RISCVException debug(CPURISCVState *env, int csrno)
+{
+if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
+return RISCV_EXCP_NONE;
+}
+
+return RISCV_EXCP_ILLEGAL_INST;
+}
 #endif
 
 /* User Floating-Point CSRs */
@@ -1464,6 +1473,48 @@ static RISCVException write_pmpaddr(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
+static RISCVException read_tselect(CPURISCVState *env, int csrno,
+   target_ulong *val)
+{
+*val = tselect_csr_read(env);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_tselect(CPURISCVState *env, int csrno,
+target_ulong val)
+{
+tselect_csr_write(env, val);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_tdata(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+/* return 0 in tdata1 to end the trigger enumeration */
+if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
+*val = 0;
+return RISCV_EXCP_NONE;
+}
+
+if (!tdata_available(env, csrno - CSR_TDATA1)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+*val = tdata_csr_read(env, csrno - CSR_TDATA1);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_tdata(CPURISCVState *env, int csrno,
+  target_ulong val)
+{
+if (!tdata_available(env, csrno - CSR_TDATA1)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+tdata_csr_write(env, csrno - CSR_TDATA1, val);
+return RISCV_EXCP_NONE;
+}
+
 /*
  * Functions to access Pointer Masking feature registers
  * We have to check if current priv lvl could modify
@@ -1962,6 +2013,12 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_PMPADDR14] =  { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
 [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
 
+/* Debug CSRs */
+[CSR_TSELECT]   =  { "tselect", debug, read_tselect, write_tselect },
+[CSR_TDATA1]=  { "tdata1",  debug, read_tdata,   write_tdata   },
+[CSR_TDATA2]=  { "tdata2",  debug, read_tdata,   write_tdata   },
+[CSR_TDATA3]=  { "tdata3",  debug, read_tdata,   write_tdata   },
+
 /* User Pointer Masking */
 [CSR_UMTE]={ "umte",pointer_masking, read_umte,write_umte  
  },
 [CSR_UPMMASK] ={ "upmmask", pointer_masking, read_upmmask, 
write_upmmask },
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 7760c4611f..041a0d3a89 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -412,3 +412,30 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp)
 
 return false;
 }
+
+void riscv_trigger_init(CPURISCVState *env)
+{
+target_ulong type2 = trigger_type(env, TRIGGER_TYPE_AD_MATCH);
+int i;
+
+/* type 2 triggers */
+for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
+/*
+ * type = TRIGGER_TYPE_AD_MATCH
+ * dmode = 0 (both debug and M-mode can write tdata)
+ * maskmax = 0 (unimplemented, always 0)
+ * sizehi = 0 (match against any size, RV64 only)
+ * hit = 0 (unimplemented, always 0)
+ * select = 0 (always 0, perform match on address)
+ * timing = 0 (always 0, trigger before instruction)
+ * sizelo = 0 (match against any size)
+ * action = 0 (always 0, raise a breakpoint exception)
+ * chain = 0 (unimplemented, alwa

[RESEND PATCH v3 2/7] target/riscv: machine: Add debug state description

2022-01-04 Thread Bin Meng
From: Bin Meng 

Add a subsection to machine.c to migrate debug CSR state.

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

(no changes since v2)

Changes in v2:
- new patch: add debug state description

 target/riscv/machine.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index ad8248ebfd..25aa3b38f7 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -164,6 +164,38 @@ static const VMStateDescription vmstate_pointermasking = {
 }
 };
 
+static bool debug_needed(void *opaque)
+{
+RISCVCPU *cpu = opaque;
+CPURISCVState *env = &cpu->env;
+
+return riscv_feature(env, RISCV_FEATURE_DEBUG);
+}
+
+static const VMStateDescription vmstate_debug_type2 = {
+.name = "cpu/debug/type2",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINTTL(mcontrol, trigger_type2_t),
+VMSTATE_UINTTL(maddress, trigger_type2_t),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static const VMStateDescription vmstate_debug = {
+.name = "cpu/debug",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = debug_needed,
+.fields = (VMStateField[]) {
+VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
+VMSTATE_STRUCT_ARRAY(env.trigger_type2, RISCVCPU, TRIGGER_TYPE2_NUM,
+ 0, vmstate_debug_type2, trigger_type2_t),
+VMSTATE_END_OF_LIST()
+}
+};
+
 const VMStateDescription vmstate_riscv_cpu = {
 .name = "cpu",
 .version_id = 3,
@@ -218,6 +250,7 @@ const VMStateDescription vmstate_riscv_cpu = {
 &vmstate_hyper,
 &vmstate_vector,
 &vmstate_pointermasking,
+&vmstate_debug,
 NULL
 }
 };
-- 
2.25.1




[RESEND PATCH v3 0/7] target/riscv: Initial support for native debug feature via M-mode CSRs

2022-01-04 Thread Bin Meng


This adds initial support for the native debug via the Trigger Module,
as defined in the RISC-V Debug Specification [1].

Only "Address / Data Match" trigger (type 2) is implemented as of now,
which is mainly used for hardware breakpoint and watchpoint. The number
of type 2 triggers implemented is 2, which is the number that we can
find in the SiFive U54/U74 cores.

[1] https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf

- RESEND to correct the email address


Changes in v3:
- drop riscv_trigger_init(), which will be moved to patch #5
- add riscv_trigger_init(), moved from patch #1 to this patch
- enable debug feature by default for all CPUs

Changes in v2:
- new patch: add debug state description
- use 0 instead of GETPC()
- change the config option to 'disabled' by default

Bin Meng (7):
  target/riscv: Add initial support for native debug
  target/riscv: machine: Add debug state description
  target/riscv: debug: Implement debug related TCGCPUOps
  target/riscv: cpu: Add a config option for native debug
  target/riscv: csr: Hook debug CSR read/write
  target/riscv: cpu: Enable native debug feature
  hw/core: tcg-cpu-ops.h: Update comments of debug_check_watchpoint()

 include/hw/core/tcg-cpu-ops.h |   1 +
 target/riscv/cpu.h|   7 +
 target/riscv/debug.h  | 114 +
 target/riscv/cpu.c|  14 ++
 target/riscv/csr.c|  57 +
 target/riscv/debug.c  | 441 ++
 target/riscv/machine.c|  33 +++
 target/riscv/meson.build  |   1 +
 8 files changed, 668 insertions(+)
 create mode 100644 target/riscv/debug.h
 create mode 100644 target/riscv/debug.c

-- 
2.25.1




[PATCH v3 6/7] target/riscv: cpu: Enable native debug feature

2022-01-04 Thread Bin Meng
Turn on native debug feature by default for all CPUs.

Signed-off-by: Bin Meng 

---

Changes in v3:
- enable debug feature by default for all CPUs

 target/riscv/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 17dcc3c14f..17444b458f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -644,7 +644,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
-DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false),
+DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
 
 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
 DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
-- 
2.25.1




[RESEND PATCH v3 1/7] target/riscv: Add initial support for native debug

2022-01-04 Thread Bin Meng
From: Bin Meng 

This adds initial support for the native debug via the Trigger Module,
as defined in the RISC-V Debug Specification [1].

Only "Address / Data Match" trigger (type 2) is implemented as of now,
which is mainly used for hardware breakpoint and watchpoint. The number
of type 2 triggers implemented is 2, which is the number that we can
find in the SiFive U54/U74 cores.

[1] https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf

Signed-off-by: Bin Meng 
---

Changes in v3:
- drop riscv_trigger_init(), which will be moved to patch #5

 target/riscv/cpu.h   |   5 +
 target/riscv/debug.h | 108 +
 target/riscv/debug.c | 339 +++
 target/riscv/meson.build |   1 +
 4 files changed, 453 insertions(+)
 create mode 100644 target/riscv/debug.h
 create mode 100644 target/riscv/debug.c

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index dc10f27093..0f3b3a4219 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -98,6 +98,7 @@ typedef struct CPURISCVState CPURISCVState;
 
 #if !defined(CONFIG_USER_ONLY)
 #include "pmp.h"
+#include "debug.h"
 #endif
 
 #define RV_VLEN_MAX 1024
@@ -234,6 +235,10 @@ struct CPURISCVState {
 pmp_table_t pmp_state;
 target_ulong mseccfg;
 
+/* trigger module */
+target_ulong trigger_cur;
+trigger_type2_t trigger_type2[TRIGGER_TYPE2_NUM];
+
 /* machine specific rdtime callback */
 uint64_t (*rdtime_fn)(uint32_t);
 uint32_t rdtime_fn_arg;
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
new file mode 100644
index 00..0a3fda6c72
--- /dev/null
+++ b/target/riscv/debug.h
@@ -0,0 +1,108 @@
+/*
+ * QEMU RISC-V Native Debug Support
+ *
+ * Copyright (c) 2022 Wind River Systems, Inc.
+ *
+ * Author:
+ *   Bin Meng 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 .
+ */
+
+#ifndef RISCV_DEBUG_H
+#define RISCV_DEBUG_H
+
+/* trigger indexes implemented */
+enum {
+TRIGGER_TYPE2_IDX_0 = 0,
+TRIGGER_TYPE2_IDX_1,
+TRIGGER_TYPE2_NUM,
+TRIGGER_NUM = TRIGGER_TYPE2_NUM
+};
+
+/* register index of tdata CSRs */
+enum {
+TDATA1 = 0,
+TDATA2,
+TDATA3,
+TDATA_NUM
+};
+
+typedef enum {
+TRIGGER_TYPE_NO_EXIST = 0,  /* trigger does not exist */
+TRIGGER_TYPE_AD_MATCH = 2,  /* address/data match trigger */
+TRIGGER_TYPE_INST_CNT = 3,  /* instruction count trigger */
+TRIGGER_TYPE_INT = 4,   /* interrupt trigger */
+TRIGGER_TYPE_EXCP = 5,  /* exception trigger */
+TRIGGER_TYPE_AD_MATCH6 = 6, /* new address/data match trigger */
+TRIGGER_TYPE_EXT_SRC = 7,   /* external source trigger */
+TRIGGER_TYPE_UNAVAIL = 15   /* trigger exists, but unavailable */
+} trigger_type_t;
+
+typedef struct {
+target_ulong mcontrol;
+target_ulong maddress;
+struct CPUBreakpoint *bp;
+struct CPUWatchpoint *wp;
+} trigger_type2_t;
+
+/* tdata field masks */
+
+#define RV32_TYPE(t)((uint32_t)(t) << 28)
+#define RV32_TYPE_MASK  (0xf << 28)
+#define RV32_DMODE  BIT(27)
+#define RV64_TYPE(t)((uint64_t)(t) << 60)
+#define RV64_TYPE_MASK  (0xfULL << 60)
+#define RV64_DMODE  BIT_ULL(59)
+
+/* mcontrol field masks */
+
+#define TYPE2_LOAD  BIT(0)
+#define TYPE2_STORE BIT(1)
+#define TYPE2_EXEC  BIT(2)
+#define TYPE2_U BIT(3)
+#define TYPE2_S BIT(4)
+#define TYPE2_M BIT(6)
+#define TYPE2_MATCH (0xf << 7)
+#define TYPE2_CHAIN BIT(11)
+#define TYPE2_ACTION(0xf << 12)
+#define TYPE2_SIZELO(0x3 << 16)
+#define TYPE2_TIMINGBIT(18)
+#define TYPE2_SELECTBIT(19)
+#define TYPE2_HIT   BIT(20)
+#define TYPE2_SIZEHI(0x3 << 21) /* RV64 only */
+
+/* access size */
+enum {
+SIZE_ANY = 0,
+SIZE_1B,
+SIZE_2B,
+SIZE_4B,
+SIZE_6B,
+SIZE_8B,
+SIZE_10B,
+SIZE_12B,
+SIZE_14B,
+SIZE_16B,
+SIZE_NUM = 16
+};
+
+bool tdata_available(CPURISCVState *env, int tdata_index);
+
+target_ulong tselect_csr_read(CPURISCVState *env);
+void tselect_csr_write(CPURISCVState *env, target_ulong val);
+
+target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index);
+void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val);
+
+#endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
new file mode 100644
index 00..530e030007
--- /dev/null
+++ b/target/riscv/debug.c
@@ -0,0 +1,339 @@

[PATCH v3 3/7] target/riscv: debug: Implement debug related TCGCPUOps

2022-01-04 Thread Bin Meng
Implement .debug_excp_handler, .debug_check_{breakpoint, watchpoint}
TCGCPUOps and hook them into riscv_tcg_ops.

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

---

(no changes since v2)

Changes in v2:
- use 0 instead of GETPC()

 target/riscv/debug.h |  4 +++
 target/riscv/cpu.c   |  3 ++
 target/riscv/debug.c | 75 
 3 files changed, 82 insertions(+)

diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index 0a3fda6c72..d0f63e2414 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -105,4 +105,8 @@ void tselect_csr_write(CPURISCVState *env, target_ulong 
val);
 target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index);
 void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val);
 
+void riscv_cpu_debug_excp_handler(CPUState *cs);
+bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
+bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
+
 #endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6ef3314bce..3aa07bc019 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -705,6 +705,9 @@ static const struct TCGCPUOps riscv_tcg_ops = {
 .do_interrupt = riscv_cpu_do_interrupt,
 .do_transaction_failed = riscv_cpu_do_transaction_failed,
 .do_unaligned_access = riscv_cpu_do_unaligned_access,
+.debug_excp_handler = riscv_cpu_debug_excp_handler,
+.debug_check_breakpoint = riscv_cpu_debug_check_breakpoint,
+.debug_check_watchpoint = riscv_cpu_debug_check_watchpoint,
 #endif /* !CONFIG_USER_ONLY */
 };
 
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 530e030007..7760c4611f 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -337,3 +337,78 @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, 
target_ulong val)
 
 return write_func(env, env->trigger_cur, tdata_index, val);
 }
+
+void riscv_cpu_debug_excp_handler(CPUState *cs)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = &cpu->env;
+
+if (cs->watchpoint_hit) {
+if (cs->watchpoint_hit->flags & BP_CPU) {
+cs->watchpoint_hit = NULL;
+riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
+}
+} else {
+if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
+riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
+}
+}
+}
+
+bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = &cpu->env;
+CPUBreakpoint *bp;
+target_ulong ctrl;
+target_ulong pc;
+int i;
+
+QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
+for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
+ctrl = env->trigger_type2[i].mcontrol;
+pc = env->trigger_type2[i].maddress;
+
+if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
+/* check U/S/M bit against current privilege level */
+if ((ctrl >> 3) & BIT(env->priv)) {
+return true;
+}
+}
+}
+}
+
+return false;
+}
+
+bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+CPURISCVState *env = &cpu->env;
+target_ulong ctrl;
+target_ulong addr;
+int flags;
+int i;
+
+for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
+ctrl = env->trigger_type2[i].mcontrol;
+addr = env->trigger_type2[i].maddress;
+flags = 0;
+
+if (ctrl & TYPE2_LOAD) {
+flags |= BP_MEM_READ;
+}
+if (ctrl & TYPE2_STORE) {
+flags |= BP_MEM_WRITE;
+}
+
+if ((wp->flags & flags) && (wp->vaddr == addr)) {
+/* check U/S/M bit against current privilege level */
+if ((ctrl >> 3) & BIT(env->priv)) {
+return true;
+}
+}
+}
+
+return false;
+}
-- 
2.25.1




[PATCH v3 5/7] target/riscv: csr: Hook debug CSR read/write

2022-01-04 Thread Bin Meng
This adds debug CSR read/write support to the RISC-V CSR RW table.

Signed-off-by: Bin Meng 

---

Changes in v3:
- add riscv_trigger_init(), moved from patch #1 to this patch

 target/riscv/debug.h |  2 ++
 target/riscv/cpu.c   |  6 +
 target/riscv/csr.c   | 57 
 target/riscv/debug.c | 27 +
 4 files changed, 92 insertions(+)

diff --git a/target/riscv/debug.h b/target/riscv/debug.h
index d0f63e2414..f4da2db35d 100644
--- a/target/riscv/debug.h
+++ b/target/riscv/debug.h
@@ -109,4 +109,6 @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
 bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
 bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
 
+void riscv_trigger_init(CPURISCVState *env);
+
 #endif /* RISCV_DEBUG_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d36c31ce9a..17dcc3c14f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -575,6 +575,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 
 riscv_cpu_register_gdb_regs_for_features(cs);
 
+#ifndef CONFIG_USER_ONLY
+if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
+riscv_trigger_init(env);
+}
+#endif
+
 qemu_init_vcpu(cs);
 cpu_reset(cs);
 
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 146447eac5..189b9cc8c6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -220,6 +220,15 @@ static RISCVException epmp(CPURISCVState *env, int csrno)
 
 return RISCV_EXCP_ILLEGAL_INST;
 }
+
+static RISCVException debug(CPURISCVState *env, int csrno)
+{
+if (riscv_feature(env, RISCV_FEATURE_DEBUG)) {
+return RISCV_EXCP_NONE;
+}
+
+return RISCV_EXCP_ILLEGAL_INST;
+}
 #endif
 
 /* User Floating-Point CSRs */
@@ -1464,6 +1473,48 @@ static RISCVException write_pmpaddr(CPURISCVState *env, 
int csrno,
 return RISCV_EXCP_NONE;
 }
 
+static RISCVException read_tselect(CPURISCVState *env, int csrno,
+   target_ulong *val)
+{
+*val = tselect_csr_read(env);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_tselect(CPURISCVState *env, int csrno,
+target_ulong val)
+{
+tselect_csr_write(env, val);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException read_tdata(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+/* return 0 in tdata1 to end the trigger enumeration */
+if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
+*val = 0;
+return RISCV_EXCP_NONE;
+}
+
+if (!tdata_available(env, csrno - CSR_TDATA1)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+*val = tdata_csr_read(env, csrno - CSR_TDATA1);
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_tdata(CPURISCVState *env, int csrno,
+  target_ulong val)
+{
+if (!tdata_available(env, csrno - CSR_TDATA1)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+tdata_csr_write(env, csrno - CSR_TDATA1, val);
+return RISCV_EXCP_NONE;
+}
+
 /*
  * Functions to access Pointer Masking feature registers
  * We have to check if current priv lvl could modify
@@ -1962,6 +2013,12 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_PMPADDR14] =  { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr },
 [CSR_PMPADDR15] =  { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr },
 
+/* Debug CSRs */
+[CSR_TSELECT]   =  { "tselect", debug, read_tselect, write_tselect },
+[CSR_TDATA1]=  { "tdata1",  debug, read_tdata,   write_tdata   },
+[CSR_TDATA2]=  { "tdata2",  debug, read_tdata,   write_tdata   },
+[CSR_TDATA3]=  { "tdata3",  debug, read_tdata,   write_tdata   },
+
 /* User Pointer Masking */
 [CSR_UMTE]={ "umte",pointer_masking, read_umte,write_umte  
  },
 [CSR_UPMMASK] ={ "upmmask", pointer_masking, read_upmmask, 
write_upmmask },
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
index 7760c4611f..041a0d3a89 100644
--- a/target/riscv/debug.c
+++ b/target/riscv/debug.c
@@ -412,3 +412,30 @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, 
CPUWatchpoint *wp)
 
 return false;
 }
+
+void riscv_trigger_init(CPURISCVState *env)
+{
+target_ulong type2 = trigger_type(env, TRIGGER_TYPE_AD_MATCH);
+int i;
+
+/* type 2 triggers */
+for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
+/*
+ * type = TRIGGER_TYPE_AD_MATCH
+ * dmode = 0 (both debug and M-mode can write tdata)
+ * maskmax = 0 (unimplemented, always 0)
+ * sizehi = 0 (match against any size, RV64 only)
+ * hit = 0 (unimplemented, always 0)
+ * select = 0 (always 0, perform match on address)
+ * timing = 0 (always 0, trigger before instruction)
+ * sizelo = 0 (match against any size)
+ * action = 0 (always 0, raise a breakpoint exception)
+ * chain = 0 (unimplemented, always 0)
+ 

[PATCH v3 4/7] target/riscv: cpu: Add a config option for native debug

2022-01-04 Thread Bin Meng
Add a config option to enable support for native M-mode debug.
This is disabled by default and can be enabled with 'debug=true'.

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

---

(no changes since v2)

Changes in v2:
- change the config option to 'disabled' by default

 target/riscv/cpu.h | 2 ++
 target/riscv/cpu.c | 5 +
 2 files changed, 7 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0f3b3a4219..35445bbc86 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -75,6 +75,7 @@ enum {
 RISCV_FEATURE_MMU,
 RISCV_FEATURE_PMP,
 RISCV_FEATURE_EPMP,
+RISCV_FEATURE_DEBUG,
 RISCV_FEATURE_MISA
 };
 
@@ -332,6 +333,7 @@ struct RISCVCPU {
 bool mmu;
 bool pmp;
 bool epmp;
+bool debug;
 uint64_t resetvec;
 } cfg;
 };
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3aa07bc019..d36c31ce9a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -448,6 +448,10 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+if (cpu->cfg.debug) {
+set_feature(env, RISCV_FEATURE_DEBUG);
+}
+
 set_resetvec(env, cpu->cfg.resetvec);
 
 /* Validate that MISA_MXL is set properly. */
@@ -634,6 +638,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
 DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false),
 
 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
 DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
-- 
2.25.1




[PATCH v3 2/7] target/riscv: machine: Add debug state description

2022-01-04 Thread Bin Meng
Add a subsection to machine.c to migrate debug CSR state.

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

---

(no changes since v2)

Changes in v2:
- new patch: add debug state description

 target/riscv/machine.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index ad8248ebfd..25aa3b38f7 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -164,6 +164,38 @@ static const VMStateDescription vmstate_pointermasking = {
 }
 };
 
+static bool debug_needed(void *opaque)
+{
+RISCVCPU *cpu = opaque;
+CPURISCVState *env = &cpu->env;
+
+return riscv_feature(env, RISCV_FEATURE_DEBUG);
+}
+
+static const VMStateDescription vmstate_debug_type2 = {
+.name = "cpu/debug/type2",
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINTTL(mcontrol, trigger_type2_t),
+VMSTATE_UINTTL(maddress, trigger_type2_t),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static const VMStateDescription vmstate_debug = {
+.name = "cpu/debug",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = debug_needed,
+.fields = (VMStateField[]) {
+VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
+VMSTATE_STRUCT_ARRAY(env.trigger_type2, RISCVCPU, TRIGGER_TYPE2_NUM,
+ 0, vmstate_debug_type2, trigger_type2_t),
+VMSTATE_END_OF_LIST()
+}
+};
+
 const VMStateDescription vmstate_riscv_cpu = {
 .name = "cpu",
 .version_id = 3,
@@ -218,6 +250,7 @@ const VMStateDescription vmstate_riscv_cpu = {
 &vmstate_hyper,
 &vmstate_vector,
 &vmstate_pointermasking,
+&vmstate_debug,
 NULL
 }
 };
-- 
2.25.1




[PATCH v3 0/7] target/riscv: Initial support for native debug feature via M-mode CSRs

2022-01-04 Thread Bin Meng


This adds initial support for the native debug via the Trigger Module,
as defined in the RISC-V Debug Specification [1].

Only "Address / Data Match" trigger (type 2) is implemented as of now,
which is mainly used for hardware breakpoint and watchpoint. The number
of type 2 triggers implemented is 2, which is the number that we can
find in the SiFive U54/U74 cores.

[1] https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf

Changes in v3:
- drop riscv_trigger_init(), which will be moved to patch #5
- add riscv_trigger_init(), moved from patch #1 to this patch
- enable debug feature by default for all CPUs

Changes in v2:
- new patch: add debug state description
- use 0 instead of GETPC()
- change the config option to 'disabled' by default

Bin Meng (7):
  target/riscv: Add initial support for native debug
  target/riscv: machine: Add debug state description
  target/riscv: debug: Implement debug related TCGCPUOps
  target/riscv: cpu: Add a config option for native debug
  target/riscv: csr: Hook debug CSR read/write
  target/riscv: cpu: Enable native debug feature
  hw/core: tcg-cpu-ops.h: Update comments of debug_check_watchpoint()

 include/hw/core/tcg-cpu-ops.h |   1 +
 target/riscv/cpu.h|   7 +
 target/riscv/debug.h  | 114 +
 target/riscv/cpu.c|  14 ++
 target/riscv/csr.c|  57 +
 target/riscv/debug.c  | 441 ++
 target/riscv/machine.c|  33 +++
 target/riscv/meson.build  |   1 +
 8 files changed, 668 insertions(+)
 create mode 100644 target/riscv/debug.h
 create mode 100644 target/riscv/debug.c

-- 
2.25.1




Re: [PULL 0/4] tcg patch queue

2022-01-04 Thread Richard Henderson

On 1/4/22 4:40 PM, Richard Henderson wrote:

The following changes since commit 67e41fe0cfb62e6cdfa659f0155417d17e5274ea:

   Merge tag 'pull-ppc-20220104' of https://github.com/legoater/qemu into 
staging (2022-01-04 07:23:27 -0800)

are available in the Git repository at:

   https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20220104

for you to fetch changes up to d7478d4229f0a2b2817a55487e6b17081099fae4:

   common-user: Fix tail calls to safe_syscall_set_errno_tail (2022-01-04 
15:41:03 -0800)


Fix for safe_syscall_base.
Fix for folding of vector add/sub.
Fix build on loongarch64 with gcc 8.
Remove decl for qemu_run_machine_init_done_notifiers.


Philippe Mathieu-Daudé (1):
   linux-user: Fix trivial build error on loongarch64 hosts

Richard Henderson (2):
   tcg/optimize: Fix folding of vector ops
   common-user: Fix tail calls to safe_syscall_set_errno_tail

Xiaoyao Li (1):
   sysemu: Cleanup qemu_run_machine_init_done_notifiers()

  include/sysemu/sysemu.h|  1 -
  linux-user/host/loongarch64/host-signal.h  |  4 +--
  tcg/optimize.c | 49 +++---
  common-user/host/i386/safe-syscall.inc.S   |  1 +
  common-user/host/mips/safe-syscall.inc.S   |  1 +
  common-user/host/x86_64/safe-syscall.inc.S |  1 +
  6 files changed, 42 insertions(+), 15 deletions(-)


Applied.

r~




[PATCH v2] FreeBSD: Upgrade to 12.3 release

2022-01-04 Thread Brad Smith
FreeBSD: Upgrade to 12.3 release

Note, since libtasn1 was fixed in 12.3 [*], this commit re-enables GnuTLS.

[*] https://gitlab.com/gnutls/libtasn1/-/merge_requests/71


Signed-off-by: Brad Smith 
Tested-by: Thomas Huth 
Reviewed-by: Warner Losh 
---
 .gitlab-ci.d/cirrus.yml | 5 +
 tests/vm/freebsd| 8 +++-
 2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/.gitlab-ci.d/cirrus.yml b/.gitlab-ci.d/cirrus.yml
index d273a9e713..18ded37c77 100644
--- a/.gitlab-ci.d/cirrus.yml
+++ b/.gitlab-ci.d/cirrus.yml
@@ -52,14 +52,11 @@ x64-freebsd-12-build:
 NAME: freebsd-12
 CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
 CIRRUS_VM_IMAGE_SELECTOR: image_family
-CIRRUS_VM_IMAGE_NAME: freebsd-12-2
+CIRRUS_VM_IMAGE_NAME: freebsd-12-3
 CIRRUS_VM_CPUS: 8
 CIRRUS_VM_RAM: 8G
 UPDATE_COMMAND: pkg update
 INSTALL_COMMAND: pkg install -y
-# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
-# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
-CONFIGURE_ARGS: --disable-gnutls
 TEST_TARGETS: check
 
 x64-freebsd-13-build:
diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index 6e20e84322..805db759d6 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -28,8 +28,8 @@ class FreeBSDVM(basevm.BaseVM):
 name = "freebsd"
 arch = "x86_64"
 
-link = 
"https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.2/FreeBSD-12.2-RELEASE-amd64-disc1.iso.xz";
-csum = "a4530246cafbf1dd42a9bd3ea441ca9a78a6a0cd070278cbdf63f3a6f803ecae"
+link = 
"https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.3/FreeBSD-12.3-RELEASE-amd64-disc1.iso.xz";
+csum = "36dd0de50f1fe5f0a88e181e94657656de26fb64254412f74e80e128e8b938b4"
 size = "20G"
 pkgs = [
 # build tools
@@ -65,8 +65,6 @@ class FreeBSDVM(basevm.BaseVM):
 "zstd",
 ]
 
-# TODO: Enable gnutls again once FreeBSD's libtasn1 got fixed
-# See: https://gitlab.com/gnutls/libtasn1/-/merge_requests/71
 BUILD_SCRIPT = """
 set -e;
 rm -rf /home/qemu/qemu-test.*
@@ -74,7 +72,7 @@ class FreeBSDVM(basevm.BaseVM):
 mkdir src build; cd src;
 tar -xf /dev/vtbd1;
 cd ../build
-../src/configure --python=python3.7 --disable-gnutls {configure_opts};
+../src/configure --python=python3.7 {configure_opts};
 gmake --output-sync -j{jobs} {target} {verbose};
 """
 
-- 
2.34.1




[PATCH v2 1/3] target/riscv: rvv-1.0: Call the correct RVF/RVD check function for widening fp insns

2022-01-04 Thread frank . chang
From: Frank Chang 

Vector widening floating-point instructions should use
require_scale_rvf() instead of require_rvf() to check whether RVF/RVD is
enabled.

Signed-off-by: Frank Chang 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 5e3f7fdb77..8d92243f2b 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2254,7 +2254,8 @@ GEN_OPFVF_TRANS(vfrsub_vf,  opfvf_check)
 static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
 {
 return require_rvv(s) &&
-   require_rvf(s) &&
+   require_scale_rvf(s) &&
+   (s->sew != MO_8) &&
vext_check_isa_ill(s) &&
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
 }
@@ -2292,7 +2293,8 @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
 static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
 {
 return require_rvv(s) &&
-   require_rvf(s) &&
+   require_scale_rvf(s) &&
+   (s->sew != MO_8) &&
vext_check_isa_ill(s) &&
vext_check_ds(s, a->rd, a->rs2, a->vm);
 }
@@ -2321,7 +2323,8 @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
 static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
 {
 return require_rvv(s) &&
-   require_rvf(s) &&
+   require_scale_rvf(s) &&
+   (s->sew != MO_8) &&
vext_check_isa_ill(s) &&
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
 }
@@ -2359,7 +2362,8 @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
 static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
 {
 return require_rvv(s) &&
-   require_rvf(s) &&
+   require_scale_rvf(s) &&
+   (s->sew != MO_8) &&
vext_check_isa_ill(s) &&
vext_check_dd(s, a->rd, a->rs2, a->vm);
 }
-- 
2.31.1




[PATCH v2 2/3] target/riscv: rvv-1.0: Call the correct RVF/RVD check function for widening fp/int type-convert insns

2022-01-04 Thread frank . chang
From: Frank Chang 

vfwcvt.xu.f.v, vfwcvt.x.f.v, vfwcvt.rtz.xu.f.v and vfwcvt.rtz.x.f.v
convert single-width floating-point to double-width integer.
Therefore, should use require_rvf() to check whether RVF/RVD is enabled.

vfwcvt.f.xu.v, vfwcvt.f.x.v convert single-width integer to double-width
floating-point, and vfwcvt.f.f.v convert double-width floating-point to
single-width floating-point. Therefore, should use require_scale_rvf() to
check whether RVF/RVD is enabled.

Signed-off-by: Frank Chang 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 34 ++---
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 8d92243f2b..f1b44ccad2 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2613,16 +2613,27 @@ GEN_OPFV_CVT_TRANS(vfcvt_rtz_x_f_v, vfcvt_x_f_v, 
RISCV_FRM_RTZ)
 static bool opfv_widen_check(DisasContext *s, arg_rmr *a)
 {
 return require_rvv(s) &&
-   require_scale_rvf(s) &&
-   (s->sew != MO_8) &&
vext_check_isa_ill(s) &&
vext_check_ds(s, a->rd, a->rs2, a->vm);
 }
 
-#define GEN_OPFV_WIDEN_TRANS(NAME, HELPER, FRM)\
+static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
+{
+return opfv_widen_check(s, a) &&
+   require_rvf(s);
+}
+
+static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
+{
+return opfv_widen_check(s, a) &&
+   require_scale_rvf(s) &&
+   (s->sew != MO_8);
+}
+
+#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
-if (opfv_widen_check(s, a)) {  \
+if (CHECK(s, a)) { \
 if (FRM != RISCV_FRM_DYN) {\
 gen_set_rm(s, RISCV_FRM_DYN);  \
 }  \
@@ -2649,12 +2660,17 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)   
   \
 return false;  \
 }
 
-GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v, vfwcvt_xu_f_v, RISCV_FRM_DYN)
-GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v, vfwcvt_x_f_v, RISCV_FRM_DYN)
-GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v, vfwcvt_f_f_v, RISCV_FRM_DYN)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v, opxfv_widen_check, vfwcvt_xu_f_v,
+ RISCV_FRM_DYN)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v, opxfv_widen_check, vfwcvt_x_f_v,
+ RISCV_FRM_DYN)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v, opffv_widen_check, vfwcvt_f_f_v,
+ RISCV_FRM_DYN)
 /* Reuse the helper functions from vfwcvt.xu.f.v and vfwcvt.x.f.v */
-GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_xu_f_v, vfwcvt_xu_f_v, RISCV_FRM_RTZ)
-GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_x_f_v, vfwcvt_x_f_v, RISCV_FRM_RTZ)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_xu_f_v, opxfv_widen_check, vfwcvt_xu_f_v,
+ RISCV_FRM_RTZ)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_rtz_x_f_v, opxfv_widen_check, vfwcvt_x_f_v,
+ RISCV_FRM_RTZ)
 
 static bool opfxv_widen_check(DisasContext *s, arg_rmr *a)
 {
-- 
2.31.1




[PATCH v2 0/3] Fix RVV calling incorrect RFV/RVD check functions bug

2022-01-04 Thread frank . chang
From: Frank Chang 

For vector widening and narrowing floating-point instructions, we should
use require_scale_rvf() instead of require_rvf() to check whether the
correspond RVF/RVD is enabled if either source or destination
floating-point operand is double-width of SEW. Otherwise, illegal
instruction exception should be raised.

e.g. For SEW=16, if the source/destination floating-point operand is
double-width of SEW, RVF needs to be enabled. Otherwise, an illegal
instruction exception will be raised. Similarly, for SEW=32, RVD
needs to be enabled.

Changelog:

v2:
  * Fix patch title typos.
  * Add missing Signed-off-by.

Frank Chang (3):
  target/riscv: rvv-1.0: Call the correct RVF/RVD check function for
widening fp insns
  target/riscv: rvv-1.0: Call the correct RVF/RVD check function for
widening fp/int type-convert insns
  target/riscv: rvv-1.0: Call the correct RVF/RVD check function for
narrowing fp/int type-convert insns

 target/riscv/insn_trans/trans_rvv.c.inc | 78 ++---
 1 file changed, 57 insertions(+), 21 deletions(-)

--
2.31.1




[PATCH v2 3/3] target/riscv: rvv-1.0: Call the correct RVF/RVD check function for narrowing fp/int type-convert insns

2022-01-04 Thread frank . chang
From: Frank Chang 

vfncvt.f.xu.w, vfncvt.f.x.w convert double-width integer to single-width
floating-point. Therefore, should use require_rvf() to check whether
RVF/RVD is enabled.

vfncvt.f.f.w, vfncvt.rod.f.f.w convert double-width floating-point to
single-width integer. Therefore, should use require_scale_rvf() to check
whether RVF/RVD is enabled.

Signed-off-by: Frank Chang 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 32 ++---
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index f1b44ccad2..6c285c958b 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2719,17 +2719,29 @@ GEN_OPFXV_WIDEN_TRANS(vfwcvt_f_x_v)
 static bool opfv_narrow_check(DisasContext *s, arg_rmr *a)
 {
 return require_rvv(s) &&
-   require_rvf(s) &&
-   (s->sew != MO_64) &&
vext_check_isa_ill(s) &&
/* OPFV narrowing instructions ignore vs1 check */
vext_check_sd(s, a->rd, a->rs2, a->vm);
 }
 
-#define GEN_OPFV_NARROW_TRANS(NAME, HELPER, FRM)   \
+static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
+{
+return opfv_narrow_check(s, a) &&
+   require_rvf(s) &&
+   (s->sew != MO_64);
+}
+
+static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
+{
+return opfv_narrow_check(s, a) &&
+   require_scale_rvf(s) &&
+   (s->sew != MO_8);
+}
+
+#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM)\
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
-if (opfv_narrow_check(s, a)) { \
+if (CHECK(s, a)) { \
 if (FRM != RISCV_FRM_DYN) {\
 gen_set_rm(s, RISCV_FRM_DYN);  \
 }  \
@@ -2756,11 +2768,15 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)   
   \
 return false;  \
 }
 
-GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_w, vfncvt_f_xu_w, RISCV_FRM_DYN)
-GEN_OPFV_NARROW_TRANS(vfncvt_f_x_w, vfncvt_f_x_w, RISCV_FRM_DYN)
-GEN_OPFV_NARROW_TRANS(vfncvt_f_f_w, vfncvt_f_f_w, RISCV_FRM_DYN)
+GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_w, opfxv_narrow_check, vfncvt_f_xu_w,
+  RISCV_FRM_DYN)
+GEN_OPFV_NARROW_TRANS(vfncvt_f_x_w, opfxv_narrow_check, vfncvt_f_x_w,
+  RISCV_FRM_DYN)
+GEN_OPFV_NARROW_TRANS(vfncvt_f_f_w, opffv_narrow_check, vfncvt_f_f_w,
+  RISCV_FRM_DYN)
 /* Reuse the helper function from vfncvt.f.f.w */
-GEN_OPFV_NARROW_TRANS(vfncvt_rod_f_f_w, vfncvt_f_f_w, RISCV_FRM_ROD)
+GEN_OPFV_NARROW_TRANS(vfncvt_rod_f_f_w, opffv_narrow_check, vfncvt_f_f_w,
+  RISCV_FRM_ROD)
 
 static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
 {
-- 
2.31.1




[PATCH v2] ui/vnc.c: Fixed a deadlock bug.

2022-01-04 Thread Rao Lei
The GDB statck is as follows:
(gdb) bt
0  __lll_lock_wait (futex=futex@entry=0x56211df20360, private=0) at 
lowlevellock.c:52
1  0x7f263caf20a3 in __GI___pthread_mutex_lock (mutex=0x56211df20360) at 
../nptl/pthread_mutex_lock.c:80
2  0x56211a757364 in qemu_mutex_lock_impl (mutex=0x56211df20360, 
file=0x56211a804857 "../ui/vnc-jobs.h", line=60)
at ../util/qemu-thread-posix.c:80
3  0x56211a0ef8c7 in vnc_lock_output (vs=0x56211df14200) at 
../ui/vnc-jobs.h:60
4  0x56211a0efcb7 in vnc_clipboard_send (vs=0x56211df14200, count=1, 
dwords=0x7ffdf1701338) at ../ui/vnc-clipboard.c:138
5  0x56211a0f0129 in vnc_clipboard_notify (notifier=0x56211df244c8, 
data=0x56211dd1bbf0) at ../ui/vnc-clipboard.c:209
6  0x56211a75dde8 in notifier_list_notify (list=0x56211afa17d0 
, data=0x56211dd1bbf0) at ../util/notify.c:39
7  0x56211a0bf0e6 in qemu_clipboard_update (info=0x56211dd1bbf0) at 
../ui/clipboard.c:50
8  0x56211a0bf05d in qemu_clipboard_peer_release (peer=0x56211df244c0, 
selection=QEMU_CLIPBOARD_SELECTION_CLIPBOARD)
at ../ui/clipboard.c:41
9  0x56211a0bef9b in qemu_clipboard_peer_unregister (peer=0x56211df244c0) 
at ../ui/clipboard.c:19
10 0x56211a0d45f3 in vnc_disconnect_finish (vs=0x56211df14200) at 
../ui/vnc.c:1358
11 0x56211a0d4c9d in vnc_client_read (vs=0x56211df14200) at ../ui/vnc.c:1611
12 0x56211a0d4df8 in vnc_client_io (ioc=0x56211ce70690, condition=G_IO_IN, 
opaque=0x56211df14200) at ../ui/vnc.c:1649
13 0x56211a5b976c in qio_channel_fd_source_dispatch
(source=0x56211ce50a00, callback=0x56211a0d4d71 , 
user_data=0x56211df14200) at ../io/channel-watch.c:84
14 0x7f263ccede8e in g_main_context_dispatch () at 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
15 0x56211a77d4a1 in glib_pollfds_poll () at ../util/main-loop.c:232
16 0x56211a77d51f in os_host_main_loop_wait (timeout=958545) at 
../util/main-loop.c:255
17 0x56211a77d630 in main_loop_wait (nonblocking=0) at 
../util/main-loop.c:531
18 0x56211a45bc8e in qemu_main_loop () at ../softmmu/runstate.c:726
19 0x56211a0b45fa in main (argc=69, argv=0x7ffdf1701778, 
envp=0x7ffdf17019a8) at ../softmmu/main.c:50

>From the call trace, we can see it is a deadlock bug.
vnc_disconnect_finish will acquire the output_mutex.
But, the output_mutex will be acquired again in vnc_clipboard_send.
Repeated locking will cause deadlock. So, I move
qemu_clipboard_peer_unregister() behind vnc_unlock_output();

Fixes: 0bf41cab93e ("ui/vnc: clipboard support")
Signed-off-by: Lei Rao 
Reviewed-by: Marc-André Lureau 
---
 ui/vnc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ui/vnc.c b/ui/vnc.c
index 1ed1c7efc6..3ccd33dedc 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1354,12 +1354,12 @@ void vnc_disconnect_finish(VncState *vs)
 /* last client gone */
 vnc_update_server_surface(vs->vd);
 }
+vnc_unlock_output(vs);
+
 if (vs->cbpeer.notifier.notify) {
 qemu_clipboard_peer_unregister(&vs->cbpeer);
 }
 
-vnc_unlock_output(vs);
-
 qemu_mutex_destroy(&vs->output_mutex);
 if (vs->bh != NULL) {
 qemu_bh_delete(vs->bh);
-- 
2.32.0




[PATCH] roms/opensbi: Upgrade from v0.9 to v1.0

2022-01-04 Thread Bin Meng
Upgrade OpenSBI from v0.9 to v1.0 and the pre-built bios images.

The v1.0 release includes the following commits:

ec5274b platform: implement K210 system reset
5487cf0 include: sbi: Simplify HSM state define names
8df1f9a lib: sbi: Use SBI_HSM_STATE_xyz defines instead of SBI_STATE_xyz defines
7c867fd lib: sbi: Rename sbi_hsm_hart_started_mask() function
638c948 lib: sbi: Remove redundant sbi_hsm_hart_started() function
ca864a9 lib: sbi: Fix error codes returned by HSM start() and stop() functions
6290a22 include: sbi: Add HSM suspend related defines
4b05df6 lib: sbi: Add sbi_hart_reinit() function
807d71c include: sbi: Add hart_suspend() platform callback
7475689 lib: sbi: Implement SBI HSM suspend function
b9cf617 include: sbi: Upgrade SBI implementation version to v0.3
50d4fde lib: Remove redundant sbi_platform_ipi_clear() calls
ff5bd94 include: sbi: SBI function IDs for RFENCE extension
22d8ee9 firmware: Use lla to access all global symbols
0f20e8a firmware: Support position independent execution
ddad02d lib: sbi: illegal CSR 0x306 access in hpm_allowed()
bfc85c7 include: headers: Replace __ASSEMBLY__ with __ASSEMBLER__
9190ad1 lib/utils: Support the official clint DT bindings
ca3f358 lib/utils: Drop the 'compat' parameter of fdt_plic_fixup()
4edc822 lib/utils: Support fixing up the official DT bindings of PLIC
4ef2f5d firware: optimize the exception exit code
3d8a952 lib: fix csr detect support
e71a7c1 firmware: Remove redundant add instruction from trap restore path
d4a94ea include: types: Add __aligned(x) to define the minimum alignement
d0e406f include: sbi: Allow direct initialization via SPIN_LOCK_INIT()
4d8e2f1 lib: sbi: Replace test-and-set locks by ticket locks
70ffc3e lib: sbi: fix atomic_add_return
27a16b1 docs: fix link to OpenPiton documentation
b1df1ac lib: sbi: Domains can be registered only before finalizing domains
7495bce lib: sbi: Add sbi_domain_memregion_init() API
4dc0001 lib: sbi: Add sbi_domain_root_add_memregion() API
8b56980 lib: utils/sys: Add CLINT memregion in the root domain
fc37c97 lib: sbi: Make the root domain instance global variable
e7e4bcd lib: utils: Copy over restricted root domain memregions to FDT domains
f41196a lib: sbi: Make sbi_domain_memregion_initfw() a local function
c5d0645 lib: utils: Implement "64bit-mmio" property parsing
49e422c lib: utils: reset: Add T-HEAD sample platform reset driver
0d56293 lib: sbi: Fix sbi_domain_root_add_memregion() for merging memregions
bf3ef53 firmware: Enable FW_PIC by default
1db8436 platform: Remove platform/thead
6d1642f docs: generic: Add T-HEAD C9xx series processors
a3689db lib: sbi: Remove domains_root_regions() platform callback
068ca08 lib: sbi: Simplify console platform operations
559a8f1 lib: sbi: Simplify timer platform operations
dc39c7b lib: sbi: Simplify ipi platform operations
043d088 lib: sbi: Simplify system reset platform operations
a84a1dd lib: sbi: Simplify HSM platform operations
e9a27ab lib: sbi: Show devices provided by platform in boot prints
632e27b docs/platform: sifive_fu540: Update U-Boot defconfig name
117fb6d lib: utils/serial: Add support for Gaisler APBUART
552f53f docs: platform: Sort platform names
d4177e7 docs: platform: Describe sifive_fu540 as supported generic platform
26998f3 platform: Remove sifive/fu540 platform
f90c4c2 lib: sbi: Have spinlock checks return bool
e822b75 lib: utils/serial: Support Synopsys DesignWare APB UART
6139ab2 Makefile: unconditionally disable SSP
c9ef2bc lib: utils: Add strncpy macro to libfdt_env.h
ee7c2b2 lib: utils/fdt: Don't use sbi_string functions
fe92347 lib: utils/fdt: Replace strcmp with strncmp
b2dbbc0 lib: Check region base for merging in sbi_domain_root_add_memregion()
54d7def lib: utils: Try other FDT drivers when we see SBI_ENODEV
d9ba653 docs: debugging OpenSBI
66c4fca lib: utils: consider ':' in stdout-path
f30b189 lib: sbi_scratch: remove owner from sbi_scratch_alloc_offset
a03ea2e platform: andes/ae350: Cosmetic fixes in plicsw.c
b32fac4 docs/platform: andes-ae350: Fix missing spaces
de446cc platform: andes/ae350: Drop plicsw_get_pending()
434198e platform: andes/ae350: Drop plicsw_ipi_sync()
1da3d80 lib: sbi_scratch: zero out scratch memory on all harts
360ab88 lib: utils: missing initialization in thead_reset_init
79f9b42 lib: sbi: Fix GET_F64_REG inline assembly
eb90e0a lib: utils/libfdt: Upgrade to v1.6.1 release
cdcf907 lib: sign conflict in sbi_tlb_entry_process()
9901794 lib: sign conflict in wake_coldboot_harts()
11c345f lib: simplify sbi_fifo_inplace_update()
4519e29 lib: utils/timer: Add ACLINT MTIMER library
5a049fe lib: utils/ipi: Add ACLINT MSWI library
bd5d208 lib: utils: Add FDT parsing API common for both ACLINT and CLINT
56fc5f7 lib: utils/ipi: Add FDT based ACLINT MSWI IPI driver
03d6bb5 lib: utils/timer: Add FDT based ACLINT MTIMER driver
a731c7e platform: Replace CLINT library usage with ACLINT library
b7f2cd2 lib: utils: reset: unify naming of 'sifive_test' device
197e089 docs/platform: thead-c9xx: Remove FW_PIC=y
17e23

[RFC 08/10] vdpa-dev: implement the get_features interface

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

Implements the .get_features interface.

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

diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index 4f97a7521b..32b3117c4b 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -184,7 +184,14 @@ static uint64_t 
vhost_vdpa_device_get_features(VirtIODevice *vdev,
uint64_t features,
Error **errp)
 {
-return (uint64_t)-1;
+VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
+uint64_t backend_features = s->dev.features;
+
+if (!virtio_has_feature(features, VIRTIO_F_IOMMU_PLATFORM)) {
+virtio_clear_feature(&backend_features, VIRTIO_F_IOMMU_PLATFORM);
+}
+
+return backend_features;
 }
 
 static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status)
-- 
2.23.0




[RFC 09/10] vdpa-dev: implement the set_status interface

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

Implements the .set_status interface.

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

diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index 32b3117c4b..64649bfb5a 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -194,9 +194,107 @@ static uint64_t 
vhost_vdpa_device_get_features(VirtIODevice *vdev,
 return backend_features;
 }
 
+static int vhost_vdpa_device_start(VirtIODevice *vdev, Error **errp)
+{
+VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
+BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+int i, ret;
+
+if (!k->set_guest_notifiers) {
+error_setg(errp, "binding does not support guest notifiers");
+return -ENOSYS;
+}
+
+ret = vhost_dev_enable_notifiers(&s->dev, vdev);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Error enabling host notifiers");
+return ret;
+}
+
+ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, true);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Error binding guest notifier");
+goto err_host_notifiers;
+}
+
+s->dev.acked_features = vdev->guest_features;
+
+ret = vhost_dev_start(&s->dev, vdev);
+if (ret < 0) {
+error_setg_errno(errp, -ret, "Error starting vhost");
+goto err_guest_notifiers;
+}
+s->started = true;
+
+/*
+ * guest_notifier_mask/pending not used yet, so just unmask
+ * everything here. virtio-pci will do the right thing by
+ * enabling/disabling irqfd.
+ */
+for (i = 0; i < s->dev.nvqs; i++) {
+vhost_virtqueue_mask(&s->dev, vdev, i, false);
+}
+
+return ret;
+
+err_guest_notifiers:
+k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
+err_host_notifiers:
+vhost_dev_disable_notifiers(&s->dev, vdev);
+return ret;
+}
+
+static void vhost_vdpa_device_stop(VirtIODevice *vdev)
+{
+VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
+BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
+VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+int ret;
+
+if (!s->started) {
+return;
+}
+s->started = false;
+
+if (!k->set_guest_notifiers) {
+return;
+}
+
+vhost_dev_stop(&s->dev, vdev);
+
+ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false);
+if (ret < 0) {
+error_report("vhost guest notifier cleanup failed: %d", ret);
+return;
+}
+
+vhost_dev_disable_notifiers(&s->dev, vdev);
+}
+
 static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status)
 {
-return;
+VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
+bool should_start = virtio_device_started(vdev, status);
+Error *local_err = NULL;
+int ret;
+
+if (!vdev->vm_running) {
+should_start = false;
+}
+
+if (s->started == should_start) {
+return;
+}
+
+if (should_start) {
+ret = vhost_vdpa_device_start(vdev, &local_err);
+if (ret < 0) {
+error_reportf_err(local_err, "vhost-vdpa-device: start failed: ");
+}
+} else {
+vhost_vdpa_device_stop(vdev);
+}
 }
 
 static Property vhost_vdpa_device_properties[] = {
-- 
2.23.0




[RFC 10/10] vdpa-dev: mark the device as unmigratable

2022-01-04 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 64649bfb5a..0644aace22 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -305,6 +305,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




[RFC 06/10] vdpa-dev: implement the unrealize interface

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

Implements the .unrealize interface.

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

diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index 2d534d837a..4e4dd3d201 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -133,9 +133,29 @@ out:
 close(fd);
 }
 
+static void vhost_vdpa_vdev_unrealize(VhostVdpaDevice *s)
+{
+VirtIODevice *vdev = VIRTIO_DEVICE(s);
+int i;
+
+for (i = 0; i < s->num_queues; i++) {
+virtio_delete_queue(s->virtqs[i]);
+}
+g_free(s->virtqs);
+virtio_cleanup(vdev);
+
+g_free(s->config);
+}
+
 static void vhost_vdpa_device_unrealize(DeviceState *dev)
 {
-return;
+VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
+
+virtio_set_status(vdev, 0);
+vhost_dev_cleanup(&s->dev);
+vhost_vdpa_vdev_unrealize(s);
+close(s->vdpa.device_fd);
 }
 
 static void
-- 
2.23.0




[RFC 07/10] vdpa-dev: implement the get_config/set_config interface

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

Implements the .get_config and .set_config interface.

Signed-off-by: Longpeng 
---
 hw/virtio/vdpa-dev.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index 4e4dd3d201..4f97a7521b 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -161,13 +161,23 @@ static void vhost_vdpa_device_unrealize(DeviceState *dev)
 static void
 vhost_vdpa_device_get_config(VirtIODevice *vdev, uint8_t *config)
 {
-return;
+VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
+
+memcpy(config, s->config, s->config_size);
 }
 
 static void
 vhost_vdpa_device_set_config(VirtIODevice *vdev, const uint8_t *config)
 {
-return;
+VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
+int ret;
+
+ret = vhost_dev_set_config(&s->dev, s->config, 0, s->config_size,
+   VHOST_SET_CONFIG_TYPE_MASTER);
+if (ret) {
+error_report("set device config space failed");
+return;
+}
 }
 
 static uint64_t vhost_vdpa_device_get_features(VirtIODevice *vdev,
-- 
2.23.0




[RFC 03/10] vdpa: add the infrastructure of vdpa-dev

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

Add the infrastructure of vdpa-dev (the generic vDPA device), we
can add a generic vDPA device as follow:
  -device vhost-vdpa-device-pci,vdpa-dev=/dev/vhost-vdpa-X

Signed-off-by: Longpeng 
---
 hw/virtio/Kconfig|  5 
 hw/virtio/meson.build|  2 ++
 hw/virtio/vdpa-dev-pci.c | 51 
 hw/virtio/vdpa-dev.c | 41 +
 include/hw/virtio/vdpa-dev.h | 16 +++
 5 files changed, 115 insertions(+)
 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

diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index c144d42f9b..2723283382 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -68,3 +68,8 @@ config VHOST_USER_RNG
 bool
 default y
 depends on VIRTIO && VHOST_USER
+
+config VHOST_VDPA_DEV
+bool
+default y if VIRTIO_PCI
+depends on VIRTIO && VHOST_VDPA && LINUX
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index 521f7d64a8..8e8943e20b 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -29,6 +29,7 @@ virtio_ss.add(when: 'CONFIG_VHOST_USER_I2C', if_true: 
files('vhost-user-i2c.c'))
 virtio_ss.add(when: ['CONFIG_VIRTIO_PCI', 'CONFIG_VHOST_USER_I2C'], if_true: 
files('vhost-user-i2c-pci.c'))
 virtio_ss.add(when: 'CONFIG_VHOST_USER_RNG', if_true: 
files('vhost-user-rng.c'))
 virtio_ss.add(when: ['CONFIG_VHOST_USER_RNG', 'CONFIG_VIRTIO_PCI'], if_true: 
files('vhost-user-rng-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'))
@@ -49,6 +50,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..a5a7b528a9
--- /dev/null
+++ b/hw/virtio/vdpa-dev-pci.c
@@ -0,0 +1,51 @@
+#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 "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)
+{
+return;
+}
+
+static void vhost_vdpa_device_pci_class_init(ObjectClass *klass, void *data)
+{
+return;
+}
+
+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(&vhost_vdpa_device_pci_info);
+}
+
+type_init(vhost_vdpa_device_pci_register);
diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
new file mode 100644
index 00..f4f92b90b0
--- /dev/null
+++ b/hw/virtio/vdpa-dev.c
@@ -0,0 +1,41 @@
+#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_class_init(ObjectClass *klass, void *data)
+{
+return;
+}
+
+static void vhost_vdpa_device_instance_init(Object *obj)
+{
+return;
+}
+
+static const TypeInfo vhost_vdpa_device_info = {
+.name = TYPE_VHOST_VDPA_DEVICE,
+.parent = TYPE_VIRTIO_DEVICE,
+.instance_size = sizeof(VhostVdpaDevice),
+.class_init = vhost_vdpa_device_class_init,
+.instance_init = vhost_vdpa_device_instance_init,

[RFC 05/10] vdpa-dev: implement the realize interface

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

Implements the .realize interface.

Signed-off-by: Longpeng 
---
 hw/virtio/vdpa-dev.c | 114 +++
 include/hw/virtio/vdpa-dev.h |   8 +++
 2 files changed, 122 insertions(+)

diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index 790117fb3b..2d534d837a 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -15,9 +15,122 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/runstate.h"
 
+static void
+vhost_vdpa_device_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+/* Nothing to do */
+}
+
+static int vdpa_dev_get_info_by_fd(int fd, uint64_t cmd, Error **errp)
+{
+int val;
+
+if (ioctl(fd, cmd, &val) < 0) {
+error_setg(errp, "vhost-vdpa-device: cmd 0x%lx failed: %s",
+   cmd, strerror(errno));
+return -1;
+}
+
+return val;
+}
+
+static inline int vdpa_dev_get_queue_size(int fd, Error **errp)
+{
+return vdpa_dev_get_info_by_fd(fd, VHOST_VDPA_GET_VRING_NUM, errp);
+}
+
+static inline int vdpa_dev_get_vqs_num(int fd, Error **errp)
+{
+return vdpa_dev_get_info_by_fd(fd, VHOST_VDPA_GET_VQS_NUM, errp);
+}
+
+static inline int vdpa_dev_get_config_size(int fd, Error **errp)
+{
+return vdpa_dev_get_info_by_fd(fd, VHOST_VDPA_GET_CONFIG_SIZE, errp);
+}
+
 static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp)
 {
+VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
+uint32_t device_id;
+int max_queue_size;
+int fd;
+int i, ret;
+
+fd = qemu_open(s->vdpa_dev, O_RDWR, errp);
+if (fd == -1) {
+return;
+}
+s->vdpa.device_fd = fd;
+
+max_queue_size = vdpa_dev_get_queue_size(fd, errp);
+if (*errp) {
+goto out;
+}
+
+if (s->queue_size > max_queue_size) {
+error_setg(errp, "vhost-vdpa-device: invalid queue_size: %d (max:%d)",
+   s->queue_size, max_queue_size);
+goto out;
+} else if (!s->queue_size) {
+s->queue_size = max_queue_size;
+}
+
+ret = vdpa_dev_get_vqs_num(fd, errp);
+if (*errp) {
+goto out;
+}
+
+s->dev.nvqs = ret;
+s->dev.vqs = g_new0(struct vhost_virtqueue, s->dev.nvqs);
+s->dev.vq_index = 0;
+s->dev.vq_index_end = s->dev.nvqs;
+s->dev.backend_features = 0;
+s->started = false;
+
+ret = vhost_dev_init(&s->dev, &s->vdpa, VHOST_BACKEND_TYPE_VDPA, 0, NULL);
+if (ret < 0) {
+error_setg(errp, "vhost-vdpa-device: vhost initialization failed: %s",
+   strerror(-ret));
+goto out;
+}
+
+ret = s->dev.vhost_ops->vhost_get_device_id(&s->dev, &device_id);
+if (ret < 0) {
+error_setg(errp, "vhost-vdpa-device: vhost get device id failed: %s",
+   strerror(-ret));
+goto vhost_cleanup;
+}
+
+s->config_size = vdpa_dev_get_config_size(fd, errp);
+if (*errp) {
+goto vhost_cleanup;
+}
+
+s->config = g_malloc0(s->config_size);
+
+ret = vhost_dev_get_config(&s->dev, s->config, s->config_size, NULL);
+if (ret < 0) {
+error_setg(errp, "vhost-vdpa-device: get config failed");
+goto config_err;
+}
+
+virtio_init(vdev, "vhost-vdpa", device_id, s->config_size);
+
+s->virtqs = g_new0(VirtQueue *, s->dev.nvqs);
+for (i = 0; i < s->dev.nvqs; i++) {
+s->virtqs[i] = virtio_add_queue(vdev, s->queue_size,
+vhost_vdpa_device_dummy_handle_output);
+}
+
 return;
+config_err:
+g_free(s->config);
+vhost_cleanup:
+vhost_dev_cleanup(&s->dev);
+out:
+close(fd);
 }
 
 static void vhost_vdpa_device_unrealize(DeviceState *dev)
@@ -51,6 +164,7 @@ static void vhost_vdpa_device_set_status(VirtIODevice *vdev, 
uint8_t status)
 
 static Property vhost_vdpa_device_properties[] = {
 DEFINE_PROP_STRING("vdpa-dev", VhostVdpaDevice, vdpa_dev),
+DEFINE_PROP_UINT16("queue-size", VhostVdpaDevice, queue_size, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/vdpa-dev.h b/include/hw/virtio/vdpa-dev.h
index 7a0e6bdcf8..49f8145d61 100644
--- a/include/hw/virtio/vdpa-dev.h
+++ b/include/hw/virtio/vdpa-dev.h
@@ -13,6 +13,14 @@ struct VhostVdpaDevice {
 VirtIODevice parent_obj;
 char *vdpa_dev;
 int32_t bootindex;
+struct vhost_dev dev;
+struct vhost_vdpa vdpa;
+VirtQueue **virtqs;
+uint8_t *config;
+int config_size;
+uint32_t num_queues;
+uint16_t queue_size;
+bool started;
 };
 
 #endif
-- 
2.23.0




[RFC 04/10] vdpa-dev: implement the instance_init/class_init interface

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

Implements the .instance_init and the .class_init interface.

Signed-off-by: Longpeng 
---
 hw/virtio/vdpa-dev-pci.c | 80 +++-
 hw/virtio/vdpa-dev.c | 68 +-
 include/hw/virtio/vdpa-dev.h |  2 +
 3 files changed, 146 insertions(+), 4 deletions(-)

diff --git a/hw/virtio/vdpa-dev-pci.c b/hw/virtio/vdpa-dev-pci.c
index a5a7b528a9..0af54a26d4 100644
--- a/hw/virtio/vdpa-dev-pci.c
+++ b/hw/virtio/vdpa-dev-pci.c
@@ -23,14 +23,90 @@ struct VhostVdpaDevicePCI {
 VhostVdpaDevice vdev;
 };
 
+static uint32_t
+vdpa_dev_pci_get_info(const char *name, uint64_t cmd, Error **errp)
+{
+int device_fd;
+uint32_t val;
+int ret;
+
+device_fd = qemu_open(name, O_RDWR, errp);
+if (device_fd == -1) {
+return (uint32_t)-1;
+}
+
+ret = ioctl(device_fd, cmd, &val);
+if (ret < 0) {
+error_setg(errp, "vhost-vdpa-device-pci: cmd 0x%lx failed: %s",
+   cmd, strerror(errno));
+goto out;
+}
+
+out:
+close(device_fd);
+return val;
+}
+
+static inline uint32_t
+vdpa_dev_pci_get_devid(VhostVdpaDevicePCI *dev, Error **errp)
+{
+return vdpa_dev_pci_get_info(dev->vdev.vdpa_dev,
+ VHOST_VDPA_GET_DEVICE_ID, errp);
+}
+
+static inline uint32_t
+vdpa_dev_pci_get_vectors_num(VhostVdpaDevicePCI *dev, Error **errp)
+{
+return vdpa_dev_pci_get_info(dev->vdev.vdpa_dev,
+ VHOST_VDPA_GET_VECTORS_NUM, errp);
+}
+
 static void vhost_vdpa_device_pci_instance_init(Object *obj)
 {
-return;
+VhostVdpaDevicePCI *dev = VHOST_VDPA_DEVICE_PCI(obj);
+
+virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+TYPE_VHOST_VDPA_DEVICE);
+object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+  "bootindex");
+}
+
+static Property vhost_vdpa_device_pci_properties[] = {
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void
+vhost_vdpa_device_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+VhostVdpaDevicePCI *dev = VHOST_VDPA_DEVICE_PCI(vpci_dev);
+DeviceState *vdev = DEVICE(&dev->vdev);
+uint32_t devid;
+uint32_t vectors;
+
+devid = vdpa_dev_pci_get_devid(dev, errp);
+if (*errp) {
+return;
+}
+
+vectors = vdpa_dev_pci_get_vectors_num(dev, errp);
+if (*errp) {
+return;
+}
+
+vpci_dev->class_code = virtio_pci_get_class_id(devid);
+vpci_dev->pdev_id = virtio_pci_get_pci_devid(devid);
+vpci_dev->nvectors = vectors;
+qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
 }
 
 static void vhost_vdpa_device_pci_class_init(ObjectClass *klass, void *data)
 {
-return;
+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 = {
diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index f4f92b90b0..790117fb3b 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -15,16 +15,80 @@
 #include "sysemu/sysemu.h"
 #include "sysemu/runstate.h"
 
-static void vhost_vdpa_device_class_init(ObjectClass *klass, void *data)
+static void vhost_vdpa_device_realize(DeviceState *dev, Error **errp)
 {
 return;
 }
 
-static void vhost_vdpa_device_instance_init(Object *obj)
+static void vhost_vdpa_device_unrealize(DeviceState *dev)
+{
+return;
+}
+
+static void
+vhost_vdpa_device_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+return;
+}
+
+static void
+vhost_vdpa_device_set_config(VirtIODevice *vdev, const uint8_t *config)
 {
 return;
 }
 
+static uint64_t vhost_vdpa_device_get_features(VirtIODevice *vdev,
+   uint64_t features,
+   Error **errp)
+{
+return (uint64_t)-1;
+}
+
+static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status)
+{
+return;
+}
+
+static Property vhost_vdpa_device_properties[] = {
+DEFINE_PROP_STRING("vdpa-dev", VhostVdpaDevice, vdpa_dev),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static const VMStateDescription vmstate_vhost_vdpa_device = {
+.name = "vhost-vdpa-device",
+.minimum_version_id = 1,
+.version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_VIRTIO_DEVICE,
+VMSTATE_END_OF_LIST()
+},
+};
+
+static void vhost_vdpa_device_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+device_class_set_props(dc, vhost_vdpa_device_properties);
+dc->desc = "VDPA-based generic PCI device assignment";
+dc->vmsd = &vmstate_vhost_vdpa_device;
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+vdc->realize = vhost_v

[RFC 02/10] vhost: add 3 commands for vhost-vdpa

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

To support generic vdpa deivce, we need add the following ioctls:
- GET_VECTORS_NUM: the count of vectors that supported
- GET_CONFIG_SIZE: the size of the virtio config space
- GET_VQS_NUM: the count of virtqueues that exported

Signed-off-by: Longpeng 
---
 linux-headers/linux/vhost.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
index c998860d7b..c5edd75d15 100644
--- a/linux-headers/linux/vhost.h
+++ b/linux-headers/linux/vhost.h
@@ -150,4 +150,14 @@
 /* Get the valid iova range */
 #define VHOST_VDPA_GET_IOVA_RANGE  _IOR(VHOST_VIRTIO, 0x78, \
 struct vhost_vdpa_iova_range)
+
+/* Get the number of vectors */
+#define VHOST_VDPA_GET_VECTORS_NUM _IOR(VHOST_VIRTIO, 0x79, int)
+
+/* Get the virtio config size */
+#define VHOST_VDPA_GET_CONFIG_SIZE _IOR(VHOST_VIRTIO, 0x80, int)
+
+/* Get the number of virtqueues */
+#define VHOST_VDPA_GET_VQS_NUM _IOR(VHOST_VIRTIO, 0x81, int)
+
 #endif
-- 
2.23.0




[RFC 01/10] virtio: get class_id and pci device id by the virtio id

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

Add helpers to get the "Transitional PCI Device ID" and "class_id" of the
deivce which is specificed by the "Virtio Device ID".

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

Signed-off-by: Longpeng 
---
 hw/virtio/virtio-pci.c | 93 ++
 hw/virtio/virtio-pci.h |  4 ++
 2 files changed, 97 insertions(+)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 750aa47ec1..843085c4ea 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,95 @@ static int virtio_pci_load_queue(DeviceState *d, int n, 
QEMUFile *f)
 return 0;
 }
 
+typedef struct VirtIOPCIIDInfo {
+uint16_t vdev_id; /* virtio id */
+uint16_t pdev_id; /* pci device id */
+uint16_t class_id;
+} VirtIOPCIIDInfo;
+
+static const VirtIOPCIIDInfo virtio_pci_id_info[] = {
+{
+.vdev_id = VIRTIO_ID_NET,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_NET,
+.class_id = PCI_CLASS_NETWORK_ETHERNET,
+},
+{
+.vdev_id = VIRTIO_ID_BLOCK,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
+.class_id = PCI_CLASS_STORAGE_SCSI,
+},
+{
+.vdev_id = VIRTIO_ID_CONSOLE,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
+.class_id = PCI_CLASS_COMMUNICATION_OTHER,
+},
+{
+.vdev_id = VIRTIO_ID_SCSI,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_SCSI,
+.class_id = PCI_CLASS_STORAGE_SCSI,
+},
+{
+.vdev_id = VIRTIO_ID_9P,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_9P,
+.class_id = PCI_BASE_CLASS_NETWORK,
+},
+{
+.vdev_id = VIRTIO_ID_VSOCK,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_VSOCK,
+.class_id = PCI_CLASS_COMMUNICATION_OTHER,
+},
+{
+.vdev_id = VIRTIO_ID_IOMMU,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_IOMMU,
+.class_id = PCI_CLASS_OTHERS,
+},
+{
+.vdev_id = VIRTIO_ID_MEM,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_MEM,
+.class_id = PCI_CLASS_OTHERS,
+},
+{
+.vdev_id = VIRTIO_ID_PMEM,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_PMEM,
+.class_id = PCI_CLASS_OTHERS,
+},
+{
+.vdev_id = VIRTIO_ID_RNG,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_RNG,
+.class_id = PCI_CLASS_OTHERS,
+},
+{
+.vdev_id = VIRTIO_ID_BALLOON,
+.pdev_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
+.class_id = PCI_CLASS_OTHERS,
+},
+};
+
+static VirtIOPCIIDInfo virtio_pci_get_id_info(uint16_t vdev_id)
+{
+VirtIOPCIIDInfo info = {};
+int i;
+
+for (i = 0; i < ARRAY_SIZE(virtio_pci_id_info); i++) {
+if (virtio_pci_id_info[i].vdev_id == vdev_id) {
+info = virtio_pci_id_info[i];
+break;
+}
+}
+
+return info;
+}
+
+uint16_t virtio_pci_get_pci_devid(uint16_t device_id)
+{
+return virtio_pci_get_id_info(device_id).pdev_id;
+}
+
+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);
@@ -1674,6 +1764,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->pdev_id) {
+pci_config_set_device_id(config, proxy->pdev_id);
+}
 } else {
 /* pure virtio-1.0 */
 pci_set_word(config + PCI_VENDOR_ID,
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 2446dcd9ae..06aa59436e 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -146,6 +146,7 @@ struct VirtIOPCIProxy {
 bool disable_modern;
 bool ignore_backend_features;
 OnOffAuto disable_legacy;
+uint16_t pdev_id;
 uint32_t class_code;
 uint32_t nvectors;
 uint32_t dfselect;
@@ -158,6 +159,9 @@ struct VirtIOPCIProxy {
 VirtioBusState bus;
 };
 
+uint16_t virtio_pci_get_pci_devid(uint16_t device_id);
+uint16_t virtio_pci_get_class_id(uint16_t device_id);
+
 static inline bool virtio_pci_modern(VirtIOPCIProxy *proxy)
 {
 return !proxy->disable_modern;
-- 
2.23.0




[RFC 00/10] add generic vDPA device support

2022-01-04 Thread Longpeng(Mike)
From: Longpeng 

Hi guys,

This patchset tries to support the generic vDPA device, the previous
disscussion can be found here [1].

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,vdpa-dev=/dev/vhost-vdpa-X

I've done some simple tests on Huawei's offloading card (net, 0.95)
and vdpa_sim_blk (1.0);

Note:
  the kernel part does not send out yet, I'll send it as soon as possible.

[1] https://lore.kernel.org/all/20211208052010.1719-1-longpe...@huawei.com/

Longpeng (Mike) (10):
  virtio: get class_id and pci device id by the virtio id
  vhost: add 3 commands for vhost-vdpa
  vdpa: add the infrastructure of vdpa-dev
  vdpa-dev: implement the instance_init/class_init interface
  vdpa-dev: implement the realize interface
  vdpa-dev: implement the unrealize interface
  vdpa-dev: implement the get_config/set_config interface
  vdpa-dev: implement the get_features interface
  vdpa-dev: implement the set_status interface
  vdpa-dev: mark the device as unmigratable

 hw/virtio/Kconfig|   5 +
 hw/virtio/meson.build|   2 +
 hw/virtio/vdpa-dev-pci.c | 127 +
 hw/virtio/vdpa-dev.c | 355 +++
 hw/virtio/virtio-pci.c   |  93 +
 hw/virtio/virtio-pci.h   |   4 +
 include/hw/virtio/vdpa-dev.h |  26 +++
 linux-headers/linux/vhost.h  |  10 +
 8 files changed, 622 insertions(+)
 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




[PULL 1/4] tcg/optimize: Fix folding of vector ops

2022-01-04 Thread Richard Henderson
Bitwise operations are easy to fold, because the operation is
identical regardless of element size.  But add and sub need
extra element size info that is not currently propagated.

Fixes: 2f9f08ba43d
Cc: qemu-sta...@nongnu.org
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/799
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
---
 tcg/optimize.c | 49 ++---
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 2397f2cf93..e573000951 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -308,13 +308,13 @@ static uint64_t do_constant_folding_2(TCGOpcode op, 
uint64_t x, uint64_t y)
 CASE_OP_32_64(mul):
 return x * y;
 
-CASE_OP_32_64(and):
+CASE_OP_32_64_VEC(and):
 return x & y;
 
-CASE_OP_32_64(or):
+CASE_OP_32_64_VEC(or):
 return x | y;
 
-CASE_OP_32_64(xor):
+CASE_OP_32_64_VEC(xor):
 return x ^ y;
 
 case INDEX_op_shl_i32:
@@ -347,16 +347,16 @@ static uint64_t do_constant_folding_2(TCGOpcode op, 
uint64_t x, uint64_t y)
 case INDEX_op_rotl_i64:
 return rol64(x, y & 63);
 
-CASE_OP_32_64(not):
+CASE_OP_32_64_VEC(not):
 return ~x;
 
 CASE_OP_32_64(neg):
 return -x;
 
-CASE_OP_32_64(andc):
+CASE_OP_32_64_VEC(andc):
 return x & ~y;
 
-CASE_OP_32_64(orc):
+CASE_OP_32_64_VEC(orc):
 return x | ~y;
 
 CASE_OP_32_64(eqv):
@@ -751,6 +751,12 @@ static bool fold_const2(OptContext *ctx, TCGOp *op)
 return false;
 }
 
+static bool fold_commutative(OptContext *ctx, TCGOp *op)
+{
+swap_commutative(op->args[0], &op->args[1], &op->args[2]);
+return false;
+}
+
 static bool fold_const2_commutative(OptContext *ctx, TCGOp *op)
 {
 swap_commutative(op->args[0], &op->args[1], &op->args[2]);
@@ -905,6 +911,16 @@ static bool fold_add(OptContext *ctx, TCGOp *op)
 return false;
 }
 
+/* We cannot as yet do_constant_folding with vectors. */
+static bool fold_add_vec(OptContext *ctx, TCGOp *op)
+{
+if (fold_commutative(ctx, op) ||
+fold_xi_to_x(ctx, op, 0)) {
+return true;
+}
+return false;
+}
+
 static bool fold_addsub2(OptContext *ctx, TCGOp *op, bool add)
 {
 if (arg_is_const(op->args[2]) && arg_is_const(op->args[3]) &&
@@ -1938,10 +1954,10 @@ static bool fold_sub_to_neg(OptContext *ctx, TCGOp *op)
 return false;
 }
 
-static bool fold_sub(OptContext *ctx, TCGOp *op)
+/* We cannot as yet do_constant_folding with vectors. */
+static bool fold_sub_vec(OptContext *ctx, TCGOp *op)
 {
-if (fold_const2(ctx, op) ||
-fold_xx_to_i(ctx, op, 0) ||
+if (fold_xx_to_i(ctx, op, 0) ||
 fold_xi_to_x(ctx, op, 0) ||
 fold_sub_to_neg(ctx, op)) {
 return true;
@@ -1949,6 +1965,11 @@ static bool fold_sub(OptContext *ctx, TCGOp *op)
 return false;
 }
 
+static bool fold_sub(OptContext *ctx, TCGOp *op)
+{
+return fold_const2(ctx, op) || fold_sub_vec(ctx, op);
+}
+
 static bool fold_sub2(OptContext *ctx, TCGOp *op)
 {
 return fold_addsub2(ctx, op, false);
@@ -2052,9 +2073,12 @@ void tcg_optimize(TCGContext *s)
  * Sorted alphabetically by opcode as much as possible.
  */
 switch (opc) {
-CASE_OP_32_64_VEC(add):
+CASE_OP_32_64(add):
 done = fold_add(&ctx, op);
 break;
+case INDEX_op_add_vec:
+done = fold_add_vec(&ctx, op);
+break;
 CASE_OP_32_64(add2):
 done = fold_add2(&ctx, op);
 break;
@@ -2193,9 +2217,12 @@ void tcg_optimize(TCGContext *s)
 CASE_OP_32_64(sextract):
 done = fold_sextract(&ctx, op);
 break;
-CASE_OP_32_64_VEC(sub):
+CASE_OP_32_64(sub):
 done = fold_sub(&ctx, op);
 break;
+case INDEX_op_sub_vec:
+done = fold_sub_vec(&ctx, op);
+break;
 CASE_OP_32_64(sub2):
 done = fold_sub2(&ctx, op);
 break;
-- 
2.25.1




[PULL 4/4] common-user: Fix tail calls to safe_syscall_set_errno_tail

2022-01-04 Thread Richard Henderson
For the ABIs in which the syscall return register is not
also the first function argument register, move the errno
value into the correct place.

Fixes: a3310c0397e2 ("linux-user: Move syscall error detection into 
safe_syscall_base")
Reported-by: Laurent Vivier 
Tested-by: Laurent Vivier 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Richard Henderson 
Message-Id: <20220104190454.542225-1-richard.hender...@linaro.org>
---
 common-user/host/i386/safe-syscall.inc.S   | 1 +
 common-user/host/mips/safe-syscall.inc.S   | 1 +
 common-user/host/x86_64/safe-syscall.inc.S | 1 +
 3 files changed, 3 insertions(+)

diff --git a/common-user/host/i386/safe-syscall.inc.S 
b/common-user/host/i386/safe-syscall.inc.S
index baf5400a29..9c45e56e48 100644
--- a/common-user/host/i386/safe-syscall.inc.S
+++ b/common-user/host/i386/safe-syscall.inc.S
@@ -120,6 +120,7 @@ safe_syscall_end:
 pop %ebp
 .cfi_adjust_cfa_offset -4
 .cfi_restore ebp
+mov %eax, (%esp)
 jmp safe_syscall_set_errno_tail
 
 .cfi_endproc
diff --git a/common-user/host/mips/safe-syscall.inc.S 
b/common-user/host/mips/safe-syscall.inc.S
index fc75a337d1..6a44614970 100644
--- a/common-user/host/mips/safe-syscall.inc.S
+++ b/common-user/host/mips/safe-syscall.inc.S
@@ -141,6 +141,7 @@ safe_syscall_end:
 1:  USE_ALT_CP(t0)
 SETUP_GPX(t1)
 SETUP_GPX64(t0, t1)
+movea0, v0
 PTR_LA  t9, safe_syscall_set_errno_tail
 jr  t9
 
diff --git a/common-user/host/x86_64/safe-syscall.inc.S 
b/common-user/host/x86_64/safe-syscall.inc.S
index a20927a783..d1a67a303a 100644
--- a/common-user/host/x86_64/safe-syscall.inc.S
+++ b/common-user/host/x86_64/safe-syscall.inc.S
@@ -99,6 +99,7 @@ safe_syscall_end:
 1:  pop %rbp
 .cfi_def_cfa_offset 8
 .cfi_restore rbp
+mov %eax, %edi
 jmp safe_syscall_set_errno_tail
 .cfi_endproc
 
-- 
2.25.1




[PULL 3/4] sysemu: Cleanup qemu_run_machine_init_done_notifiers()

2022-01-04 Thread Richard Henderson
From: Xiaoyao Li 

Remove qemu_run_machine_init_done_notifiers() since no implementation
and user.

Fixes: f66dc8737c9 ("vl: move all generic initialization out of vl.c")
Signed-off-by: Xiaoyao Li 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20220104024136.1433545-1-xiaoyao...@intel.com>
Signed-off-by: Richard Henderson 
---
 include/sysemu/sysemu.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 8fae667172..b9421e03ff 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -16,7 +16,6 @@ extern bool qemu_uuid_set;
 void qemu_add_exit_notifier(Notifier *notify);
 void qemu_remove_exit_notifier(Notifier *notify);
 
-void qemu_run_machine_init_done_notifiers(void);
 void qemu_add_machine_init_done_notifier(Notifier *notify);
 void qemu_remove_machine_init_done_notifier(Notifier *notify);
 
-- 
2.25.1




[PULL 2/4] linux-user: Fix trivial build error on loongarch64 hosts

2022-01-04 Thread Richard Henderson
From: Philippe Mathieu-Daudé 

When building using GCC 8.3.0 on loongarch64 (Loongnix) we get:

  In file included from ../linux-user/signal.c:33:
  ../linux-user/host/loongarch64/host-signal.h: In function ‘host_signal_write’:
  ../linux-user/host/loongarch64/host-signal.h:57:9: error: a label can only be 
part of a statement and a declaration is not a statement
 uint32_t sel = (insn >> 15) & 0b111;
 ^~~~

We don't use the 'sel' variable more than once, so drop it.

Meson output for the record:

  Host machine cpu family: loongarch64
  Host machine cpu: loongarch64
  C compiler for the host machine: cc (gcc 8.3.0 "cc (Loongnix 
8.3.0-6.lnd.vec.27) 8.3.0")
  C linker for the host machine: cc ld.bfd 2.31.1-system

Fixes: ad812c3bd65 ("linux-user: Implement CPU-specific signal handler for 
loongarch64 hosts")
Reported-by: Song Gao 
Suggested-by: Song Gao 
Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: WANG Xuerui 
Reviewed-by: Richard Henderson 
Message-Id: <20220104215027.2180972-1-f4...@amsat.org>
Signed-off-by: Richard Henderson 
---
 linux-user/host/loongarch64/host-signal.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/linux-user/host/loongarch64/host-signal.h 
b/linux-user/host/loongarch64/host-signal.h
index 05e2c82371..7effa24251 100644
--- a/linux-user/host/loongarch64/host-signal.h
+++ b/linux-user/host/loongarch64/host-signal.h
@@ -54,9 +54,7 @@ static inline bool host_signal_write(siginfo_t *info, 
ucontext_t *uc)
 }
 break;
 case 0b001110: /* indexed, atomic, bounds-checking memory operations */
-uint32_t sel = (insn >> 15) & 0b111;
-
-switch (sel) {
+switch ((insn >> 15) & 0b111) {
 case 0b010: /* stx.b */
 case 0b0101000: /* stx.h */
 case 0b011: /* stx.w */
-- 
2.25.1




[PULL 0/4] tcg patch queue

2022-01-04 Thread Richard Henderson
The following changes since commit 67e41fe0cfb62e6cdfa659f0155417d17e5274ea:

  Merge tag 'pull-ppc-20220104' of https://github.com/legoater/qemu into 
staging (2022-01-04 07:23:27 -0800)

are available in the Git repository at:

  https://gitlab.com/rth7680/qemu.git tags/pull-tcg-20220104

for you to fetch changes up to d7478d4229f0a2b2817a55487e6b17081099fae4:

  common-user: Fix tail calls to safe_syscall_set_errno_tail (2022-01-04 
15:41:03 -0800)


Fix for safe_syscall_base.
Fix for folding of vector add/sub.
Fix build on loongarch64 with gcc 8.
Remove decl for qemu_run_machine_init_done_notifiers.


Philippe Mathieu-Daudé (1):
  linux-user: Fix trivial build error on loongarch64 hosts

Richard Henderson (2):
  tcg/optimize: Fix folding of vector ops
  common-user: Fix tail calls to safe_syscall_set_errno_tail

Xiaoyao Li (1):
  sysemu: Cleanup qemu_run_machine_init_done_notifiers()

 include/sysemu/sysemu.h|  1 -
 linux-user/host/loongarch64/host-signal.h  |  4 +--
 tcg/optimize.c | 49 +++---
 common-user/host/i386/safe-syscall.inc.S   |  1 +
 common-user/host/mips/safe-syscall.inc.S   |  1 +
 common-user/host/x86_64/safe-syscall.inc.S |  1 +
 6 files changed, 42 insertions(+), 15 deletions(-)



Re: [PATCH] common-user: Fix tail calls to safe_syscall_set_errno_tail

2022-01-04 Thread Richard Henderson

On 1/4/22 11:04 AM, Richard Henderson wrote:

For the ABIs in which the syscall return register is not
also the first function argument register, move the errno
value into the correct place.

Fixes: a3310c0397e2
Reported-by: Laurent Vivier 
Signed-off-by: Richard Henderson 
---
  common-user/host/i386/safe-syscall.inc.S   | 1 +
  common-user/host/mips/safe-syscall.inc.S   | 1 +
  common-user/host/x86_64/safe-syscall.inc.S | 1 +
  3 files changed, 3 insertions(+)


Queued to tcg-next.

r~



Re: [PATCH] sysemu: Cleanup qemu_run_machine_init_done_notifiers()

2022-01-04 Thread Richard Henderson

On 1/3/22 6:41 PM, Xiaoyao Li wrote:

Remove qemu_run_machine_init_done_notifiers() since no implementation
and user.

Signed-off-by: Xiaoyao Li
---
  include/sysemu/sysemu.h | 1 -
  1 file changed, 1 deletion(-)


Queued to tcg-next.  Thanks.

r~



Re: [PATCH for 7.0 5/5] bsd-user-smoke: Add to build

2022-01-04 Thread Warner Losh
On Tue, Jan 4, 2022 at 4:25 PM Philippe Mathieu-Daudé 
wrote:

> +Paolo for meson
>
> On 11/27/21 21:18, Warner Losh wrote:
> > Add a simple bsd-user smoke test for ensuring bsd-user is minimally
> > functional. This runs only when bsd-user has been configured. It adds a
> > simple execution of 'hello world' type binaries for bsd-user. At the
> > present these are tiny, hand-crafted binaries that are statically linked
> > and do not depend on any host libraries being present (they also take
> > advantage of the fact that on FreeBSD all system call numbers are
> > uniform on all architectures). This was done both for building and
> > testing simplicity, as well as recognizing the current state of bsd-user
> > in qemu upstream is extremely basic.
> >
> > Signed-off-by: Warner Losh 
> > ---
> >  tests/bsd-user-smoke/meson.build | 31 +++
> >  tests/meson.build|  1 +
> >  2 files changed, 32 insertions(+)
> >  create mode 100644 tests/bsd-user-smoke/meson.build
> >
> > diff --git a/tests/bsd-user-smoke/meson.build
> b/tests/bsd-user-smoke/meson.build
> > new file mode 100644
> > index 000..586697ab3b6
> > --- /dev/null
> > +++ b/tests/bsd-user-smoke/meson.build
> > @@ -0,0 +1,31 @@
> > +if not have_bsd_user
> > +   subdir_done()
> > +endif
> > +
> > +smoke_bsd_user = find_program('smoke-bsd-user')
> > +
> > +bsd_user_archs = [ 'armv7', 'amd64', 'i386' ]
> > +targs = []
> > +foreach i : bsd_user_archs
> > +h = 'h.' + i
> > +targs += custom_target('bsd-user h.' + i,
> > +output : h,
> > + input : h + '.S',
> > + command : ['clang',
>
> Do we want a find_program(clang) somewhere?
>

I am new and naive in the ways of meson... :) I am willing, however, to
learn...
Is it just s/'clang'/find_program(clang)/ here or something more complex


> > + '-target',
> > + i + '-unknown-freebsd14.0',
>
> Also, I wonder if this trailer shouldn´t be populated by meson.
>

I like that idea. See above :)

Warner


> > + '-o',
> > + '@OUTPUT@',
> > + '@INPUT@',
> > + '-nostdlib',
> > + '-Wl,-e',
> > + '-Wl,qemu_start',
> > + '-static'],
> > + install : false)
> > +endforeach
> > +
> > +test('bsd-user-smoke', smoke_bsd_user,
> > +args: [meson.project_build_root(), meson.current_build_dir()],
> > +suite: 'smoke',
> > +depends: targs
> > +)
> > diff --git a/tests/meson.build b/tests/meson.build
> > index 3f3882748ae..3b95efe8896 100644
> > --- a/tests/meson.build
> > +++ b/tests/meson.build
> > @@ -1,6 +1,7 @@
> >  py3 = import('python').find_installation()
> >
> >  subdir('bench')
> > +subdir('bsd-user-smoke')
> >
> >  test_qapi_outputs = [
> >'qapi-builtin-types.c',
>


Re: [PATCH v2] linux-user: Fix trivial build error on loongarch64 hosts

2022-01-04 Thread Richard Henderson

On 1/4/22 1:50 PM, Philippe Mathieu-Daudé wrote:

When building using GCC 8.3.0 on loongarch64 (Loongnix) we get:

   In file included from ../linux-user/signal.c:33:
   ../linux-user/host/loongarch64/host-signal.h: In function 
‘host_signal_write’:
   ../linux-user/host/loongarch64/host-signal.h:57:9: error: a label can only 
be part of a statement and a declaration is not a statement
  uint32_t sel = (insn >> 15) & 0b111;
  ^~~~

We don't use the 'sel' variable more than once, so drop it.

Meson output for the record:

   Host machine cpu family: loongarch64
   Host machine cpu: loongarch64
   C compiler for the host machine: cc (gcc 8.3.0 "cc (Loongnix 8.3.0-6.lnd.vec.27) 
8.3.0")
   C linker for the host machine: cc ld.bfd 2.31.1-system

Fixes: ad812c3bd65 ("linux-user: Implement CPU-specific signal handler for 
loongarch64 hosts")
Reported-by: Song Gao 
Suggested-by: Song Gao 
Reviewed-by: WANG Xuerui 
Signed-off-by: Philippe Mathieu-Daudé 


As a build fix, I'll pop this into tcg-next.


r~



Re: [PATCH 1/2] hw/display/vmware_vga: replace fprintf calls with trace events

2022-01-04 Thread Philippe Mathieu-Daudé
On 1/4/22 19:06, Carwyn Ellis wrote:
> Debug output was always being sent to STDERR.
> 
> This has been replaced with trace events.
> 
> Signed-off-by: Carwyn Ellis 
> ---
>  hw/display/trace-events |  3 +++
>  hw/display/vmware_vga.c | 22 ++
>  2 files changed, 13 insertions(+), 12 deletions(-)
> 
> diff --git a/hw/display/trace-events b/hw/display/trace-events
> index 3a7a2c957f..e1a0d2a88a 100644
> --- a/hw/display/trace-events
> +++ b/hw/display/trace-events
> @@ -21,6 +21,9 @@ vmware_palette_write(uint32_t index, uint32_t value) "index 
> %d, value 0x%x"
>  vmware_scratch_read(uint32_t index, uint32_t value) "index %d, value 0x%x"
>  vmware_scratch_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
>  vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp"
> +vmware_verify_rect_less_than_zero(const char *name, const char *param, int 
> x) "%s: %s was < 0 (%d)"
> +vmware_verify_rect_greater_than_bound(const char *name, const char *param, 
> int bound, int x) "%s: %s was > %d (%d)"
> +vmware_verify_rect_surface_bound_exceeded(const char *name, const char 
> *component, int bound, const char *param1, int value1, const char *param2, 
> int value2) "%s: %s > %d (%s: %d, %s, %d)"

"%s: %s > %d (%s: %d, %s: %d)", otherwise:

Reviewed-by: Philippe Mathieu-Daudé 





Re: [PATCH for 7.0 5/5] bsd-user-smoke: Add to build

2022-01-04 Thread Philippe Mathieu-Daudé
+Paolo for meson

On 11/27/21 21:18, Warner Losh wrote:
> Add a simple bsd-user smoke test for ensuring bsd-user is minimally
> functional. This runs only when bsd-user has been configured. It adds a
> simple execution of 'hello world' type binaries for bsd-user. At the
> present these are tiny, hand-crafted binaries that are statically linked
> and do not depend on any host libraries being present (they also take
> advantage of the fact that on FreeBSD all system call numbers are
> uniform on all architectures). This was done both for building and
> testing simplicity, as well as recognizing the current state of bsd-user
> in qemu upstream is extremely basic.
> 
> Signed-off-by: Warner Losh 
> ---
>  tests/bsd-user-smoke/meson.build | 31 +++
>  tests/meson.build|  1 +
>  2 files changed, 32 insertions(+)
>  create mode 100644 tests/bsd-user-smoke/meson.build
> 
> diff --git a/tests/bsd-user-smoke/meson.build 
> b/tests/bsd-user-smoke/meson.build
> new file mode 100644
> index 000..586697ab3b6
> --- /dev/null
> +++ b/tests/bsd-user-smoke/meson.build
> @@ -0,0 +1,31 @@
> +if not have_bsd_user
> +   subdir_done()
> +endif
> +
> +smoke_bsd_user = find_program('smoke-bsd-user')
> +
> +bsd_user_archs = [ 'armv7', 'amd64', 'i386' ]
> +targs = []
> +foreach i : bsd_user_archs
> +h = 'h.' + i
> +targs += custom_target('bsd-user h.' + i,
> +output : h,
> + input : h + '.S',
> + command : ['clang',

Do we want a find_program(clang) somewhere?

> + '-target',
> + i + '-unknown-freebsd14.0',

Also, I wonder if this trailer shouldn´t be populated by meson.

> + '-o',
> + '@OUTPUT@',
> + '@INPUT@',
> + '-nostdlib',
> + '-Wl,-e',
> + '-Wl,qemu_start',
> + '-static'],
> + install : false)
> +endforeach
> +
> +test('bsd-user-smoke', smoke_bsd_user,
> +args: [meson.project_build_root(), meson.current_build_dir()],
> +suite: 'smoke',
> +depends: targs
> +)
> diff --git a/tests/meson.build b/tests/meson.build
> index 3f3882748ae..3b95efe8896 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -1,6 +1,7 @@
>  py3 = import('python').find_installation()
>  
>  subdir('bench')
> +subdir('bsd-user-smoke')
>  
>  test_qapi_outputs = [
>'qapi-builtin-types.c',



Re: [PULL v3 00/15] Build system and KVM changes for 2021-12-23

2022-01-04 Thread Richard Henderson

On 1/4/22 6:57 AM, Paolo Bonzini wrote:

The following changes since commit b5a3d8bc9146ba22a25116cb748c97341bf99737:

   Merge tag 'pull-misc-20220103' of https://gitlab.com/rth7680/qemu into 
staging (2022-01-03 09:34:41 -0800)

are available in the Git repository at:

   https://gitlab.com/bonzini/qemu.git tags/for-upstream

for you to fetch changes up to a2c137e7e00d1bfcc80a17ff8e5104d0e1de2f9a:

   tests/tcg: Fix target-specific Makefile variables path for user-mode 
(2022-01-04 14:08:44 +0100)


* configure and meson cleanups
* KVM_GET/SET_SREGS2 support for x86



I dropped the tricore Dockerfile change because it is still broken occasionally
with the patch.

Maxim Levitsky (1):
   KVM: use KVM_{GET|SET}_SREGS2 when supported.

Paolo Bonzini (12):
   meson: reuse common_user_inc when building files specific to user-mode 
emulators
   user: move common-user includes to a subdirectory of {bsd,linux}-user/
   meson: cleanup common-user/ build
   configure: simplify creation of plugin symbol list
   configure: do not set bsd_user/linux_user early
   configure, makefile: remove traces of really old files
   configure: parse --enable/--disable-strip automatically, flip default
   configure: move non-command-line variables away from command-line 
parsing section
   meson: build contrib/ executables after generated headers
   configure, meson: move config-poison.h to meson
   meson: add comments in the target-specific flags section
   KVM: x86: ignore interrupt_bitmap field of KVM_GET/SET_SREGS

Philippe Mathieu-Daudé (1):
   tests/tcg: Fix target-specific Makefile variables path for user-mode

Thomas Huth (1):
   block/file-posix: Simplify the XFS_IOC_DIOINFO handling

  Makefile   |  11 +-
  block/file-posix.c |  37 ++---
  bsd-user/{ => include}/special-errno.h |   0
  bsd-user/meson.build   |   2 +-
  common-user/meson.build|   2 +-
  configure  | 182 +++--
  contrib/elf2dmp/meson.build|   2 +-
  contrib/ivshmem-client/meson.build |   2 +-
  contrib/ivshmem-server/meson.build |   2 +-
  contrib/rdmacm-mux/meson.build |   2 +-
  .../{ => include}/host/aarch64/host-signal.h   |   0
  linux-user/{ => include}/host/alpha/host-signal.h  |   0
  linux-user/{ => include}/host/arm/host-signal.h|   0
  linux-user/{ => include}/host/i386/host-signal.h   |   0
  .../{ => include}/host/loongarch64/host-signal.h   |   0
  linux-user/{ => include}/host/mips/host-signal.h   |   0
  linux-user/{ => include}/host/ppc/host-signal.h|   0
  linux-user/{ => include}/host/ppc64/host-signal.h  |   0
  linux-user/{ => include}/host/riscv/host-signal.h  |   0
  linux-user/{ => include}/host/s390/host-signal.h   |   0
  linux-user/{ => include}/host/s390x/host-signal.h  |   0
  linux-user/{ => include}/host/sparc/host-signal.h  |   0
  .../{ => include}/host/sparc64/host-signal.h   |   0
  linux-user/{ => include}/host/x32/host-signal.h|   0
  linux-user/{ => include}/host/x86_64/host-signal.h |   0
  linux-user/{ => include}/special-errno.h   |   0
  linux-user/meson.build |   4 +-
  meson.build|  33 ++--
  pc-bios/s390-ccw/Makefile  |   2 -
  plugins/meson.build|  11 +-
  scripts/make-config-poison.sh  |  16 ++
  scripts/meson-buildoptions.py  |  21 ++-
  scripts/meson-buildoptions.sh  |   3 +
  target/i386/cpu.h  |   3 +
  target/i386/kvm/kvm.c  | 130 +--
  target/i386/machine.c  |  29 
  tests/tcg/Makefile.target  |   2 +-
  37 files changed, 259 insertions(+), 237 deletions(-)
  rename bsd-user/{ => include}/special-errno.h (100%)
  rename linux-user/{ => include}/host/aarch64/host-signal.h (100%)
  rename linux-user/{ => include}/host/alpha/host-signal.h (100%)
  rename linux-user/{ => include}/host/arm/host-signal.h (100%)
  rename linux-user/{ => include}/host/i386/host-signal.h (100%)
  rename linux-user/{ => include}/host/loongarch64/host-signal.h (100%)
  rename linux-user/{ => include}/host/mips/host-signal.h (100%)
  rename linux-user/{ => include}/host/ppc/host-signal.h (100%)
  rename linux-user/{ => include}/host/ppc64/host-signal.h (100%)
  rename linux-user/{ => include}/host/riscv/host-signal.h (100%)
  rename linux-user/{ => include}/host/s390/host-signal.h (100%)
  rename linux-user/{ => include}/host/s390x/host-signal.h (

Re: [PATCH 1/2] tests/tcg/multiarch: Read fp flags before printf

2022-01-04 Thread Richard Henderson

On 1/4/22 2:48 PM, Taylor Simpson wrote:

Was Hexagon the only target that needed new ref files?


Yep.  A curiosity of the guest libc, I guess.

r~



Re: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver

2022-01-04 Thread Richard Henderson

On 1/4/22 7:51 AM, Konrad Schwarz wrote:

+++ b/target/riscv/csr32-op-gdbserver.h

...

+++ b/target/riscv/csr64-op-gdbserver.h


There is a *lot* of overlap between these two files.
Why not add this data to the main csr_ops array?
That would put all the info for each csr in one place.


+  [CSR_CYCLE] { .gdb_type = "uint64", .gdb_group = "user" },


I think you should be able to use "unsigned long" as a proxy for the native 
register size.


+char const riscv_gdb_csr_types[] =
+#ifdef TARGET_RISCV32

...

+#elif defined TARGET_RISCV64

...

+# endif
+;


Ideally we shouldn't use ifdefs for this -- we should choose one or the other depending on 
the startup env->misa_mxl_max.  We are still using an ifdef for the main 
riscv-*-virtual.xml, but that could be considered a bug to fix.



r~



RE: [PATCH 1/2] tests/tcg/multiarch: Read fp flags before printf

2022-01-04 Thread Taylor Simpson



> -Original Message-
> From: Richard Henderson 
> Sent: Thursday, December 23, 2021 9:56 PM
> To: qemu-devel@nongnu.org
> Cc: alex.ben...@linaro.org; Taylor Simpson 
> Subject: [PATCH 1/2] tests/tcg/multiarch: Read fp flags before printf
> 
> We need to read the floating-point flags before printf may do other floating-
> point operations which may affect the flags.
> 
> Hexagon reference files regenerated by Taylor Simpson.
> 
> Signed-off-by: Taylor Simpson 
> Signed-off-by: Richard Henderson 
> Message-Id: <1639510781-3790-1-git-send-email-tsimp...@quicinc.com>
> ---
>  tests/tcg/multiarch/float_convs.c |   2 +-
>  tests/tcg/multiarch/float_madds.c |   2 +-
>  tests/tcg/hexagon/float_convs.ref | 152 +++---
> tests/tcg/hexagon/float_madds.ref |  48 +-
>  4 files changed, 102 insertions(+), 102 deletions(-)

Reviewed-by: Taylor Simpson 

Was Hexagon the only target that needed new ref files?





Re: [PATCH v2 1/5] hw/arm/virt: Key enablement of highmem PCIe on highmem_ecam

2022-01-04 Thread Marc Zyngier
Hi Eric,

On Tue, 04 Jan 2022 15:31:33 +,
Eric Auger  wrote:
> 
> Hi Marc,
> 
> On 12/27/21 4:53 PM, Marc Zyngier wrote:
> > Hi Eric,
> >
> > Picking this up again after a stupidly long time...
> >
> > On Mon, 04 Oct 2021 13:00:21 +0100,
> > Eric Auger  wrote:
> >> Hi Marc,
> >>
> >> On 10/3/21 6:46 PM, Marc Zyngier wrote:
> >>> Currently, the highmem PCIe region is oddly keyed on the highmem
> >>> attribute instead of highmem_ecam. Move the enablement of this PCIe
> >>> region over to highmem_ecam.
> >>>
> >>> Signed-off-by: Marc Zyngier 
> >>> ---
> >>>  hw/arm/virt-acpi-build.c | 10 --
> >>>  hw/arm/virt.c|  4 ++--
> >>>  2 files changed, 6 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> >>> index 037cc1fd82..d7bef0e627 100644
> >>> --- a/hw/arm/virt-acpi-build.c
> >>> +++ b/hw/arm/virt-acpi-build.c
> >>> @@ -157,10 +157,9 @@ static void acpi_dsdt_add_virtio(Aml *scope,
> >>>  }
> >>>  
> >>>  static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
> >>> -  uint32_t irq, bool use_highmem, bool 
> >>> highmem_ecam,
> >>> -  VirtMachineState *vms)
> >>> +  uint32_t irq, VirtMachineState *vms)
> >>>  {
> >>> -int ecam_id = VIRT_ECAM_ID(highmem_ecam);
> >>> +int ecam_id = VIRT_ECAM_ID(vms->highmem_ecam);
> >>>  struct GPEXConfig cfg = {
> >>>  .mmio32 = memmap[VIRT_PCIE_MMIO],
> >>>  .pio= memmap[VIRT_PCIE_PIO],
> >>> @@ -169,7 +168,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const 
> >>> MemMapEntry *memmap,
> >>>  .bus= vms->bus,
> >>>  };
> >>>  
> >>> -if (use_highmem) {
> >>> +if (vms->highmem_ecam) {
> >> highmem_ecam is more restrictive than use_highmem:
> >> vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
> >>
> >> If I remember correctly there was a problem using highmem ECAM with 32b
> >> AAVMF FW.
> >>
> >> However 5125f9cd2532 ("hw/arm/virt: Add high MMIO PCI region, 512G in
> >> size") introduced high MMIO PCI region without this constraint.
> > Then I really don't understand the point of this highmem_ecam. We only
> > register the highmem version if highmem_ecam is set (see the use of
> > VIRT_ECAM_ID() to pick the right ECAM window).
> 
> but aren't we talking about different regions? On one hand the [high]
> MMIO region (512GB wide) and the [high] ECAM region (256MB large).
> To me you can enable either independently. High MMIO region is used by
> some devices likes ivshmem/video cards while high ECAM was introduced to
> extend the number of supported buses: 601d626d148a (hw/arm/virt: Add a
> new 256MB ECAM region).
> 
> with the above change the high MMIO region won't be set with 32b
> FW+kernel and LPAE whereas it is currently.
> 
> high ECAM was not supported by 32b FW, hence the highmem_ecam.
> 
> but maybe I miss your point?

There are two issues.

First, I have been conflating the ECAM and MMIO ranges, and you only
made me realise that they were supposed to be independent.  I still
think the keying on highmem is wrong, but the main issue is that the
highmem* flags don't quite describe the shape of the platform.

All these booleans indicate is whether the feature they describe (the
high MMIO range, the high ECAM range, and in one of my patches the
high RD range) are *allowed* to live above 4GB, but do not express
whether then are actually usable (i.e. fit in the PA range).

Maybe we need to be more thorough in the way we describe the extended
region in the VirtMachineState structure:

- highmem: overall control for anything that *can* live above 4GB
- highmem_ecam: Has a PCIe ECAM region above 256GB
- highmem_mmio: Has a PCIe MMIO region above 256GB
- highmem_redist: Has 512 RDs above 256GB

Crucially, the last 3 items must fit in the PA range or be disabled.

We have highmem_ecam which is keyed on highmem, but not on the PA
range.  highmem_mmio doesn't exist at all (we use highmem instead),
and I'm only introducing highmem_redist.

For these 3 ranges, we should have something like

vms->highmem_xxx &= (vms->highmem &&
 (vms->memmap[XXX].base + vms->vms->memmap[XXX].size) < 
vms->highest_gpa);

and treat them as independent entities.  Unless someone shouts, I'm
going to go ahead and implement this logic.

Thanks,

M.

-- 
Without deviation from the norm, progress is not possible.



Re: [PATCH v2 4/5] RISC-V: Typed CSRs in gdbserver

2022-01-04 Thread Alistair Francis
On Wed, Jan 5, 2022 at 1:56 AM Konrad Schwarz
 wrote:
>
> GDB target descriptions support typed registers;
> such that `info register X' displays not only the hex value of
> register `X', but also the individual bitfields the register
> comprises (if any), using textual labels if possible.
>
> This patch includes type information for GDB for
> a large subset of the RISC-V Control and Status Registers (CSRs).
>
> Signed-off-by: Konrad Schwarz 
> ---
>  target/riscv/csr.c|   2 +
>  target/riscv/csr32-op-gdbserver.h | 109 ++
>  target/riscv/csr64-op-gdbserver.h |  76 +++
>  target/riscv/gdb_csr_type_group.c |  16 ++
>  target/riscv/gdb_csr_type_group.h |   3 +
>  target/riscv/gdb_csr_types.c  | 333 ++
>  target/riscv/gdb_csr_types.h  |   3 +
>  target/riscv/gdbstub.c|  26 ++-
>  target/riscv/meson.build  |   4 +-
>  9 files changed, 566 insertions(+), 6 deletions(-)
>  create mode 100644 target/riscv/csr32-op-gdbserver.h
>  create mode 100644 target/riscv/csr64-op-gdbserver.h
>  create mode 100644 target/riscv/gdb_csr_type_group.c
>  create mode 100644 target/riscv/gdb_csr_type_group.h
>  create mode 100644 target/riscv/gdb_csr_types.c
>  create mode 100644 target/riscv/gdb_csr_types.h
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 9f41954894..557b4afe0e 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3,6 +3,7 @@
>   *
>   * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
>   * Copyright (c) 2017-2018 SiFive, Inc.
> + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com

Please don't add these to existing files. In this case you have just
added a newline to this file

>   *
>   * This program is free software; you can redistribute it and/or modify it
>   * under the terms and conditions of the GNU General Public License,
> @@ -2094,5 +2095,6 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32,  read_zero },
>  [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32,  read_zero },
>  [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32,  read_zero },
> +
>  #endif /* !CONFIG_USER_ONLY */
>  };
> diff --git a/target/riscv/csr32-op-gdbserver.h 
> b/target/riscv/csr32-op-gdbserver.h
> new file mode 100644
> index 00..e8ec527f23
> --- /dev/null
> +++ b/target/riscv/csr32-op-gdbserver.h
> @@ -0,0 +1,109 @@
> +/* Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com */

All of these files should have the usual file boiler plate

> +
> +  [CSR_USTATUS] { .gdb_type = "sstatus-fields", .gdb_group = "user" },
> +  [CSR_UIE] { .gdb_type = "sie-fields", .gdb_group = "user" },
> +  [CSR_UTVEC] { .gdb_type = "code_ptr", .gdb_group = "user" },
> +  [CSR_USCRATCH] { .gdb_type = "data_ptr", .gdb_group = "user" },
> +  [CSR_UEPC] { .gdb_type = "code_ptr", .gdb_group = "user" },
> +  [CSR_UCAUSE] { .gdb_type = "scause-fields", .gdb_group = "user" },
> +  [CSR_UTVAL] { .gdb_type = "data_ptr", .gdb_group = "user" },
> +  [CSR_UIP] { .gdb_type = "code_ptr", .gdb_group = "user" },
> +  [CSR_CYCLE] { .gdb_type = "uint32", .gdb_group = "user" },
> +  [CSR_TIME] { .gdb_type = "uint32", .gdb_group = "user" },
> +  [CSR_INSTRET] { .gdb_type = "uint32", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER3] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER4] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER5] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER6] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER7] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER8] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER9] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER10] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER11] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER12] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER13] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER14] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER15] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER16] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER17] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER18] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER19] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER20] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER21] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER22] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER23] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER24] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER25] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER26] { .gdb_type = "int", .gdb_group = "user" },
> +  [CSR_HPMCOUNTER27] { .gdb_type = "int", .gdb_group = "use

Re: [PATCH v2] linux-user: Fix trivial build error on loongarch64 hosts

2022-01-04 Thread Richard Henderson

On 1/4/22 1:50 PM, Philippe Mathieu-Daudé wrote:

When building using GCC 8.3.0 on loongarch64 (Loongnix) we get:

   In file included from ../linux-user/signal.c:33:
   ../linux-user/host/loongarch64/host-signal.h: In function 
‘host_signal_write’:
   ../linux-user/host/loongarch64/host-signal.h:57:9: error: a label can only 
be part of a statement and a declaration is not a statement
  uint32_t sel = (insn >> 15) & 0b111;
  ^~~~

We don't use the 'sel' variable more than once, so drop it.

Meson output for the record:

   Host machine cpu family: loongarch64
   Host machine cpu: loongarch64
   C compiler for the host machine: cc (gcc 8.3.0 "cc (Loongnix 8.3.0-6.lnd.vec.27) 
8.3.0")
   C linker for the host machine: cc ld.bfd 2.31.1-system

Fixes: ad812c3bd65 ("linux-user: Implement CPU-specific signal handler for 
loongarch64 hosts")
Reported-by: Song Gao
Suggested-by: Song Gao
Reviewed-by: WANG Xuerui
Signed-off-by: Philippe Mathieu-Daudé
---
  linux-user/host/loongarch64/host-signal.h | 4 +---
  1 file changed, 1 insertion(+), 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 1/2] linux-user/ppc: deliver SIGTRAP on POWERPC_EXCP_TRAP

2022-01-04 Thread Richard Henderson

On 1/4/22 1:00 PM, matheus.fe...@eldorado.org.br wrote:

From: Matheus Ferst

Handle POWERPC_EXCP_TRAP in cpu_loop to deliver SIGTRAP on tw[i]/td[i].
The si_code comes from do_program_check in the kernel source file
arch/powerpc/kernel/traps.c

Signed-off-by: Matheus Ferst
---
  linux-user/ppc/cpu_loop.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH v2 3/5] RISC-V: 'info gmem' to show hypervisor guest -> physical address translations

2022-01-04 Thread Alistair Francis
On Wed, Jan 5, 2022 at 1:55 AM Konrad Schwarz
 wrote:
>
> This is analog to the existing 'info mem' command and is implemented
> using the same machinery.
>
> Signed-off-by: Konrad Schwarz 

Hello and thanks for the patches

> ---
>  hmp-commands-info.hx |  16 +
>  include/monitor/hmp-target.h |   2 +
>  target/riscv/monitor.c   | 135 +--
>  3 files changed, 117 insertions(+), 36 deletions(-)
>
> diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
> index 407a1da800..fa519f0129 100644
> --- a/hmp-commands-info.hx
> +++ b/hmp-commands-info.hx
> @@ -237,6 +237,22 @@ SRST
>  Show the active virtual memory mappings.
>  ERST
>
> +#if defined TARGET_RISCV
> +{
> +.name   = "gmem",
> +.args_type  = "",
> +.params = "",
> +.help   = "show the hypervisor guest's physical address"
> +   " translation",
> +.cmd= hmp_info_gmem,
> +},
> +#endif

I don't think we want RISC-V specific commands. Could we not just
extend `info mem` instead?

> +
> +SRST
> +  ``info gmem``
> +Show the hypervisor guest's physical address translation.
> +ERST
> +
>  {
>  .name   = "mtree",
>  .args_type  = "flatview:-f,dispatch_tree:-d,owner:-o,disabled:-D",
> diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h
> index ffdc15a34b..9f2dd976f6 100644
> --- a/include/monitor/hmp-target.h
> +++ b/include/monitor/hmp-target.h
> @@ -2,6 +2,7 @@
>   * QEMU monitor
>   *
>   * Copyright (c) 2003-2004 Fabrice Bellard
> + * Copyright (c) 2021 Siemens AG, konrad.schw...@siemens.com

Generally you would only add a copyright claim for a very large
change. Adding a single function prototype doesn't really cut it.

>   *
>   * Permission is hereby granted, free of charge, to any person obtaining a 
> copy
>   * of this software and associated documentation files (the "Software"), to 
> deal
> @@ -45,6 +46,7 @@ CPUArchState *mon_get_cpu_env(Monitor *mon);
>  CPUState *mon_get_cpu(Monitor *mon);
>
>  void hmp_info_mem(Monitor *mon, const QDict *qdict);
> +void hmp_info_gmem(Monitor *mon, const QDict *qdict);
>  void hmp_info_tlb(Monitor *mon, const QDict *qdict);
>  void hmp_mce(Monitor *mon, const QDict *qdict);
>  void hmp_info_local_apic(Monitor *mon, const QDict *qdict);
> diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
> index 3f74ea9934..ad58bdf9ca 100644
> --- a/target/riscv/monitor.c
> +++ b/target/riscv/monitor.c
> @@ -25,16 +25,6 @@
>  #include "monitor/monitor.h"
>  #include "monitor/hmp-target.h"
>
> -#ifdef TARGET_RISCV64
> -#define PTE_HEADER_FIELDS   "vaddrpaddr"\
> -"size attr\n"
> -#define PTE_HEADER_DELIMITER"  "\
> -" ---\n"
> -#else
> -#define PTE_HEADER_FIELDS   "vaddrpaddrsize attr\n"
> -#define PTE_HEADER_DELIMITER"   
> ---\n"
> -#endif
> -
>  /* Perform linear address sign extension */
>  static target_ulong addr_canonical(int va_bits, target_ulong addr)
>  {
> @@ -47,10 +37,34 @@ static target_ulong addr_canonical(int va_bits, 
> target_ulong addr)
>  return addr;
>  }
>
> -static void print_pte_header(Monitor *mon)
> +static void print_pte_header(Monitor *mon,
> +char const vaddr_char, char const paddr_char)
>  {
> -monitor_printf(mon, PTE_HEADER_FIELDS);
> -monitor_printf(mon, PTE_HEADER_DELIMITER);
> +
> +# defineVIRTUAL_WIDTH\
> +((int) ((sizeof "ff" - sizeof "") * sizeof(target_ulong)))
> +# definePHYSICAL_WIDTH\
> +((int) ((sizeof "ff" - sizeof "") * sizeof(hwaddr)))
> +# defineATTRIBUTE_WIDTH ((int) (sizeof "rwxugad" - sizeof ""))
> +
> +# defineVIRTUAL_COLUMN_WIDTH(1 + VIRTUAL_WIDTH)
> +# definePHYSICAL_COLUMN_WIDTH   (1 + PHYSICAL_WIDTH)
> +
> +static char const dashes[PHYSICAL_WIDTH] = "";
> +
> +monitor_printf(mon,
> +"%c%-*s%c%-*s%-*s%-*s\n"
> +"%-*.*s%-*.*s%-*.*s%-*.*s\n",
> +
> +vaddr_char, VIRTUAL_COLUMN_WIDTH - 1, "addr",
> +paddr_char, PHYSICAL_COLUMN_WIDTH - 1, "addr",
> +VIRTUAL_COLUMN_WIDTH, "size",
> +ATTRIBUTE_WIDTH, "attr",
> +
> +VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, dashes,
> +PHYSICAL_COLUMN_WIDTH, PHYSICAL_WIDTH, dashes,
> +VIRTUAL_COLUMN_WIDTH, VIRTUAL_WIDTH, dashes,
> +ATTRIBUTE_WIDTH, ATTRIBUTE_WIDTH, dashes);
>  }
>
>  static void print_pte(Monitor *mon, int va_bits, target_ulong vaddr,
> @@ -65,21 +79,36 @@ static void print_pte(Monitor *mon, int va_bits, 
> target_ulong vaddr,
>  return;
>  }
>
> -monitor_printf(mon, TARGET_FMT_lx " " TARGET_FMT_plx " " TARGET_FMT_lx
> -   " %c%c%c%c%c%c%c\n",
> -   addr_canonical(va

Re: [PATCH v2 0/2] Align SiFive PDMA behavior to real hardware

2022-01-04 Thread Alistair Francis
On Tue, Jan 4, 2022 at 4:56 PM Jim Shu  wrote:
>
> HiFive Unmatched PDMA supports high/low 32-bit access of 64-bit
> register, but QEMU emulation supports low part access now. Enhance QEMU
> emulation to support high 32-bit access.
>
> Also, permit 4/8-byte valid access in PDMA as we have verified 32/64-bit
> accesses of PDMA registers are supported.
>
> Changelog:
>
> v2:
>   * Fix high 32-bit write access of 64-bit RO registers
>   * Fix commit log
>
> Jim Shu (2):
>   hw/dma: sifive_pdma: support high 32-bit access of 64-bit register
>   hw/dma: sifive_pdma: permit 4/8-byte access size of PDMA registers

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  hw/dma/sifive_pdma.c | 181 +--
>  1 file changed, 159 insertions(+), 22 deletions(-)
>
> --
> 2.25.1
>
>



[PATCH v2] linux-user: Fix trivial build error on loongarch64 hosts

2022-01-04 Thread Philippe Mathieu-Daudé
When building using GCC 8.3.0 on loongarch64 (Loongnix) we get:

  In file included from ../linux-user/signal.c:33:
  ../linux-user/host/loongarch64/host-signal.h: In function ‘host_signal_write’:
  ../linux-user/host/loongarch64/host-signal.h:57:9: error: a label can only be 
part of a statement and a declaration is not a statement
 uint32_t sel = (insn >> 15) & 0b111;
 ^~~~

We don't use the 'sel' variable more than once, so drop it.

Meson output for the record:

  Host machine cpu family: loongarch64
  Host machine cpu: loongarch64
  C compiler for the host machine: cc (gcc 8.3.0 "cc (Loongnix 
8.3.0-6.lnd.vec.27) 8.3.0")
  C linker for the host machine: cc ld.bfd 2.31.1-system

Fixes: ad812c3bd65 ("linux-user: Implement CPU-specific signal handler for 
loongarch64 hosts")
Reported-by: Song Gao 
Suggested-by: Song Gao 
Reviewed-by: WANG Xuerui 
Signed-off-by: Philippe Mathieu-Daudé 
---
 linux-user/host/loongarch64/host-signal.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/linux-user/host/loongarch64/host-signal.h 
b/linux-user/host/loongarch64/host-signal.h
index 05e2c823717..7effa242515 100644
--- a/linux-user/host/loongarch64/host-signal.h
+++ b/linux-user/host/loongarch64/host-signal.h
@@ -54,9 +54,7 @@ static inline bool host_signal_write(siginfo_t *info, 
ucontext_t *uc)
 }
 break;
 case 0b001110: /* indexed, atomic, bounds-checking memory operations */
-uint32_t sel = (insn >> 15) & 0b111;
-
-switch (sel) {
+switch ((insn >> 15) & 0b111) {
 case 0b010: /* stx.b */
 case 0b0101000: /* stx.h */
 case 0b011: /* stx.w */
-- 
2.33.1




Re: [PATCH 1/3] target/riscv: rvv-1.0: Call the correct RVF/RVD check funtion for widening fp insns

2022-01-04 Thread Alistair Francis
On Wed, Dec 29, 2021 at 12:15 PM  wrote:
>
> From: Frank Chang 
>
> Vector widening floating-point instructions should use
> require_scale_rvf() instead of require_rvf() to check whether RVF/RVD is
> enabled.

Missing Signed off by line

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 12 
>  1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
> b/target/riscv/insn_trans/trans_rvv.c.inc
> index 5e3f7fdb77..8d92243f2b 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -2254,7 +2254,8 @@ GEN_OPFVF_TRANS(vfrsub_vf,  opfvf_check)
>  static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
>  {
>  return require_rvv(s) &&
> -   require_rvf(s) &&
> +   require_scale_rvf(s) &&
> +   (s->sew != MO_8) &&
> vext_check_isa_ill(s) &&
> vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
>  }
> @@ -2292,7 +2293,8 @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
>  static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
>  {
>  return require_rvv(s) &&
> -   require_rvf(s) &&
> +   require_scale_rvf(s) &&
> +   (s->sew != MO_8) &&
> vext_check_isa_ill(s) &&
> vext_check_ds(s, a->rd, a->rs2, a->vm);
>  }
> @@ -2321,7 +2323,8 @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
>  static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
>  {
>  return require_rvv(s) &&
> -   require_rvf(s) &&
> +   require_scale_rvf(s) &&
> +   (s->sew != MO_8) &&
> vext_check_isa_ill(s) &&
> vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
>  }
> @@ -2359,7 +2362,8 @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
>  static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
>  {
>  return require_rvv(s) &&
> -   require_rvf(s) &&
> +   require_scale_rvf(s) &&
> +   (s->sew != MO_8) &&
> vext_check_isa_ill(s) &&
> vext_check_dd(s, a->rd, a->rs2, a->vm);
>  }
> --
> 2.31.1
>
>



Re: [PATCH] net/tap: Set return code on failure

2022-01-04 Thread Philippe Mathieu-Daudé

Cc'ing Daniel

On 4/1/22 22:18, Patrick Venture wrote:

From: Peter Foley 

Match the other error handling in this function.



Fixes: e7b347d0bf6 ("net: detect errors from probing vnet hdr flag for 
TAP devices")


Reviewed-by: Philippe Mathieu-Daudé 


Signed-off-by: Peter Foley 
---
  net/tap.c | 1 +
  1 file changed, 1 insertion(+)

diff --git a/net/tap.c b/net/tap.c
index f716be3e3f..c5cbeaa7a2 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -900,6 +900,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
  if (i == 0) {
  vnet_hdr = tap_probe_vnet_hdr(fd, errp);
  if (vnet_hdr < 0) {
+ret = -1;
  goto free_fail;
  }
  } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {





Re: [PATCH] Set return code on failure

2022-01-04 Thread Patrick Venture
On Tue, Jan 4, 2022 at 1:18 PM Patrick Venture  wrote:

> From: Peter Foley 
>
> Match the other error handling in this function.
>

Just noticed I didn't fix up the commit title here to match style.  Should
I do a PATCH RESEND or a new patch, or can you add the "net/tap: " to the
title before applying (should it be accepted).


>
> Signed-off-by: Peter Foley 
>
Reviewed-by: Patrick Venture 

> ---
>  net/tap.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/net/tap.c b/net/tap.c
> index f716be3e3f..c5cbeaa7a2 100644
> --- a/net/tap.c
> +++ b/net/tap.c
> @@ -900,6 +900,7 @@ int net_init_tap(const Netdev *netdev, const char
> *name,
>  if (i == 0) {
>  vnet_hdr = tap_probe_vnet_hdr(fd, errp);
>  if (vnet_hdr < 0) {
> +ret = -1;
>  goto free_fail;
>  }
>  } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
>


[PATCH] Set return code on failure

2022-01-04 Thread Patrick Venture
From: Peter Foley 

Match the other error handling in this function.

Signed-off-by: Peter Foley 
---
 net/tap.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/tap.c b/net/tap.c
index f716be3e3f..c5cbeaa7a2 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -900,6 +900,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
 if (i == 0) {
 vnet_hdr = tap_probe_vnet_hdr(fd, errp);
 if (vnet_hdr < 0) {
+ret = -1;
 goto free_fail;
 }
 } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
-- 
2.34.1.448.ga2b2bfdf31-goog




[PATCH v2 1/2] linux-user/ppc: deliver SIGTRAP on POWERPC_EXCP_TRAP

2022-01-04 Thread matheus . ferst
From: Matheus Ferst 

Handle POWERPC_EXCP_TRAP in cpu_loop to deliver SIGTRAP on tw[i]/td[i].
The si_code comes from do_program_check in the kernel source file
arch/powerpc/kernel/traps.c

Signed-off-by: Matheus Ferst 
---
 linux-user/ppc/cpu_loop.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index 46e6ffd6d3..6c99feb19b 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -188,7 +188,8 @@ void cpu_loop(CPUPPCState *env)
 }
 break;
 case POWERPC_EXCP_TRAP:
-cpu_abort(cs, "Tried to call a TRAP\n");
+si_signo = TARGET_SIGTRAP;
+si_code = TARGET_TRAP_BRKPT;
 break;
 default:
 /* Should not happen ! */
-- 
2.25.1




[PATCH v2 2/2] tests/tcg/ppc64le: change signal_save_restore_xer to use SIGTRAP

2022-01-04 Thread matheus . ferst
From: Matheus Ferst 

Now that linux-user delivers the signal on tw, we can change
signal_save_restore_xer to use SIGTRAP instead of SIGILL.

Suggested-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: Matheus Ferst 
---
 tests/tcg/ppc64le/signal_save_restore_xer.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/tcg/ppc64le/signal_save_restore_xer.c 
b/tests/tcg/ppc64le/signal_save_restore_xer.c
index e4f8a07dd7..9227f4f455 100644
--- a/tests/tcg/ppc64le/signal_save_restore_xer.c
+++ b/tests/tcg/ppc64le/signal_save_restore_xer.c
@@ -11,7 +11,7 @@
 
 uint64_t saved;
 
-void sigill_handler(int sig, siginfo_t *si, void *ucontext)
+void sigtrap_handler(int sig, siginfo_t *si, void *ucontext)
 {
 ucontext_t *uc = ucontext;
 uc->uc_mcontext.regs->nip += 4;
@@ -23,14 +23,14 @@ int main(void)
 {
 uint64_t initial = XER_CA | XER_CA32, restored;
 struct sigaction sa = {
-.sa_sigaction = sigill_handler,
+.sa_sigaction = sigtrap_handler,
 .sa_flags = SA_SIGINFO
 };
 
-sigaction(SIGILL, &sa, NULL);
+sigaction(SIGTRAP, &sa, NULL);
 
 asm("mtspr 1, %1\n\t"
-".long 0x0\n\t"
+"trap\n\t"
 "mfspr %0, 1\n\t"
 : "=r" (restored)
 : "r" (initial));
-- 
2.25.1




[PATCH v2 0/2] linux-user/ppc: Deliver SIGTRAP on tw[i]/td[i]

2022-01-04 Thread matheus . ferst
From: Matheus Ferst 

In the review of 66c6b40aba1, Richard Henderson suggested[1] using
"trap" instead of ".long 0x0" to generate the signal to test XER
save/restore behavior. However, linux-user aborts when a trap
exception is raised, so we kept the patch with SIGILL.

This patch series is a follow-up to remove the cpu_abort call, deliver
SIGTRAP instead (using TRAP_BRKPT as si_code), and apply the suggestion
to the signal_save_restore_xer test.

This change removes the "qemu: fatal: Tried to call a TRAP" reported in
issue #588[2], but we still have the "Unknown privilege violation (03)"
error.

I had some problems building with
--static, so I couldn't test if it solves the problem.

Based-on: https://lists.gnu.org/archive/html/qemu-devel/2021-12/msg03454.html

[1] https://lists.gnu.org/archive/html/qemu-ppc/2021-10/msg00143.html

v2:
 - Based-on rth's patch to use force_sig_fault and avoid merge conflicts

Matheus Ferst (2):
  linux-user/ppc: deliver SIGTRAP on POWERPC_EXCP_TRAP
  tests/tcg/ppc64le: change signal_save_restore_xer to use SIGTRAP

 linux-user/ppc/cpu_loop.c   | 3 ++-
 tests/tcg/ppc64le/signal_save_restore_xer.c | 8 
 2 files changed, 6 insertions(+), 5 deletions(-)

-- 
2.25.1




Re: [PATCH v2 1/5] RISC-V: larger and more consistent register set for 'info registers'

2022-01-04 Thread Richard Henderson

On 1/4/22 7:51 AM, Konrad Schwarz wrote:

  static const int dump_csrs[] = {
+
+#  if 0
+CSR_USTATUS,
+CSR_UIE,
+CSR_UTVEC,


Adding huge sections of #if 0 code is not acceptable.


r~



Re: [PATCH 6/9] target/ppc: powerpc_excp: Preserve MSR_LE bit

2022-01-04 Thread Fabiano Rosas
Fabiano Rosas  writes:

> We currently clear MSR_LE when copying bits from env->msr to
> new_msr. However, for CPUs that do not have LPCR_ILE we always set
> new_msr[LE] according to env->msr[LE]. And for CPUs that do have ILE
> support we need to check LPCR/HID0 anyway, so there's no need to clear
> the bit when copying.
>
> Signed-off-by: Fabiano Rosas 
> ---
>  target/ppc/excp_helper.c | 14 +-
>  1 file changed, 5 insertions(+), 9 deletions(-)
>
> diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
> index 5d31940426..e56ddbe5d5 100644
> --- a/target/ppc/excp_helper.c
> +++ b/target/ppc/excp_helper.c
> @@ -348,10 +348,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> excp)
>  }
>  
>  /*
> - * new interrupt handler msr preserves existing HV and ME unless
> - * explicitly overriden
> + * new interrupt handler msr preserves existing HV, ME and LE
> + * unless explicitly overriden.
>   */
> -new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
> +new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB | MSR_LE);
>  
>  /* target registers */
>  srr0 = SPR_SRR0;
> @@ -763,13 +763,9 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> excp)
>  if (excp_model >= POWERPC_EXCP_970) {
>  if (ppc_interrupts_little_endian(cpu, !!(new_msr & MSR_HVB))) {
>  new_msr |= (target_ulong)1 << MSR_LE;
> +} else {
> +new_msr &= ~((target_ulong)1 << MSR_LE);
>  }
> -} else if (msr_ile) {
> -new_msr |= (target_ulong)1 << MSR_LE;
> -}
> -#else
> -if (msr_ile) {
> -new_msr |= (target_ulong)1 << MSR_LE;
>  }
>  #endif

This patch is incorrect, don't bother with it. I misread the msr_ile
macro as msr_le. I'll think of an alternative.



Re: [PATCH] tests/docker: Add gentoo-loongarch64-cross image and run cross builds in GitLab

2022-01-04 Thread Richard Henderson

On 1/4/22 10:31 AM, Alex Bennée wrote:

+docker-image-gentoo-loongarch64-cross: 
$(DOCKER_FILES_DIR)/gentoo-loongarch64-cross.docker
+   $(if $(NOCACHE),
\
+   $(call quiet-command,   
\
+   $(DOCKER_SCRIPT) build -t qemu/gentoo-loongarch64-cross -f 
$<\
+   $(if $V,,--quiet) --no-cache
\
+   --registry $(DOCKER_REGISTRY) --extra-files 
\
+   
$(DOCKER_FILES_DIR)/gentoo-loongarch64-cross.docker.d/build-toolchain.sh, \
+   "BUILD", "gentoo-loongarch64-cross"),   
\
+   $(call quiet-command,   
\
+   $(DOCKER_SCRIPT) fetch $(if $V,,--quiet)
\
+   qemu/gentoo-loongarch64-cross 
$(DOCKER_REGISTRY),   \
+   "FETCH", "gentoo-loongarch64-cross")
\
+   $(call quiet-command,   
\
+   $(DOCKER_SCRIPT) update $(if $V,,--quiet)   
\
+   qemu/gentoo-loongarch64-cross 
--add-current-user,   \
+   "PREPARE", "gentoo-loongarch64-cross"))
+
+


Can this not use debian-toolchain-run (possibly renamed) like the
microblaze and nios2 toolchains?


At present there are too many "debian" prefixes in the macro.
It could be reorganized, but perhaps not trivially.


r~



Re: [PATCH] common-user: Fix tail calls to safe_syscall_set_errno_tail

2022-01-04 Thread Laurent Vivier

Le 04/01/2022 à 20:04, Richard Henderson a écrit :

For the ABIs in which the syscall return register is not
also the first function argument register, move the errno
value into the correct place.

Fixes: a3310c0397e2
Reported-by: Laurent Vivier 
Signed-off-by: Richard Henderson 
---
  common-user/host/i386/safe-syscall.inc.S   | 1 +
  common-user/host/mips/safe-syscall.inc.S   | 1 +
  common-user/host/x86_64/safe-syscall.inc.S | 1 +
  3 files changed, 3 insertions(+)



Tested-by: Laurent Vivier 




Re: [PATCH 0/2] tests/tcg: Fix float_{convs,madds}

2022-01-04 Thread Alex Bennée


Richard Henderson  writes:

> We didn't read the fp flags early enough, so we got whatever
> came out of the guest printf.  With careful review of the
> hexagon output, we would have seen this long ago.

Queued to testing/next, thanks.

-- 
Alex Bennée



Re: [PATCH v2] linux-user: don't adjust base of found hole

2022-01-04 Thread Richard Henderson

On 1/4/22 3:32 AM, Alex Bennée wrote:

The pgb_find_hole function goes to the trouble of taking account of
both mmap_min_addr and any offset we've applied to decide the starting
address of a potential hole. This is especially important for
emulating 32bit ARM in a 32bit build as we have applied the offset to
ensure there will be space to map the ARM_COMMPAGE bellow the main
guest map (using wrapped arithmetic).

Signed-off-by: Alex Bennée
Resolves:https://gitlab.com/qemu-project/qemu/-/issues/690

---
v2
   - also make same adjustment to fallback
---
  linux-user/elfload.c | 5 ++---
  1 file changed, 2 insertions(+), 3 deletions(-)


Reviewed-by: Richard Henderson 

r~



Re: [PATCH 0/3] Reorg ppc64 pmu insn counting

2022-01-04 Thread Daniel Henrique Barboza




On 1/4/22 07:32, Alex Bennée wrote:


Daniel Henrique Barboza  writes:


On 1/3/22 12:07, Alex Bennée wrote:

Daniel Henrique Barboza  writes:


On 12/23/21 00:01, Richard Henderson wrote:

In contrast to Daniel's version, the code stays in power8-pmu.c,
but is better organized to not take so much overhead.
Before:
   32.97%  qemu-system-ppc  qemu-system-ppc64   [.] pmc_get_event
   20.22%  qemu-system-ppc  qemu-system-ppc64   [.] helper_insns_inc
4.52%  qemu-system-ppc  qemu-system-ppc64   [.] 
hreg_compute_hflags_value
3.30%  qemu-system-ppc  qemu-system-ppc64   [.] helper_lookup_tb_ptr
2.68%  qemu-system-ppc  qemu-system-ppc64   [.] tcg_gen_code
2.28%  qemu-system-ppc  qemu-system-ppc64   [.] cpu_exec
1.84%  qemu-system-ppc  qemu-system-ppc64   [.] pmu_insn_cnt_enabled
After:
8.42%  qemu-system-ppc  qemu-system-ppc64   [.]
hreg_compute_hflags_value
6.65%  qemu-system-ppc  qemu-system-ppc64   [.] cpu_exec
6.63%  qemu-system-ppc  qemu-system-ppc64   [.] helper_insns_inc



Thanks for looking this up. I had no idea the original C code was that slow.





With that in mind I decided to post a new version of my TCG rework, with less 
repetition and
a bit more concise, to have an alternative that can be used upstream to fix the 
Avocado tests.
Meanwhile I'll see if I can get your reorg working with all EBB tests we need. 
All things
equal - similar performance, all EBB tests passing - I'd rather stay with your 
C code than my
TCG rework since yours doesn't rely on TCG Ops knowledge to maintain
it.

Reading this series did make me wonder if we need a more generic
service
from the TCG for helping with "internal" instrumentation needed for
things like decent PMU emulation. We haven't gone as much for it in ARM
yet but it would be nice to. It would be even nicer if such a facility
could be used by stuff like icount as well so we don't end up doing the
same thing twice.


Back in May 2021 when I first starting working on this code I tried to base 
myself in the
ARM PMU code. In fact, the cycle and insn calculation done in the very first 
version of
this work was based on what ARM does in target/arm/helper.c, cycles_get_count() 
and
instructions_get_count(). The cycle calculation got simplified because our 
PPC64 CPU
has a 1Ghz clock so it's easier to just consider 1ns = 1 cycle.

For instruction count, aside from my 2-3 weeks of spectacular failures trying 
to count
instructions inside translate.c, I also looked into how TCG plugins work and 
tried to do
something similar to what plugin_gen_tb_end() does at the end of the 
translator_loop()
in accel/tcg/translator.c. For some reason I wasn't able to replicate the same 
behavior
that I would have if I used the TCG plugin framework in the
'canonical' way.


plugin_gen_tb_end is probably overkill because we should already know
how many instructions there are in a translated block on account of the
insn_start and insn_end ops that mark them. In fact see gen_tb_end()
which is where icount updates the value used in the decrement at the
start of each block. Assuming no synchronous exceptions occur you could
just increment a counter at the end of the block as no async IRQs will
occur until we have executed all of those instructions.

Of course it's never quite so simple and when running in full icount
mode we have to take into account exceptions that can be triggered by IO
accesses. This involves doing a re-translation to ensures the IO
instruction is always the last we execute.

I'm guessing for PMU counters to be somewhat correct we would want to
ensure updates throughout the block (before each memory op and helper
call). This would hopefully avoid the cost of "full" icount support
which is only single threaded. However this is the opposite to icount's
budget and pre-decrement approach which feels messier than it could be.



What about cycle counting without icount? With icount is a rather simple matter
of making some assumptions about the CPU freq and relying on the shift parameter
to have a somewhat good precision. Without icount the cycle count, at least in
the current implementation in the ppc64 PMU, is erratic.

The problem is that, at least as far as I've read pSeries and powernv code 
(guest
and bare metal IBM Power emulation), the CPU freq is a 1Ghz that we write in
the FDT and do nothing else with it. We do not enforce (or throttle) the CPU 
freq
in the emulation. A quick look into ARM code also seems to do similar 
assumptions:


static uint64_t cycles_get_count(CPUARMState *env)
{
#ifndef CONFIG_USER_ONLY
return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
   ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
#else
return cpu_get_host_ticks();
#endif
}

#ifndef CONFIG_USER_ONLY
static int64_t cycles_ns_per(uint64_t cycles)
{
return (ARM_CPU_FREQ / NANOSECONDS_PER_SECOND) * cycles;
}


$ git grep 'ARM_CPU_FREQ'
target/arm/helper.c:#define ARM_CPU_FREQ 10 /* 

Re: [PATCH] tests/docker: Add gentoo-loongarch64-cross image and run cross builds in GitLab

2022-01-04 Thread Alex Bennée


WANG Xuerui  writes:

> Normally this would be based on qemu/debian10 or qemu/ubuntu2004, but
> after a week-long struggle, I still cannot build stage2 gcc with the
> known-good LoongArch toolchain sources, so I chose the least-resistance
> path with Gentoo as base image. As this image is not expected to be
> re-built by CI, like hexagon, it should not take much maintenance
> effort; also it's expected to be replaced as soon as Debian is
> available.
>
> As the LoongArch *target* has not been merged yet, a check-tcg job is
> not added at the moment, but cross builds with the TCG *host* port are
> already possible, and added to CI matrix.
>
> Due to constant flux of the toolchain sources used (especially that of
> glibc), the binaries built with this image may or may not work when
> run on actual hardware, but still useful for ensuring things correctly
> build. This image is expected to be updated every once in a while,
> before everything settles down.
>
> As a reference, the image takes about 25 minutes to rebuild on a
> Threadripper 3990X system with Docker operating on HDD; YMMV but it
> probably wouldn't become significantly shorter, as everything needs to
> be built from source in our case.
>
> (In the original submission along with the rest of LoongArch TCG
> patches, I forgot to make the dependency to the container build job
> optional, thus CI was passing in my own fork but broke upstream. Fixed
> for a 2nd take, and I also took the chance to update base image versions
> and such.)
>
> Signed-off-by: WANG Xuerui 
> ---
>
> (Note to CI maintainers: obviously this image has to be built and pushed
> manually, for everything to keep working. Sorry for the extra work
> early-on, but the community around LoongArch still hope to upstream most
> things during 2022 so eventually we will transition away from this.
> This work is no hurry though, and Happy Holidays everyone!)
>
>  .gitlab-ci.d/container-cross.yml  |  27 +
>  .gitlab-ci.d/crossbuilds.yml  |  25 
>  MAINTAINERS   |   2 +
>  tests/docker/Makefile.include |  21 
>  .../gentoo-loongarch64-cross.docker   |  21 
>  .../build-toolchain.sh| 109 ++
>  6 files changed, 205 insertions(+)
>  create mode 100644 tests/docker/dockerfiles/gentoo-loongarch64-cross.docker
>  create mode 100755 
> tests/docker/dockerfiles/gentoo-loongarch64-cross.docker.d/build-toolchain.sh
>
> diff --git a/.gitlab-ci.d/container-cross.yml 
> b/.gitlab-ci.d/container-cross.yml
> index a3b5b90552..7a8cc556cc 100644
> --- a/.gitlab-ci.d/container-cross.yml
> +++ b/.gitlab-ci.d/container-cross.yml
> @@ -82,6 +82,33 @@ hppa-debian-cross-container:
>variables:
>  NAME: debian-hppa-cross
>  
> +# Similar to hexagon, we don't want to build loongarch64 in the CI either.
> +loongarch64-cross-container:
> +  image: docker:stable
> +  stage: containers
> +  rules:
> +- if: '$CI_PROJECT_NAMESPACE == "qemu-project"'
> +  when: never
> +- when: always
> +  variables:
> +NAME: gentoo-loongarch64-cross
> +GIT_DEPTH: 1
> +  services:
> +- docker:dind
> +  before_script:
> +- export TAG="$CI_REGISTRY_IMAGE/qemu/$NAME:latest"
> +- export COMMON_TAG="$CI_REGISTRY/qemu-project/qemu/qemu/$NAME:latest"
> +- docker info
> +- docker login $CI_REGISTRY -u "$CI_REGISTRY_USER" -p 
> "$CI_REGISTRY_PASSWORD"
> +  script:
> +- echo "TAG:$TAG"
> +- echo "COMMON_TAG:$COMMON_TAG"
> +- docker pull $COMMON_TAG
> +- docker tag $COMMON_TAG $TAG
> +- docker push "$TAG"
> +  after_script:
> +- docker logout
> +
>  m68k-debian-cross-container:
>extends: .container_job_template
>stage: containers-layer2
> diff --git a/.gitlab-ci.d/crossbuilds.yml b/.gitlab-ci.d/crossbuilds.yml
> index 17d6cb3e45..ef19ade554 100644
> --- a/.gitlab-ci.d/crossbuilds.yml
> +++ b/.gitlab-ci.d/crossbuilds.yml
> @@ -68,6 +68,31 @@ cross-i386-tci:
>  EXTRA_CONFIGURE_OPTS: 
> --target-list=i386-softmmu,i386-linux-user,aarch64-softmmu,aarch64-linux-user,ppc-softmmu,ppc-linux-user
>  MAKE_CHECK_ARGS: check check-tcg
>  
> +# Upstream LoongArch support is still incomplete, but toolchain is already
> +# usable and partially merged, so the host support is already testable; but
> +# don't let failures block CI.
> +#
> +# Similar to hexagon, the container image is built outside of CI and manually
> +# uploaded at the moment, so make the dependency to container build job
> +# optional.
> +cross-loongarch64-system:
> +  extends: .cross_system_build_job
> +  allow_failure: true
> +  needs:
> +job: loongarch64-cross-container
> +optional: true
> +  variables:
> +IMAGE: gentoo-loongarch64-cross
> +
> +cross-loongarch64-user:
> +  extends: .cross_user_build_job
> +  allow_failure: true
> +  needs:
> +job: loongarch64-cross-container
> +optional: true
> +  variables:
> +IMAGE: gentoo-loongarch64-cross
> +
>  c

Re: [PATCH 01/17] pnv_phb3.c: add unique chassis and slot for pnv_phb3_root_port

2022-01-04 Thread Daniel Henrique Barboza




On 1/3/22 05:24, Cédric Le Goater wrote:

On 12/28/21 20:37, Daniel Henrique Barboza wrote:

When creating a pnv_phb3_root_port using the command line, the first
root port is created successfully, but the second fails with the
following error:

qemu-system-ppc64: -device pnv-phb3-root-port,bus=phb3-root.0,id=pcie.3:
Can't add chassis slot, error -16

This error comes from the realize() function of its parent type,
rp_realize() from TYPE_PCIE_ROOT_PORT. pcie_chassis_add_slot() fails
with -EBUSY if there's an existing PCIESlot that has the same
chassis/slot value, regardless of being in a different bus.

One way to prevent this error is simply set chassis and slot values in
the command line. However, since phb3 root buses only supports a single
root port, we can just get an unique chassis/slot value by checking
which root bus the pnv_phb3_root_port is going to be attached, get the
equivalent phb3 device and use its chip-id and index values, which are
guaranteed to be unique.


I guess parent_realize() will fail if we add 2 root port devices under
the same phb ?


If we change chassis/slot for each new pci root port the QEMU emulation will
allow it. The problem is with skiboot which, at least according to the commit
that introduced powernv9 support [1], does not support multiple PCIE devices in 
the
same PHB:


No default device layout is provided and PCI devices can be added on
any of the available PCIe Root Port (pcie.0 .. 2 of a Power9 chip)
with address 0x0 as the firwware (skiboot) only accepts a single
device per root port.


That said, I'm taking this information at face value. Perhaps this is a test
worth doing to at least document this restriction more explicitly in the
docs.


[1] https://github.com/qemu/qemu/commit/4f9924c4d4cf9c039e247c5cdbbf71bce4e573c3


Thanks,

Daniel



Thanks,

C.




Signed-off-by: Daniel Henrique Barboza 
---
  hw/pci-host/pnv_phb3.c | 16 
  1 file changed, 16 insertions(+)

diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c
index 4e2d680d44..130d392b3e 100644
--- a/hw/pci-host/pnv_phb3.c
+++ b/hw/pci-host/pnv_phb3.c
@@ -1156,8 +1156,24 @@ static const TypeInfo pnv_phb3_root_bus_info = {
  static void pnv_phb3_root_port_realize(DeviceState *dev, Error **errp)
  {
  PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev);
+    PCIDevice *pci = PCI_DEVICE(dev);
+    PCIBus *bus = pci_get_bus(pci);
+    PnvPHB3 *phb = NULL;
  Error *local_err = NULL;
+    phb = (PnvPHB3 *) object_dynamic_cast(OBJECT(bus->qbus.parent),
+  TYPE_PNV_PHB3);
+
+    if (!phb) {
+    error_setg(errp,
+"pnv_phb3_root_port devices must be connected to pnv-phb3 buses");
+    return;
+    }
+
+    /* Set unique chassis/slot values for the root port */
+    qdev_prop_set_uint8(&pci->qdev, "chassis", phb->chip_id);
+    qdev_prop_set_uint16(&pci->qdev, "slot", phb->phb_id);
+
  rpc->parent_realize(dev, &local_err);
  if (local_err) {
  error_propagate(errp, local_err);







  1   2   3   >