Re: [PATCH v2 5/6] migration: Modified 'migrate-incoming' QAPI and HMP side changes on the destination interface.

2023-02-08 Thread Het Gala



On 09/02/23 1:49 am, Eric Blake wrote:

On Wed, Feb 08, 2023 at 09:35:59AM +, Het Gala wrote:

'migrate-incoming' QAPI design have been modified into well-defined
MigrateChannel struct to prevent multiple encoding of uri strings on
the destination side.'uri' parameter is kept for backward compatibility.

Suggested-by: Daniel P. Berrange 
Suggested-by: Manish Mishra 
Suggested-by: Aravind Retnakaran 
Signed-off-by: Het Gala 
---
  migration/migration-hmp-cmds.c |  8 +++-
  migration/migration.c  |  3 ++-
  qapi/migration.json| 22 --
  softmmu/vl.c   |  2 +-
  4 files changed, 30 insertions(+), 5 deletions(-)
+++ b/qapi/migration.json
@@ -1623,7 +1623,11 @@
  # with -incoming defer
  #
  # @uri: The Uniform Resource Identifier identifying the source or
-#   address to listen on
+#   the address to listen on
+#
+# @channel: Struct containing migration channel type, along with
+#   all the details of the destination interface required
+#   for the address to listen on for migration stream.

Missing a '(since 8.0)' tag.

Ack.

  #
  # Returns: nothing on success
  #
@@ -1640,14 +1644,28 @@
  #
  # 3. The uri format is the same as for -incoming
  #
+# 4. The 'uri' and 'channel' arguments are mutually exclusive but, atleast
+#one of the two arguments should be present.

Grammar:

The 'uri' and 'channel' arguments are mutually exclusive; exactly one
of the two should be present.


Ack.

Regards,
Het Gala.



Re: [PATCH v2 2/4] hw/gpio: add PCA9538 8-bit GPIO expander

2023-02-08 Thread Philippe Mathieu-Daudé

On 8/2/23 23:43, Titus Rwantare wrote:

   The 8-bit expander has different register offsets than the 16-bit one,
   making them incompatible.


Following extract/deposit API suggestion on previous patch, an
alternatively is to use PCAGPIOClass::input_port/output_port/...
offset fields.


Reviewed-by: Hao Wu 
Signed-off-by: Titus Rwantare 
---
  hw/gpio/pca_i2c_gpio.c | 94 ++
  include/hw/gpio/pca_i2c_gpio.h |  7 +++
  2 files changed, 101 insertions(+)




diff --git a/include/hw/gpio/pca_i2c_gpio.h b/include/hw/gpio/pca_i2c_gpio.h
index 99322959e1..3ab7d19a97 100644
--- a/include/hw/gpio/pca_i2c_gpio.h
+++ b/include/hw/gpio/pca_i2c_gpio.h
@@ -19,6 +19,7 @@
  
  #define PCA_I2C_MAX_PINS 16

  #define PCA6416_NUM_PINS 16
+#define PCA9538_NUM_PINS 8
  
  typedef struct PCAGPIOClass {

  I2CSlaveClass parent;
@@ -62,8 +63,14 @@ OBJECT_DECLARE_TYPE(PCAGPIOState, PCAGPIOClass, PCA_I2C_GPIO)
  #define PCA6416_CONFIGURATION_PORT_0 0x06 /* read/write */
  #define PCA6416_CONFIGURATION_PORT_1 0x07 /* read/write */
  
+#define PCA9538_INPUT_PORT   0x00 /* read */

+#define PCA9538_OUTPUT_PORT  0x01 /* read/write */
+#define PCA9538_POLARITY_INVERSION_PORT  0x02 /* read/write */
+#define PCA9538_CONFIGURATION_PORT   0x03 /* read/write */


Something like this maybe:

static uint8_t pca_i2c_gpio_recv(I2CSlave *i2c)
{
PCAGPIOState *ps = PCA_I2C_GPIO(i2c);
PCAGPIOClass *pc = PCA_I2C_GPIO_GET_CLASS(i2c);
unsigned shift = (ps->command) & pc->shift ? 8 : 0;
uint8_t data;

if (ps->command == pc->input_port) {
data = extract16(ps->curr_input, shift, 8);
} else if (ps->command == pc->output_port) {
data = extract16(ps->curr_input, shift, 8);
} else if (...) {

Maybe I'm over-engineering :)



Re: [PATCH v2 2/6] migration: Updated QAPI format for 'migrate' qemu monitor command

2023-02-08 Thread Het Gala



On 09/02/23 1:47 am, Eric Blake wrote:

On Wed, Feb 08, 2023 at 09:35:56AM +, Het Gala wrote:

Existing 'migrate' QAPI design enforces transport mechanism, ip address
of destination interface and corresponding port number in the form
of a unified string 'uri' parameter for initiating a migration stream.
This scheme has a significant flaw in it - double encoding of existing
URIs to extract migration info.

+##
+# @MigrateTransport:
+#
+# The supported communication transport mechanisms for migration
+#
+# @socket: Supported communication type between two devices for migration.
+#  Socket is able to cover all of 'tcp', 'unix', 'vsock' and
+#  'fd' already
+#
+# @exec: Supported communication type to redirect migration stream into file.
+#
+# @rdma: Supported communication type to redirect rdma type migration stream.
+#
+# Since 8.0
+##
+{ 'enum': 'MigrateTransport',
+  'data': ['socket', 'exec', 'rdma'] }
+
+##
+# @MigrateSocketAddr:
+#
+# To support different type of socket.
+#
+# @socket-type: Different type of socket connections.
+#
+# Since 8.0
+##
+{ 'struct': 'MigrateSocketAddr',
+  'data': {'socket-type': 'SocketAddress' } }

Here, you use 'socket-type',...
Yes, I wanted a suggestion here actually. Will 'data' instead of 
'socket-type' be the right fit ? It will also be consistent with exec 
and rdma if changed to 'data'.

+
+##
+# @MigrateExecAddr:
+ #
+ # Since 8.0
+ ##
+{ 'struct': 'MigrateExecAddr',
+   'data' : {'data': ['str'] } }

Inconsistent on whether you have a space before :.  Most of our qapi
files prefer the layout:

'key': 'value'

that is, no space before, one space after.  It doesn't affect
correctness, but a consistent visual style is worth striving for.
Okay, thanks Eric for pointing it out. Will make sure I follow this 
going forward.

+
+##
+# @MigrateRdmaAddr:
+#
+# Since 8.0
+##
+{ 'struct': 'MigrateRdmaAddr',
+   'data' : {'data': 'InetSocketAddress' } }

...while these branches supply everything else under 'data'. Also,
while you documented @socket-type above, you did not document @data in
either of these two types.  [1]
Ack. In that case, I feel it would be better if I change from 
'socket-type' to 'data' to keep consistency among the QAPI.

+
+##
+# @MigrateAddress:
+#
+# The options available for communication transport mechanisms for migration
+#
+# Since 8.0
+##
+{ 'union' : 'MigrateAddress',
+  'base' : { 'transport' : 'MigrateTransport'},
+  'discriminator' : 'transport',
+  'data' : {
+'socket' : 'MigrateSocketAddr',
+'exec' : 'MigrateExecAddr',
+'rdma': 'MigrateRdmaAddr' } }

Another example of inconsistent spacing around :.

I'm guessing the reason you didn't go with 'socket': 'SocketAddress'
is that SocketAddress is itself a discriminated union, and Markus does
not yet have the QAPI generator wired up to support one union as a
branch of another larger union?  It leads to extra nesting on the wire
[2]
Yes Eric. I did search if it is possible for a union inside a branch of 
union. That's the reason, I had to choose this path for 'socket' and 
'rdma', and to keep consistency, I did the same with 'exec' too.

+
+##
+# @MigrateChannelType:
+#
+# The supported options for migration channel type requests
+#
+# @main: Support request for main outbound migration control channel
+#
+# Since 8.0
+##
+{ 'enum': 'MigrateChannelType',
+  'data': [ 'main'] }

A different spacing issue: most arrays in QAPI either have spaces at
both ends (as in [ 'string' ]) or neither (as in ['string']).  Here,
it looks lopsided with space at the front but not the back.
Ack Eric. Thanks for pointing it out. Will take care about this small 
issues from next time.

+
+##
+# @MigrateChannel:
+#
+# Information regarding migration Channel-type for transferring packets,
+# source and corresponding destination interface for socket connection
+# and number of multifd channels over the interface.
+#
+# @channeltype: Name of Channel type for transfering packet information
+#
+# @addr: SocketAddress of destination interface

More than just a SocketAddress, per the discriminated union type defined above.

Yes, infact one of the branches MigrateChannel. Ack.

+#
+# Since 8.0
+##
+{ 'struct': 'MigrateChannel',
+  'data' : {
+   'channeltype' : 'MigrateChannelType',
+   'addr' : 'MigrateAddress' } }
+
  ##
  # @migrate:
  #
  # Migrates the current running guest to another Virtual Machine.
  #
  # @uri: the Uniform Resource Identifier of the destination VM
+#   for migration thread
+#
+# @channel: Struct containing migration channel type, along with all
+#   the details of destination interface required for initiating
+#   a migration stream.
  #
  # @blk: do block migration (full disk copy)
  #
@@ -1479,15 +1575,46 @@
  # 3. The user Monitor's "detach" argument is invalid in QMP and should not
  #be used
  #
+# 4. The uri argument should have the Uniform Resource Identifier of default
+#destination VM. This connection will be bound to 

Re: [PULL 03/30] migration: Split save_live_pending() into state_pending_*

2023-02-08 Thread Avihai Horon



On 07/02/2023 2:56, Juan Quintela wrote:

External email: Use caution opening links or attachments


We split the function into to:

- state_pending_estimate: We estimate the remaining state size without
   stopping the machine.

- state pending_exact: We calculate the exact amount of remaining
   state.

The only "device" that implements different functions for _estimate()
and _exact() is ram.

Signed-off-by: Juan Quintela 
Reviewed-by: Dr. David Alan Gilbert 
---
  docs/devel/migration.rst   | 18 ---
  docs/devel/vfio-migration.rst  |  4 ++--
  include/migration/register.h   | 19 +--
  migration/savevm.h | 12 ++
  hw/s390x/s390-stattrib.c   | 11 +
  hw/vfio/migration.c| 21 +
  migration/block-dirty-bitmap.c | 15 ++--
  migration/block.c  | 13 ++-
  migration/migration.c  | 20 +++-
  migration/ram.c| 35 
  migration/savevm.c | 42 +++---
  hw/vfio/trace-events   |  2 +-
  migration/trace-events |  7 +++---
  13 files changed, 143 insertions(+), 76 deletions(-)


[snip]


diff --git a/migration/savevm.c b/migration/savevm.c
index 5e4bccb966..7f9f770c1e 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1472,10 +1472,10 @@ flush:
   * the result is split into the amount for units that can and
   * for units that can't do postcopy.
   */
-void qemu_savevm_state_pending(uint64_t threshold_size,
-   uint64_t *res_precopy_only,
-   uint64_t *res_compatible,
-   uint64_t *res_postcopy_only)
+void qemu_savevm_state_pending_estimate(uint64_t threshold_size,
+uint64_t *res_precopy_only,
+uint64_t *res_compatible,
+uint64_t *res_postcopy_only)
  {
  SaveStateEntry *se;

@@ -1485,7 +1485,7 @@ void qemu_savevm_state_pending(uint64_t threshold_size,


  QTAILQ_FOREACH(se, _state.handlers, entry) {
-if (!se->ops || !se->ops->save_live_pending) {
+if (!se->ops || !se->ops->state_pending_exact) {
  continue;
  }
  if (se->ops->is_active) {
@@ -1493,9 +1493,35 @@ void qemu_savevm_state_pending(uint64_t threshold_size,
  continue;
  }
  }
-se->ops->save_live_pending(se->opaque, threshold_size,
-   res_precopy_only, res_compatible,
-   res_postcopy_only);
+se->ops->state_pending_exact(se->opaque, threshold_size,
+ res_precopy_only, res_compatible,
+ res_postcopy_only);
+}
+}
+
+void qemu_savevm_state_pending_exact(uint64_t threshold_size,
+ uint64_t *res_precopy_only,
+ uint64_t *res_compatible,
+ uint64_t *res_postcopy_only)
+{
+SaveStateEntry *se;
+
+*res_precopy_only = 0;
+*res_compatible = 0;
+*res_postcopy_only = 0;
+
+QTAILQ_FOREACH(se, _state.handlers, entry) {
+if (!se->ops || !se->ops->state_pending_estimate) {
+continue;
+}
+if (se->ops->is_active) {
+if (!se->ops->is_active(se->opaque)) {
+continue;
+}
+}
+se->ops->state_pending_estimate(se->opaque, threshold_size,
+res_precopy_only, res_compatible,
+res_postcopy_only);
  }
  }


Hi Juan,

I only noticed it now while rebasing my series on top of yours.

I think the exact and estimate callbacks got mixed up here: we call 
.state_pending_estimate() in qemu_savevm_state_pending_exact() and 
.state_pending_exact() in qemu_savevm_state_pending_estimate().

Also need to switch the !se->ops->state_pending_exact/estimate checks.

Thanks.




Re: [PATCH v2 1/4] hw/gpio: add PCA6416 i2c GPIO expander

2023-02-08 Thread Philippe Mathieu-Daudé

Hi Titus,

On 8/2/23 23:43, Titus Rwantare wrote:

The PCA6416 is an i2c device with 16 GPIOs.

Reviewed-by: Hao Wu 
Signed-off-by: Titus Rwantare 
---
  hw/arm/Kconfig  |   1 +
  hw/gpio/Kconfig |   4 +
  hw/gpio/meson.build |   1 +
  hw/gpio/pca_i2c_gpio.c  | 388 
  hw/gpio/trace-events|   5 +
  include/hw/gpio/pca_i2c_gpio.h  |  69 ++
  tests/lcitool/libvirt-ci|   2 +-
  tests/qtest/meson.build |   1 +
  tests/qtest/pca_i2c_gpio-test.c | 169 ++
  9 files changed, 639 insertions(+), 1 deletion(-)
  create mode 100644 hw/gpio/pca_i2c_gpio.c
  create mode 100644 include/hw/gpio/pca_i2c_gpio.h
  create mode 100644 tests/qtest/pca_i2c_gpio-test.c

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 2d157de9b8..1b533ddd76 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -418,6 +418,7 @@ config NPCM7XX
  select SSI
  select UNIMP
  select PCA954X
+select PCA_I2C_GPIO


Shouldn't this be s/select/imply/? See docs/devel/kconfig.rst:

  Boards specify their constituent devices using ``imply`` and
  ``select``  directives.  A device should be listed under ``select``
  if the board cannot be started at all without it.  It should be
  listed under ``imply`` if (depending on the QEMU command line) the
  board may or may not be started without it.  Boards also default to
  false; they are  enabled by the ``default-configs/*.mak`` for the
  target they apply to.

Better to split this as another "hw/arm: Allow NPCM7xx machines to use
the PCA6416 i2c GPIO expander" patch.


+/*
+ * compare new_output to curr_output and update irq to match new_output
+ *
+ * The Input port registers (registers 0 and 1) reflect the incoming logic
+ * levels of the pins, regardless of whether the pin is defined as an input or
+ * an output by the Configuration register.
+ */
+static void pca_i2c_update_irqs(PCAGPIOState *ps)
+{
+PCAGPIOClass *pc = PCA_I2C_GPIO_GET_CLASS(ps);
+uint16_t out_diff = ps->new_output ^ ps->curr_output;
+uint16_t in_diff = ps->new_input ^ ps->curr_input;
+uint16_t mask, pin_i;
+
+if (in_diff || out_diff) {
+for (int i = 0; i < pc->num_pins; i++) {
+mask = BIT(i);
+/* pin must be configured as an output to be set here */
+if (out_diff & ~ps->config & mask) {
+pin_i = mask & ps->new_output;
+qemu_set_irq(ps->output[i], pin_i > 0);
+ps->curr_output &= ~mask;
+ps->curr_output |= pin_i;
+}
+
+if (in_diff & mask) {
+ps->curr_input &= ~mask;
+ps->curr_input |= mask & ps->new_input;
+}
+}
+/* make diff = 0 */
+ps->new_input = ps->curr_input;
+}
+}



+static void pca_i2c_enter_reset(Object *obj, ResetType type)
+{
+PCAGPIOState *ps = PCA_I2C_GPIO(obj);
+PCAGPIOClass *pc = PCA_I2C_GPIO_GET_CLASS(obj);
+
+for (int i = 0; i < pc->num_pins; i++) {
+qemu_irq_lower(ps->output[i]);
+}
+
+ps->polarity_inv = 0;
+ps->config = 0;
+ps->curr_input = 0;
+ps->curr_output = 0;
+ps->new_input = 0;
+ps->new_output = 0;
+ps->command = 0;
+}
+
+static void pca_i2c_realize(DeviceState *dev, Error **errp)
+{
+PCAGPIOState *ps = PCA_I2C_GPIO(dev);
+pca_i2c_update_irqs(ps);
+}


pca_i2c_realize() occurs once before the reset() handler, so it
seems redundant. We can probably remove it.


+static void pca_i2c_gpio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+dc->realize = pca_i2c_realize;
+dc->vmsd = _pca_i2c_gpio;
+rc->phases.enter = pca_i2c_enter_reset;
+k->event = pca_i2c_event;
+}



+static const TypeInfo pca_gpio_types[] = {
+{
+.name = TYPE_PCA_I2C_GPIO,
+.parent = TYPE_I2C_SLAVE,
+.instance_size = sizeof(PCAGPIOState),
+.instance_init = pca_i2c_gpio_init,
+.class_size = sizeof(PCAGPIOClass),
+.class_init = pca_i2c_gpio_class_init,
+.abstract = true,


Per CODING_STYLE this should be indented +4 spaces.


+},
+{
+.name = TYPE_PCA6416_GPIO,
+.parent = TYPE_PCA_I2C_GPIO,
+.class_init = pca6416_gpio_class_init,
+},
+};




+#define PCA6416_INPUT_PORT_0 0x00 /* read */
+#define PCA6416_INPUT_PORT_1 0x01 /* read */
+#define PCA6416_OUTPUT_PORT_00x02 /* read/write */
+#define PCA6416_OUTPUT_PORT_10x03 /* read/write */
+#define PCA6416_POLARITY_INVERSION_PORT_00x04 /* read/write */
+#define PCA6416_POLARITY_INVERSION_PORT_10x05 /* read/write */
+#define PCA6416_CONFIGURATION_PORT_0 0x06 /* read/write */
+#define PCA6416_CONFIGURATION_PORT_1 0x07 /* read/write */


IIUC the registers are 16-bit but the I2CSlaveClass API 

Re: [PATCH RFC 5/7] Revert "x86: use typedef for SetupData struct"

2023-02-08 Thread Michael S. Tsirkin
On Wed, Feb 08, 2023 at 04:12:51PM -0500, Michael S. Tsirkin wrote:
> This reverts commit eebb38a5633a77f5fa79d6486d5b2fcf8fbe3c07.
> 
> Fixes: eebb38a563 ("x86: use typedef for SetupData struct")
> Signed-off-by: Michael S. Tsirkin 


This one was actually good, I reverted so other reverts are clean.
Jason I would appreciate it if you can rebase this on top
of the revert.


> ---
>  hw/i386/x86.c | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/i386/x86.c b/hw/i386/x86.c
> index 32f37ab7c2..76b12108b4 100644
> --- a/hw/i386/x86.c
> +++ b/hw/i386/x86.c
> @@ -657,12 +657,12 @@ DeviceState *ioapic_init_secondary(GSIState *gsi_state)
>  return dev;
>  }
>  
> -typedef struct SetupData {
> +struct setup_data {
>  uint64_t next;
>  uint32_t type;
>  uint32_t len;
>  uint8_t data[];
> -} __attribute__((packed)) SetupData;
> +} __attribute__((packed));
>  
>  
>  /*
> @@ -803,7 +803,7 @@ void x86_load_linux(X86MachineState *x86ms,
>  FILE *f;
>  char *vmode;
>  MachineState *machine = MACHINE(x86ms);
> -SetupData *setup_data;
> +struct setup_data *setup_data;
>  const char *kernel_filename = machine->kernel_filename;
>  const char *initrd_filename = machine->initrd_filename;
>  const char *dtb_filename = machine->dtb;
> @@ -1086,11 +1086,11 @@ void x86_load_linux(X86MachineState *x86ms,
>  }
>  
>  setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
> -kernel_size = setup_data_offset + sizeof(SetupData) + dtb_size;
> +kernel_size = setup_data_offset + sizeof(struct setup_data) + 
> dtb_size;
>  kernel = g_realloc(kernel, kernel_size);
>  
>  
> -setup_data = (SetupData *)(kernel + setup_data_offset);
> +setup_data = (struct setup_data *)(kernel + setup_data_offset);
>  setup_data->next = cpu_to_le64(first_setup_data);
>  first_setup_data = prot_addr + setup_data_offset;
>  setup_data->type = cpu_to_le32(SETUP_DTB);
> @@ -1101,9 +1101,9 @@ void x86_load_linux(X86MachineState *x86ms,
>  
>  if (!legacy_no_rng_seed) {
>  setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
> -kernel_size = setup_data_offset + sizeof(SetupData) + 
> RNG_SEED_LENGTH;
> +kernel_size = setup_data_offset + sizeof(struct setup_data) + 
> RNG_SEED_LENGTH;
>  kernel = g_realloc(kernel, kernel_size);
> -setup_data = (SetupData *)(kernel + setup_data_offset);
> +setup_data = (struct setup_data *)(kernel + setup_data_offset);
>  setup_data->next = cpu_to_le64(first_setup_data);
>  first_setup_data = prot_addr + setup_data_offset;
>  setup_data->type = cpu_to_le32(SETUP_RNG_SEED);
> -- 
> MST
> 




Re: [PATCH v10 2/9] KVM: Introduce per-page memory attributes

2023-02-08 Thread Isaku Yamahata
On Fri, Dec 02, 2022 at 02:13:40PM +0800,
Chao Peng  wrote:

> +static int kvm_vm_ioctl_set_mem_attributes(struct kvm *kvm,
> +struct kvm_memory_attributes *attrs)
> +{
> + gfn_t start, end;
> + unsigned long i;
> + void *entry;
> + u64 supported_attrs = kvm_supported_mem_attributes(kvm);
> +
> + /* flags is currently not used. */
> + if (attrs->flags)
> + return -EINVAL;
> + if (attrs->attributes & ~supported_attrs)
> + return -EINVAL;
> + if (attrs->size == 0 || attrs->address + attrs->size < attrs->address)
> + return -EINVAL;
> + if (!PAGE_ALIGNED(attrs->address) || !PAGE_ALIGNED(attrs->size))
> + return -EINVAL;
> +
> + start = attrs->address >> PAGE_SHIFT;
> + end = (attrs->address + attrs->size - 1 + PAGE_SIZE) >> PAGE_SHIFT;
> +
> + entry = attrs->attributes ? xa_mk_value(attrs->attributes) : NULL;
> +
> + mutex_lock(>lock);
> + for (i = start; i < end; i++)
> + if (xa_err(xa_store(>mem_attr_array, i, entry,
> + GFP_KERNEL_ACCOUNT)))
> + break;
> + mutex_unlock(>lock);
> +
> + attrs->address = i << PAGE_SHIFT;
> + attrs->size = (end - i) << PAGE_SHIFT;
> +
> + return 0;
> +}
> +#endif /* CONFIG_HAVE_KVM_MEMORY_ATTRIBUTES */
> +

If memslot isn't private, it should return error if private attribute is set.
Something like following check is needed.

+   if (attrs->flags & KVM_MEM_PRIVATE) {
+   /* non-private memory slot doesn't allow KVM_MEM_PRIVATE */
+   for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) {
+   struct kvm_memslot_iter iter;
+   struct kvm_memslots *slots;
+
+   slots = __kvm_memslots(kvm, i);
+   kvm_for_each_memslot_in_gfn_range(, slots, start, 
end) {
+   if (!kvm_slot_can_be_private(iter.slot)) {
+   mutex_unlock(>slots_lock);
+   return -EINVAL;
+   }
+   }
+   }
+   }
+


-- 
Isaku Yamahata 



Re: [PATCH 1/3] hw/gpio: add PCA6414 i2c GPIO expander

2023-02-08 Thread Philippe Mathieu-Daudé

On 8/2/23 23:40, Titus Rwantare wrote:

On Mon, 6 Feb 2023 at 13:38, Philippe Mathieu-Daudé  wrote:


Hi Titus,

On 6/2/23 20:49, Titus Rwantare wrote:

This is a simple i2c device that allows i2c capable devices to have
GPIOs.

Reviewed-by: Hao Wu 
Signed-off-by: Titus Rwantare 
---
   hw/arm/Kconfig  |   1 +
   hw/gpio/meson.build |   1 +
   hw/gpio/pca_i2c_gpio.c  | 362 
   hw/gpio/trace-events|   5 +
   hw/i2c/Kconfig  |   4 +
   include/hw/gpio/pca_i2c_gpio.h  |  72 +++
   tests/qtest/meson.build |   1 +
   tests/qtest/pca_i2c_gpio-test.c | 169 +++
   8 files changed, 615 insertions(+)
   create mode 100644 hw/gpio/pca_i2c_gpio.c
   create mode 100644 include/hw/gpio/pca_i2c_gpio.h
   create mode 100644 tests/qtest/pca_i2c_gpio-test.c



+#define PCA6416_INPUT_PORT_0 0x00 /* read */
+#define PCA6416_INPUT_PORT_1 0x01 /* read */
+#define PCA6416_OUTPUT_PORT_00x02 /* read/write */
+#define PCA6416_OUTPUT_PORT_10x03 /* read/write */
+#define PCA6416_POLARITY_INVERSION_PORT_00x04 /* read/write */
+#define PCA6416_POLARITY_INVERSION_PORT_10x05 /* read/write */
+#define PCA6416_CONFIGURATION_PORT_0 0x06 /* read/write */
+#define PCA6416_CONFIGURATION_PORT_1 0x07 /* read/write */
+
+#define PCA6416_OUTPUT_DEFAULT   0x
+#define PCA6416_CONFIG_DEFAULT   0x
+
+#define PCA_I2C_OUTPUT_DEFAULT   0x
+#define PCA_I2C_CONFIG_DEFAULT   0x


(These register definitions could be kept internal in pca_i2c_gpio.c).


I put these here to use them in the qtests.


Oh right, I missed that.


diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index e97616d327..49f406af6b 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -241,6 +241,7 @@ qos_test_ss.add(
 'ne2000-test.c',
 'tulip-test.c',
 'nvme-test.c',
+  'pca_i2c_gpio-test.c',


Should this be conditional to
config_all_devices.has_key('CONFIG_PCA_I2C_GPIO')?


Is that the guidance for qos tests? All these tests would also need to
be separated out.

This is not clear to me, adding Thomas.



Re: [PULL 00/11] Misc patches for 2022-02-08

2023-02-08 Thread Philippe Mathieu-Daudé

On 9/2/23 06:19, Thomas Huth wrote:

On 08/02/2023 18.19, Paolo Bonzini wrote:
The following changes since commit 
ae2b5d8381a73b27f35f19c988d45c78bb4d5768:


   Merge tag 'pull-include-2023-02-06-v2' of 
https://repo.or.cz/qemu/armbru into staging (2023-02-08 10:40:06 +)


are available in the Git repository at:

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

for you to fetch changes up to e0de04cf9bd7cf03db16f33276679caf1724b75c:

   target/i386: fix ADOX followed by ADCX (2023-02-08 18:16:55 +0100)


* block/iscsi: fix double-free on BUSY or similar statuses
* catch [accel] entry without accelerator
* target/i386: various fixes for BMI and ADX instructions
* make the contents of meson-buildoptions.sh stable


Paolo Bonzini (8):
   build: make meson-buildoptions.sh stable
   remove unnecessary extern "C" blocks
   block/iscsi: fix double-free on BUSY or similar statuses
   vl: catch [accel] entry without accelerator


You missed Philippe's review comment for that patch:

https://lore.kernel.org/qemu-devel/8ec3abf5-f4aa-db40-cb7e-2f5733d93...@linaro.org/


I interpreted "no response" as "the result is the same".



Re: [PATCH v2 0/7] qapi: static typing conversion, pt5c

2023-02-08 Thread Markus Armbruster
John Snow  writes:

> On Wed, Feb 8, 2023 at 11:31 AM Markus Armbruster  wrote:
>>
>> John Snow  writes:
>>
>> > This is part five (c), and focuses on sharing strict types between
>> > parser.py and expr.py.
>> >
>> > gitlab: https://gitlab.com/jsnow/qemu/-/commits/python-qapi-cleanup-pt5c
>> >
>> > Every commit should pass with:
>> >  - `isort -c qapi/`
>> >  - `flake8 qapi/`
>> >  - `pylint --rcfile=qapi/pylintrc qapi/`
>> >  - `mypy --config-file=qapi/mypy.ini qapi/`
>> >
>> > Some notes on this series:
>> >
>> > Patches 2 and 3 are almost entirely superseded by patch 5, but I wasn't
>> > as confident that Markus would like patch 5, so these patches aren't
>> > squashed quite as tightly as they could be -- I recommend peeking ahead
>> > at the cover letters before reviewing the actual patch diffs.
>>
>> Yes, you're taking a somewhat roundabout path there.
>
> The result of trying 10 different things and seeing what was feasible
> through trial and error, and rather less the product of an intentional
> design. In the name of just getting the ball rolling again, I sent it
> out instead of hemming and hawing over perfection. Publish early,
> Publish often! ... is what people doing the publishing say. Apologies
> to the reviewer.

The series was easy enough to review, in good part thanks to your cover
letter.

>> I think I like PATCH 5 well enough.  Do you have a tighter squash in
>> mind?
>
> Not directly. I could essentially just squash them, but that becomes a
> pretty big patch.

Worth a try.

>> > By the end of this series, the only JSON-y types we have left are:
>> >
>> > (A) QAPIExpression,
>> > (B) JSONValue,
>> > (C) _ExprValue.
>> >
>> > The argument I'm making here is that QAPIExpression and JSONValue are
>> > distinct enough to warrant having both types (for now, at least); and
>> > that _ExprValue is specialized enough to also warrant its inclusion.
>> >
>> > (Brutal honesty: my attempts at unifying this even further had even more
>> > hacks and unsatisfying conclusions, and fully unifying these types
>> > should probably wait until we're allowed to rely on some fairly modern
>> > Python versions.)
>>
>> Feels okay to me.
>
> Sorry, best I could do with reasonable effort. I will try to improve
> the situation when we bump the Python version!

Pretty low priority as far as I'm concerned.

mypy is (surprisingly, inexplicably, inexcusably, take your pick) bad at
recursive types.  We've sunk quite a bit of effort into getting the most
out of it around these fundamentally recursive data structures anyway.
I'd like to remind you that my gut feeling was "alright, let's just not
type them then."  You persuaded me to go this far.  No regrets.

The three types you mentioned are indeed distinct.

_ExprValue is the obvious stupid abstract syntax tree for the QAPI
schema language, with str and bool leaves (QAPI doesn't support
floating-point numbers), OrderedDict and list inner nodes.  It is used
for parser output.

Note that the type definition says Dict[str, object].  It's really
OrderedDict.  Plain dict should do for us since 3.6 made it ordered.

QAPIExpression augments _ExprValue, adding a QAPISourceInfo (identifying
the expression's source) and a QAPIDoc (the expressions documentation).
It is used to represent QAPI top-level expressions.  Two observations.

One, having source information only at the top-level is lazy, and leads
to sub-optimal error messages.  I'm not asking for improvement there; we
have bigger fish to fry.

Two, the fact that it wraps around _ExprValue is less than obvious.  The
type doesn't mention _ExprValue.  QAPISchemaParser._add_expr(), the
function we use turn an _ExprValue into a QAPIExpression doesn't mention
it either.  Both work on Mapping[str, object] instead.  Also not a
request for improvement.

JSONValue is an annotated JSON abstract syntax tree.  It's related to
the other two only insofar as JSON is related to the QAPI language.
Unifying plain syntax trees for these separate languages feels like a
dubious proposition to me.  Unifying *annotated* syntax trees feels
worse.




Re: [PATCH] MAINTAINERS: Add some RISC-V reviewers

2023-02-08 Thread Philippe Mathieu-Daudé

On 9/2/23 01:33, Alistair Francis wrote:

From: Alistair Francis 

This patch adds some active RISC-V members as reviewers to the
MAINTAINERS file.

Signed-off-by: Alistair Francis 
---
  MAINTAINERS | 3 +++
  1 file changed, 3 insertions(+)


Reviewed-by: Philippe Mathieu-Daudé 





Re: [PATCH v2 0/3] Vhost-user: replace _SLAVE_ with _BACKEND_

2023-02-08 Thread Philippe Mathieu-Daudé

On 8/2/23 21:32, Maxime Coquelin wrote:


Maxime Coquelin (3):
   docs: vhost-user: replace _SLAVE_ with _BACKEND_
   libvhost-user: Adopt new backend naming
   vhost-user: Adopt new backend naming

  docs/interop/vhost-user.rst   | 40 +++
  hw/virtio/vhost-user.c| 30 -
  hw/virtio/virtio-qmp.c| 12 +++
  subprojects/libvhost-user/libvhost-user.c | 20 ++--
  subprojects/libvhost-user/libvhost-user.h | 20 ++--
  5 files changed, 61 insertions(+), 61 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 





Re: [PATCH v2 5/7] qapi/parser: [RFC] add QAPIExpression

2023-02-08 Thread Markus Armbruster
John Snow  writes:

> The idea here is to combine 'TopLevelExpr' and 'ParsedExpression' into
> one type that accomplishes the purposes of both types;
>
> 1. TopLevelExpr is meant to represent a JSON Object, but only those that
> represent what qapi-schema calls a TOP-LEVEL-EXPR, i.e. definitions,
> pragmas, and includes.
>
> 2. ParsedExpression is meant to represent a container around the above
> type, alongside QAPI-specific metadata -- the QAPISourceInfo and QAPIDoc
> objects.
>
> We can actually just roll these up into one type: A python mapping that
> has the metadata embedded directly inside of it.
>
> NB: This necessitates a change of typing for check_if() and
> check_keys(), because mypy does not believe UserDict[str, object] ⊆
> Dict[str, object]. It will, however, accept Mapping or
> MutableMapping. In this case, the immutable form is preferred as an
> input parameter because we don't actually mutate the input.
>
> Without this change, we will observe:
> qapi/expr.py:631: error: Argument 1 to "check_keys" has incompatible
> type "QAPIExpression"; expected "Dict[str, object]"
>
> Signed-off-by: John Snow 

[...]

> diff --git a/scripts/qapi/parser.py b/scripts/qapi/parser.py
> index f897dffbfd4..88f6fdfa67b 100644
> --- a/scripts/qapi/parser.py
> +++ b/scripts/qapi/parser.py

[...]

> @@ -38,21 +38,32 @@
>  from .schema import QAPISchemaFeature, QAPISchemaMember
>  
>  
> -#: Represents a single Top Level QAPI schema expression.
> -TopLevelExpr = Dict[str, object]
> -
>  # Return value alias for get_expr().
>  _ExprValue = Union[List[object], Dict[str, object], str, bool]
>  
> -# FIXME: Consolidate and centralize definitions for TopLevelExpr,
> -# _ExprValue, _JSONValue, and _JSONObject; currently scattered across
> -# several modules.
>  
> +# FIXME: Consolidate and centralize definitions for _ExprValue,
> +# JSONValue, and _JSONObject; currently scattered across several
> +# modules.
>  
> -class ParsedExpression(NamedTuple):
> -expr: TopLevelExpr
> -info: QAPISourceInfo
> -doc: Optional['QAPIDoc']
> +
> +# 3.6 workaround: can be removed when Python 3.7+ is our required version.
> +if TYPE_CHECKING:
> +_UserDict = UserDict[str, object]
> +else:
> +_UserDict = UserDict
> +
> +
> +class QAPIExpression(_UserDict):
> +def __init__(
> +self,
> +initialdata: Mapping[str, object],
> +info: QAPISourceInfo,
> +doc: Optional['QAPIDoc'] = None,
> +):

Style nitpick:

   doc: Optional['QAPIDoc'] = None):

> +super().__init__(initialdata)
> +self.info = info
> +self.doc: Optional['QAPIDoc'] = doc
>  
>  
>  class QAPIParseError(QAPISourceError):

[...]




Re: [PATCH RFC 0/7] revert RNG seed mess

2023-02-08 Thread Dov Murik



On 09/02/2023 8:03, Dov Murik wrote:
> Hi Michael,
> 
> On 08/02/2023 23:12, Michael S. Tsirkin wrote:
>> All attempts to fix up passing RNG seed via setup_data entry failed.
>> Let's just rip out all of it.  We'll start over.
>>
>>
>> Warning: all I did was git revert the relevant patches and resolve the
>> (trivial) conflicts. Not even compiled - it's almost midnight here.
>>
>> Jason this is the kind of approach I'd like to see, not yet another
>> pointer math rich patch I need to spend time reviewing. Just get us back
>> to where we started. We can redo "x86: use typedef for SetupData struct"
>> later if we want, it's benign.
>>
>> Could you do something like this pls?
>> Or test and ack if this patchset happens to work by luck.
>>
>> Michael S. Tsirkin (7):
>>   Revert "x86: don't let decompressed kernel image clobber setup_data"
>>   Revert "x86: do not re-randomize RNG seed on snapshot load"
>>   Revert "x86: re-initialize RNG seed when selecting kernel"
>>   Revert "x86: reinitialize RNG seed on system reboot"
>>   Revert "x86: use typedef for SetupData struct"
>>   Revert "x86: return modified setup_data only if read as memory, not as
>> file"
>>   Revert "hw/i386: pass RNG seed via setup_data entry"
>>
>>  include/hw/i386/microvm.h |   5 +-
>>  include/hw/i386/pc.h  |   3 -
>>  include/hw/i386/x86.h |   3 +-
>>  include/hw/nvram/fw_cfg.h |  31 --
>>  hw/i386/microvm.c |  17 ++
>>  hw/i386/pc.c  |   4 +-
>>  hw/i386/pc_piix.c |   2 -
>>  hw/i386/pc_q35.c  |   2 -
>>  hw/i386/x86.c | 122 ++
>>  hw/nvram/fw_cfg.c |  21 ++-
>>  10 files changed, 49 insertions(+), 161 deletions(-)
>>
> 
> 
> I tested this series with SEV measured boot using AmdSev OVMF.  The boot
> succeeds, and the hashes computed for kernel/initrd/cmdline are
> identical to the ones computed by qemu 7.1.0, which are the hashes that
> the guest owner would expect.
> 

I also tested that backporting this series to 7.2.0 (skipping
PATCH 1/7 because it was added after the 7.2.0 release) works OK for
booting SEV guest with AmdSev measured boot (and retains the same
kernel/initrd/cmdline hashes as qemu 7.1.0).

-Dov


> As for non-EFI (non-SEV) guests, I did a very simple test of starting a
> non-EFI guest and it looks OK, but more testing is needed.
> 
> So:
> 
> Tested-by: Dov Murik 
> 
> 
> Thank you!
> 
> -Dov



[PATCH v1 RFC Zisslpcfi 7/9] target/riscv: Tracking indirect branches (fcfi) using TCG

2023-02-08 Thread Deepak Gupta
zisslpcfi protects forward control flow (if enabled) by enforcing all
indirect call and jmp must land on a landing pad instruction `lpcll`
short for landing pad and check lower label value. If target of an
indirect call or jmp is not `lpcll` then cpu/hart must raise an illegal
instruction exception.

This patch implements the mechanism using TCG. Target architecture branch
instruction must define the end of a TB. Using this property, during
translation of branch instruction, TB flag = FCFI_LP_EXPECTED can be set.
Translation of target TB can check if FCFI_LP_EXPECTED flag is set and a
flag (fcfi_lp_expected) can be set in DisasContext. If `lpcll` gets
translated, fcfi_lp_expected flag in DisasContext can be cleared. Else
it'll fault.

This patch also also adds flag for forward and backward cfi in
DisasContext.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu.h|  3 +++
 target/riscv/cpu_helper.c | 12 +
 target/riscv/translate.c  | 52 +++
 3 files changed, 67 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8803ea6426..98b272bcad 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -644,6 +644,9 @@ FIELD(TB_FLAGS, VMA, 25, 1)
 /* Native debug itrigger */
 FIELD(TB_FLAGS, ITRIGGER, 26, 1)
 
+/* Zisslpcfi needs a TB flag to track indirect branches */
+FIELD(TB_FLAGS, FCFI_LP_EXPECTED, 27, 1)
+
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
 #else
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 63377abc2f..d15918f534 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -129,6 +129,18 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
 }
 
+if (cpu->cfg.ext_cfi) {
+/*
+ * For Forward CFI, only the expectation of a lpcll at
+ * the start of the block is tracked (which can only happen
+ * when FCFI is enabled for the current processor mode). A jump
+ * or call at the end of the previous TB will have updated
+ * env->elp to indicate the expectation.
+ */
+flags = FIELD_DP32(flags, TB_FLAGS, FCFI_LP_EXPECTED,
+   env->elp != NO_LP_EXPECTED);
+}
+
 #ifdef CONFIG_USER_ONLY
 flags |= TB_FLAGS_MSTATUS_FS;
 flags |= TB_FLAGS_MSTATUS_VS;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index df38db7553..7d43d20fc3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -41,6 +41,7 @@ static TCGv load_val;
 /* globals for PM CSRs */
 static TCGv pm_mask;
 static TCGv pm_base;
+static TCGOp *cfi_lp_check;
 
 #include "exec/gen-icount.h"
 
@@ -116,6 +117,10 @@ typedef struct DisasContext {
 bool itrigger;
 /* TCG of the current insn_start */
 TCGOp *insn_start;
+/* CFI extension */
+bool bcfi_enabled;
+bool fcfi_enabled;
+bool fcfi_lp_expected;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -1166,11 +1171,44 @@ static void 
riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
 ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
 ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
 ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
+ctx->bcfi_enabled = cpu_get_bcfien(env);
+ctx->fcfi_enabled = cpu_get_fcfien(env);
+ctx->fcfi_lp_expected = FIELD_EX32(tb_flags, TB_FLAGS, FCFI_LP_EXPECTED);
 ctx->zero = tcg_constant_tl(0);
 }
 
 static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
 {
+DisasContext *ctx = container_of(db, DisasContext, base);
+
+if (ctx->fcfi_lp_expected) {
+/*
+ * Since we can't look ahead to confirm that the first
+ * instruction is a legal landing pad instruction, emit
+ * compare-and-branch sequence that will be fixed-up in
+ * riscv_tr_tb_stop() to either statically hit or skip an
+ * illegal instruction exception depending on whether the
+ * flag was lowered by translation of a CJLP or JLP as
+ * the first instruction in the block.
+ */
+TCGv_i32 immediate;
+TCGLabel *l;
+l = gen_new_label();
+immediate = tcg_temp_local_new_i32();
+tcg_gen_movi_i32(immediate, 0);
+cfi_lp_check = tcg_last_op();
+tcg_gen_brcondi_i32(TCG_COND_EQ, immediate, 0, l);
+tcg_temp_free_i32(immediate);
+gen_exception_illegal(ctx);
+gen_set_label(l);
+/*
+ * Despite the use of gen_exception_illegal(), the rest of
+ * the TB needs to be generated. The TCG optimizer will
+ * clean things up depending on which path ends up being
+ * active.
+ */
+ctx->base.is_jmp = DISAS_NEXT;
+}
 }
 
 static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
@@ 

[PATCH v1 RFC Zisslpcfi 3/9] target/riscv: implements CSRs and new bits in existing CSRs in zisslpcfi

2023-02-08 Thread Deepak Gupta
CSR_SSP and CSR_LPLR are new CSR additions to cpu/hart. This patch allows
access to these CSRs. A predicate routine handles access to these CSR as
per specification.

This patch also implments new bit definitions in menvcfg/henvcfg/mstatus/
sstatus CSRs to master enabled cfi and enable forward cfi in S and M mode.
mstatus CSR holds forward and backward cfi enabling for U mode.

There is no enabling bit for backward cfi in S and M mode. It is always
enabled if extension is implemented by CPU.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/csr.c | 137 -
 target/riscv/pmp.c |   9 +++
 2 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0db2c233e5..24e208ebed 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -163,6 +163,50 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
 return ctr(env, csrno);
 }
 
+static RISCVException cfi(CPURISCVState *env, int csrno)
+{
+/* no cfi extension */
+if (!env_archcpu(env)->cfg.ext_cfi) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+/*
+ * CONFIG_USER_MODE always allow access for now. Better for user mode only
+ * functionality
+ */
+#if !defined(CONFIG_USER_ONLY)
+/* current priv not M */
+if (env->priv != PRV_M) {
+/* menvcfg says no CFI */
+if (!get_field(env->menvcfg, MENVCFG_CFI)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+/* V = 1 and henvcfg says no CFI. raise virtual instr fault */
+if (riscv_cpu_virt_enabled(env) &&
+!get_field(env->henvcfg, HENVCFG_CFI)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+
+/*
+ * LPLR and SSP are not accessible to U mode if disabled via status
+ * CSR
+ */
+if (env->priv == PRV_U) {
+if (csrno == CSR_LPLR &&
+!get_field(env->mstatus, MSTATUS_UFCFIEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+if (csrno == CSR_SSP &&
+!get_field(env->mstatus, MSTATUS_UBCFIEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+}
+#endif
+
+return RISCV_EXCP_NONE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
@@ -485,6 +529,32 @@ static RISCVException seed(CPURISCVState *env, int csrno)
 #endif
 }
 
+/* Zisslpcfi CSR_LPLR read/write */
+static int read_lplr(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->lplr;
+return RISCV_EXCP_NONE;
+}
+
+static int write_lplr(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->lplr = val & (LPLR_UL | LPLR_ML | LPLR_LL);
+return RISCV_EXCP_NONE;
+}
+
+/* Zisslpcfi CSR_SSP read/write */
+static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->ssp;
+return RISCV_EXCP_NONE;
+}
+
+static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->ssp = val;
+return RISCV_EXCP_NONE;
+}
+
 /* User Floating-Point CSRs */
 static RISCVException read_fflags(CPURISCVState *env, int csrno,
   target_ulong *val)
@@ -1227,7 +1297,7 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 
 /* flush tlb on mstatus fields that affect VM */
 if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
-MSTATUS_MPRV | MSTATUS_SUM)) {
+MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_UFCFIEN | MSTATUS_UBCFIEN)) {
 tlb_flush(env_cpu(env));
 }
 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
@@ -1250,6 +1320,11 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 }
 }
 
+/* If cfi extension is available, then apply cfi status mask */
+if (env_archcpu(env)->cfg.ext_cfi) {
+mask |= CFISTATUS_M_MASK;
+}
+
 mstatus = (mstatus & ~mask) | (val & mask);
 
 if (xl > MXL_RV32) {
@@ -1880,9 +1955,17 @@ static RISCVException write_menvcfg(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
+uint64_t cfi_mask = MENVCFG_CFI | MENVCFG_SFCFIEN;
 
 if (riscv_cpu_mxl(env) == MXL_RV64) {
 mask |= MENVCFG_PBMTE | MENVCFG_STCE;
+if (env_archcpu(env)->cfg.ext_cfi) {
+mask |= cfi_mask;
+/* If any cfi enabling bit changes in menvcfg, flush tlb */
+if ((val ^ env->menvcfg) & cfi_mask) {
+tlb_flush(env_cpu(env));
+}
+}
 }
 env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
 
@@ -1900,8 +1983,17 @@ static RISCVException write_menvcfgh(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE;
+uint64_t cfi_mask = MENVCFG_CFI | 

[PATCH v1 RFC Zisslpcfi 4/9] target/riscv: helper functions for forward and backward cfi

2023-02-08 Thread Deepak Gupta
Implementation for forward cfi and backward cfi needs helper function
to determine if currently fcfi and bcfi are enabled. Enable depends on
privilege mode and settings in sstatus/menvcfg/henvcfg/mseccfg CSRs.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu_helper.c | 51 +++
 2 files changed, 53 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 18db61a06a..d14ea4f91d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -568,6 +568,8 @@ bool riscv_cpu_virt_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
 bool riscv_cpu_two_stage_lookup(int mmu_idx);
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
+bool cpu_get_fcfien(CPURISCVState *env);
+bool cpu_get_bcfien(CPURISCVState *env);
 hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type, int 
mmu_idx,
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9a28816521..a397023840 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -30,6 +30,7 @@
 #include "sysemu/cpu-timers.h"
 #include "cpu_bits.h"
 #include "debug.h"
+#include "pmp.h"
 
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 {
@@ -40,6 +41,56 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #endif
 }
 
+bool cpu_get_fcfien(CPURISCVState *env)
+{
+#ifdef CONFIG_USER_ONLY
+return false;
+#else
+/* no cfi extension, return false */
+if (!env_archcpu(env)->cfg.ext_cfi) {
+return false;
+}
+
+switch (env->priv) {
+case PRV_U:
+return (env->mstatus & MSTATUS_UFCFIEN) ? true : false;
+case PRV_S:
+return (env->menvcfg & MENVCFG_SFCFIEN) ? true : false;
+case PRV_M:
+return (env->mseccfg & MSECCFG_MFCFIEN) ? true : false;
+default:
+g_assert_not_reached();
+}
+#endif
+}
+
+bool cpu_get_bcfien(CPURISCVState *env)
+{
+#ifdef CONFIG_USER_ONLY
+return false;
+#else
+/* no cfi extension, return false */
+if (!env_archcpu(env)->cfg.ext_cfi) {
+return false;
+}
+
+switch (env->priv) {
+case PRV_U:
+return (env->mstatus & MSTATUS_UBCFIEN) ? true : false;
+
+/*
+ * no gating for back cfi in M/S mode. back cfi is always on for
+ * M/S mode
+ */
+case PRV_S:
+case PRV_M:
+return true;
+default:
+g_assert_not_reached();
+}
+#endif
+}
+
 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags)
 {
-- 
2.25.1




[PATCH v1 RFC Zisslpcfi 2/9] target/riscv: zisslpcfi CSR, bit positions and other definitions

2023-02-08 Thread Deepak Gupta
`zisslpcfi` extension adds two new CSRs. CSR_SSP and CSR_LPLR.
- CSR_SSP: This CSR holds shadow stack pointer for current privilege mode
   CSR_SSP is accessible in all modes. Each mode must establish
   it's own CSR_SSP.

- CSR_LPLR: This CSR holds label value set at the callsite by compiler.
On call target label check instructions are emitted by
compiler which check label value against value present in
CSR_LPRL.

Enabling of `zisslpcfi` is controlled via menvcfg (for S/HS/VS/U/VU) and
henvcfg (for VS/VU) at bit position 60.

Each mode has enable/disable bits for forward cfi. Backward cfi doesn't
have separate enable/disable bits for S and M mode. User forward cfi and
user backward cfi enable/disable bits are in mstatus/sstatus CSR.
Supervisor forward cfi enable/disable bit are in menvcfg and henvcfg CSR.
Machine mode forward cfi enable/disable bit is in mseccfg CSR.

If forward cfi enabled, all indirect branches must land on a landing pad
instruction (`lpcll`, introduced in later commits). CPU/hart tracks this
internally using a landing pad tracker called `elp` short for `expecting
landing pad`. An interrupt can occur between an indirect branch and
target. If such an event occurs `elp` is saved away in mstatus/sstatus
CSR

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu.h  |  5 +
 target/riscv/cpu_bits.h | 25 +
 target/riscv/pmp.h  |  3 ++-
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9a923760b2..18db61a06a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -181,6 +181,11 @@ struct CPUArchState {
 
 uint32_t features;
 
+/* CFI Extension user mode registers and state */
+uint32_t lplr;
+target_ulong ssp;
+cfi_elp  elp;
+
 #ifdef CONFIG_USER_ONLY
 uint32_t elf_flags;
 #endif
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..1663ba5775 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -39,6 +39,10 @@
 
 /* Control and Status Registers */
 
+/* CFI CSRs */
+#define CSR_LPLR0x006
+#define CSR_SSP 0x020
+
 /* User Trap Setup */
 #define CSR_USTATUS 0x000
 #define CSR_UIE 0x004
@@ -542,6 +546,10 @@
 #define MSTATUS_TVM 0x0010 /* since: priv-1.10 */
 #define MSTATUS_TW  0x0020 /* since: priv-1.10 */
 #define MSTATUS_TSR 0x0040 /* since: priv-1.10 */
+#define MSTATUS_UFCFIEN 0x0080 /* Zisslpcfi-0.1 */
+#define MSTATUS_UBCFIEN 0x0100 /* Zisslpcfi-0.1 */
+#define MSTATUS_SPELP   0x0200 /* Zisslpcfi-0.1 */
+#define MSTATUS_MPELP   0x0400 /* Zisslpcfi-0.1 */
 #define MSTATUS_GVA 0x40ULL
 #define MSTATUS_MPV 0x80ULL
 
@@ -572,12 +580,21 @@ typedef enum {
 #define SSTATUS_XS  0x00018000
 #define SSTATUS_SUM 0x0004 /* since: priv-1.10 */
 #define SSTATUS_MXR 0x0008
+#define SSTATUS_UFCFIEN MSTATUS_UFCFIEN /* Zisslpcfi-0.1 */
+#define SSTATUS_UBCFIEN MSTATUS_UBCFIEN /* Zisslpcfi-0.1 */
+#define SSTATUS_SPELP   MSTATUS_SPELP   /* Zisslpcfi-0.1 */
 
 #define SSTATUS64_UXL   0x0003ULL
 
 #define SSTATUS32_SD0x8000
 #define SSTATUS64_SD0x8000ULL
 
+#define CFISTATUS_M_MASK(MSTATUS_UFCFIEN | MSTATUS_UBCFIEN | \
+ MSTATUS_MPELP | MSTATUS_SPELP)
+
+#define CFISTATUS_S_MASK(SSTATUS_UFCFIEN | SSTATUS_UBCFIEN | \
+ SSTATUS_SPELP)
+
 /* hstatus CSR bits */
 #define HSTATUS_VSBE 0x0020
 #define HSTATUS_GVA  0x0040
@@ -747,10 +764,14 @@ typedef enum RISCVException {
 #define MENVCFG_CBIE   (3UL << 4)
 #define MENVCFG_CBCFE  BIT(6)
 #define MENVCFG_CBZE   BIT(7)
+#define MENVCFG_SFCFIENBIT(59)
+#define MENVCFG_CFIBIT(60)
 #define MENVCFG_PBMTE  (1ULL << 62)
 #define MENVCFG_STCE   (1ULL << 63)
 
 /* For RV32 */
+#define MENVCFGH_SFCFIEN   BIT(27)
+#define MENVCFGH_CFI   BIT(28)
 #define MENVCFGH_PBMTE BIT(30)
 #define MENVCFGH_STCE  BIT(31)
 
@@ -763,10 +784,14 @@ typedef enum RISCVException {
 #define HENVCFG_CBIE   MENVCFG_CBIE
 #define HENVCFG_CBCFE  MENVCFG_CBCFE
 #define HENVCFG_CBZE   MENVCFG_CBZE
+#define HENVCFG_SFCFIENMENVCFG_SFCFIEN
+#define HENVCFG_CFIMENVCFG_CFI
 #define HENVCFG_PBMTE  MENVCFG_PBMTE
 #define HENVCFG_STCE   MENVCFG_STCE
 
 /* For RV32 */
+#define HENVCFGH_SFCFIENMENVCFGH_SFCFIEN
+#define HENVCFGH_CFIMENVCFGH_CFI
 

[PATCH v1 RFC Zisslpcfi 6/9] target/riscv: MMU changes for back cfi's shadow stack

2023-02-08 Thread Deepak Gupta
zisslpcfi protects returns(back cfi) using shadow stack. If compiled with
enabled compiler, function prologs will have `sspush ra` instruction to
push return address on shadow stack and function epilogs will have
`sspop t0; sschckra` instruction sequences. `sspop t0` will pop the
value from top of the shadow stack in t0. `sschckra` will compare `t0`
and `x1` and if they don't match then hart will raise an illegal
instruction exception.

Shadow stack is read-only memory except stores can be performed via
`sspush` and `ssamoswap` instructions. This requires new PTE encoding for
shadow stack. zisslpcfi uses R=0, W=1, X=0 (an existing reserved encoding
) to encode a shadow stack. If backward cfi is not enabled for current
mode, shadow stack PTE encodings remain reserved. Regular stores to
shadow stack raise AMO/store access fault. Shadow stack loads/stores on
regular memory raise load access/store access fault.

This patch creates a new MMU TLB index for shadow stack and flushes TLB
for shadow stack on privileges changes. This patch doesn't implement
`Smepmp` related enforcement on shadow stack pmp entry. Reason being qemu
doesn't have `Smepmp` implementation yet. `Smepmp` enforcement should come
whenever it is implemented.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu-param.h  |   1 +
 target/riscv/cpu.c|   2 +
 target/riscv/cpu.h|   3 ++
 target/riscv/cpu_helper.c | 107 +++---
 4 files changed, 94 insertions(+), 19 deletions(-)

diff --git a/target/riscv/cpu-param.h b/target/riscv/cpu-param.h
index ebaf26d26d..a1e379beb7 100644
--- a/target/riscv/cpu-param.h
+++ b/target/riscv/cpu-param.h
@@ -25,6 +25,7 @@
  *  - M mode 0b011
  *  - U mode HLV/HLVX/HSV 0b100
  *  - S mode HLV/HLVX/HSV 0b101
+ *  - BCFI shadow stack   0b110
  *  - M mode HLV/HLVX/HSV 0b111
  */
 #define NB_MMU_MODES 8
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6b4e90eb91..14cfb93288 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -584,6 +584,8 @@ static void riscv_cpu_reset_hold(Object *obj)
 }
 /* mmte is supposed to have pm.current hardwired to 1 */
 env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
+/* Initialize ss_priv to current priv. */
+env->ss_priv = env->priv;
 #endif
 env->xl = riscv_cpu_mxl(env);
 riscv_cpu_update_mask(env);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d14ea4f91d..8803ea6426 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -379,6 +379,7 @@ struct CPUArchState {
 uint64_t sstateen[SMSTATEEN_MAX_COUNT];
 target_ulong senvcfg;
 uint64_t henvcfg;
+target_ulong ss_priv;
 #endif
 target_ulong cur_pmmask;
 target_ulong cur_pmbase;
@@ -617,6 +618,8 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
 #define TB_FLAGS_PRIV_HYP_ACCESS_MASK   (1 << 2)
 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
 #define TB_FLAGS_MSTATUS_VS MSTATUS_VS
+/* TLB MMU index for shadow stack accesses */
+#define MMU_IDX_SS_ACCESS6
 
 #include "exec/cpu-all.h"
 
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index fc188683c9..63377abc2f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -657,7 +657,8 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool 
enable)
 
 bool riscv_cpu_two_stage_lookup(int mmu_idx)
 {
-return mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+return (mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK) &&
+   (mmu_idx != MMU_IDX_SS_ACCESS);
 }
 
 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
@@ -745,6 +746,38 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
  * preemptive context switch. As a result, do both.
  */
 env->load_res = -1;
+
+if (cpu_get_bcfien(env) && (env->priv != env->ss_priv)) {
+/*
+ * If backward CFI is enabled in the new privilege state, the
+ * shadow stack TLB needs to be flushed - unless the most recent
+ * use of the SS TLB was for the same privilege mode.
+ */
+tlb_flush_by_mmuidx(env_cpu(env), 1 << MMU_IDX_SS_ACCESS);
+/*
+ * Ignoring env->virt here since currently every time it flips,
+ * all TLBs are flushed anyway.
+ */
+env->ss_priv = env->priv;
+}
+}
+
+typedef enum {
+SSTACK_NO,  /* Access is not for a shadow stack instruction */
+SSTACK_YES, /* Access is for a shadow stack instruction */
+SSTACK_DC   /* Don't care about SS attribute in PMP */
+} SStackPmpMode;
+
+static bool legal_sstack_access(int access_type, bool sstack_inst,
+bool sstack_attribute)
+{
+/*
+ * Read/write/execution permissions are checked as usual. Shadow
+ * stack enforcement is just that (1) instruction type must match
+ * the attribute unless (2) a non-SS load to an SS region.
+ */
+return (sstack_inst == sstack_attribute) ||
+

[PATCH v1 RFC Zisslpcfi 1/9] target/riscv: adding zimops and zisslpcfi extension to RISCV cpu config

2023-02-08 Thread Deepak Gupta
Introducing riscv `zisslpcfi` extension to riscv target. `zisslpcfi`
extension provides hardware assistance to riscv hart to enable control
flow integrity (CFI) for software.

`zisslpcfi` extension expects hart to implement `zimops`. `zimops` stands
for "unprivileged integer maybe operations". `zimops` carve out certain
reserved opcodes encodings from integer spec to "may be operations"
encodings. `zimops` opcode encodings simply move 0 to rd.
`zisslpcfi` claims some of the `zimops` encodings and use them for shadow
stack management or indirect branch tracking. Any future extension can
also claim `zimops` encodings.

This patch also adds a dependency check for `zimops` to be enabled if
`zisslpcfi` is enabled on the hart.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu.c | 13 +
 target/riscv/cpu.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index cc75ca7667..6b4e90eb91 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -110,6 +110,8 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
 ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
 ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
+ISA_EXT_DATA_ENTRY(zimops, true, PRIV_VERSION_1_12_0, ext_zimops),
+ISA_EXT_DATA_ENTRY(zisslpcfi, true, PRIV_VERSION_1_12_0, ext_cfi),
 };
 
 static bool isa_ext_is_enabled(RISCVCPU *cpu,
@@ -792,6 +794,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (cpu->cfg.ext_cfi && !cpu->cfg.ext_zimops) {
+error_setg(errp, "Zisslpcfi extension requires Zimops extension");
+return;
+}
+
 /* Set the ISA extensions, checks should have happened above */
 if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
 cpu->cfg.ext_zhinxmin) {
@@ -1102,6 +1109,12 @@ static Property riscv_cpu_properties[] = {
 #ifndef CONFIG_USER_ONLY
 DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
 #endif
+/*
+ * Zisslpcfi CFI extension, Zisslpcfi implicitly means Zimops is
+ * implemented
+ */
+DEFINE_PROP_BOOL("zisslpcfi", RISCVCPU, cfg.ext_cfi, true),
+DEFINE_PROP_BOOL("zimops", RISCVCPU, cfg.ext_zimops, true),
 
 DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, 
false),
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f5609b62a2..9a923760b2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -471,6 +471,8 @@ struct RISCVCPUConfig {
 uint32_t mvendorid;
 uint64_t marchid;
 uint64_t mimpid;
+bool ext_zimops;
+bool ext_cfi;
 
 /* Vendor-specific custom extensions */
 bool ext_XVentanaCondOps;
-- 
2.25.1




[PATCH v1 RFC Zisslpcfi 9/9] target/riscv: diassembly support for zisslpcfi instructions

2023-02-08 Thread Deepak Gupta
This patch adds support to disassemble Zisslpcfi instructions.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 disas/riscv.c | 127 +-
 1 file changed, 126 insertions(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index d216b9c39b..d16ee617b0 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -163,6 +163,7 @@ typedef enum {
 rv_codec_v_i,
 rv_codec_vsetvli,
 rv_codec_vsetivli,
+rv_codec_lp,
 } rv_codec;
 
 typedef enum {
@@ -935,6 +936,19 @@ typedef enum {
 rv_op_vsetvli = 766,
 rv_op_vsetivli = 767,
 rv_op_vsetvl = 768,
+rv_op_lpsll = 769,
+rv_op_lpcll = 770,
+rv_op_lpsml = 771,
+rv_op_lpcml = 772,
+rv_op_lpsul = 773,
+rv_op_lpcul = 774,
+rv_op_sspush = 775,
+rv_op_sspop = 776,
+rv_op_ssprr = 777,
+rv_op_ssamoswap = 778,
+rv_op_sschkra = 779,
+rv_op_zimops_r = 780,
+rv_op_zimops_rr = 781,
 } rv_op;
 
 /* structures */
@@ -1011,6 +1025,7 @@ static const char rv_vreg_name_sym[32][4] = {
 #define rv_fmt_pred_succ  "O\tp,s"
 #define rv_fmt_rs1_rs2"O\t1,2"
 #define rv_fmt_rd_imm "O\t0,i"
+#define rv_fmt_imm"O\ti"
 #define rv_fmt_rd_offset  "O\t0,o"
 #define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
 #define rv_fmt_frd_rs1"O\t3,1"
@@ -2065,7 +2080,20 @@ const rv_opcode_data opcode_data[] = {
 { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, 
rv_op_vsext_vf8, 0 },
 { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, 
rv_op_vsetvli, 0 },
 { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, 
rv_op_vsetivli, 0 },
-{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 }
+{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 },
+{ "lpsll", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpcll", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpsml", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpcml", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpsul", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpcul", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "sspush", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+{ "sspop", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 },
+{ "ssprr", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 },
+{ "ssamoswap", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sschkra", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+{ "zimops_r", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 },
+{ "zimops_rr", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 }
 };
 
 /* CSR names */
@@ -2084,6 +2112,8 @@ static const char *csr_name(int csrno)
 case 0x000a: return "vxrm";
 case 0x000f: return "vcsr";
 case 0x0015: return "seed";
+case 0x0006: return "lplr";
+case 0x0020: return "ssp";
 case 0x0040: return "uscratch";
 case 0x0041: return "uepc";
 case 0x0042: return "ucause";
@@ -3554,6 +3584,87 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 case 1: op = rv_op_csrrw; break;
 case 2: op = rv_op_csrrs; break;
 case 3: op = rv_op_csrrc; break;
+case 4:
+/* if matches mop_r mask */
+if inst >> 15) & 0b101100000) ==
+0b100111000)) {
+if ((inst >> 25) == 0b100) {
+switch ((inst >> 20) & 0b11) {
+case 0: /* sspush and sspop */
+if (((inst >> 15) & 0b1) &&
+!((inst >> 7) & 0b1))
+op = rv_op_sspush;
+if (!((inst >> 15) & 0b1) &&
+((inst >> 7) & 0b1))
+op = rv_op_sspop;
+break;
+
+case 1: /* ssprr */
+if (!((inst >> 15) & 0b1) &&
+((inst >> 7) & 0b1))
+op = rv_op_ssprr;
+break;
+
+default:
+op = rv_op_zimops_r;
+break;
+}
+} else {
+op = rv_op_zimops_r;
+}
+} else if (((inst >> 15) & 0b101100100) ==
+0b10100) { /* if matches mop_rr mask */
+switch (inst >> 28) {
+case 0b1000:
+switch ((inst >> 7) & 0b1) {
+case 0b0:
+/* collect 5 bits */
+switch (((inst >> 23) & 0b1)) {
+case 23:
+op = 

[PATCH v1 RFC Zisslpcfi 8/9] target/riscv: Instructions encodings, implementation and handlers

2023-02-08 Thread Deepak Gupta
This patch implements instruction encodings for zisslpcfi instructions.
Additionally this patch implements zimops encodings as well. If Zisslpcfi
is supported by CPU but not enabled then all Zisslpcfi instructions
default to Zimops instuction behavior i.e. mov 0 to rd.

zisslpcfi defines following instructions.
- Backward control flow
- sspush x1/x5 : Decrement shadow stack pointer and pushes x1 or x5
 on shadow stack.
- sspop x1/x5 : Pops from shadow stack into x1 or x5. Increments
shadow stack pointer.
- ssprr : Reads current shadow stack pointer into a destination
  register.
- sscheckra : Compares x1 with x5. Raises illegal instr fault if
x1 != x5
- ssamoswap : Atomically swaps value on top of shadow stack

- Forward control flow
- lpsll, lpsml, lpsul : sets lower (9bit), mid (8bit) and upper
(8bit) label values in CSR_ULLP respectively.
- lpcll, lpcml, lpcul : checks lower (9bit), mid (8bit) and upper
(8bit) label values with CSR_ULLP
respectively.
Check label instructions raise illegal instruction fault when labels
mismatch.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu_bits.h   |  10 +
 target/riscv/helper.h |   7 +
 target/riscv/insn32.decode|  29 ++
 target/riscv/insn_trans/trans_rvi.c.inc   |  14 +
 target/riscv/insn_trans/trans_zimops.c.inc|  53 +++
 target/riscv/insn_trans/trans_zisslpcfi.c.inc | 310 ++
 target/riscv/op_helper.c  |  67 
 target/riscv/translate.c  |   2 +
 8 files changed, 492 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_zimops.c.inc
 create mode 100644 target/riscv/insn_trans/trans_zisslpcfi.c.inc

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 37100ec8f6..b2d527c626 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -600,6 +600,16 @@ typedef enum {
 LP_EXPECTED = 1,
 } cfi_elp;
 
+#define LPLR_UL(((1 << 8) - 1) << 17)
+#define LPLR_ML(((1 << 8) - 1) << 9)
+#define LPLR_LL((1 << 9) - 1)
+
+typedef enum {
+FCFI_LPLL = 0,
+FCFI_ML = 1,
+FCFI_UL = 2,
+} cfi_label_inst;
+
 /* hstatus CSR bits */
 #define HSTATUS_VSBE 0x0020
 #define HSTATUS_GVA  0x0040
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 227c7122ef..6484415612 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -97,6 +97,11 @@ DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
 DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
 DEF_HELPER_FLAGS_2(fclass_h, TCG_CALL_NO_RWG_SE, tl, env, i64)
 
+/* Forward CFI label checking */
+DEF_HELPER_2(cfi_jalr, void, env, int)
+DEF_HELPER_3(cfi_check_landing_pad, void, env, int, int)
+DEF_HELPER_3(cfi_set_landing_pad, void, env, int, int)
+
 /* Special functions */
 DEF_HELPER_2(csrr, tl, env, int)
 DEF_HELPER_3(csrw, void, env, int, tl)
@@ -112,6 +117,8 @@ DEF_HELPER_1(tlb_flush, void, env)
 /* Native Debug */
 DEF_HELPER_1(itrigger_match, void, env)
 #endif
+/* helper for back cfi mismatch */
+DEF_HELPER_1(sschkra_mismatch, void, env)
 
 /* Hypervisor functions */
 #ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b7e7613ea2..cd734f03ae 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -37,6 +37,8 @@
 %imm_u12:s20 !function=ex_shift_12
 %imm_bs   30:2   !function=ex_shift_3
 %imm_rnum 20:4
+%imm_cfi9  15:9
+%imm_cfi8  15:8
 
 # Argument sets:
 
@@ -163,6 +165,33 @@ csrrwi    . 101 . 1110011 @csr
 csrrsi    . 110 . 1110011 @csr
 csrrci    . 111 . 1110011 @csr
 
+# zimops (unpriv integer may be operations) instructions with system opcode
+# These're superset of for cfi encodings. zimops_r and zimops_rr should be last
+# entry in below overlapping patterns so that it acts as final sink for 
overlapping patterns.
+# Any new encoding that can be used should be placed above mop.r and mop.rr
+
+# cfi instructions carved out of mop.r
+{
+  sspush10 0 11100 . 100 0 1110011 %rs1
+  sspop 10 0 11100 0 100 . 1110011 %rd
+  ssprr 10 0 11101 0 100 . 1110011 %rd
+  zimops_r  1-00-- 0 111-- - 100 . 1110011 %rd
+}
+
+# cfi instructions carved out of mop.rr
+{
+  sschckra  100010 1 1 00101 100 0 1110011
+  ssamoswap 10 1 . . 100 . 1110011 @r
+
+  lpsll 10 1 0 .100 0 1110011 %imm_cfi9
+  lpcll 10 1 1 .100 0 1110011 %imm_cfi9
+  lpsml 11 1 0 0100 0 1110011 %imm_cfi8
+  lpcml 11 1 0 1100 0 

[PATCH v1 RFC Zisslpcfi 5/9] target/riscv: state save and restore of zisslppcfi state

2023-02-08 Thread Deepak Gupta
zisslpcfi's forward cfi if enabled on a hart, enables tracking of
indirect branches. CPU/hart internally keeps a state `elp` short
for expecting landing pad instruction. This state goes into
LP_EXPECTED on an indirect branch. But an interrupt/exception can occur
before target instruction is executed. In such a case this state must be
preserved so that it can be restored later. zisslpcfi saves elp state in
`sstatus` CSR. This patch saves elp state in sstatus CSR on trap delivery
while restores from sstatus CSR on trap return.

Additionally state in sstatus CSR must have save and restore zisslpcfi
state on exiting from hypervisor and entering into hypervisor.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu_bits.h   |  5 +
 target/riscv/cpu_helper.c | 26 ++
 target/riscv/op_helper.c  | 12 
 3 files changed, 43 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 1663ba5775..37100ec8f6 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -594,6 +594,11 @@ typedef enum {
 
 #define CFISTATUS_S_MASK(SSTATUS_UFCFIEN | SSTATUS_UBCFIEN | \
  SSTATUS_SPELP)
+/* enum for branch tracking state in cpu/hart */
+typedef enum {
+NO_LP_EXPECTED = 0,
+LP_EXPECTED = 1,
+} cfi_elp;
 
 /* hstatus CSR bits */
 #define HSTATUS_VSBE 0x0020
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index a397023840..fc188683c9 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -534,6 +534,16 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
 if (riscv_has_ext(env, RVF)) {
 mstatus_mask |= MSTATUS_FS;
 }
+
+/*
+ * If cfi extension available, menvcfg.CFI = 1 and henvcfg.CFI = 1,
+ * then apply CFI mask on mstatus
+ */
+if (env_archcpu(env)->cfg.ext_cfi &&
+get_field(env->menvcfg, MENVCFG_CFI) &&
+get_field(env->henvcfg, HENVCFG_CFI)) {
+mstatus_mask |= CFISTATUS_S_MASK;
+}
 bool current_virt = riscv_cpu_virt_enabled(env);
 
 g_assert(riscv_has_ext(env, RVH));
@@ -1723,6 +1733,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 if (env->priv <= PRV_S &&
 cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) {
 /* handle the trap in S-mode */
+/* save elp status */
+if (cpu_get_fcfien(env)) {
+env->mstatus = set_field(env->mstatus, MSTATUS_SPELP, env->elp);
+}
 if (riscv_has_ext(env, RVH)) {
 uint64_t hdeleg = async ? env->hideleg : env->hedeleg;
 
@@ -1772,6 +1786,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 riscv_cpu_set_mode(env, PRV_S);
 } else {
 /* handle the trap in M-mode */
+/* save elp status */
+if (cpu_get_fcfien(env)) {
+env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, env->elp);
+}
 if (riscv_has_ext(env, RVH)) {
 if (riscv_cpu_virt_enabled(env)) {
 riscv_cpu_swap_hypervisor_regs(env);
@@ -1803,6 +1821,14 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 riscv_cpu_set_mode(env, PRV_M);
 }
 
+/*
+ * Interrupt/exception/trap delivery is asynchronous event and as per
+ * Zisslpcfi spec CPU should clear up the ELP state. If cfi extension is
+ * available, clear ELP state.
+ */
+if (cpu->cfg.ext_cfi) {
+env->elp = NO_LP_EXPECTED;
+}
 /* NOTE: it is not necessary to yield load reservations here. It is only
  * necessary for an SC from "another hart" to cause a load reservation
  * to be yielded. Refer to the memory consistency model section of the
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 878bcb03b8..d15893aa82 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -176,6 +176,12 @@ target_ulong helper_sret(CPURISCVState *env)
 riscv_cpu_set_virt_enabled(env, prev_virt);
 }
 
+/* If forward cfi enabled for target, restore elp status */
+if (cpu_get_fcfien(env)) {
+env->elp = get_field(env->mstatus, MSTATUS_SPELP);
+env->mstatus = set_field(env->mstatus, MSTATUS_SPELP, 0);
+}
+
 riscv_cpu_set_mode(env, prev_priv);
 
 return retpc;
@@ -220,6 +226,12 @@ target_ulong helper_mret(CPURISCVState *env)
 riscv_cpu_set_virt_enabled(env, prev_virt);
 }
 
+/* If forward cfi enabled for target, restore elp status */
+if (cpu_get_fcfien(env)) {
+env->elp = get_field(env->mstatus, MSTATUS_MPELP);
+env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, 0);
+}
+
 return retpc;
 }
 
-- 
2.25.1




[PATCH v1 RFC Zisslpcfi 0/9] zimops and zisslpcfi extension to riscv

2023-02-08 Thread Deepak Gupta
Still learning to use git send-mail. Hopefully this time cover-letter
also reaches everyone.

I am sending this patch series as RFC for an extension which helps
software enforce control-flow integrity (cfi) on riscv CPUs. Currently
spec is called zisslpcfi spec - https://github.com/riscv/riscv-cfi.
This literally means "unprivileged integer shadow stack & landing pad
based cfi".

Sending this as RFC because
- Even though I dont expect major change in zimops, it's still on the stove.
- zisslpcfi is tied up nicely still being worked on.
- I would like eyeballing on indirect branch tracking implementation.

zisslpcfi (CFI) extends ISA in following manner:

Forward cfi (indirect call/jmp)
- Landing pad instruction requirement for indirect call/jmp
  All indirect call and jump must land on landing pad instruction `lpcll`
  else CPU will raise illegal instruction exception. `lpcll` stands for
  land pad check lower label.

- Static label (25bit label) checking instructions for indirect call/jmp
  Extension provides mechanism using which a compiler generated label
  value can be set in a designated CSR at call site and it can be checked
  at the call target. If mismatch happens, CPU will raise illegal
  instruction exception. Compiler can generate hash based on function
  signature type. Extension provide mechanisms using which label value
  is part of the instruction itself as immediate and thus has static
  immutable property.

Backward cfi (returns)
- Shadow stack (SS) for function returns
  Extension provides sspush x1/x5, sspop x1/x5 and sschkra instructions.
  sspush will push on shadow stack while sspop will pop from shadow stack
  sschkra will succeed only when x1 == x5 is true else it will raise
  illegal instruction exception. Shadow stacks introduces new virtual
  memory type and thus new PTE encodings. Existing reserved encoding of
  R=0,W=1,X=0 is now shadow stack PTE encoding (only if backward cfi is
  enabled for current mode). New virtual memory type allows CPU to
  distinguish so that stores coming from sspush or ssamoswap can succeed
  while regular stores raise access violations.

opcodes:
zisslpcfi opcodes are carved out of new opcode encodings. These opcodes
encodings were reserved until now. A new extension called zimops make
these opcodes into "may be operations". zimops stands for unprivileged
may be operations (mops) and if implemented default behavior is to mov 0
to rd. zisslpcfi extension changes executable in a way where it should be
able to run on riscv cpu which implements cfi extension as well as riscv
cpu which doesn't implement cfi extension. As long as zimops is
implemented, all such instructions will not fault and simply move 0 to rd.
A hart implementing cfi must implement zimops. Any future extension can
re-purpose zimops to change behavior and claim them while also not
breaking binary/executable compatiblity . zisslpcfi is first such
extension to modify zimops behavior.

Instructions:
zisslpcfi defines following instructions.

Backward control flow
*

sspush x1/x5:
Decrement shadow stack pointer and pushes x1 or x5 on shadow stack.

sspop x1/x5:
Pops from shadow stack into x1 or x5. Increments shadow stack pointer.

ssprr:
Reads current shadow stack pointer into a destination register.

sschckra:
Compares x1 with x5. Raises illegal instr exception if x1 != x5.

ssamoswap:
Atomically swaps value on top of shadow stack.


Forward control flow

Forward control flow extends architecture to allow software to set labels
(25bits of label) at call/jmp site and check labels at target. Extension
gives instructions to set label as part of immediate in instruction itself
. Since immediate is limited in terms of bit length, labels are set and
checked in ladder fashion of 9, 8 and 8 bits.

lpsll, lpsml, lpsul:
sets lower (9bit), mid (8bit) and upper (8bit) label values in CSR_LPLR
respectively.

lpcll, lpcml, lpcul:
checks lower (9bit), mid (8bit) and upper (8bit) label values with
CSR_LPLR respectively. Check label instructions raise illegal instruction
fault when labels mismatch. `lpcll` has dual purpose; it acts as landing
pad instruction as well label checking for lower 9 bits.

More on shadow stack

Shadow stacks have new encodings (R=0,W=1,X=0) in first level page tables
to ensure they can be writeable only via special shadow stack management
instructions and regular stores are disallowed. Regular stores on shadow
stack memory raise AMO/store access fault. Shadow stack load (sspop) on
non-shadow stack memory raise load access fault. Shadow stack store
(sspush) on non-shadow stack memory raise store access fault.

To provide each mode their own shadow stack translations, this
implementation flushes shadow stack translations on privilege change and
thus each mode keep their own translation as long as mode doesn't change.
Shadow stack accesses need to coexist with normal accesses, but have
different permission checks. Since 

[PATCH v1 RFC Zisslpcfi 3/9] target/riscv: implements CSRs and new bits in existing CSRs in zisslpcfi

2023-02-08 Thread Deepak Gupta
CSR_SSP and CSR_LPLR are new CSR additions to cpu/hart. This patch allows
access to these CSRs. A predicate routine handles access to these CSR as
per specification.

This patch also implments new bit definitions in menvcfg/henvcfg/mstatus/
sstatus CSRs to master enabled cfi and enable forward cfi in S and M mode.
mstatus CSR holds forward and backward cfi enabling for U mode.

There is no enabling bit for backward cfi in S and M mode. It is always
enabled if extension is implemented by CPU.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/csr.c | 137 -
 target/riscv/pmp.c |   9 +++
 2 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0db2c233e5..24e208ebed 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -163,6 +163,50 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
 return ctr(env, csrno);
 }
 
+static RISCVException cfi(CPURISCVState *env, int csrno)
+{
+/* no cfi extension */
+if (!env_archcpu(env)->cfg.ext_cfi) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+/*
+ * CONFIG_USER_MODE always allow access for now. Better for user mode only
+ * functionality
+ */
+#if !defined(CONFIG_USER_ONLY)
+/* current priv not M */
+if (env->priv != PRV_M) {
+/* menvcfg says no CFI */
+if (!get_field(env->menvcfg, MENVCFG_CFI)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+/* V = 1 and henvcfg says no CFI. raise virtual instr fault */
+if (riscv_cpu_virt_enabled(env) &&
+!get_field(env->henvcfg, HENVCFG_CFI)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+
+/*
+ * LPLR and SSP are not accessible to U mode if disabled via status
+ * CSR
+ */
+if (env->priv == PRV_U) {
+if (csrno == CSR_LPLR &&
+!get_field(env->mstatus, MSTATUS_UFCFIEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+if (csrno == CSR_SSP &&
+!get_field(env->mstatus, MSTATUS_UBCFIEN)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+}
+}
+#endif
+
+return RISCV_EXCP_NONE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
@@ -485,6 +529,32 @@ static RISCVException seed(CPURISCVState *env, int csrno)
 #endif
 }
 
+/* Zisslpcfi CSR_LPLR read/write */
+static int read_lplr(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->lplr;
+return RISCV_EXCP_NONE;
+}
+
+static int write_lplr(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->lplr = val & (LPLR_UL | LPLR_ML | LPLR_LL);
+return RISCV_EXCP_NONE;
+}
+
+/* Zisslpcfi CSR_SSP read/write */
+static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env->ssp;
+return RISCV_EXCP_NONE;
+}
+
+static int write_ssp(CPURISCVState *env, int csrno, target_ulong val)
+{
+env->ssp = val;
+return RISCV_EXCP_NONE;
+}
+
 /* User Floating-Point CSRs */
 static RISCVException read_fflags(CPURISCVState *env, int csrno,
   target_ulong *val)
@@ -1227,7 +1297,7 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 
 /* flush tlb on mstatus fields that affect VM */
 if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
-MSTATUS_MPRV | MSTATUS_SUM)) {
+MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_UFCFIEN | MSTATUS_UBCFIEN)) {
 tlb_flush(env_cpu(env));
 }
 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
@@ -1250,6 +1320,11 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 }
 }
 
+/* If cfi extension is available, then apply cfi status mask */
+if (env_archcpu(env)->cfg.ext_cfi) {
+mask |= CFISTATUS_M_MASK;
+}
+
 mstatus = (mstatus & ~mask) | (val & mask);
 
 if (xl > MXL_RV32) {
@@ -1880,9 +1955,17 @@ static RISCVException write_menvcfg(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
+uint64_t cfi_mask = MENVCFG_CFI | MENVCFG_SFCFIEN;
 
 if (riscv_cpu_mxl(env) == MXL_RV64) {
 mask |= MENVCFG_PBMTE | MENVCFG_STCE;
+if (env_archcpu(env)->cfg.ext_cfi) {
+mask |= cfi_mask;
+/* If any cfi enabling bit changes in menvcfg, flush tlb */
+if ((val ^ env->menvcfg) & cfi_mask) {
+tlb_flush(env_cpu(env));
+}
+}
 }
 env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
 
@@ -1900,8 +1983,17 @@ static RISCVException write_menvcfgh(CPURISCVState *env, 
int csrno,
   target_ulong val)
 {
 uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE;
+uint64_t cfi_mask = MENVCFG_CFI | 

[PATCH v1 RFC Zisslpcfi 6/9] target/riscv: MMU changes for back cfi's shadow stack

2023-02-08 Thread Deepak Gupta
zisslpcfi protects returns(back cfi) using shadow stack. If compiled with
enabled compiler, function prologs will have `sspush ra` instruction to
push return address on shadow stack and function epilogs will have
`sspop t0; sschckra` instruction sequences. `sspop t0` will pop the
value from top of the shadow stack in t0. `sschckra` will compare `t0`
and `x1` and if they don't match then hart will raise an illegal
instruction exception.

Shadow stack is read-only memory except stores can be performed via
`sspush` and `ssamoswap` instructions. This requires new PTE encoding for
shadow stack. zisslpcfi uses R=0, W=1, X=0 (an existing reserved encoding
) to encode a shadow stack. If backward cfi is not enabled for current
mode, shadow stack PTE encodings remain reserved. Regular stores to
shadow stack raise AMO/store access fault. Shadow stack loads/stores on
regular memory raise load access/store access fault.

This patch creates a new MMU TLB index for shadow stack and flushes TLB
for shadow stack on privileges changes. This patch doesn't implement
`Smepmp` related enforcement on shadow stack pmp entry. Reason being qemu
doesn't have `Smepmp` implementation yet. `Smepmp` enforcement should come
whenever it is implemented.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu-param.h  |   1 +
 target/riscv/cpu.c|   2 +
 target/riscv/cpu.h|   3 ++
 target/riscv/cpu_helper.c | 107 +++---
 4 files changed, 94 insertions(+), 19 deletions(-)

diff --git a/target/riscv/cpu-param.h b/target/riscv/cpu-param.h
index ebaf26d26d..a1e379beb7 100644
--- a/target/riscv/cpu-param.h
+++ b/target/riscv/cpu-param.h
@@ -25,6 +25,7 @@
  *  - M mode 0b011
  *  - U mode HLV/HLVX/HSV 0b100
  *  - S mode HLV/HLVX/HSV 0b101
+ *  - BCFI shadow stack   0b110
  *  - M mode HLV/HLVX/HSV 0b111
  */
 #define NB_MMU_MODES 8
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6b4e90eb91..14cfb93288 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -584,6 +584,8 @@ static void riscv_cpu_reset_hold(Object *obj)
 }
 /* mmte is supposed to have pm.current hardwired to 1 */
 env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
+/* Initialize ss_priv to current priv. */
+env->ss_priv = env->priv;
 #endif
 env->xl = riscv_cpu_mxl(env);
 riscv_cpu_update_mask(env);
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d14ea4f91d..8803ea6426 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -379,6 +379,7 @@ struct CPUArchState {
 uint64_t sstateen[SMSTATEEN_MAX_COUNT];
 target_ulong senvcfg;
 uint64_t henvcfg;
+target_ulong ss_priv;
 #endif
 target_ulong cur_pmmask;
 target_ulong cur_pmbase;
@@ -617,6 +618,8 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
 #define TB_FLAGS_PRIV_HYP_ACCESS_MASK   (1 << 2)
 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
 #define TB_FLAGS_MSTATUS_VS MSTATUS_VS
+/* TLB MMU index for shadow stack accesses */
+#define MMU_IDX_SS_ACCESS6
 
 #include "exec/cpu-all.h"
 
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index fc188683c9..63377abc2f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -657,7 +657,8 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool 
enable)
 
 bool riscv_cpu_two_stage_lookup(int mmu_idx)
 {
-return mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+return (mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK) &&
+   (mmu_idx != MMU_IDX_SS_ACCESS);
 }
 
 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
@@ -745,6 +746,38 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong 
newpriv)
  * preemptive context switch. As a result, do both.
  */
 env->load_res = -1;
+
+if (cpu_get_bcfien(env) && (env->priv != env->ss_priv)) {
+/*
+ * If backward CFI is enabled in the new privilege state, the
+ * shadow stack TLB needs to be flushed - unless the most recent
+ * use of the SS TLB was for the same privilege mode.
+ */
+tlb_flush_by_mmuidx(env_cpu(env), 1 << MMU_IDX_SS_ACCESS);
+/*
+ * Ignoring env->virt here since currently every time it flips,
+ * all TLBs are flushed anyway.
+ */
+env->ss_priv = env->priv;
+}
+}
+
+typedef enum {
+SSTACK_NO,  /* Access is not for a shadow stack instruction */
+SSTACK_YES, /* Access is for a shadow stack instruction */
+SSTACK_DC   /* Don't care about SS attribute in PMP */
+} SStackPmpMode;
+
+static bool legal_sstack_access(int access_type, bool sstack_inst,
+bool sstack_attribute)
+{
+/*
+ * Read/write/execution permissions are checked as usual. Shadow
+ * stack enforcement is just that (1) instruction type must match
+ * the attribute unless (2) a non-SS load to an SS region.
+ */
+return (sstack_inst == sstack_attribute) ||
+

[PATCH v1 RFC Zisslpcfi 8/9] target/riscv: Instructions encodings, implementation and handlers

2023-02-08 Thread Deepak Gupta
This patch implements instruction encodings for zisslpcfi instructions.
Additionally this patch implements zimops encodings as well. If Zisslpcfi
is supported by CPU but not enabled then all Zisslpcfi instructions
default to Zimops instuction behavior i.e. mov 0 to rd.

zisslpcfi defines following instructions.
- Backward control flow
- sspush x1/x5 : Decrement shadow stack pointer and pushes x1 or x5
 on shadow stack.
- sspop x1/x5 : Pops from shadow stack into x1 or x5. Increments
shadow stack pointer.
- ssprr : Reads current shadow stack pointer into a destination
  register.
- sscheckra : Compares x1 with x5. Raises illegal instr fault if
x1 != x5
- ssamoswap : Atomically swaps value on top of shadow stack

- Forward control flow
- lpsll, lpsml, lpsul : sets lower (9bit), mid (8bit) and upper
(8bit) label values in CSR_ULLP respectively.
- lpcll, lpcml, lpcul : checks lower (9bit), mid (8bit) and upper
(8bit) label values with CSR_ULLP
respectively.
Check label instructions raise illegal instruction fault when labels
mismatch.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu_bits.h   |  10 +
 target/riscv/helper.h |   7 +
 target/riscv/insn32.decode|  29 ++
 target/riscv/insn_trans/trans_rvi.c.inc   |  14 +
 target/riscv/insn_trans/trans_zimops.c.inc|  53 +++
 target/riscv/insn_trans/trans_zisslpcfi.c.inc | 310 ++
 target/riscv/op_helper.c  |  67 
 target/riscv/translate.c  |   2 +
 8 files changed, 492 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_zimops.c.inc
 create mode 100644 target/riscv/insn_trans/trans_zisslpcfi.c.inc

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 37100ec8f6..b2d527c626 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -600,6 +600,16 @@ typedef enum {
 LP_EXPECTED = 1,
 } cfi_elp;
 
+#define LPLR_UL(((1 << 8) - 1) << 17)
+#define LPLR_ML(((1 << 8) - 1) << 9)
+#define LPLR_LL((1 << 9) - 1)
+
+typedef enum {
+FCFI_LPLL = 0,
+FCFI_ML = 1,
+FCFI_UL = 2,
+} cfi_label_inst;
+
 /* hstatus CSR bits */
 #define HSTATUS_VSBE 0x0020
 #define HSTATUS_GVA  0x0040
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 227c7122ef..6484415612 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -97,6 +97,11 @@ DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
 DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
 DEF_HELPER_FLAGS_2(fclass_h, TCG_CALL_NO_RWG_SE, tl, env, i64)
 
+/* Forward CFI label checking */
+DEF_HELPER_2(cfi_jalr, void, env, int)
+DEF_HELPER_3(cfi_check_landing_pad, void, env, int, int)
+DEF_HELPER_3(cfi_set_landing_pad, void, env, int, int)
+
 /* Special functions */
 DEF_HELPER_2(csrr, tl, env, int)
 DEF_HELPER_3(csrw, void, env, int, tl)
@@ -112,6 +117,8 @@ DEF_HELPER_1(tlb_flush, void, env)
 /* Native Debug */
 DEF_HELPER_1(itrigger_match, void, env)
 #endif
+/* helper for back cfi mismatch */
+DEF_HELPER_1(sschkra_mismatch, void, env)
 
 /* Hypervisor functions */
 #ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index b7e7613ea2..cd734f03ae 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -37,6 +37,8 @@
 %imm_u12:s20 !function=ex_shift_12
 %imm_bs   30:2   !function=ex_shift_3
 %imm_rnum 20:4
+%imm_cfi9  15:9
+%imm_cfi8  15:8
 
 # Argument sets:
 
@@ -163,6 +165,33 @@ csrrwi    . 101 . 1110011 @csr
 csrrsi    . 110 . 1110011 @csr
 csrrci    . 111 . 1110011 @csr
 
+# zimops (unpriv integer may be operations) instructions with system opcode
+# These're superset of for cfi encodings. zimops_r and zimops_rr should be last
+# entry in below overlapping patterns so that it acts as final sink for 
overlapping patterns.
+# Any new encoding that can be used should be placed above mop.r and mop.rr
+
+# cfi instructions carved out of mop.r
+{
+  sspush10 0 11100 . 100 0 1110011 %rs1
+  sspop 10 0 11100 0 100 . 1110011 %rd
+  ssprr 10 0 11101 0 100 . 1110011 %rd
+  zimops_r  1-00-- 0 111-- - 100 . 1110011 %rd
+}
+
+# cfi instructions carved out of mop.rr
+{
+  sschckra  100010 1 1 00101 100 0 1110011
+  ssamoswap 10 1 . . 100 . 1110011 @r
+
+  lpsll 10 1 0 .100 0 1110011 %imm_cfi9
+  lpcll 10 1 1 .100 0 1110011 %imm_cfi9
+  lpsml 11 1 0 0100 0 1110011 %imm_cfi8
+  lpcml 11 1 0 1100 0 

[PATCH v1 RFC Zisslpcfi 5/9] target/riscv: state save and restore of zisslppcfi state

2023-02-08 Thread Deepak Gupta
zisslpcfi's forward cfi if enabled on a hart, enables tracking of
indirect branches. CPU/hart internally keeps a state `elp` short
for expecting landing pad instruction. This state goes into
LP_EXPECTED on an indirect branch. But an interrupt/exception can occur
before target instruction is executed. In such a case this state must be
preserved so that it can be restored later. zisslpcfi saves elp state in
`sstatus` CSR. This patch saves elp state in sstatus CSR on trap delivery
while restores from sstatus CSR on trap return.

Additionally state in sstatus CSR must have save and restore zisslpcfi
state on exiting from hypervisor and entering into hypervisor.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu_bits.h   |  5 +
 target/riscv/cpu_helper.c | 26 ++
 target/riscv/op_helper.c  | 12 
 3 files changed, 43 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 1663ba5775..37100ec8f6 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -594,6 +594,11 @@ typedef enum {
 
 #define CFISTATUS_S_MASK(SSTATUS_UFCFIEN | SSTATUS_UBCFIEN | \
  SSTATUS_SPELP)
+/* enum for branch tracking state in cpu/hart */
+typedef enum {
+NO_LP_EXPECTED = 0,
+LP_EXPECTED = 1,
+} cfi_elp;
 
 /* hstatus CSR bits */
 #define HSTATUS_VSBE 0x0020
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index a397023840..fc188683c9 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -534,6 +534,16 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
 if (riscv_has_ext(env, RVF)) {
 mstatus_mask |= MSTATUS_FS;
 }
+
+/*
+ * If cfi extension available, menvcfg.CFI = 1 and henvcfg.CFI = 1,
+ * then apply CFI mask on mstatus
+ */
+if (env_archcpu(env)->cfg.ext_cfi &&
+get_field(env->menvcfg, MENVCFG_CFI) &&
+get_field(env->henvcfg, HENVCFG_CFI)) {
+mstatus_mask |= CFISTATUS_S_MASK;
+}
 bool current_virt = riscv_cpu_virt_enabled(env);
 
 g_assert(riscv_has_ext(env, RVH));
@@ -1723,6 +1733,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 if (env->priv <= PRV_S &&
 cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) {
 /* handle the trap in S-mode */
+/* save elp status */
+if (cpu_get_fcfien(env)) {
+env->mstatus = set_field(env->mstatus, MSTATUS_SPELP, env->elp);
+}
 if (riscv_has_ext(env, RVH)) {
 uint64_t hdeleg = async ? env->hideleg : env->hedeleg;
 
@@ -1772,6 +1786,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 riscv_cpu_set_mode(env, PRV_S);
 } else {
 /* handle the trap in M-mode */
+/* save elp status */
+if (cpu_get_fcfien(env)) {
+env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, env->elp);
+}
 if (riscv_has_ext(env, RVH)) {
 if (riscv_cpu_virt_enabled(env)) {
 riscv_cpu_swap_hypervisor_regs(env);
@@ -1803,6 +1821,14 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 riscv_cpu_set_mode(env, PRV_M);
 }
 
+/*
+ * Interrupt/exception/trap delivery is asynchronous event and as per
+ * Zisslpcfi spec CPU should clear up the ELP state. If cfi extension is
+ * available, clear ELP state.
+ */
+if (cpu->cfg.ext_cfi) {
+env->elp = NO_LP_EXPECTED;
+}
 /* NOTE: it is not necessary to yield load reservations here. It is only
  * necessary for an SC from "another hart" to cause a load reservation
  * to be yielded. Refer to the memory consistency model section of the
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 878bcb03b8..d15893aa82 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -176,6 +176,12 @@ target_ulong helper_sret(CPURISCVState *env)
 riscv_cpu_set_virt_enabled(env, prev_virt);
 }
 
+/* If forward cfi enabled for target, restore elp status */
+if (cpu_get_fcfien(env)) {
+env->elp = get_field(env->mstatus, MSTATUS_SPELP);
+env->mstatus = set_field(env->mstatus, MSTATUS_SPELP, 0);
+}
+
 riscv_cpu_set_mode(env, prev_priv);
 
 return retpc;
@@ -220,6 +226,12 @@ target_ulong helper_mret(CPURISCVState *env)
 riscv_cpu_set_virt_enabled(env, prev_virt);
 }
 
+/* If forward cfi enabled for target, restore elp status */
+if (cpu_get_fcfien(env)) {
+env->elp = get_field(env->mstatus, MSTATUS_MPELP);
+env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, 0);
+}
+
 return retpc;
 }
 
-- 
2.25.1




[PATCH v1 RFC Zisslpcfi 1/9] target/riscv: adding zimops and zisslpcfi extension to RISCV cpu config

2023-02-08 Thread Deepak Gupta
Introducing riscv `zisslpcfi` extension to riscv target. `zisslpcfi`
extension provides hardware assistance to riscv hart to enable control
flow integrity (CFI) for software.

`zisslpcfi` extension expects hart to implement `zimops`. `zimops` stands
for "unprivileged integer maybe operations". `zimops` carve out certain
reserved opcodes encodings from integer spec to "may be operations"
encodings. `zimops` opcode encodings simply move 0 to rd.
`zisslpcfi` claims some of the `zimops` encodings and use them for shadow
stack management or indirect branch tracking. Any future extension can
also claim `zimops` encodings.

This patch also adds a dependency check for `zimops` to be enabled if
`zisslpcfi` is enabled on the hart.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu.c | 13 +
 target/riscv/cpu.h |  2 ++
 2 files changed, 15 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index cc75ca7667..6b4e90eb91 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -110,6 +110,8 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
 ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
 ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
+ISA_EXT_DATA_ENTRY(zimops, true, PRIV_VERSION_1_12_0, ext_zimops),
+ISA_EXT_DATA_ENTRY(zisslpcfi, true, PRIV_VERSION_1_12_0, ext_cfi),
 };
 
 static bool isa_ext_is_enabled(RISCVCPU *cpu,
@@ -792,6 +794,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 
+if (cpu->cfg.ext_cfi && !cpu->cfg.ext_zimops) {
+error_setg(errp, "Zisslpcfi extension requires Zimops extension");
+return;
+}
+
 /* Set the ISA extensions, checks should have happened above */
 if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
 cpu->cfg.ext_zhinxmin) {
@@ -1102,6 +1109,12 @@ static Property riscv_cpu_properties[] = {
 #ifndef CONFIG_USER_ONLY
 DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
 #endif
+/*
+ * Zisslpcfi CFI extension, Zisslpcfi implicitly means Zimops is
+ * implemented
+ */
+DEFINE_PROP_BOOL("zisslpcfi", RISCVCPU, cfg.ext_cfi, true),
+DEFINE_PROP_BOOL("zimops", RISCVCPU, cfg.ext_zimops, true),
 
 DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, 
false),
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f5609b62a2..9a923760b2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -471,6 +471,8 @@ struct RISCVCPUConfig {
 uint32_t mvendorid;
 uint64_t marchid;
 uint64_t mimpid;
+bool ext_zimops;
+bool ext_cfi;
 
 /* Vendor-specific custom extensions */
 bool ext_XVentanaCondOps;
-- 
2.25.1




[PATCH v1 RFC Zisslpcfi 2/9] target/riscv: zisslpcfi CSR, bit positions and other definitions

2023-02-08 Thread Deepak Gupta
`zisslpcfi` extension adds two new CSRs. CSR_SSP and CSR_LPLR.
- CSR_SSP: This CSR holds shadow stack pointer for current privilege mode
   CSR_SSP is accessible in all modes. Each mode must establish
   it's own CSR_SSP.

- CSR_LPLR: This CSR holds label value set at the callsite by compiler.
On call target label check instructions are emitted by
compiler which check label value against value present in
CSR_LPRL.

Enabling of `zisslpcfi` is controlled via menvcfg (for S/HS/VS/U/VU) and
henvcfg (for VS/VU) at bit position 60.

Each mode has enable/disable bits for forward cfi. Backward cfi doesn't
have separate enable/disable bits for S and M mode. User forward cfi and
user backward cfi enable/disable bits are in mstatus/sstatus CSR.
Supervisor forward cfi enable/disable bit are in menvcfg and henvcfg CSR.
Machine mode forward cfi enable/disable bit is in mseccfg CSR.

If forward cfi enabled, all indirect branches must land on a landing pad
instruction (`lpcll`, introduced in later commits). CPU/hart tracks this
internally using a landing pad tracker called `elp` short for `expecting
landing pad`. An interrupt can occur between an indirect branch and
target. If such an event occurs `elp` is saved away in mstatus/sstatus
CSR

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu.h  |  5 +
 target/riscv/cpu_bits.h | 25 +
 target/riscv/pmp.h  |  3 ++-
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9a923760b2..18db61a06a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -181,6 +181,11 @@ struct CPUArchState {
 
 uint32_t features;
 
+/* CFI Extension user mode registers and state */
+uint32_t lplr;
+target_ulong ssp;
+cfi_elp  elp;
+
 #ifdef CONFIG_USER_ONLY
 uint32_t elf_flags;
 #endif
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..1663ba5775 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -39,6 +39,10 @@
 
 /* Control and Status Registers */
 
+/* CFI CSRs */
+#define CSR_LPLR0x006
+#define CSR_SSP 0x020
+
 /* User Trap Setup */
 #define CSR_USTATUS 0x000
 #define CSR_UIE 0x004
@@ -542,6 +546,10 @@
 #define MSTATUS_TVM 0x0010 /* since: priv-1.10 */
 #define MSTATUS_TW  0x0020 /* since: priv-1.10 */
 #define MSTATUS_TSR 0x0040 /* since: priv-1.10 */
+#define MSTATUS_UFCFIEN 0x0080 /* Zisslpcfi-0.1 */
+#define MSTATUS_UBCFIEN 0x0100 /* Zisslpcfi-0.1 */
+#define MSTATUS_SPELP   0x0200 /* Zisslpcfi-0.1 */
+#define MSTATUS_MPELP   0x0400 /* Zisslpcfi-0.1 */
 #define MSTATUS_GVA 0x40ULL
 #define MSTATUS_MPV 0x80ULL
 
@@ -572,12 +580,21 @@ typedef enum {
 #define SSTATUS_XS  0x00018000
 #define SSTATUS_SUM 0x0004 /* since: priv-1.10 */
 #define SSTATUS_MXR 0x0008
+#define SSTATUS_UFCFIEN MSTATUS_UFCFIEN /* Zisslpcfi-0.1 */
+#define SSTATUS_UBCFIEN MSTATUS_UBCFIEN /* Zisslpcfi-0.1 */
+#define SSTATUS_SPELP   MSTATUS_SPELP   /* Zisslpcfi-0.1 */
 
 #define SSTATUS64_UXL   0x0003ULL
 
 #define SSTATUS32_SD0x8000
 #define SSTATUS64_SD0x8000ULL
 
+#define CFISTATUS_M_MASK(MSTATUS_UFCFIEN | MSTATUS_UBCFIEN | \
+ MSTATUS_MPELP | MSTATUS_SPELP)
+
+#define CFISTATUS_S_MASK(SSTATUS_UFCFIEN | SSTATUS_UBCFIEN | \
+ SSTATUS_SPELP)
+
 /* hstatus CSR bits */
 #define HSTATUS_VSBE 0x0020
 #define HSTATUS_GVA  0x0040
@@ -747,10 +764,14 @@ typedef enum RISCVException {
 #define MENVCFG_CBIE   (3UL << 4)
 #define MENVCFG_CBCFE  BIT(6)
 #define MENVCFG_CBZE   BIT(7)
+#define MENVCFG_SFCFIENBIT(59)
+#define MENVCFG_CFIBIT(60)
 #define MENVCFG_PBMTE  (1ULL << 62)
 #define MENVCFG_STCE   (1ULL << 63)
 
 /* For RV32 */
+#define MENVCFGH_SFCFIEN   BIT(27)
+#define MENVCFGH_CFI   BIT(28)
 #define MENVCFGH_PBMTE BIT(30)
 #define MENVCFGH_STCE  BIT(31)
 
@@ -763,10 +784,14 @@ typedef enum RISCVException {
 #define HENVCFG_CBIE   MENVCFG_CBIE
 #define HENVCFG_CBCFE  MENVCFG_CBCFE
 #define HENVCFG_CBZE   MENVCFG_CBZE
+#define HENVCFG_SFCFIENMENVCFG_SFCFIEN
+#define HENVCFG_CFIMENVCFG_CFI
 #define HENVCFG_PBMTE  MENVCFG_PBMTE
 #define HENVCFG_STCE   MENVCFG_STCE
 
 /* For RV32 */
+#define HENVCFGH_SFCFIENMENVCFGH_SFCFIEN
+#define HENVCFGH_CFIMENVCFGH_CFI
 

[PATCH v1 RFC Zisslpcfi 7/9] target/riscv: Tracking indirect branches (fcfi) using TCG

2023-02-08 Thread Deepak Gupta
zisslpcfi protects forward control flow (if enabled) by enforcing all
indirect call and jmp must land on a landing pad instruction `lpcll`
short for landing pad and check lower label value. If target of an
indirect call or jmp is not `lpcll` then cpu/hart must raise an illegal
instruction exception.

This patch implements the mechanism using TCG. Target architecture branch
instruction must define the end of a TB. Using this property, during
translation of branch instruction, TB flag = FCFI_LP_EXPECTED can be set.
Translation of target TB can check if FCFI_LP_EXPECTED flag is set and a
flag (fcfi_lp_expected) can be set in DisasContext. If `lpcll` gets
translated, fcfi_lp_expected flag in DisasContext can be cleared. Else
it'll fault.

This patch also also adds flag for forward and backward cfi in
DisasContext.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu.h|  3 +++
 target/riscv/cpu_helper.c | 12 +
 target/riscv/translate.c  | 52 +++
 3 files changed, 67 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8803ea6426..98b272bcad 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -644,6 +644,9 @@ FIELD(TB_FLAGS, VMA, 25, 1)
 /* Native debug itrigger */
 FIELD(TB_FLAGS, ITRIGGER, 26, 1)
 
+/* Zisslpcfi needs a TB flag to track indirect branches */
+FIELD(TB_FLAGS, FCFI_LP_EXPECTED, 27, 1)
+
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
 #else
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 63377abc2f..d15918f534 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -129,6 +129,18 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
 }
 
+if (cpu->cfg.ext_cfi) {
+/*
+ * For Forward CFI, only the expectation of a lpcll at
+ * the start of the block is tracked (which can only happen
+ * when FCFI is enabled for the current processor mode). A jump
+ * or call at the end of the previous TB will have updated
+ * env->elp to indicate the expectation.
+ */
+flags = FIELD_DP32(flags, TB_FLAGS, FCFI_LP_EXPECTED,
+   env->elp != NO_LP_EXPECTED);
+}
+
 #ifdef CONFIG_USER_ONLY
 flags |= TB_FLAGS_MSTATUS_FS;
 flags |= TB_FLAGS_MSTATUS_VS;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index df38db7553..7d43d20fc3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -41,6 +41,7 @@ static TCGv load_val;
 /* globals for PM CSRs */
 static TCGv pm_mask;
 static TCGv pm_base;
+static TCGOp *cfi_lp_check;
 
 #include "exec/gen-icount.h"
 
@@ -116,6 +117,10 @@ typedef struct DisasContext {
 bool itrigger;
 /* TCG of the current insn_start */
 TCGOp *insn_start;
+/* CFI extension */
+bool bcfi_enabled;
+bool fcfi_enabled;
+bool fcfi_lp_expected;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -1166,11 +1171,44 @@ static void 
riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
 ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
 ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
 ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
+ctx->bcfi_enabled = cpu_get_bcfien(env);
+ctx->fcfi_enabled = cpu_get_fcfien(env);
+ctx->fcfi_lp_expected = FIELD_EX32(tb_flags, TB_FLAGS, FCFI_LP_EXPECTED);
 ctx->zero = tcg_constant_tl(0);
 }
 
 static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
 {
+DisasContext *ctx = container_of(db, DisasContext, base);
+
+if (ctx->fcfi_lp_expected) {
+/*
+ * Since we can't look ahead to confirm that the first
+ * instruction is a legal landing pad instruction, emit
+ * compare-and-branch sequence that will be fixed-up in
+ * riscv_tr_tb_stop() to either statically hit or skip an
+ * illegal instruction exception depending on whether the
+ * flag was lowered by translation of a CJLP or JLP as
+ * the first instruction in the block.
+ */
+TCGv_i32 immediate;
+TCGLabel *l;
+l = gen_new_label();
+immediate = tcg_temp_local_new_i32();
+tcg_gen_movi_i32(immediate, 0);
+cfi_lp_check = tcg_last_op();
+tcg_gen_brcondi_i32(TCG_COND_EQ, immediate, 0, l);
+tcg_temp_free_i32(immediate);
+gen_exception_illegal(ctx);
+gen_set_label(l);
+/*
+ * Despite the use of gen_exception_illegal(), the rest of
+ * the TB needs to be generated. The TCG optimizer will
+ * clean things up depending on which path ends up being
+ * active.
+ */
+ctx->base.is_jmp = DISAS_NEXT;
+}
 }
 
 static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
@@ 

[PATCH v1 RFC Zisslpcfi 4/9] target/riscv: helper functions for forward and backward cfi

2023-02-08 Thread Deepak Gupta
Implementation for forward cfi and backward cfi needs helper function
to determine if currently fcfi and bcfi are enabled. Enable depends on
privilege mode and settings in sstatus/menvcfg/henvcfg/mseccfg CSRs.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu_helper.c | 51 +++
 2 files changed, 53 insertions(+)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 18db61a06a..d14ea4f91d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -568,6 +568,8 @@ bool riscv_cpu_virt_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
 bool riscv_cpu_two_stage_lookup(int mmu_idx);
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
+bool cpu_get_fcfien(CPURISCVState *env);
+bool cpu_get_bcfien(CPURISCVState *env);
 hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type, int 
mmu_idx,
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9a28816521..a397023840 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -30,6 +30,7 @@
 #include "sysemu/cpu-timers.h"
 #include "cpu_bits.h"
 #include "debug.h"
+#include "pmp.h"
 
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 {
@@ -40,6 +41,56 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #endif
 }
 
+bool cpu_get_fcfien(CPURISCVState *env)
+{
+#ifdef CONFIG_USER_ONLY
+return false;
+#else
+/* no cfi extension, return false */
+if (!env_archcpu(env)->cfg.ext_cfi) {
+return false;
+}
+
+switch (env->priv) {
+case PRV_U:
+return (env->mstatus & MSTATUS_UFCFIEN) ? true : false;
+case PRV_S:
+return (env->menvcfg & MENVCFG_SFCFIEN) ? true : false;
+case PRV_M:
+return (env->mseccfg & MSECCFG_MFCFIEN) ? true : false;
+default:
+g_assert_not_reached();
+}
+#endif
+}
+
+bool cpu_get_bcfien(CPURISCVState *env)
+{
+#ifdef CONFIG_USER_ONLY
+return false;
+#else
+/* no cfi extension, return false */
+if (!env_archcpu(env)->cfg.ext_cfi) {
+return false;
+}
+
+switch (env->priv) {
+case PRV_U:
+return (env->mstatus & MSTATUS_UBCFIEN) ? true : false;
+
+/*
+ * no gating for back cfi in M/S mode. back cfi is always on for
+ * M/S mode
+ */
+case PRV_S:
+case PRV_M:
+return true;
+default:
+g_assert_not_reached();
+}
+#endif
+}
+
 void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
   target_ulong *cs_base, uint32_t *pflags)
 {
-- 
2.25.1




[PATCH v1 RFC Zisslpcfi 9/9] target/riscv: diassembly support for zisslpcfi instructions

2023-02-08 Thread Deepak Gupta
This patch adds support to disassemble Zisslpcfi instructions.

Signed-off-by: Deepak Gupta 
Signed-off-by: Kip Walker  
---
 disas/riscv.c | 127 +-
 1 file changed, 126 insertions(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index d216b9c39b..d16ee617b0 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -163,6 +163,7 @@ typedef enum {
 rv_codec_v_i,
 rv_codec_vsetvli,
 rv_codec_vsetivli,
+rv_codec_lp,
 } rv_codec;
 
 typedef enum {
@@ -935,6 +936,19 @@ typedef enum {
 rv_op_vsetvli = 766,
 rv_op_vsetivli = 767,
 rv_op_vsetvl = 768,
+rv_op_lpsll = 769,
+rv_op_lpcll = 770,
+rv_op_lpsml = 771,
+rv_op_lpcml = 772,
+rv_op_lpsul = 773,
+rv_op_lpcul = 774,
+rv_op_sspush = 775,
+rv_op_sspop = 776,
+rv_op_ssprr = 777,
+rv_op_ssamoswap = 778,
+rv_op_sschkra = 779,
+rv_op_zimops_r = 780,
+rv_op_zimops_rr = 781,
 } rv_op;
 
 /* structures */
@@ -1011,6 +1025,7 @@ static const char rv_vreg_name_sym[32][4] = {
 #define rv_fmt_pred_succ  "O\tp,s"
 #define rv_fmt_rs1_rs2"O\t1,2"
 #define rv_fmt_rd_imm "O\t0,i"
+#define rv_fmt_imm"O\ti"
 #define rv_fmt_rd_offset  "O\t0,o"
 #define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
 #define rv_fmt_frd_rs1"O\t3,1"
@@ -2065,7 +2080,20 @@ const rv_opcode_data opcode_data[] = {
 { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, 
rv_op_vsext_vf8, 0 },
 { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, 
rv_op_vsetvli, 0 },
 { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, 
rv_op_vsetivli, 0 },
-{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 }
+{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 },
+{ "lpsll", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpcll", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpsml", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpcml", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpsul", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "lpcul", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 },
+{ "sspush", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+{ "sspop", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 },
+{ "ssprr", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 },
+{ "ssamoswap", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
+{ "sschkra", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
+{ "zimops_r", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 },
+{ "zimops_rr", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 }
 };
 
 /* CSR names */
@@ -2084,6 +2112,8 @@ static const char *csr_name(int csrno)
 case 0x000a: return "vxrm";
 case 0x000f: return "vcsr";
 case 0x0015: return "seed";
+case 0x0006: return "lplr";
+case 0x0020: return "ssp";
 case 0x0040: return "uscratch";
 case 0x0041: return "uepc";
 case 0x0042: return "ucause";
@@ -3554,6 +3584,87 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 case 1: op = rv_op_csrrw; break;
 case 2: op = rv_op_csrrs; break;
 case 3: op = rv_op_csrrc; break;
+case 4:
+/* if matches mop_r mask */
+if inst >> 15) & 0b101100000) ==
+0b100111000)) {
+if ((inst >> 25) == 0b100) {
+switch ((inst >> 20) & 0b11) {
+case 0: /* sspush and sspop */
+if (((inst >> 15) & 0b1) &&
+!((inst >> 7) & 0b1))
+op = rv_op_sspush;
+if (!((inst >> 15) & 0b1) &&
+((inst >> 7) & 0b1))
+op = rv_op_sspop;
+break;
+
+case 1: /* ssprr */
+if (!((inst >> 15) & 0b1) &&
+((inst >> 7) & 0b1))
+op = rv_op_ssprr;
+break;
+
+default:
+op = rv_op_zimops_r;
+break;
+}
+} else {
+op = rv_op_zimops_r;
+}
+} else if (((inst >> 15) & 0b101100100) ==
+0b10100) { /* if matches mop_rr mask */
+switch (inst >> 28) {
+case 0b1000:
+switch ((inst >> 7) & 0b1) {
+case 0b0:
+/* collect 5 bits */
+switch (((inst >> 23) & 0b1)) {
+case 23:
+op = 

Re: [PATCH v3 4/6] i386: Mask and report unavailable multi-bit feature values

2023-02-08 Thread Wang, Lei
On 2/9/2023 1:59 PM, Xiaoyao Li wrote:
> On 2/9/2023 12:21 PM, Wang, Lei wrote:
>> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
>> index 88aa780566..e638a31d34 100644
>> --- a/target/i386/cpu.c
>> +++ b/target/i386/cpu.c
>> @@ -4377,6 +4377,28 @@ static bool x86_cpu_have_filtered_features(X86CPU
>> *cpu)
>>    return false;
>>    }
>>
>> +static void mark_unavailable_multi_bit_default(X86CPU *cpu, FeatureWord 
>> w,
>> +   int index,
>> +   const char 
>> *verbose_prefix)
>> +{
>> +    FeatureWordInfo *f = _word_info[w];
>> +    g_autofree char *feat_word_str = feature_word_description(f);
>> +    uint64_t host_feat = x86_cpu_get_supported_feature_word(w, false);
>> +    MultiBitFeatureInfo mf = f->multi_bit_features[index];
>> +
>> +    if ((cpu->env.features[w] & mf.mask) &&
> With this checking bits are all 0 but covered by mf.mask's range are 
> skippped,
> even if they're different from the host_feat, please check whether it's
> desried
> behavior.
 This is the intended design because there are quite a number of multi-bit
 CPUIDs
 should support passing all 0 to them.
>>> you didn't answer the question. The question is why the handling can be 
>>> skipped
>>> when the value of multi-bit feature is 0.
>> I think the default function should handle the most common case, which is,
>> passing all 0 multi-bits to KVM is valid and shouldn't be warned. E.g, when 
>> we
>> are using some earlier CPU models which doesn't support AMX, we shouldn't be
>> warned that all 0 values don't match the CPUID reported by KVM.
>>
> 
> passing value 0 to KVM is valid, is not the reason why the handling can be 
> skipped.
> 
> The correct reason is that when value is 0, it means the multi-bit feature is
> not enabled/requested. It's always legal and doesn't need any handling. So it
> can be just skipped.

Currently, we can say yes, but I doubt if there will be a multi-bit field in the
future that only accepts the non-zero value specified.



Re: [PATCH RFC 0/7] revert RNG seed mess

2023-02-08 Thread Dov Murik
Hi Michael,

On 08/02/2023 23:12, Michael S. Tsirkin wrote:
> All attempts to fix up passing RNG seed via setup_data entry failed.
> Let's just rip out all of it.  We'll start over.
> 
> 
> Warning: all I did was git revert the relevant patches and resolve the
> (trivial) conflicts. Not even compiled - it's almost midnight here.
> 
> Jason this is the kind of approach I'd like to see, not yet another
> pointer math rich patch I need to spend time reviewing. Just get us back
> to where we started. We can redo "x86: use typedef for SetupData struct"
> later if we want, it's benign.
> 
> Could you do something like this pls?
> Or test and ack if this patchset happens to work by luck.
> 
> Michael S. Tsirkin (7):
>   Revert "x86: don't let decompressed kernel image clobber setup_data"
>   Revert "x86: do not re-randomize RNG seed on snapshot load"
>   Revert "x86: re-initialize RNG seed when selecting kernel"
>   Revert "x86: reinitialize RNG seed on system reboot"
>   Revert "x86: use typedef for SetupData struct"
>   Revert "x86: return modified setup_data only if read as memory, not as
> file"
>   Revert "hw/i386: pass RNG seed via setup_data entry"
> 
>  include/hw/i386/microvm.h |   5 +-
>  include/hw/i386/pc.h  |   3 -
>  include/hw/i386/x86.h |   3 +-
>  include/hw/nvram/fw_cfg.h |  31 --
>  hw/i386/microvm.c |  17 ++
>  hw/i386/pc.c  |   4 +-
>  hw/i386/pc_piix.c |   2 -
>  hw/i386/pc_q35.c  |   2 -
>  hw/i386/x86.c | 122 ++
>  hw/nvram/fw_cfg.c |  21 ++-
>  10 files changed, 49 insertions(+), 161 deletions(-)
> 


I tested this series with SEV measured boot using AmdSev OVMF.  The boot
succeeds, and the hashes computed for kernel/initrd/cmdline are
identical to the ones computed by qemu 7.1.0, which are the hashes that
the guest owner would expect.

As for non-EFI (non-SEV) guests, I did a very simple test of starting a
non-EFI guest and it looks OK, but more testing is needed.

So:

Tested-by: Dov Murik 


Thank you!

-Dov



Re: [PATCH v3 4/6] i386: Mask and report unavailable multi-bit feature values

2023-02-08 Thread Xiaoyao Li

On 2/9/2023 12:21 PM, Wang, Lei wrote:

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 88aa780566..e638a31d34 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4377,6 +4377,28 @@ static bool x86_cpu_have_filtered_features(X86CPU *cpu)
   return false;
   }

+static void mark_unavailable_multi_bit_default(X86CPU *cpu, FeatureWord w,
+   int index,
+   const char *verbose_prefix)
+{
+    FeatureWordInfo *f = _word_info[w];
+    g_autofree char *feat_word_str = feature_word_description(f);
+    uint64_t host_feat = x86_cpu_get_supported_feature_word(w, false);
+    MultiBitFeatureInfo mf = f->multi_bit_features[index];
+
+    if ((cpu->env.features[w] & mf.mask) &&

With this checking bits are all 0 but covered by mf.mask's range are skippped,
even if they're different from the host_feat, please check whether it's desried
behavior.

This is the intended design because there are quite a number of multi-bit CPUIDs
should support passing all 0 to them.

you didn't answer the question. The question is why the handling can be skipped
when the value of multi-bit feature is 0.

I think the default function should handle the most common case, which is,
passing all 0 multi-bits to KVM is valid and shouldn't be warned. E.g, when we
are using some earlier CPU models which doesn't support AMX, we shouldn't be
warned that all 0 values don't match the CPUID reported by KVM.



passing value 0 to KVM is valid, is not the reason why the handling can 
be skipped.


The correct reason is that when value is 0, it means the multi-bit 
feature is not enabled/requested. It's always legal and doesn't need any 
handling. So it can be just skipped.




[PATCH] target/riscv: Smepmp: Skip applying default rules when address matches

2023-02-08 Thread Himanshu Chauhan
When MSECCFG.MML is set, after checking the address range in PMP if the
asked permissions are not same as programmed in PMP, the default
permissions are applied. This should only be the case when there
is no matching address is found.

This patch skips applying default rules when matching address range
is found. It returns the index of the match PMP entry.

fixes: 824cac681c3 (target/riscv: Fix PMP propagation for tlb)

Signed-off-by: Himanshu Chauhan 
---
 target/riscv/pmp.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index d85ad07caa..0dfdb35828 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -446,9 +446,12 @@ int pmp_hart_has_privs(CPURISCVState *env, target_ulong 
addr,
 }
 }
 
-if ((privs & *allowed_privs) == privs) {
-ret = i;
-}
+/*
+ * If matching address range was found, the protection bits
+ * defined with PMP must be used. We shouldn't fallback on
+ * finding default privileges.
+ */
+ret = i;
 break;
 }
 }
-- 
2.39.1




Re: [PATCH v2 00/10] Kconfig vs. default devices

2023-02-08 Thread Thomas Huth

On 08/02/2023 20.43, Philippe Mathieu-Daudé wrote:

On 8/2/23 20:26, Fabiano Rosas wrote:


We currently have a situation where disabling a Kconfig might result
in a runtime error when QEMU selects the corresponding device as a
default value for an option. But first a disambiguation:

Kconfig default::
   a device "Foo" for which there's "config FOO default y" or "config X
   imply FOO" in Kconfig.

QEMU hardcoded default::
   a fallback; a device "Foo" that is chosen in case no corresponding
   option is given in the command line.

The issue I'm trying to solve is that there is no link between the two
"defaults" above, which means that when the user at build time
de-selects a Kconfig default, either via configs/devices/*/*.mak or
--without-default-devices, the subsequent invocation at runtime might
continue to try to create the missing device due to QEMU defaults.


This will keep bitrotting if we don't cover such configs in our CI.

Why do you want to get this fixed BTW? I'm not sure there is a big
interest (as in "almost no users").

I tried to do that few years ago [*] and Thomas said:

"in our CI, we should test what users really need,
  and not each and every distantly possible combination."


You're mis-quoting me here. That comment was made when we were talking about 
very arbitrary configs that likely nobody is going to use.
Fabiano's series here is about the --without-default-devices configure 
option which everybody could add to their set of "configure" options easily.


 Thomas




Re: [PULL 07/11] readconfig-test: add test for accelerator configuration

2023-02-08 Thread Thomas Huth

On 08/02/2023 18.19, Paolo Bonzini wrote:

Test that it does not cause a SIGSEGV, and cover a valid configuration
as well.

Signed-off-by: Paolo Bonzini 
---
  tests/qtest/libqtest.c| 28 +-
  tests/qtest/libqtest.h| 12 ++
  tests/qtest/readconfig-test.c | 45 ---
  3 files changed, 70 insertions(+), 15 deletions(-)

diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index ce5f235e25f1..4fba2bb27f06 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -420,6 +420,26 @@ static QTestState *G_GNUC_PRINTF(1, 2) 
qtest_spawn_qemu(const char *fmt, ...)
  return s;
  }
  
+QTestState *G_GNUC_PRINTF(1, 0) qtest_init_bare(const char *args)

+{
+QTestState *s = qtest_spawn_qemu("%s", args);
+
+/*
+ * Stopping QEMU for debugging is not supported on Windows.
+ *
+ * Using DebugActiveProcess() API can suspend the QEMU process,
+ * but gdb cannot attach to the process. Using the undocumented
+ * NtSuspendProcess() can suspend the QEMU process and gdb can
+ * attach to the process, but gdb cannot resume it.
+ */
+#ifndef _WIN32
+if (getenv("QTEST_STOP")) {
+kill(s->qemu_pid, SIGSTOP);
+}
+#endif
+return s;
+}


You missed my review comments here:

https://lore.kernel.org/qemu-devel/2f17c06f-90a9-9bac-8e9a-a1a284266...@redhat.com/

 Thomas




Re: [PULL 00/11] Misc patches for 2022-02-08

2023-02-08 Thread Thomas Huth

On 08/02/2023 18.19, Paolo Bonzini wrote:

The following changes since commit ae2b5d8381a73b27f35f19c988d45c78bb4d5768:

   Merge tag 'pull-include-2023-02-06-v2' of https://repo.or.cz/qemu/armbru 
into staging (2023-02-08 10:40:06 +)

are available in the Git repository at:

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

for you to fetch changes up to e0de04cf9bd7cf03db16f33276679caf1724b75c:

   target/i386: fix ADOX followed by ADCX (2023-02-08 18:16:55 +0100)


* block/iscsi: fix double-free on BUSY or similar statuses
* catch [accel] entry without accelerator
* target/i386: various fixes for BMI and ADX instructions
* make the contents of meson-buildoptions.sh stable


Paolo Bonzini (8):
   build: make meson-buildoptions.sh stable
   remove unnecessary extern "C" blocks
   block/iscsi: fix double-free on BUSY or similar statuses
   vl: catch [accel] entry without accelerator


You missed Philippe's review comment for that patch:

https://lore.kernel.org/qemu-devel/8ec3abf5-f4aa-db40-cb7e-2f5733d93...@linaro.org/

 Thomas




Re: [PATCH 02/10] hw/riscv/virt: Add a switch to enable/disable ACPI

2023-02-08 Thread Thomas Huth

On 08/02/2023 17.48, Andrea Bolognani wrote:

On Tue, Feb 07, 2023 at 08:20:31PM +0100, Andrew Jones wrote:

On Tue, Feb 07, 2023 at 06:38:15AM -0800, Andrea Bolognani wrote:

Well, it looks like -no-acpi will come for free after all, thanks to
the code you pasted above, as long as the machine property follows
the convention established by x86, arm and (I just noticed this one)
loongarch.


Not quite, because we also have

$ grep -A1 '"no-acpi"' qemu-options.hx
DEF("no-acpi", 0, QEMU_OPTION_no_acpi,
"-no-acpidisable ACPI\n", QEMU_ARCH_I386 | QEMU_ARCH_ARM)

So that means neither riscv nor loongarch get -no-acpi just by adding
the "acpi" machine property.

If the plan is to deprecate -no-acpi, then riscv can be like loongarch
and only have the "acpi" property from the start.


Makes sense.


For the libvirt integration, do I understand correctly that the
machine property was added by commit

   commit 17e89077b7e3bc1d96540e21ddc7451c3e077049
   Author: Gerd Hoffmann 
   Date:   Fri Mar 20 11:01:36 2020 +0100

 acpi: add acpi=OnOffAuto machine property to x86 and arm virt

 Remove the global acpi_enabled bool and replace it with an
 acpi OnOffAuto machine property.

 qemu throws an error now if you use -no-acpi while the machine
 type you are using doesn't support acpi in the first place.

 Signed-off-by: Gerd Hoffmann 
 Message-Id: <20200320100136.11717-1-kra...@redhat.com>
 Reviewed-by: Philippe Mathieu-Daudé 
 Acked-by: Paolo Bonzini 
 Reviewed-by: Michael S. Tsirkin 
 Signed-off-by: Michael S. Tsirkin 

included in QEMU 5.0? libvirt still officially supports QEMU 4.2, so
we'll have to make the use of the machine property conditional.


Sounds right, and testing for the machine option should be possible with the 
upcoming QEMU 8.0. FWIW, I assume this is similar to the -no-hpet option 
which has been turned into a machine property, too:


https://gitlab.com/libvirt/libvirt/-/commit/3c508e7d4310aeb8

 Thomas




Re: [PATCH] MAINTAINERS: Add some RISC-V reviewers

2023-02-08 Thread weiwei



On 2023/2/9 08:33, Alistair Francis wrote:

From: Alistair Francis 

This patch adds some active RISC-V members as reviewers to the
MAINTAINERS file.

Signed-off-by: Alistair Francis 
---
  MAINTAINERS | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e25f62ac..847bc7f131 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -287,6 +287,9 @@ RISC-V TCG CPUs
  M: Palmer Dabbelt 
  M: Alistair Francis 
  M: Bin Meng 
+R: Weiwei Li 
+R: Daniel Henrique Barboza 
+R: Liu Zhiwei 
  L: qemu-ri...@nongnu.org
  S: Supported
  F: target/riscv/


Acked-by: Weiwei Li 

Regards,

Weiwei Li




Re: [PATCH v3 4/6] i386: Mask and report unavailable multi-bit feature values

2023-02-08 Thread Wang, Lei
On 2/9/2023 11:29 AM, Xiaoyao Li wrote:
> On 2/9/2023 9:04 AM, Wang, Lei wrote:
>> On 2/6/2023 3:43 PM, Yuan Yao wrote:
>>> On Fri, Jan 06, 2023 at 12:38:24AM -0800, Lei Wang wrote:
 Some feature words, e.g., feature words in AMX-related CPUID leaf 0x1D and
 0x1E are not bit-wise but multiple bits represents one value. Handle this
 situation when the values specified are not the same as which are reported
 by KVM. The handling includes:

   - The responsibility of masking bits and giving warnings are delegated to
     the feature enabler. A framework is also provided to enable this.
   - To simplify the initialization, a default function is provided if the
     the function is not specified.
> 
> What's the behavior of default ? you need to call out it clearly.
> 
 The reason why delegating this responsibility rather than just marking
 them as zeros when they are not same is because different multi-bit
 features may have different logic, which is case by case, for example:

   1. CPUID.0x14_0x1:EBX[15:0]. Even though it's multi-bits field, it's a
  bitmap and each bit represents a separate capability.

   2. CPUID.0x14_0x1:EAX[2:0] represents the number of configurable Address
  Ranges. 3 bits as a whole to represent a integer value. It means the
  maximum capability of HW. If KVM reports M, then M to 0 is legal
  value to configure (because KVM can emulate each value correctly).

   3. CPUID.0x1D_0x1:EAX[31:16] represents palette 1 bytes_per_tile. 16 bits
  as a whole represent an integer value. It's not like case 2 and SW
  needs to configure the same value as reported. Because it's not
  possible for SW to configure to a different value and KVM cannot
  emulate it.

 So marking them blindly as zeros is incorrect, and delegating this
 responsibility can let each multi-bit feature have its own way to mask 
 bits.
> 
> you can first describe there are such 3 cases of multi-bit features and they
> need different handling for checking whether configured value is supported by
> KVM or not. So introduce a handling callback function that each multi-bit
> feature can implement their own. Meanwhile, provide a default handling 
> callback
> that handles case x: when configured value is not the same as the one reported
> by KVM, clearing it to zero to mark it as unavailable.

OK, will rephrase the commit message.

> 
 Signed-off-by: Lei Wang 
 ---
   target/i386/cpu-internal.h |  2 ++
   target/i386/cpu.c  | 36 
   2 files changed, 38 insertions(+)

 diff --git a/target/i386/cpu-internal.h b/target/i386/cpu-internal.h
 index 66b3d66cb4..83c7b53926 100644
 --- a/target/i386/cpu-internal.h
 +++ b/target/i386/cpu-internal.h
 @@ -30,6 +30,8 @@ typedef struct MultiBitFeatureInfo {
   uint64_t mask;
   unsigned high_bit_position;
   unsigned low_bit_position;
 +    void (*mark_unavailable_multi_bit)(X86CPU *cpu, FeatureWord w, int 
 index,
 +   const char *verbose_prefix);
   } MultiBitFeatureInfo;

   typedef struct FeatureWordInfo {
 diff --git a/target/i386/cpu.c b/target/i386/cpu.c
 index 88aa780566..e638a31d34 100644
 --- a/target/i386/cpu.c
 +++ b/target/i386/cpu.c
 @@ -4377,6 +4377,28 @@ static bool x86_cpu_have_filtered_features(X86CPU 
 *cpu)
   return false;
   }

 +static void mark_unavailable_multi_bit_default(X86CPU *cpu, FeatureWord w,
 +   int index,
 +   const char *verbose_prefix)
 +{
 +    FeatureWordInfo *f = _word_info[w];
 +    g_autofree char *feat_word_str = feature_word_description(f);
 +    uint64_t host_feat = x86_cpu_get_supported_feature_word(w, false);
 +    MultiBitFeatureInfo mf = f->multi_bit_features[index];
 +
 +    if ((cpu->env.features[w] & mf.mask) &&
>>>
>>> With this checking bits are all 0 but covered by mf.mask's range are 
>>> skippped,
>>> even if they're different from the host_feat, please check whether it's 
>>> desried
>>> behavior.
>>
>> This is the intended design because there are quite a number of multi-bit 
>> CPUIDs
>> should support passing all 0 to them.
> 
> you didn't answer the question. The question is why the handling can be 
> skipped
> when the value of multi-bit feature is 0.

I think the default function should handle the most common case, which is,
passing all 0 multi-bits to KVM is valid and shouldn't be warned. E.g, when we
are using some earlier CPU models which doesn't support AMX, we shouldn't be
warned that all 0 values don't match the CPUID reported by KVM.

> 
 +    ((cpu->env.features[w] ^ host_feat) & mf.mask)) {
 +    if (!cpu->force_features) {

[PATCH v11 6/9] target/riscv: add support for Zcmp extension

2023-02-08 Thread Weiwei Li
Add encode, trans* functions for Zcmp instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn16.decode|  18 +++
 target/riscv/insn_trans/trans_rvzce.c.inc | 189 +-
 target/riscv/translate.c  |   5 +
 3 files changed, 211 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index ab780fa46a..55c9574299 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -21,6 +21,8 @@
 %rs1_3 7:3!function=ex_rvc_register
 %rs2_3 2:3!function=ex_rvc_register
 %rs2_5 2:5
+%r1s   7:3!function=ex_sreg_register
+%r2s   2:3!function=ex_sreg_register
 
 # Immediates:
 %imm_ci12:s1 2:5
@@ -45,6 +47,8 @@
 
 %uimm_cl_b  5:1 6:1
 %uimm_cl_h  5:1  !function=ex_shift_1
+%spimm  2:2  !function=ex_shift_4
+%urlist 4:4
 
 # Argument sets imported from insn32.decode:
   !extern
@@ -56,7 +60,9 @@
  imm rd   !extern
  shamt rs1 rd !extern
 rd rs1   !extern
+_s  rs1 rs2  !extern
 
+  urlist spimm
 
 # Formats 16:
 @cr  . .  ..   rs2=%rs2_5   rs1=%rd %rd
@@ -97,6 +103,8 @@
 @cl_h ... . .. ... .. ... ..imm=%uimm_cl_h  rs1=%rs1_3 rd=%rs2_3
 @cs_b ... . .. ... .. ... ..imm=%uimm_cl_b  rs1=%rs1_3 rs2=%rs2_3
 @cs_h ... . .. ... .. ... ..imm=%uimm_cl_h  rs1=%rs1_3 rs2=%rs2_3
+@cm_pp... ...     ..%urlist  %spimm
+@cm_mv... ...  ... .. ... ..  _s  rs2=%r2s rs1=%r1s
 
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
@@ -176,6 +184,16 @@ slli  000 .  .  . 10 @c_shift2
 {
   sq  101  ... ... .. ... 10 @c_sqsp
   c_fsd   101   ..  . 10 @c_sdsp
+
+  # *** RV64 and RV32 Zcmp Extension ***
+  [
+cm_push 101  11000   .. 10 @cm_pp
+cm_pop  101  11010   .. 10 @cm_pp
+cm_popret   101  0   .. 10 @cm_pp
+cm_popretz  101  11100   .. 10 @cm_pp
+cm_mva01s   101  011 ... 11 ... 10 @cm_mv
+cm_mvsa01   101  011 ... 01 ... 10 @cm_mv
+  ]
 }
 sw110 .  .  . 10 @c_swsp
 
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
index de96c4afaf..ac597e1ee2 100644
--- a/target/riscv/insn_trans/trans_rvzce.c.inc
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -1,5 +1,5 @@
 /*
- * RISC-V translation routines for the Zcb Standard Extension.
+ * RISC-V translation routines for the Zc[b,mp] Standard Extensions.
  *
  * Copyright (c) 2021-2022 PLCT Lab
  *
@@ -21,6 +21,11 @@
 return false;   \
 } while (0)
 
+#define REQUIRE_ZCMP(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zcmp) \
+return false;\
+} while (0)
+
 static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
 {
 REQUIRE_ZCB(ctx);
@@ -98,3 +103,185 @@ static bool trans_c_sh(DisasContext *ctx, arg_c_sh *a)
 REQUIRE_ZCB(ctx);
 return gen_store(ctx, a, MO_UW);
 }
+
+#define X_S08
+#define X_S19
+#define X_Sn16
+
+static uint32_t decode_push_pop_list(DisasContext *ctx, target_ulong rlist)
+{
+uint32_t reg_bitmap = 0;
+
+if (ctx->cfg_ptr->ext_e && rlist > 6) {
+return 0;
+}
+
+switch (rlist) {
+case 15:
+reg_bitmap |=  1 << (X_Sn + 11) ;
+reg_bitmap |=  1 << (X_Sn + 10) ;
+/* FALL THROUGH */
+case 14:
+reg_bitmap |=  1 << (X_Sn + 9) ;
+/* FALL THROUGH */
+case 13:
+reg_bitmap |=  1 << (X_Sn + 8) ;
+/* FALL THROUGH */
+case 12:
+reg_bitmap |=  1 << (X_Sn + 7) ;
+/* FALL THROUGH */
+case 11:
+reg_bitmap |=  1 << (X_Sn + 6) ;
+/* FALL THROUGH */
+case 10:
+reg_bitmap |=  1 << (X_Sn + 5) ;
+/* FALL THROUGH */
+case 9:
+reg_bitmap |=  1 << (X_Sn + 4) ;
+/* FALL THROUGH */
+case 8:
+reg_bitmap |=  1 << (X_Sn + 3) ;
+/* FALL THROUGH */
+case 7:
+reg_bitmap |=  1 << (X_Sn + 2) ;
+/* FALL THROUGH */
+case 6:
+reg_bitmap |=  1 << X_S1 ;
+/* FALL THROUGH */
+case 5:
+reg_bitmap |= 1 << X_S0;
+/* FALL THROUGH */
+case 4:
+reg_bitmap |= 1 << xRA;
+break;
+default:
+break;
+}
+
+return reg_bitmap;
+}
+
+static bool gen_pop(DisasContext *ctx, arg_cmpp *a, bool ret, bool ret_val)
+{
+REQUIRE_ZCMP(ctx);
+
+uint32_t reg_bitmap = decode_push_pop_list(ctx, a->urlist);
+if (reg_bitmap == 0) {
+return false;
+}
+
+MemOp memop = get_ol(ctx) == MXL_RV32 ? MO_TEUL : MO_TEUQ;
+int reg_size = memop_size(memop);
+target_ulong stack_adj = 

[PATCH v11 4/9] target/riscv: add support for Zcd extension

2023-02-08 Thread Weiwei Li
Separate c_fld/c_fsd from fld/fsd to add additional check for
c.fld{sp}/c.fsd{sp} which is useful for zcmp/zcmt to reuse
their encodings

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn16.decode  |  8 
 target/riscv/insn_trans/trans_rvd.c.inc | 18 ++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index f3ea650325..b62664b6af 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -97,12 +97,12 @@
 }
 {
   lq  001  ... ... .. ... 00 @cl_q
-  fld 001  ... ... .. ... 00 @cl_d
+  c_fld   001  ... ... .. ... 00 @cl_d
 }
 lw010  ... ... .. ... 00 @cl_w
 {
   sq  101  ... ... .. ... 00 @cs_q
-  fsd 101  ... ... .. ... 00 @cs_d
+  c_fsd   101  ... ... .. ... 00 @cs_d
 }
 sw110  ... ... .. ... 00 @cs_w
 
@@ -148,7 +148,7 @@ addw  100 1 11 ... 01 ... 01 @cs_2
 slli  000 .  .  . 10 @c_shift2
 {
   lq  001  ... ... .. ... 10 @c_lqsp
-  fld 001 .  .  . 10 @c_ldsp
+  c_fld   001 .  .  . 10 @c_ldsp
 }
 {
   illegal 010 -  0  - 10 # c.lwsp, RES rd=0
@@ -166,7 +166,7 @@ slli  000 .  .  . 10 @c_shift2
 }
 {
   sq  101  ... ... .. ... 10 @c_sqsp
-  fsd 101   ..  . 10 @c_sdsp
+  c_fsd   101   ..  . 10 @c_sdsp
 }
 sw110 .  .  . 10 @c_swsp
 
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc 
b/target/riscv/insn_trans/trans_rvd.c.inc
index 6e3159b797..47849ffdfd 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -31,6 +31,12 @@
 } \
 } while (0)
 
+#define REQUIRE_ZCD(ctx) do { \
+if (!ctx->cfg_ptr->ext_zcd) {  \
+return false; \
+} \
+} while (0)
+
 static bool trans_fld(DisasContext *ctx, arg_fld *a)
 {
 TCGv addr;
@@ -59,6 +65,18 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 return true;
 }
 
+static bool trans_c_fld(DisasContext *ctx, arg_fld *a)
+{
+REQUIRE_ZCD(ctx);
+return trans_fld(ctx, a);
+}
+
+static bool trans_c_fsd(DisasContext *ctx, arg_fsd *a)
+{
+REQUIRE_ZCD(ctx);
+return trans_fsd(ctx, a);
+}
+
 static bool trans_fmadd_d(DisasContext *ctx, arg_fmadd_d *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v11 7/9] target/riscv: add support for Zcmt extension

2023-02-08 Thread Weiwei Li
Add encode, trans* functions and helper functions support for Zcmt
instrutions
Add support for jvt csr

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h|  4 ++
 target/riscv/cpu_bits.h   |  7 +++
 target/riscv/csr.c| 38 +++-
 target/riscv/helper.h |  3 ++
 target/riscv/insn16.decode|  7 ++-
 target/riscv/insn_trans/trans_rvzce.c.inc | 28 +++-
 target/riscv/machine.c| 19 
 target/riscv/meson.build  |  3 +-
 target/riscv/zce_helper.c | 55 +++
 9 files changed, 159 insertions(+), 5 deletions(-)
 create mode 100644 target/riscv/zce_helper.c

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4bfe22c468..403c4ff894 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -186,6 +186,8 @@ struct CPUArchState {
 
 uint32_t features;
 
+target_ulong jvt;
+
 #ifdef CONFIG_USER_ONLY
 uint32_t elf_flags;
 #endif
@@ -612,6 +614,8 @@ void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, 
uint32_t priv,
  target_ulong new_val,
  target_ulong write_mask),
void *rmw_fn_arg);
+
+RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit);
 #endif
 void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8b0d7e20ea..ce347e5575 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -319,6 +319,7 @@
 #define SMSTATEEN_MAX_COUNT 4
 #define SMSTATEEN0_CS   (1ULL << 0)
 #define SMSTATEEN0_FCSR (1ULL << 1)
+#define SMSTATEEN0_JVT  (1ULL << 2)
 #define SMSTATEEN0_HSCONTXT (1ULL << 57)
 #define SMSTATEEN0_IMSIC(1ULL << 58)
 #define SMSTATEEN0_AIA  (1ULL << 59)
@@ -523,6 +524,9 @@
 /* Crypto Extension */
 #define CSR_SEED0x015
 
+/* Zcmt Extension */
+#define CSR_JVT 0x017
+
 /* mstatus CSR bits */
 #define MSTATUS_UIE 0x0001
 #define MSTATUS_SIE 0x0002
@@ -894,4 +898,7 @@ typedef enum RISCVException {
 #define MHPMEVENT_IDX_MASK 0xF
 #define MHPMEVENT_SSCOF_RESVD  16
 
+/* JVT CSR bits */
+#define JVT_MODE   0x3F
+#define JVT_BASE   (~0x3F)
 #endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index fa17d7770c..bc666b5350 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -42,8 +42,7 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 
 /* Predicates */
 #if !defined(CONFIG_USER_ONLY)
-static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
-   uint64_t bit)
+RISCVException smstateen_acc_ok(CPURISCVState *env, int index, uint64_t bit)
 {
 bool virt = riscv_cpu_virt_enabled(env);
 CPUState *cs = env_cpu(env);
@@ -163,6 +162,24 @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
 return ctr(env, csrno);
 }
 
+static RISCVException zcmt(CPURISCVState *env, int csrno)
+{
+RISCVCPU *cpu = env_archcpu(env);
+
+if (!cpu->cfg.ext_zcmt) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+#if !defined(CONFIG_USER_ONLY)
+RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT);
+if (ret != RISCV_EXCP_NONE) {
+return ret;
+}
+#endif
+
+return RISCV_EXCP_NONE;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 static RISCVException mctr(CPURISCVState *env, int csrno)
 {
@@ -3973,6 +3990,20 @@ RISCVException riscv_csrrw_debug(CPURISCVState *env, int 
csrno,
 return ret;
 }
 
+static RISCVException read_jvt(CPURISCVState *env, int csrno,
+   target_ulong *val)
+{
+*val = env->jvt;
+return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_jvt(CPURISCVState *env, int csrno,
+target_ulong val)
+{
+env->jvt = val;
+return RISCV_EXCP_NONE;
+}
+
 /* Control and Status Register function table */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* User Floating-Point CSRs */
@@ -4010,6 +4041,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* Crypto Extension */
 [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed },
 
+/* Zcmt Extension */
+[CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt},
+
 #if !defined(CONFIG_USER_ONLY)
 /* Machine Timers and Counters */
 [CSR_MCYCLE]= { "mcycle",any,   read_hpmcounter,
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 0497370afd..992ec62afa 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1137,3 +1137,6 @@ DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
 

[PATCH v11 0/9] support subsets of code size reduction extension

2023-02-08 Thread Weiwei Li
This patchset implements RISC-V Zc* extension v1.0.2-1 version instructions.

Specification:
https://github.com/riscv/riscv-code-size-reduction/tree/main/Zc-specification

The port is available here:
https://github.com/plctlab/plct-qemu/tree/plct-zce-upstream-v11

To test Zc* implementation, specify cpu argument with 
'x-zca=true,x-zcb=true,x-zcf=true,f=true" and "x-zcd=true,d=true" (or 
"x-zcmp=true,x-zcmt=true" with c or d=false) to enable Zca/Zcb/Zcf and Zcd(or 
Zcmp,Zcmt) extensions support.


This implementation can pass the basic zc tests from 
https://github.com/yulong-plct/zc-test

v11
* update format and field name based on the latest spec in patch 5, 6, 7 
(without other functional changes)
* rebase on riscv-to-apply.next

v10:
* rebase on Daniel's series(riscv-to-apply.next) and adjust riscv-tests to test 
on sifive related CPUs

v9:
* rebase on riscv-to-apply.next

v8:
* improve disas support in Patch 9

v7:
* Fix description for Zca

v6:
* fix base address for jump table in Patch 7
* rebase on riscv-to-apply.next

v5:
* fix exception unwind problem for cpu_ld*_code in helper of cm_jalt

v4:
* improve Zcmp suggested by Richard
* fix stateen related check for Zcmt

v3:
* update the solution for Zcf to the way of Zcd
* update Zcb to reuse gen_load/store
* use trans function instead of helper for push/pop

v2:
* add check for relationship between Zca/Zcf/Zcd with C/F/D based on related 
discussion in review of Zc* spec
* separate c.fld{sp}/fsd{sp} with fld{sp}/fsd{sp} before support of zcmp/zcmt

Weiwei Li (9):
  target/riscv: add cfg properties for Zc* extension
  target/riscv: add support for Zca extension
  target/riscv: add support for Zcf extension
  target/riscv: add support for Zcd extension
  target/riscv: add support for Zcb extension
  target/riscv: add support for Zcmp extension
  target/riscv: add support for Zcmt extension
  target/riscv: expose properties for Zc* extension
  disas/riscv.c: add disasm support for Zc*

 disas/riscv.c | 228 +++-
 target/riscv/cpu.c|  56 
 target/riscv/cpu.h|  10 +
 target/riscv/cpu_bits.h   |   7 +
 target/riscv/csr.c|  38 ++-
 target/riscv/helper.h |   3 +
 target/riscv/insn16.decode|  62 -
 target/riscv/insn_trans/trans_rvd.c.inc   |  18 ++
 target/riscv/insn_trans/trans_rvf.c.inc   |  18 ++
 target/riscv/insn_trans/trans_rvi.c.inc   |   4 +-
 target/riscv/insn_trans/trans_rvzce.c.inc | 313 ++
 target/riscv/machine.c|  19 ++
 target/riscv/meson.build  |   3 +-
 target/riscv/translate.c  |  15 +-
 target/riscv/zce_helper.c |  55 
 15 files changed, 833 insertions(+), 16 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc
 create mode 100644 target/riscv/zce_helper.c

-- 
2.25.1




Re: [PATCH v1 1/1] migration: Fix yank on postcopy multifd crashing guest after migration

2023-02-08 Thread Leonardo Brás
On Tue, 2022-11-29 at 15:50 -0500, Peter Xu wrote:
> On Tue, Nov 29, 2022 at 05:28:26PM -0300, Leonardo Bras Soares Passos wrote:
> > Hello Peter,
> 
> Leo,
> 
> > 
> > On Thu, Nov 24, 2022 at 1:04 PM Peter Xu  wrote:
> > > 
> > > On Wed, Nov 09, 2022 at 02:56:29AM -0300, Leonardo Bras wrote:
> > > > diff --git a/migration/savevm.c b/migration/savevm.c
> > > > index a0cdb714f7..250caff7f4 100644
> > > > --- a/migration/savevm.c
> > > > +++ b/migration/savevm.c
> > > > @@ -1889,6 +1889,8 @@ static void *postcopy_ram_listen_thread(void 
> > > > *opaque)
> > > >  exit(EXIT_FAILURE);
> > > >  }
> > > > 
> > > > +migration_load_cleanup();
> > > 
> > > It's a bit weird to call multifd-load-clean in a listen phase..
> > 
> > I agree.
> > 
> > > 
> > > How about moving it right above
> > > trace_process_incoming_migration_co_postcopy_end_main()?  Then the new
> > > helper can also be static.
> > 
> > Seems a nice Idea to have this function to be static.
> > 
> > We have to guarantee this is run after the migration finished, but
> > before migration_incoming_state_destroy().
> 
> IIUC it doesn't need to be when migration finished.  It should be fine as
> long as we finished precopy phase, and that's what the migration coroutine
> does, iiuc.  The thing is postcopy doesn't use multifd at all, so logically
> it can be released before postcopy starts.
> 
> Actually, IMHO it'll be safer to do it like that, just to make sure we
> won't accidentally receive multifd pages _after_ postcopy starts, because
> that'll be another more severe and hard to debug issue since the guest can
> see partial copied pages from multifd recv channels.
> 
> > 
> > You suggested calling it right above of
> > trace_process_incoming_migration_co_postcopy_end_main(), which git
> > grep pointed me to an if clause in process_incoming_migration_co().
> > If I got the location correctly, it would not help: this coroutine is
> > ran just after the VM went to the target host, and not when the
> > migration finished.
> > 
> > If we are using multifd channels, this will break the migration with
> > segmentation fault (SIGSEGV), since the channels have not finished
> > sending yet.
> 
> If this happens, then I had a feeling that there's something else that
> needs syncs.  As I discussed above, we should make sure multifd pages all
> landed before we start vcpu threads.
> 
> Said that, now I think I'm not against your original proposal to fix this
> immediate crash.  However I am still wondering whether we really should
> disable multifd with postcopy, as there seem to be still a few missing
> pieces even to enable multifd during precopy-only.
> 
> Thanks,
> 


I got side-tracked on this issue.

Is there any patch disabling multifd + postcopy, or would it be fine to go back
working on a V2 for this one?

Best regards,
Leo





[PATCH v11 8/9] target/riscv: expose properties for Zc* extension

2023-02-08 Thread Weiwei Li
Expose zca,zcb,zcf,zcd,zcmp,zcmt properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 196473a60f..eb9e74ecd5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -82,6 +82,12 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
 ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
 ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
+ISA_EXT_DATA_ENTRY(zca, true, PRIV_VERSION_1_12_0, ext_zca),
+ISA_EXT_DATA_ENTRY(zcb, true, PRIV_VERSION_1_12_0, ext_zcb),
+ISA_EXT_DATA_ENTRY(zcf, true, PRIV_VERSION_1_12_0, ext_zcf),
+ISA_EXT_DATA_ENTRY(zcd, true, PRIV_VERSION_1_12_0, ext_zcd),
+ISA_EXT_DATA_ENTRY(zcmp, true, PRIV_VERSION_1_12_0, ext_zcmp),
+ISA_EXT_DATA_ENTRY(zcmt, true, PRIV_VERSION_1_12_0, ext_zcmt),
 ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba),
 ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb),
 ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc),
@@ -1187,6 +1193,13 @@ static Property riscv_cpu_extensions[] = {
 
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
+
+DEFINE_PROP_BOOL("x-zca", RISCVCPU, cfg.ext_zca, false),
+DEFINE_PROP_BOOL("x-zcb", RISCVCPU, cfg.ext_zcb, false),
+DEFINE_PROP_BOOL("x-zcd", RISCVCPU, cfg.ext_zcd, false),
+DEFINE_PROP_BOOL("x-zcf", RISCVCPU, cfg.ext_zcf, false),
+DEFINE_PROP_BOOL("x-zcmp", RISCVCPU, cfg.ext_zcmp, false),
+DEFINE_PROP_BOOL("x-zcmt", RISCVCPU, cfg.ext_zcmt, false),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
 DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
-- 
2.25.1




[PATCH v11 5/9] target/riscv: add support for Zcb extension

2023-02-08 Thread Weiwei Li
Add encode and trans* functions support for Zcb instructions

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn16.decode|  23 +
 target/riscv/insn_trans/trans_rvzce.c.inc | 100 ++
 target/riscv/translate.c  |   2 +
 3 files changed, 125 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzce.c.inc

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index b62664b6af..ab780fa46a 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -43,6 +43,8 @@
 %imm_addi16sp  12:s1 3:2 5:1 2:1 6:1 !function=ex_shift_4
 %imm_lui   12:s1 2:5 !function=ex_shift_12
 
+%uimm_cl_b  5:1 6:1
+%uimm_cl_h  5:1  !function=ex_shift_1
 
 # Argument sets imported from insn32.decode:
   !extern
@@ -53,6 +55,7 @@
  imm rs2 rs1  !extern
  imm rd   !extern
  shamt rs1 rd !extern
+rd rs1   !extern
 
 
 # Formats 16:
@@ -89,6 +92,12 @@
 
 @c_andi ... . .. ... . ..  imm=%imm_ci rs1=%rs1_3 rd=%rs1_3
 
+@cu   ... ...  ... .. ... ..   rs1=%rs1_3 rd=%rs1_3
+@cl_b ... . .. ... .. ... ..imm=%uimm_cl_b  rs1=%rs1_3 rd=%rs2_3
+@cl_h ... . .. ... .. ... ..imm=%uimm_cl_h  rs1=%rs1_3 rd=%rs2_3
+@cs_b ... . .. ... .. ... ..imm=%uimm_cl_b  rs1=%rs1_3 rs2=%rs2_3
+@cs_h ... . .. ... .. ... ..imm=%uimm_cl_h  rs1=%rs1_3 rs2=%rs2_3
+
 # *** RV32/64C Standard Extension (Quadrant 0) ***
 {
   # Opcode of all zeros is illegal; rd != 0, nzuimm == 0 is reserved.
@@ -180,3 +189,17 @@ sw110 .  .  . 10 @c_swsp
   sd  111 .  .  . 10 @c_sdsp
   c_fsw   111 .  .  . 10 @c_swsp
 }
+
+# *** RV64 and RV32 Zcb Extension ***
+c_zext_b  100 111  ... 11 000 01 @cu
+c_sext_b  100 111  ... 11 001 01 @cu
+c_zext_h  100 111  ... 11 010 01 @cu
+c_sext_h  100 111  ... 11 011 01 @cu
+c_zext_w  100 111  ... 11 100 01 @cu
+c_not 100 111  ... 11 101 01 @cu
+c_mul 100 111  ... 10 ... 01 @cs_2
+c_lbu 100 000  ... .. ... 00 @cl_b
+c_lhu 100 001  ... 0. ... 00 @cl_h
+c_lh  100 001  ... 1. ... 00 @cl_h
+c_sb  100 010  ... .. ... 00 @cs_b
+c_sh  100 011  ... 0. ... 00 @cs_h
diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc 
b/target/riscv/insn_trans/trans_rvzce.c.inc
new file mode 100644
index 00..de96c4afaf
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzce.c.inc
@@ -0,0 +1,100 @@
+/*
+ * RISC-V translation routines for the Zcb Standard Extension.
+ *
+ * Copyright (c) 2021-2022 PLCT Lab
+ *
+ * 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 .
+ */
+
+#define REQUIRE_ZCB(ctx) do {   \
+if (!ctx->cfg_ptr->ext_zcb) \
+return false;   \
+} while (0)
+
+static bool trans_c_zext_b(DisasContext *ctx, arg_c_zext_b *a)
+{
+REQUIRE_ZCB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8u_tl);
+}
+
+static bool trans_c_zext_h(DisasContext *ctx, arg_c_zext_h *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl);
+}
+
+static bool trans_c_sext_b(DisasContext *ctx, arg_c_sext_b *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8s_tl);
+}
+
+static bool trans_c_sext_h(DisasContext *ctx, arg_c_sext_h *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16s_tl);
+}
+
+static bool trans_c_zext_w(DisasContext *ctx, arg_c_zext_w *a)
+{
+REQUIRE_64BIT(ctx);
+REQUIRE_ZCB(ctx);
+REQUIRE_ZBA(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext32u_tl);
+}
+
+static bool trans_c_not(DisasContext *ctx, arg_c_not *a)
+{
+REQUIRE_ZCB(ctx);
+return gen_unary(ctx, a, EXT_NONE, tcg_gen_not_tl);
+}
+
+static bool trans_c_mul(DisasContext *ctx, arg_c_mul *a)
+{
+REQUIRE_ZCB(ctx);
+REQUIRE_M_OR_ZMMUL(ctx);
+return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL);
+}
+
+static bool trans_c_lbu(DisasContext *ctx, arg_c_lbu *a)
+{
+REQUIRE_ZCB(ctx);
+return gen_load(ctx, a, MO_UB);
+}
+
+static bool trans_c_lhu(DisasContext *ctx, arg_c_lhu *a)
+{
+REQUIRE_ZCB(ctx);
+return 

[PATCH v11 1/9] target/riscv: add cfg properties for Zc* extension

2023-02-08 Thread Weiwei Li
Add properties for Zca,Zcb,Zcf,Zcd,Zcmp,Zcmt extension
Add check for these properties

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 43 +++
 target/riscv/cpu.h |  6 ++
 2 files changed, 49 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0dd2f0c753..196473a60f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -767,6 +767,49 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 }
 }
 
+if (cpu->cfg.ext_c) {
+cpu->cfg.ext_zca = true;
+if (cpu->cfg.ext_f && env->misa_mxl_max == MXL_RV32) {
+cpu->cfg.ext_zcf = true;
+}
+if (cpu->cfg.ext_d) {
+cpu->cfg.ext_zcd = true;
+}
+}
+
+if (env->misa_mxl_max != MXL_RV32 && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension is only relevant to RV32");
+return;
+}
+
+if (!cpu->cfg.ext_f && cpu->cfg.ext_zcf) {
+error_setg(errp, "Zcf extension requires F extension");
+return;
+}
+
+if (!cpu->cfg.ext_d && cpu->cfg.ext_zcd) {
+error_setg(errp, "Zcd extension requires D extension");
+return;
+}
+
+if ((cpu->cfg.ext_zcf || cpu->cfg.ext_zcd || cpu->cfg.ext_zcb ||
+cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt) && !cpu->cfg.ext_zca) {
+error_setg(errp, "Zcf/Zcd/Zcb/Zcmp/Zcmt extensions require Zca "
+ "extension");
+return;
+}
+
+if (cpu->cfg.ext_zcd && (cpu->cfg.ext_zcmp || cpu->cfg.ext_zcmt)) {
+error_setg(errp, "Zcmp/Zcmt extensions are incompatible with "
+ "Zcd extension");
+return;
+}
+
+if (cpu->cfg.ext_zcmt && !cpu->cfg.ext_icsr) {
+error_setg(errp, "Zcmt extension requires Zicsr extension");
+return;
+}
+
 if (cpu->cfg.ext_zk) {
 cpu->cfg.ext_zkn = true;
 cpu->cfg.ext_zkr = true;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7128438d8e..4bfe22c468 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -435,6 +435,12 @@ struct RISCVCPUConfig {
 bool ext_zbkc;
 bool ext_zbkx;
 bool ext_zbs;
+bool ext_zca;
+bool ext_zcb;
+bool ext_zcd;
+bool ext_zcf;
+bool ext_zcmp;
+bool ext_zcmt;
 bool ext_zk;
 bool ext_zkn;
 bool ext_zknd;
-- 
2.25.1




[PATCH v11 3/9] target/riscv: add support for Zcf extension

2023-02-08 Thread Weiwei Li
Separate c_flw/c_fsw from flw/fsw to add check for Zcf extension

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn16.decode  |  8 
 target/riscv/insn_trans/trans_rvf.c.inc | 18 ++
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn16.decode b/target/riscv/insn16.decode
index ccfe59f294..f3ea650325 100644
--- a/target/riscv/insn16.decode
+++ b/target/riscv/insn16.decode
@@ -109,11 +109,11 @@ sw110  ... ... .. ... 00 @cs_w
 # *** RV32C and RV64C specific Standard Extension (Quadrant 0) ***
 {
   ld  011  ... ... .. ... 00 @cl_d
-  flw 011  ... ... .. ... 00 @cl_w
+  c_flw   011  ... ... .. ... 00 @cl_w
 }
 {
   sd  111  ... ... .. ... 00 @cs_d
-  fsw 111  ... ... .. ... 00 @cs_w
+  c_fsw   111  ... ... .. ... 00 @cs_w
 }
 
 # *** RV32/64C Standard Extension (Quadrant 1) ***
@@ -174,9 +174,9 @@ sw110 .  .  . 10 @c_swsp
 {
   c64_illegal 011 -  0  - 10 # c.ldsp, RES rd=0
   ld  011 .  .  . 10 @c_ldsp
-  flw 011 .  .  . 10 @c_lwsp
+  c_flw   011 .  .  . 10 @c_lwsp
 }
 {
   sd  111 .  .  . 10 @c_sdsp
-  fsw 111 .  .  . 10 @c_swsp
+  c_fsw   111 .  .  . 10 @c_swsp
 }
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc 
b/target/riscv/insn_trans/trans_rvf.c.inc
index 965e1f8d11..5df9c148dc 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -30,6 +30,12 @@
 } \
 } while (0)
 
+#define REQUIRE_ZCF(ctx) do {  \
+if (!ctx->cfg_ptr->ext_zcf) {  \
+return false;  \
+}  \
+} while (0)
+
 static bool trans_flw(DisasContext *ctx, arg_flw *a)
 {
 TCGv_i64 dest;
@@ -61,6 +67,18 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 return true;
 }
 
+static bool trans_c_flw(DisasContext *ctx, arg_flw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_flw(ctx, a);
+}
+
+static bool trans_c_fsw(DisasContext *ctx, arg_fsw *a)
+{
+REQUIRE_ZCF(ctx);
+return trans_fsw(ctx, a);
+}
+
 static bool trans_fmadd_s(DisasContext *ctx, arg_fmadd_s *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v11 2/9] target/riscv: add support for Zca extension

2023-02-08 Thread Weiwei Li
Modify the check for C extension to Zca (C implies Zca)

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Wilfred Mallawa 
---
 target/riscv/insn_trans/trans_rvi.c.inc | 4 ++--
 target/riscv/translate.c| 8 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 4496f21266..ef7c3002b0 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -56,7 +56,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
 gen_set_pc(ctx, cpu_pc);
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 TCGv t0 = tcg_temp_new();
 
 misaligned = gen_new_label();
@@ -178,7 +178,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 
 gen_set_label(l); /* branch taken */
 
-if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+if (!ctx->cfg_ptr->ext_zca && ((ctx->base.pc_next + a->imm) & 0x3)) {
 /* misaligned */
 gen_exception_inst_addr_mis(ctx);
 } else {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 772f9d7973..1f388ef089 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -569,7 +569,7 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 
 /* check misaligned: */
 next_pc = ctx->base.pc_next + imm;
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
 return;
@@ -1145,7 +1145,11 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 if (insn_len(opcode) == 2) {
 ctx->opcode = opcode;
 ctx->pc_succ_insn = ctx->base.pc_next + 2;
-if (has_ext(ctx, RVC) && decode_insn16(ctx, opcode)) {
+/*
+ * The Zca extension is added as way to refer to instructions in the C
+ * extension that do not include the floating-point loads and stores
+ */
+if (ctx->cfg_ptr->ext_zca && decode_insn16(ctx, opcode)) {
 return;
 }
 } else {
-- 
2.25.1




[PATCH v11 9/9] disas/riscv.c: add disasm support for Zc*

2023-02-08 Thread Weiwei Li
Zcmp/Zcmt instructions will override disasm for c.fld*/c.fsd*
instructions currently

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Acked-by: Alistair Francis 
---
 disas/riscv.c | 228 +-
 1 file changed, 227 insertions(+), 1 deletion(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index ddda687c13..f4d8d7b11a 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -163,6 +163,13 @@ typedef enum {
 rv_codec_v_i,
 rv_codec_vsetvli,
 rv_codec_vsetivli,
+rv_codec_zcb_ext,
+rv_codec_zcb_mul,
+rv_codec_zcb_lb,
+rv_codec_zcb_lh,
+rv_codec_zcmp_cm_pushpop,
+rv_codec_zcmp_cm_mv,
+rv_codec_zcmt_jt,
 } rv_codec;
 
 typedef enum {
@@ -935,6 +942,26 @@ typedef enum {
 rv_op_vsetvli = 766,
 rv_op_vsetivli = 767,
 rv_op_vsetvl = 768,
+rv_op_c_zext_b = 769,
+rv_op_c_sext_b = 770,
+rv_op_c_zext_h = 771,
+rv_op_c_sext_h = 772,
+rv_op_c_zext_w = 773,
+rv_op_c_not = 774,
+rv_op_c_mul = 775,
+rv_op_c_lbu = 776,
+rv_op_c_lhu = 777,
+rv_op_c_lh = 778,
+rv_op_c_sb = 779,
+rv_op_c_sh = 780,
+rv_op_cm_push = 781,
+rv_op_cm_pop = 782,
+rv_op_cm_popret = 783,
+rv_op_cm_popretz = 784,
+rv_op_cm_mva01s = 785,
+rv_op_cm_mvsa01 = 786,
+rv_op_cm_jt = 787,
+rv_op_cm_jalt = 788,
 } rv_op;
 
 /* structures */
@@ -958,6 +985,7 @@ typedef struct {
 uint8_t   rnum;
 uint8_t   vm;
 uint32_t  vzimm;
+uint8_t   rlist;
 } rv_decode;
 
 typedef struct {
@@ -1070,6 +1098,10 @@ static const char rv_vreg_name_sym[32][4] = {
 #define rv_fmt_vd_vm  "O\tDm"
 #define rv_fmt_vsetvli"O\t0,1,v"
 #define rv_fmt_vsetivli   "O\t0,u,v"
+#define rv_fmt_rs1_rs2_zce_ldst   "O\t2,i(1)"
+#define rv_fmt_push_rlist "O\tx,-i"
+#define rv_fmt_pop_rlist  "O\tx,i"
+#define rv_fmt_zcmt_index "O\ti"
 
 /* pseudo-instruction constraints */
 
@@ -2065,7 +2097,27 @@ const rv_opcode_data opcode_data[] = {
 { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, 
rv_op_vsext_vf8, 0 },
 { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, 
rv_op_vsetvli, 0 },
 { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, 
rv_op_vsetivli, 0 },
-{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 }
+{ "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, 
rv_op_vsetvl, 0 },
+{ "c.zext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.b", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.sext.h", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.zext.w", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.not", rv_codec_zcb_ext, rv_fmt_rd, NULL, 0 },
+{ "c.mul", rv_codec_zcb_mul, rv_fmt_rd_rs2, NULL, 0, 0 },
+{ "c.lbu", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lhu", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.lh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sb", rv_codec_zcb_lb, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "c.sh", rv_codec_zcb_lh, rv_fmt_rs1_rs2_zce_ldst, NULL, 0, 0, 0 },
+{ "cm.push", rv_codec_zcmp_cm_pushpop, rv_fmt_push_rlist, NULL, 0, 0 },
+{ "cm.pop", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.popret", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0, 0 },
+{ "cm.popretz", rv_codec_zcmp_cm_pushpop, rv_fmt_pop_rlist, NULL, 0, 0 },
+{ "cm.mva01s", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.mvsa01", rv_codec_zcmp_cm_mv, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
+{ "cm.jt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
+{ "cm.jalt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
 };
 
 /* CSR names */
@@ -2084,6 +2136,7 @@ static const char *csr_name(int csrno)
 case 0x000a: return "vxrm";
 case 0x000f: return "vcsr";
 case 0x0015: return "seed";
+case 0x0017: return "jvt";
 case 0x0040: return "uscratch";
 case 0x0041: return "uepc";
 case 0x0042: return "ucause";
@@ -2306,6 +2359,24 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa 
isa)
 op = rv_op_c_ld;
 }
 break;
+case 4:
+switch ((inst >> 10) & 0b111) {
+case 0: op = rv_op_c_lbu; break;
+case 1:
+if (((inst >> 6) & 1) == 0) {
+op = rv_op_c_lhu;
+} else {
+op = rv_op_c_lh;
+}
+break;
+case 2: op = rv_op_c_sb; break;
+case 3:
+if (((inst >> 6) & 1) == 0) {
+op = rv_op_c_sh;
+}
+break;
+}
+break;
 case 5:
 if (isa == rv128) {
 op = rv_op_c_sq;
@@ 

Re: [PATCH v2] target/riscv: Remove privileged spec version restriction for RVV

2023-02-08 Thread Alistair Francis
On Wed, Feb 8, 2023 at 4:32 PM  wrote:
>
> From: Frank Chang 
>
> The RVV specification does not require that the core needs to support
> the privileged specification v1.12.0 to support RVV, and there is no
> dependency from ISA level.
>
> This commit removes the restriction from both RVV CSRs and extension CPU
> ISA string.
>
> Signed-off-by: Frank Chang 
> Reviewed-by: Bin Meng 
> Reviewed-by: LIU Zhiwei 

Acked-by: Alistair Francis 

Alistair

> ---
>  target/riscv/cpu.c |  2 +-
>  target/riscv/csr.c | 21 +++--
>  2 files changed, 8 insertions(+), 15 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 0dd2f0c753..93b52b826c 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -73,7 +73,7 @@ struct isa_ext_data {
>   */
>  static const struct isa_ext_data isa_edata_arr[] = {
>  ISA_EXT_DATA_ENTRY(h, false, PRIV_VERSION_1_12_0, ext_h),
> -ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_12_0, ext_v),
> +ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_10_0, ext_v),
>  ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
>  ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
>  ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, 
> ext_zihintpause),
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index fa17d7770c..1b0a0c1693 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -3980,20 +3980,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
>  [CSR_FRM]  = { "frm",  fs, read_frm, write_frm},
>  [CSR_FCSR] = { "fcsr", fs, read_fcsr,write_fcsr   },
>  /* Vector CSRs */
> -[CSR_VSTART]   = { "vstart",   vs, read_vstart,  write_vstart,
> -   .min_priv_ver = PRIV_VERSION_1_12_0},
> -[CSR_VXSAT]= { "vxsat",vs, read_vxsat,   write_vxsat,
> -   .min_priv_ver = PRIV_VERSION_1_12_0},
> -[CSR_VXRM] = { "vxrm", vs, read_vxrm,write_vxrm,
> -   .min_priv_ver = PRIV_VERSION_1_12_0},
> -[CSR_VCSR] = { "vcsr", vs, read_vcsr,write_vcsr,
> -   .min_priv_ver = PRIV_VERSION_1_12_0},
> -[CSR_VL]   = { "vl",   vs, read_vl,
> -   .min_priv_ver = PRIV_VERSION_1_12_0},
> -[CSR_VTYPE]= { "vtype",vs, read_vtype,
> -   .min_priv_ver = PRIV_VERSION_1_12_0},
> -[CSR_VLENB]= { "vlenb",vs, read_vlenb,
> -   .min_priv_ver = PRIV_VERSION_1_12_0},
> +[CSR_VSTART]   = { "vstart",   vs, read_vstart,  write_vstart },
> +[CSR_VXSAT]= { "vxsat",vs, read_vxsat,   write_vxsat  },
> +[CSR_VXRM] = { "vxrm", vs, read_vxrm,write_vxrm   },
> +[CSR_VCSR] = { "vcsr", vs, read_vcsr,write_vcsr   },
> +[CSR_VL]   = { "vl",   vs, read_vl},
> +[CSR_VTYPE]= { "vtype",vs, read_vtype },
> +[CSR_VLENB]= { "vlenb",vs, read_vlenb },
>  /* User Timers and Counters */
>  [CSR_CYCLE]= { "cycle",ctr,read_hpmcounter  },
>  [CSR_INSTRET]  = { "instret",  ctr,read_hpmcounter  },
> --
> 2.36.1
>
>



Re: [PATCH v3 4/6] i386: Mask and report unavailable multi-bit feature values

2023-02-08 Thread Xiaoyao Li

On 2/9/2023 9:04 AM, Wang, Lei wrote:

On 2/6/2023 3:43 PM, Yuan Yao wrote:

On Fri, Jan 06, 2023 at 12:38:24AM -0800, Lei Wang wrote:

Some feature words, e.g., feature words in AMX-related CPUID leaf 0x1D and
0x1E are not bit-wise but multiple bits represents one value. Handle this
situation when the values specified are not the same as which are reported
by KVM. The handling includes:

  - The responsibility of masking bits and giving warnings are delegated to
the feature enabler. A framework is also provided to enable this.
  - To simplify the initialization, a default function is provided if the
the function is not specified.


What's the behavior of default ? you need to call out it clearly.


The reason why delegating this responsibility rather than just marking
them as zeros when they are not same is because different multi-bit
features may have different logic, which is case by case, for example:

  1. CPUID.0x14_0x1:EBX[15:0]. Even though it's multi-bits field, it's a
 bitmap and each bit represents a separate capability.

  2. CPUID.0x14_0x1:EAX[2:0] represents the number of configurable Address
 Ranges. 3 bits as a whole to represent a integer value. It means the
 maximum capability of HW. If KVM reports M, then M to 0 is legal
 value to configure (because KVM can emulate each value correctly).

  3. CPUID.0x1D_0x1:EAX[31:16] represents palette 1 bytes_per_tile. 16 bits
 as a whole represent an integer value. It's not like case 2 and SW
 needs to configure the same value as reported. Because it's not
 possible for SW to configure to a different value and KVM cannot
 emulate it.

So marking them blindly as zeros is incorrect, and delegating this
responsibility can let each multi-bit feature have its own way to mask bits.


you can first describe there are such 3 cases of multi-bit features and 
they need different handling for checking whether configured value is 
supported by KVM or not. So introduce a handling callback function that 
each multi-bit feature can implement their own. Meanwhile, provide a 
default handling callback that handles case x: when configured value is 
not the same as the one reported by KVM, clearing it to zero to mark it 
as unavailable.



Signed-off-by: Lei Wang 
---
  target/i386/cpu-internal.h |  2 ++
  target/i386/cpu.c  | 36 
  2 files changed, 38 insertions(+)

diff --git a/target/i386/cpu-internal.h b/target/i386/cpu-internal.h
index 66b3d66cb4..83c7b53926 100644
--- a/target/i386/cpu-internal.h
+++ b/target/i386/cpu-internal.h
@@ -30,6 +30,8 @@ typedef struct MultiBitFeatureInfo {
  uint64_t mask;
  unsigned high_bit_position;
  unsigned low_bit_position;
+void (*mark_unavailable_multi_bit)(X86CPU *cpu, FeatureWord w, int index,
+   const char *verbose_prefix);
  } MultiBitFeatureInfo;

  typedef struct FeatureWordInfo {
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 88aa780566..e638a31d34 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4377,6 +4377,28 @@ static bool x86_cpu_have_filtered_features(X86CPU *cpu)
  return false;
  }

+static void mark_unavailable_multi_bit_default(X86CPU *cpu, FeatureWord w,
+   int index,
+   const char *verbose_prefix)
+{
+FeatureWordInfo *f = _word_info[w];
+g_autofree char *feat_word_str = feature_word_description(f);
+uint64_t host_feat = x86_cpu_get_supported_feature_word(w, false);
+MultiBitFeatureInfo mf = f->multi_bit_features[index];
+
+if ((cpu->env.features[w] & mf.mask) &&


With this checking bits are all 0 but covered by mf.mask's range are skippped,
even if they're different from the host_feat, please check whether it's desried
behavior.


This is the intended design because there are quite a number of multi-bit CPUIDs
should support passing all 0 to them.


you didn't answer the question. The question is why the handling can be 
skipped when the value of multi-bit feature is 0.



+((cpu->env.features[w] ^ host_feat) & mf.mask)) {
+if (!cpu->force_features) {
+cpu->env.features[w] &= ~mf.mask;
+}
+cpu->filtered_features[w] |= mf.mask;
+if (verbose_prefix)
+warn_report("%s: %s.%s [%u:%u]", verbose_prefix, feat_word_str,
+mf.feat_name, mf.high_bit_position,
+mf.low_bit_position);
+}
+}
+
  static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t 
mask,
const char *verbose_prefix)
  {
@@ -6442,6 +6464,20 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool 
verbose)
  x86_cpu_get_supported_feature_word(w, false);
  uint64_t requested_features = env->features[w];
  uint64_t unavailable_features = requested_features & ~host_feat;
+

Re: [PATCH 1/1] hw/core/cpu: always print cpu index with cpu state

2023-02-08 Thread Alistair Francis
On Tue, Feb 7, 2023 at 9:46 AM Dongli Zhang  wrote:
>
> The cpu_dump_state() does not print the cpu index. When the
> cpu_dump_state() is invoked due to the KVM failure, we are not able to tell
> from which CPU the state is. The below is an example.
>
> KVM internal error. Suberror: 764064
> RAX=0002 RBX=8a9e57c38400 RCX= 
> RDX=8a9cc00ba8a0
> RSI=0003 RDI=8a9e57c38400 RBP=b6120c5b3c50 
> RSP=b6120c5b3c40
> R8 = R9 =8a9cc00ba8a0 R10=8e467350 
> R11=0007
> R12=000a R13=8f987e25 R14=8f988a01 
> R15=
> RIP=8e51bb04 RFL=00010046 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
> ES =   00c0
> CS =0010   00a09b00 DPL=0 CS64 [-RA]
> SS =   00c0
> DS =   00c0
> FS =   00c0
> GS = 8ac27fcc  00c0
> LDT=   00c0
> TR =0040 fe096000 206f 8b00 DPL=0 TSS64-busy
> GDT= fe094000 007f
> IDT= fe00 0fff
> CR0=80050033 CR2= CR3=0010ca40a001 CR4=003606e0
> DR0= DR1= DR2= 
> DR3=
> DR6=fffe0ff0 DR7=0400
> EFER=0d01
> Code=0f 1f ... ...
>
> Print the cpu->cpu_index in cpu_dump_state() and remove it from the caller.
>
> Cc: Joe Jin 
> Signed-off-by: Dongli Zhang 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  hw/core/cpu-common.c  | 1 +
>  monitor/hmp-cmds-target.c | 2 --
>  softmmu/cpus.c| 1 -
>  3 files changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c
> index 5ccc3837b6..d2503f2d09 100644
> --- a/hw/core/cpu-common.c
> +++ b/hw/core/cpu-common.c
> @@ -105,6 +105,7 @@ void cpu_dump_state(CPUState *cpu, FILE *f, int flags)
>
>  if (cc->dump_state) {
>  cpu_synchronize_state(cpu);
> +qemu_fprintf(f, "\nCPU#%d\n", cpu->cpu_index);
>  cc->dump_state(cpu, f, flags);
>  }
>  }
> diff --git a/monitor/hmp-cmds-target.c b/monitor/hmp-cmds-target.c
> index 0d3e84d960..f7dd354d2a 100644
> --- a/monitor/hmp-cmds-target.c
> +++ b/monitor/hmp-cmds-target.c
> @@ -99,7 +99,6 @@ void hmp_info_registers(Monitor *mon, const QDict *qdict)
>
>  if (all_cpus) {
>  CPU_FOREACH(cs) {
> -monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
>  cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
>  }
>  } else {
> @@ -114,7 +113,6 @@ void hmp_info_registers(Monitor *mon, const QDict *qdict)
>  return;
>  }
>
> -monitor_printf(mon, "\nCPU#%d\n", cs->cpu_index);
>  cpu_dump_state(cs, NULL, CPU_DUMP_FPU);
>  }
>  }
> diff --git a/softmmu/cpus.c b/softmmu/cpus.c
> index 9cbc8172b5..f69bbe6abc 100644
> --- a/softmmu/cpus.c
> +++ b/softmmu/cpus.c
> @@ -122,7 +122,6 @@ void hw_error(const char *fmt, ...)
>  vfprintf(stderr, fmt, ap);
>  fprintf(stderr, "\n");
>  CPU_FOREACH(cpu) {
> -fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
>  cpu_dump_state(cpu, stderr, CPU_DUMP_FPU);
>  }
>  va_end(ap);
> --
> 2.34.1
>
>



Re: [PATCH] roms/opensbi: Upgrade from v1.1 to v1.2

2023-02-08 Thread Alistair Francis
On Tue, Feb 7, 2023 at 2:41 PM Bin Meng  wrote:
>
> Upgrade OpenSBI from v1.1 to v1.2 and the pre-built bios images.
>
> The v1.2 release includes the following commits:
>
> 994c8cf lib: sbi_timer: Added a conditional wait function which can timeout
> caa5eea lib: sbi: add check for ipi device for hsm start
> 0374ccf lib: sbi_hart: Shorten the code to set MPV bit
> 4e21cca lib: utils/serial: Update Shakti UART based on latest implementation
> 88b790f lib: sbi: Fix sbi_snprintf
> 1545afd lib: sbi: Fix counter index sanity check
> 83db3af lib: sbi: Add the bound check for events during config match
> 860a376 lib: sbi: Fix possible buffer overrun in counter validation
> 11c0008 lib: sbi: Fix fw_event_map initialization
> 8e86b23 lib: utils/fdt: Factor out common uart node code
> 7d28d3b lib: utils/serial: Initialize platform_uart_data to zero
> 7198e1d lib: serial: Clean up coding style in sifive-uart.c
> f272035 lib: utils/serial: Ensure baudrate is non-zero before using
> b9edf49 lib: sbi: Fix printf handling of long long
> 422f0e0 scripts: Add Kconfiglib v14.1.0 under scripts directory
> 662e631 Makefile: Add initial kconfig support for each platform
> de80e93 Makefile: Compile lib/utils sources separately for each platform
> 26bbff5 lib: utils/serial: Use kconfig for enabling/disabling drivers
> 2adc94b lib: utils/reset: Use kconfig for enabling/disabling drivers
> 3e76a60 lib: utils/sys: Use kconfig for enabling/disabling drivers
> 013dbb3 lib: utils/timer: Use kconfig for enabling/disabling drivers
> 76af9d4 lib: utils/ipi: Use kconfig for enabling/disabling drivers
> 0b1cf2f lib: utils/irqchip: Use kconfig for enabling/disabling drivers
> b126ce4 lib: utils/i2c: Use kconfig for enabling/disabling drivers
> 5616aa4 lib: utils/gpio: Use kconfig for enabling/disabling drivers
> 68d7b85 lib: utils/fdt: Use kconfig for enabling/disabling
> d514a8f platform: generic: Use kconfig for enabling/disabling overrides
> bc317a3 platform: generic: Use kconfig to set platform version and default 
> name
> eccb9df platform: Remove redundant config.mk from all platforms
> 0723bab docs: Update documentation for kconfig support
> a6a8557 Makefile: Fix typo related to object.mk
> 9529e36 include: Add mstatus[h].GVA encodings
> 1fbe777 lib: sbi_trap: Save mstatus[h].GVA in trap->gva
> 1c4ce74 lib: sbi: Set gva when creating sbi_trap_info
> 5a0ca09 lib: sbi_trap: Set hypervisor CSRs for HS-mode
> a69eb6c lib: sbi_trap: Set hstatus.GVA when going to HS-mode
> 111afc1 lib: sbi_illegal_insn: Fix FENCE.TSO emulation infinite trap loop
> adf44b5 lib: sbi: Use the official extension name for AIA M-mode CSRs
> cbaa9b0 lib: utils: serial: Add Cadence UART driver
> 622cc5f include: Remove sideleg and sedeleg
> a90cf6b lib: sbi_pmu: Remove "event_idx" member from struct sbi_pmu_fw_event
> 1664d0e lib: sbi_pmu: Replace sbi_pmu_ctr_read() with sbi_pmu_ctr_fw_read()
> e238459 lib: sbi_pmu: Firmware counters are always 64 bits wide
> c9b388d lib: sbi_pmu: Simplify FW counters to reduce memory usage
> d10c1f4 lib: sbi_pmu: Add custom PMU device operations
> ee69f8e lib: sbi: Print platform PMU device at boot-time
> 5019fd1 include: sbi: Reduce includes in sbi_pmu.h
> d32b0a9 docs: pmu: fix Unmatched example typo
> 19664f6 docs: pmu: extend bindings example for Unmatched
> 37a0d83 lib: sbi_trap: Add helper to get GVA in sbi_trap_regs
> 46e744a lib: sbi_misaligned_ldst: Set GVA if not emulating
> 8ce486a lib: utils/fdt: Fix DT parsing in fdt_pmu_setup()
> 49372f2 lib: sbi: Fix sbi_strnlen wrong count decrement
> 7f09fba lib: utils/serial: add semihosting support
> 7105c18 docs/firmware: Update FW_JUMP documentation
> 3f3d401 docs: Fix some typos
> e54cb32 lib: sbi_pmu: move pmu irq information into pmu itself
> c316fa3 lib: sbi_hart: move hart_features struct to a public location
> 4f2acb5 lib: sbi_platform: expose hart_features to extension_init callback
> 2f63f24 platform: generic: add extensions_init handler and platform-override
> b6e520b platform: generic: allwinner: add support for c9xx pmu
> 98aa127 include: sbi: Fix typo in comment
> 11d14ae lib: sbi: Fix typo in comment
> 60b78fe include: sbi: Fix grammar in comment
> dcdaf30 lib: sbi: Add sbi_domain_root_add_memrange() API
> bd7ef41 platform: andes/ae350: Remove enabling cache from an350_final_init
> 9899b59 platform: andes/ae350: Use kconfig to set platform version and 
> default name
> 88f58a3 platform: andes/ae350: Use fdt serial driver
> ef9f02e lib: utils/timer: Add Andes fdt timer support
> 8234fc1 lib: utils/reset: Add Andes fdt reset driver support
> 127a3f2 platform: andes/ae350: Use fdt irqchip driver
> 6f3258e platform: andes/ae350: Add fw_platform_init for platform 
> initialization
> ce7c490 lib: utils/ipi: Add Andes fdt ipi driver support
> c8683c5 platform: andes/ae350: Add AE350 domain support
> d682a0a docs: andes-ae350.md: Update ae350 documentation for fdt driver 
> support
> 0fee0bf Makefile: Add cscope support
> 51acd49 docs/firmware: update the document
> 

Re: [PATCH] roms/opensbi: Upgrade from v1.1 to v1.2

2023-02-08 Thread Alistair Francis
On Tue, Feb 7, 2023 at 2:41 PM Bin Meng  wrote:
>
> Upgrade OpenSBI from v1.1 to v1.2 and the pre-built bios images.
>
> The v1.2 release includes the following commits:
>
> 994c8cf lib: sbi_timer: Added a conditional wait function which can timeout
> caa5eea lib: sbi: add check for ipi device for hsm start
> 0374ccf lib: sbi_hart: Shorten the code to set MPV bit
> 4e21cca lib: utils/serial: Update Shakti UART based on latest implementation
> 88b790f lib: sbi: Fix sbi_snprintf
> 1545afd lib: sbi: Fix counter index sanity check
> 83db3af lib: sbi: Add the bound check for events during config match
> 860a376 lib: sbi: Fix possible buffer overrun in counter validation
> 11c0008 lib: sbi: Fix fw_event_map initialization
> 8e86b23 lib: utils/fdt: Factor out common uart node code
> 7d28d3b lib: utils/serial: Initialize platform_uart_data to zero
> 7198e1d lib: serial: Clean up coding style in sifive-uart.c
> f272035 lib: utils/serial: Ensure baudrate is non-zero before using
> b9edf49 lib: sbi: Fix printf handling of long long
> 422f0e0 scripts: Add Kconfiglib v14.1.0 under scripts directory
> 662e631 Makefile: Add initial kconfig support for each platform
> de80e93 Makefile: Compile lib/utils sources separately for each platform
> 26bbff5 lib: utils/serial: Use kconfig for enabling/disabling drivers
> 2adc94b lib: utils/reset: Use kconfig for enabling/disabling drivers
> 3e76a60 lib: utils/sys: Use kconfig for enabling/disabling drivers
> 013dbb3 lib: utils/timer: Use kconfig for enabling/disabling drivers
> 76af9d4 lib: utils/ipi: Use kconfig for enabling/disabling drivers
> 0b1cf2f lib: utils/irqchip: Use kconfig for enabling/disabling drivers
> b126ce4 lib: utils/i2c: Use kconfig for enabling/disabling drivers
> 5616aa4 lib: utils/gpio: Use kconfig for enabling/disabling drivers
> 68d7b85 lib: utils/fdt: Use kconfig for enabling/disabling
> d514a8f platform: generic: Use kconfig for enabling/disabling overrides
> bc317a3 platform: generic: Use kconfig to set platform version and default 
> name
> eccb9df platform: Remove redundant config.mk from all platforms
> 0723bab docs: Update documentation for kconfig support
> a6a8557 Makefile: Fix typo related to object.mk
> 9529e36 include: Add mstatus[h].GVA encodings
> 1fbe777 lib: sbi_trap: Save mstatus[h].GVA in trap->gva
> 1c4ce74 lib: sbi: Set gva when creating sbi_trap_info
> 5a0ca09 lib: sbi_trap: Set hypervisor CSRs for HS-mode
> a69eb6c lib: sbi_trap: Set hstatus.GVA when going to HS-mode
> 111afc1 lib: sbi_illegal_insn: Fix FENCE.TSO emulation infinite trap loop
> adf44b5 lib: sbi: Use the official extension name for AIA M-mode CSRs
> cbaa9b0 lib: utils: serial: Add Cadence UART driver
> 622cc5f include: Remove sideleg and sedeleg
> a90cf6b lib: sbi_pmu: Remove "event_idx" member from struct sbi_pmu_fw_event
> 1664d0e lib: sbi_pmu: Replace sbi_pmu_ctr_read() with sbi_pmu_ctr_fw_read()
> e238459 lib: sbi_pmu: Firmware counters are always 64 bits wide
> c9b388d lib: sbi_pmu: Simplify FW counters to reduce memory usage
> d10c1f4 lib: sbi_pmu: Add custom PMU device operations
> ee69f8e lib: sbi: Print platform PMU device at boot-time
> 5019fd1 include: sbi: Reduce includes in sbi_pmu.h
> d32b0a9 docs: pmu: fix Unmatched example typo
> 19664f6 docs: pmu: extend bindings example for Unmatched
> 37a0d83 lib: sbi_trap: Add helper to get GVA in sbi_trap_regs
> 46e744a lib: sbi_misaligned_ldst: Set GVA if not emulating
> 8ce486a lib: utils/fdt: Fix DT parsing in fdt_pmu_setup()
> 49372f2 lib: sbi: Fix sbi_strnlen wrong count decrement
> 7f09fba lib: utils/serial: add semihosting support
> 7105c18 docs/firmware: Update FW_JUMP documentation
> 3f3d401 docs: Fix some typos
> e54cb32 lib: sbi_pmu: move pmu irq information into pmu itself
> c316fa3 lib: sbi_hart: move hart_features struct to a public location
> 4f2acb5 lib: sbi_platform: expose hart_features to extension_init callback
> 2f63f24 platform: generic: add extensions_init handler and platform-override
> b6e520b platform: generic: allwinner: add support for c9xx pmu
> 98aa127 include: sbi: Fix typo in comment
> 11d14ae lib: sbi: Fix typo in comment
> 60b78fe include: sbi: Fix grammar in comment
> dcdaf30 lib: sbi: Add sbi_domain_root_add_memrange() API
> bd7ef41 platform: andes/ae350: Remove enabling cache from an350_final_init
> 9899b59 platform: andes/ae350: Use kconfig to set platform version and 
> default name
> 88f58a3 platform: andes/ae350: Use fdt serial driver
> ef9f02e lib: utils/timer: Add Andes fdt timer support
> 8234fc1 lib: utils/reset: Add Andes fdt reset driver support
> 127a3f2 platform: andes/ae350: Use fdt irqchip driver
> 6f3258e platform: andes/ae350: Add fw_platform_init for platform 
> initialization
> ce7c490 lib: utils/ipi: Add Andes fdt ipi driver support
> c8683c5 platform: andes/ae350: Add AE350 domain support
> d682a0a docs: andes-ae350.md: Update ae350 documentation for fdt driver 
> support
> 0fee0bf Makefile: Add cscope support
> 51acd49 docs/firmware: update the document
> 

RE: [PULL 28/30] multifd: Fix flush of zero copy page send request

2023-02-08 Thread Duan, Zhenzhong
Hi Juan,

>-Original Message-
>From: Juan Quintela 
>Sent: Tuesday, February 7, 2023 8:57 AM
>To: qemu-devel@nongnu.org
>Cc: qemu-bl...@nongnu.org; Stefan Berger ;
>Stefan Hajnoczi ; Halil Pasic ;
>John Snow ; David Hildenbrand ;
>Fam Zheng ; Thomas Huth ; Daniel P.
>Berrangé ; Laurent Vivier ;
>Vladimir Sementsov-Ogievskiy ; qemu-
>s3...@nongnu.org; Christian Borntraeger ;
>Marc-André Lureau ; Michael S. Tsirkin
>; Juan Quintela ; Philippe
>Mathieu-Daudé ; Dr. David Alan Gilbert
>; Marcel Apfelbaum ;
>Coiby Xu ; Ilya Leoshkevich ;
>Eduardo Habkost ; Yanan Wang
>; Richard Henderson
>; Markus Armbruster ;
>Paolo Bonzini ; Alex Williamson
>; Eric Blake ; Eric
>Farman ; Duan, Zhenzhong
>
>Subject: [PULL 28/30] multifd: Fix flush of zero copy page send request
>
>From: Zhenzhong Duan 
>
>Make IO channel flush call after the inflight request has been drained in
>multifd thread, or else we may missed to flush the inflight request.
>
>Signed-off-by: Zhenzhong Duan 
>Reviewed-by: Juan Quintela 
>Signed-off-by: Juan Quintela 
>---
> .../x86_64-quintela-devices.mak   |7 +
> .../x86_64-quintela2-devices.mak  |6 +
> migration/multifd.c   |8 +-
> migration/multifd.c.orig  | 1274 +
> 4 files changed, 1291 insertions(+), 4 deletions(-)  create mode 100644
>configs/devices/x86_64-softmmu/x86_64-quintela-devices.mak
> create mode 100644 configs/devices/x86_64-softmmu/x86_64-quintela2-
>devices.mak
> create mode 100644 migration/multifd.c.orig
>
Just back from vacation, hoping it's not too late to report: 
x86_64-quintela-devices.mak x86_64-quintela2-devices.mak and multifd.c.orig 
might be unrelated to this patch?

Thanks
Zhenzhong



Re: Call for GSoC and Outreachy project ideas for summer 2023

2023-02-08 Thread Stefan Hajnoczi
On Wed, 8 Feb 2023 at 18:02, Warner Losh  wrote:
> On Fri, Jan 27, 2023 at 3:02 PM Stefan Hajnoczi  wrote:
>>
>> On Fri, 27 Jan 2023 at 12:10, Warner Losh  wrote:
>> >
>> > [[ cc list trimmed to just qemu-devel ]]
>> >
>> > On Fri, Jan 27, 2023 at 8:18 AM Stefan Hajnoczi  wrote:
>> >>
>> >> Dear QEMU, KVM, and rust-vmm communities,
>> >> QEMU will apply for Google Summer of Code 2023
>> >> (https://summerofcode.withgoogle.com/) and has been accepted into
>> >> Outreachy May 2023 (https://www.outreachy.org/). You can now
>> >> submit internship project ideas for QEMU, KVM, and rust-vmm!
>> >>
>> >> Please reply to this email by February 6th with your project ideas.
>> >>
>> >> If you have experience contributing to QEMU, KVM, or rust-vmm you can
>> >> be a mentor. Mentors support interns as they work on their project. It's a
>> >> great way to give back and you get to work with people who are just
>> >> starting out in open source.
>> >>
>> >> Good project ideas are suitable for remote work by a competent
>> >> programmer who is not yet familiar with the codebase. In
>> >> addition, they are:
>> >> - Well-defined - the scope is clear
>> >> - Self-contained - there are few dependencies
>> >> - Uncontroversial - they are acceptable to the community
>> >> - Incremental - they produce deliverables along the way
>> >>
>> >> Feel free to post ideas even if you are unable to mentor the project.
>> >> It doesn't hurt to share the idea!
>> >
>> >
>> > I've been a GSoC mentor for the FreeBSD project on and off for maybe
>> > 10-15 years now. I thought I'd share this for feedback here.
>> >
>> > My project idea falls between the two projects. I've been trying
>> > to get bsd-user reviewed and upstreamed for some time now and my
>> > time available to do the upstreaming has been greatly diminished lately.
>> > It got me thinking: upstreaming is more than just getting patches reviewed
>> > often times. While there is a rather mechanical aspect to it (and I could 
>> > likely
>> > automate that aspect more), the real value of going through the review 
>> > process
>> > is that it points out things that had been done wrong, things that need to 
>> > be
>> > redone or refactored, etc. It's often these suggestions that lead to the 
>> > biggest
>> > investment of time on my part: Is this idea good? if I do it, does it 
>> > break things?
>> > Is the feedback right about what's wrong, but wrong about how to fix it? 
>> > etc.
>> > Plus the inevitable, I thought this was a good idea, implemented it only 
>> > to find
>> > it broke other things, and how do I explain that and provide feedback to 
>> > the
>> > reviewer about that breakage to see if it is worth pursuing further or not?
>> >
>> > So my idea for a project is two fold: First, to create scripts to automate 
>> > the
>> > upstreaming process: to break big files into bite-sized chunks for review 
>> > on
>> > this list. git publish does a great job from there. The current backlog to 
>> > upstream
>> > is approximately " 175 files changed, 30270 insertions(+), 640 
>> > deletions(-)" which
>> > is 300-600 patches at the 50-100 line patch guidance I've been given. So 
>> > even
>> > at .1hr (6 minutes) per patch (which is about 3x faster than I can do it 
>> > by hand),
>> > that's ~60 hours just to create the patches. Writing automation should take
>> > much less time. Realistically, this is on the order of 10-20 hours to get 
>> > done.
>> >
>> > Second, it's to take feedback from the reviews for refactoring
>> > the bsd-user code base (which will eventually land in upstream). I often 
>> > spend
>> > a few hours creating my patches each quarter, then about 10 or so hours 
>> > for the
>> > 30ish patches that I do processing the review feedback by refactoring 
>> > other things
>> > (typically other architectures), checking details of other architectures 
>> > (usually by
>> > looking at the FreeBSD kernel), or looking for ways to refactor to share 
>> > code with
>> > linux-user  (though so far only the safe signals is upstream: elf could be 
>> > too), or
>> > chatting online about the feedback to better understand it, to see what I 
>> > can mine
>> > from linux-user (since the code is derived from that, but didn't pick up 
>> > all the changes
>> > linus-user has), etc. This would be on the order of 100 hours.
>> >
>> > Third, the testing infrastructure that exists for linux-user is not well 
>> > leveraged to test
>> > bsd-user. I've done some tests from time to time with it, but it's not in 
>> > a state that it
>> > can be used as, say, part of a CI pipeline. In addition, the FreeBSD 
>> > project has some
>> > very large jobs, a subset of which could be used to further ensure that 
>> > critical bits of
>> > infrastructure don't break (or are working if not in a CI pipeline). 
>> > Things like building
>> > and using go, rust and the like are constantly breaking for reasons too 
>> > long to enumerate
>> > here. This job could be as little as 50 hours to do 

Re: [PATCH] MAINTAINERS: Add some RISC-V reviewers

2023-02-08 Thread LIU Zhiwei

On 2023/2/9 8:33, Alistair Francis wrote:


From: Alistair Francis 

This patch adds some active RISC-V members as reviewers to the
MAINTAINERS file.

Signed-off-by: Alistair Francis 
---
  MAINTAINERS | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e25f62ac..847bc7f131 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -287,6 +287,9 @@ RISC-V TCG CPUs
  M: Palmer Dabbelt 
  M: Alistair Francis 
  M: Bin Meng 
+R: Weiwei Li 
+R: Daniel Henrique Barboza 
+R: Liu Zhiwei 


Acked-by: LIU Zhiwei 

Zhiwei


  L: qemu-ri...@nongnu.org
  S: Supported
  F: target/riscv/




CXL 2.0 memory pooling emulation

2023-02-08 Thread zhiting zhu
Hi,

I saw a PoC:
https://lore.kernel.org/qemu-devel/20220525121422.3...@huawei.com/T/ to
implement memory pooling and fabric manager on qemu. Is there any further
development on this? Can qemu emulate a memory pooling on a simple case
that two virtual machines connected to a CXL switch where some memory
devices are attached to?

Best,
Zhiting


Re: [PATCH v3 4/6] i386: Mask and report unavailable multi-bit feature values

2023-02-08 Thread Wang, Lei
On 2/6/2023 3:43 PM, Yuan Yao wrote:
> On Fri, Jan 06, 2023 at 12:38:24AM -0800, Lei Wang wrote:
>> Some feature words, e.g., feature words in AMX-related CPUID leaf 0x1D and
>> 0x1E are not bit-wise but multiple bits represents one value. Handle this
>> situation when the values specified are not the same as which are reported
>> by KVM. The handling includes:
>>
>>  - The responsibility of masking bits and giving warnings are delegated to
>>the feature enabler. A framework is also provided to enable this.
>>  - To simplify the initialization, a default function is provided if the
>>the function is not specified.
>>
>> The reason why delegating this responsibility rather than just marking
>> them as zeros when they are not same is because different multi-bit
>> features may have different logic, which is case by case, for example:
>>
>>  1. CPUID.0x14_0x1:EBX[15:0]. Even though it's multi-bits field, it's a
>> bitmap and each bit represents a separate capability.
>>
>>  2. CPUID.0x14_0x1:EAX[2:0] represents the number of configurable Address
>> Ranges. 3 bits as a whole to represent a integer value. It means the
>> maximum capability of HW. If KVM reports M, then M to 0 is legal
>> value to configure (because KVM can emulate each value correctly).
>>
>>  3. CPUID.0x1D_0x1:EAX[31:16] represents palette 1 bytes_per_tile. 16 bits
>> as a whole represent an integer value. It's not like case 2 and SW
>> needs to configure the same value as reported. Because it's not
>> possible for SW to configure to a different value and KVM cannot
>> emulate it.
>>
>> So marking them blindly as zeros is incorrect, and delegating this
>> responsibility can let each multi-bit feature have its own way to mask bits.
>>
>> Signed-off-by: Lei Wang 
>> ---
>>  target/i386/cpu-internal.h |  2 ++
>>  target/i386/cpu.c  | 36 
>>  2 files changed, 38 insertions(+)
>>
>> diff --git a/target/i386/cpu-internal.h b/target/i386/cpu-internal.h
>> index 66b3d66cb4..83c7b53926 100644
>> --- a/target/i386/cpu-internal.h
>> +++ b/target/i386/cpu-internal.h
>> @@ -30,6 +30,8 @@ typedef struct MultiBitFeatureInfo {
>>  uint64_t mask;
>>  unsigned high_bit_position;
>>  unsigned low_bit_position;
>> +void (*mark_unavailable_multi_bit)(X86CPU *cpu, FeatureWord w, int 
>> index,
>> +   const char *verbose_prefix);
>>  } MultiBitFeatureInfo;
>>
>>  typedef struct FeatureWordInfo {
>> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
>> index 88aa780566..e638a31d34 100644
>> --- a/target/i386/cpu.c
>> +++ b/target/i386/cpu.c
>> @@ -4377,6 +4377,28 @@ static bool x86_cpu_have_filtered_features(X86CPU 
>> *cpu)
>>  return false;
>>  }
>>
>> +static void mark_unavailable_multi_bit_default(X86CPU *cpu, FeatureWord w,
>> +   int index,
>> +   const char *verbose_prefix)
>> +{
>> +FeatureWordInfo *f = _word_info[w];
>> +g_autofree char *feat_word_str = feature_word_description(f);
>> +uint64_t host_feat = x86_cpu_get_supported_feature_word(w, false);
>> +MultiBitFeatureInfo mf = f->multi_bit_features[index];
>> +
>> +if ((cpu->env.features[w] & mf.mask) &&
> 
> With this checking bits are all 0 but covered by mf.mask's range are skippped,
> even if they're different from the host_feat, please check whether it's 
> desried
> behavior.

This is the intended design because there are quite a number of multi-bit CPUIDs
should support passing all 0 to them.

>> +((cpu->env.features[w] ^ host_feat) & mf.mask)) {
>> +if (!cpu->force_features) {
>> +cpu->env.features[w] &= ~mf.mask;
>> +}
>> +cpu->filtered_features[w] |= mf.mask;
>> +if (verbose_prefix)
>> +warn_report("%s: %s.%s [%u:%u]", verbose_prefix, feat_word_str,
>> +mf.feat_name, mf.high_bit_position,
>> +mf.low_bit_position);
>> +}
>> +}
>> +
>>  static void mark_unavailable_features(X86CPU *cpu, FeatureWord w, uint64_t 
>> mask,
>>const char *verbose_prefix)
>>  {
>> @@ -6442,6 +6464,20 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool 
>> verbose)
>>  x86_cpu_get_supported_feature_word(w, false);
>>  uint64_t requested_features = env->features[w];
>>  uint64_t unavailable_features = requested_features & ~host_feat;
>> +FeatureWordInfo f = feature_word_info[w];
>> +int i;
>> +
>> +for (i = 0; i < f.num_multi_bit_features; i++) {
>> +MultiBitFeatureInfo mf = f.multi_bit_features[i];
>> +if (mf.mark_unavailable_multi_bit) {
>> +mf.mark_unavailable_multi_bit(cpu, w, i, prefix);
>> +} else {
>> +mark_unavailable_multi_bit_default(cpu, w, i, prefix);
>> +}
>> +
>> +

Re: [PATCH v11 0/3] Consolidate all kernel init in load_kernel()

2023-02-08 Thread Alistair Francis
On Tue, Feb 7, 2023 at 12:03 AM Daniel Henrique Barboza
 wrote:
>
> Hi,
>
> In this new version patch 1 was changed to extract the lower 32 bits of
> the 64 bit address when running 32 bit CPUs. The difference now, in comparison
> with what was being done in version 6, is that now we're doing that for
> all uses of kernel_entry, not just the one resulting from load_elf_ram_sym().
>
> This will ensure that the current behavior, that is now based on the fact that
> load_initrd() uses the target_ulong returned by load_kernel(), that happens to
> be a 32 bit var when running in 32 bit targets, is preserved by doing a
> explicit 32 bit extract of the uint64_t kernel_entry for 32 bit CPUs.
>
> Changes in v10:
> - patch 1:
>   - extract the lower 32 bits of kernel_entry for all cases, not just
> the one from load_elf_ram_sym().
> - v10 link: 
> https://lists.gnu.org/archive/html/qemu-devel/2023-02/msg00529.html
>
> Daniel Henrique Barboza (3):
>   hw/riscv: handle 32 bit CPUs kernel_entry in riscv_load_kernel()
>   hw/riscv/boot.c: consolidate all kernel init in riscv_load_kernel()
>   hw/riscv/boot.c: make riscv_load_initrd() static

Thanks!

Applied to riscv-to-apply.next

Alistair

>
>  hw/riscv/boot.c| 97 --
>  hw/riscv/microchip_pfsoc.c | 12 +
>  hw/riscv/opentitan.c   |  4 +-
>  hw/riscv/sifive_e.c|  4 +-
>  hw/riscv/sifive_u.c| 12 +
>  hw/riscv/spike.c   | 14 ++
>  hw/riscv/virt.c| 12 +
>  include/hw/riscv/boot.h|  3 +-
>  8 files changed, 78 insertions(+), 80 deletions(-)
>
> --
> 2.39.1
>
>



[PATCH] MAINTAINERS: Add some RISC-V reviewers

2023-02-08 Thread Alistair Francis
From: Alistair Francis 

This patch adds some active RISC-V members as reviewers to the
MAINTAINERS file.

Signed-off-by: Alistair Francis 
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 96e25f62ac..847bc7f131 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -287,6 +287,9 @@ RISC-V TCG CPUs
 M: Palmer Dabbelt 
 M: Alistair Francis 
 M: Bin Meng 
+R: Weiwei Li 
+R: Daniel Henrique Barboza 
+R: Liu Zhiwei 
 L: qemu-ri...@nongnu.org
 S: Supported
 F: target/riscv/
-- 
2.39.1




Re: [PATCH 10/10] MAINTAINERS: Add entry for RISC-V ACPI

2023-02-08 Thread Alistair Francis
On Thu, Feb 2, 2023 at 2:54 PM Sunil V L  wrote:
>
> RISC-V ACPI related functionality for virt machine is added in
> virt-acpi-build.c. Add the maintainer entry.
>
> Signed-off-by: Sunil V L 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  MAINTAINERS | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c581c11a64..23fcaaf54a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -995,6 +995,12 @@ L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/virt-acpi-build.c
>
> +RISC-V ACPI Subsystem
> +M: Sunil V L 
> +L: qemu-ri...@nongnu.org
> +S: Maintained
> +F: hw/riscv/virt-acpi-build.c
> +
>  STM32F100
>  M: Alexandre Iooss 
>  L: qemu-...@nongnu.org
> --
> 2.38.0
>
>



Re: [PATCH 05/10] hw/riscv/virt: virt-acpi-build.c: Add RINTC in MADT

2023-02-08 Thread Alistair Francis
On Thu, Feb 2, 2023 at 2:54 PM Sunil V L  wrote:
>
> Add Multiple APIC Description Table (MADT) with the
> INTC structure for each cpu.
>
> Signed-off-by: Sunil V L 

Acked-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/virt-acpi-build.c | 37 +
>  1 file changed, 37 insertions(+)
>
> diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
> index 0410b955bd..2f65f1e2e5 100644
> --- a/hw/riscv/virt-acpi-build.c
> +++ b/hw/riscv/virt-acpi-build.c
> @@ -137,6 +137,43 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
> RISCVVirtState *vms)
>  free_aml_allocator();
>  }
>
> +/* MADT */
> +static void
> +build_madt(GArray *table_data, BIOSLinker *linker, RISCVVirtState *vms)
> +{
> +MachineState *mc = MACHINE(vms);
> +int socket;
> +uint16_t base_hartid = 0;
> +uint32_t cpu_id = 0;
> +
> +AcpiTable table = { .sig = "APIC", .rev = 6, .oem_id = vms->oem_id,
> +.oem_table_id = vms->oem_table_id };
> +
> +acpi_table_begin(, table_data);
> +/* Local Interrupt Controller Address */
> +build_append_int_noprefix(table_data, 0, 4);
> +build_append_int_noprefix(table_data, 0, 4);   /* MADT Flags */
> +
> +/* RISC-V Local INTC structures per HART */
> +for (socket = 0; socket < riscv_socket_count(mc); socket++) {
> +base_hartid = riscv_socket_first_hartid(mc, socket);
> +
> +for (int i = 0; i < vms->soc[socket].num_harts; i++) {
> +build_append_int_noprefix(table_data, 0x18, 1);/* Type */
> +build_append_int_noprefix(table_data, 20, 1);  /* Length   */
> +build_append_int_noprefix(table_data, 1, 1);   /* Version  */
> +build_append_int_noprefix(table_data, 0, 1);   /* Reserved */
> +build_append_int_noprefix(table_data, 1, 4);   /* Flags*/
> +build_append_int_noprefix(table_data,
> +  (base_hartid + i), 8);   /* hartid   */
> +build_append_int_noprefix(table_data, cpu_id, 4);  /* ACPI ID  */
> +cpu_id++;
> +}
> +}
> +
> +acpi_table_end(linker, );
> +}
> +
>  static void
>  virt_acpi_build(RISCVVirtState *vms, AcpiBuildTables *tables)
>  {
> --
> 2.38.0
>
>



Re: [PATCH 03/10] hw/riscv/virt: Add memmap pointer to RiscVVirtState

2023-02-08 Thread Alistair Francis
On Thu, Feb 2, 2023 at 2:54 PM Sunil V L  wrote:
>
> memmap needs to be exported outside of virt.c so that
> modules like acpi can use it. Hence, add a pointer field
> in RiscVVirtState structure and initialize it with the
> memorymap.
>
> Signed-off-by: Sunil V L 

Acked-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/virt.c | 2 ++
>  include/hw/riscv/virt.h | 1 +
>  2 files changed, 3 insertions(+)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 84962962ff..26caea59ff 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -1459,6 +1459,8 @@ static void virt_machine_init(MachineState *machine)
>  ROUND_UP(virt_high_pcie_memmap.base, virt_high_pcie_memmap.size);
>  }
>
> +s->memmap = virt_memmap;
> +
>  /* register system main memory (actual RAM) */
>  memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base,
>  machine->ram);
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index 62efebaa32..379501edcc 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -59,6 +59,7 @@ struct RISCVVirtState {
>  char *oem_id;
>  char *oem_table_id;
>  OnOffAuto acpi;
> +const MemMapEntry *memmap;
>  };
>
>  enum {
> --
> 2.38.0
>
>



Re: [PATCH 01/10] hw/riscv/virt: Add OEM_ID and OEM_TABLE_ID fields

2023-02-08 Thread Alistair Francis
On Thu, Feb 2, 2023 at 2:54 PM Sunil V L  wrote:
>
> ACPI needs OEM_ID and OEM_TABLE_ID for the machine. Add these fields
> in the RISCVVirtState structure and initialize with default values.
>
> Signed-off-by: Sunil V L 

Acked-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/virt.c | 4 
>  include/hw/riscv/virt.h | 2 ++
>  2 files changed, 6 insertions(+)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index a061151a6f..7ad9fda20c 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -49,6 +49,7 @@
>  #include "hw/pci/pci.h"
>  #include "hw/pci-host/gpex.h"
>  #include "hw/display/ramfb.h"
> +#include "hw/acpi/aml-build.h"
>
>  /*
>   * The virt machine physical address space used by some of the devices
> @@ -1512,6 +1513,9 @@ static void virt_machine_init(MachineState *machine)
>  }
>  virt_flash_map(s, system_memory);
>
> +s->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
> +s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
> +
>  /* create device tree */
>  create_fdt(s, memmap);
>
> diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> index b3d26135c0..6c7885bf89 100644
> --- a/include/hw/riscv/virt.h
> +++ b/include/hw/riscv/virt.h
> @@ -56,6 +56,8 @@ struct RISCVVirtState {
>  bool have_aclint;
>  RISCVVirtAIAType aia_type;
>  int aia_guests;
> +char *oem_id;
> +char *oem_table_id;
>  };
>
>  enum {
> --
> 2.38.0
>
>



[PATCH v3 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-08 Thread Hao Wu
Nuvoton's PSPI is a general purpose SPI module which enables
connections to SPI-based peripheral devices.

Signed-off-by: Hao Wu 
Reviewed-by: Chris Rauer 
Reviewed-by: Philippe Mathieu-Daude 
---
 MAINTAINERS|   6 +-
 hw/ssi/meson.build |   2 +-
 hw/ssi/npcm_pspi.c | 221 +
 hw/ssi/trace-events|   5 +
 include/hw/ssi/npcm_pspi.h |  53 +
 5 files changed, 283 insertions(+), 4 deletions(-)
 create mode 100644 hw/ssi/npcm_pspi.c
 create mode 100644 include/hw/ssi/npcm_pspi.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 347936e41c..1e2a711373 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -803,9 +803,9 @@ M: Tyrone Ting 
 M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
-F: hw/*/npcm7xx*
-F: include/hw/*/npcm7xx*
-F: tests/qtest/npcm7xx*
+F: hw/*/npcm*
+F: include/hw/*/npcm*
+F: tests/qtest/npcm*
 F: pc-bios/npcm7xx_bootrom.bin
 F: roms/vbootrom
 F: docs/system/arm/nuvoton.rst
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 702aa5e4df..904a47161a 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -1,6 +1,6 @@
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_smc.c'))
 softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-spi.c'))
-softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c'))
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c', 
'npcm_pspi.c'))
 softmmu_ss.add(when: 'CONFIG_PL022', if_true: files('pl022.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_SPI', if_true: files('sifive_spi.c'))
 softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c
new file mode 100644
index 00..3fb935043a
--- /dev/null
+++ b/hw/ssi/npcm_pspi.c
@@ -0,0 +1,221 @@
+/*
+ * Nuvoton NPCM Peripheral SPI Module (PSPI)
+ *
+ * Copyright 2023 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/irq.h"
+#include "hw/registerfields.h"
+#include "hw/ssi/npcm_pspi.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+
+#include "trace.h"
+
+REG16(PSPI_DATA, 0x0)
+REG16(PSPI_CTL1, 0x2)
+FIELD(PSPI_CTL1, SPIEN, 0,  1)
+FIELD(PSPI_CTL1, MOD,   2,  1)
+FIELD(PSPI_CTL1, EIR,   5,  1)
+FIELD(PSPI_CTL1, EIW,   6,  1)
+FIELD(PSPI_CTL1, SCM,   7,  1)
+FIELD(PSPI_CTL1, SCIDL, 8,  1)
+FIELD(PSPI_CTL1, SCDV,  9,  7)
+REG16(PSPI_STAT, 0x4)
+FIELD(PSPI_STAT, BSY,  0,  1)
+FIELD(PSPI_STAT, RBF,  1,  1)
+
+static void npcm_pspi_update_irq(NPCMPSPIState *s)
+{
+int level = 0;
+
+/* Only fire IRQ when the module is enabled. */
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, SPIEN)) {
+/* Update interrupt as BSY is cleared. */
+if ((!FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, BSY)) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIW)) {
+level = 1;
+}
+
+/* Update interrupt as RBF is set. */
+if (FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, RBF) &&
+FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIR)) {
+level = 1;
+}
+}
+qemu_set_irq(s->irq, level);
+}
+
+static uint16_t npcm_pspi_read_data(NPCMPSPIState *s)
+{
+uint16_t value = s->regs[R_PSPI_DATA];
+
+/* Clear stat bits as the value are read out. */
+s->regs[R_PSPI_STAT] = 0;
+
+return value;
+}
+
+static void npcm_pspi_write_data(NPCMPSPIState *s, uint16_t data)
+{
+uint16_t value = 0;
+
+if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) {
+value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8;
+}
+value |= ssi_transfer(s->spi, extract16(data, 0, 8));
+s->regs[R_PSPI_DATA] = value;
+
+/* Mark data as available */
+s->regs[R_PSPI_STAT] = R_PSPI_STAT_BSY_MASK | R_PSPI_STAT_RBF_MASK;
+}
+
+/* Control register read handler. */
+static uint64_t npcm_pspi_ctrl_read(void *opaque, hwaddr addr,
+unsigned int size)
+{
+NPCMPSPIState *s = opaque;
+uint16_t value;
+
+switch (addr) {
+case A_PSPI_DATA:
+value = npcm_pspi_read_data(s);
+break;
+
+case A_PSPI_CTL1:
+value = s->regs[R_PSPI_CTL1];
+break;
+
+case A_PSPI_STAT:
+value = s->regs[R_PSPI_STAT];
+break;
+
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: write to invalid offset 

[PATCH v3 3/3] hw/arm: Attach PSPI module to NPCM7XX SoC

2023-02-08 Thread Hao Wu
Signed-off-by: Hao Wu 
Reviewed-by: Titus Rwantare 
Reviewed-by: Philippe Mathieu-Daude 
---
 docs/system/arm/nuvoton.rst |  2 +-
 hw/arm/npcm7xx.c| 25 +++--
 include/hw/arm/npcm7xx.h|  2 ++
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
index c38df32bde..0424cae4b0 100644
--- a/docs/system/arm/nuvoton.rst
+++ b/docs/system/arm/nuvoton.rst
@@ -49,6 +49,7 @@ Supported devices
  * SMBus controller (SMBF)
  * Ethernet controller (EMC)
  * Tachometer
+ * Peripheral SPI controller (PSPI)
 
 Missing devices
 ---
@@ -64,7 +65,6 @@ Missing devices
 
  * Ethernet controller (GMAC)
  * USB device (USBD)
- * Peripheral SPI controller (PSPI)
  * SD/MMC host
  * PECI interface
  * PCI and PCIe root complex and bridges
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
index d85cc02765..15ff21d047 100644
--- a/hw/arm/npcm7xx.c
+++ b/hw/arm/npcm7xx.c
@@ -86,6 +86,8 @@ enum NPCM7xxInterrupt {
 NPCM7XX_EMC1RX_IRQ  = 15,
 NPCM7XX_EMC1TX_IRQ,
 NPCM7XX_MMC_IRQ = 26,
+NPCM7XX_PSPI2_IRQ   = 28,
+NPCM7XX_PSPI1_IRQ   = 31,
 NPCM7XX_TIMER0_IRQ  = 32,   /* Timer Module 0 */
 NPCM7XX_TIMER1_IRQ,
 NPCM7XX_TIMER2_IRQ,
@@ -220,6 +222,12 @@ static const hwaddr npcm7xx_emc_addr[] = {
 0xf0826000,
 };
 
+/* Register base address for each PSPI Module */
+static const hwaddr npcm7xx_pspi_addr[] = {
+0xf020,
+0xf0201000,
+};
+
 static const struct {
 hwaddr regs_addr;
 uint32_t unconnected_pins;
@@ -444,6 +452,10 @@ static void npcm7xx_init(Object *obj)
 object_initialize_child(obj, "emc[*]", >emc[i], TYPE_NPCM7XX_EMC);
 }
 
+for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
+object_initialize_child(obj, "pspi[*]", >pspi[i], TYPE_NPCM_PSPI);
+}
+
 object_initialize_child(obj, "mmc", >mmc, TYPE_NPCM7XX_SDHCI);
 }
 
@@ -715,6 +727,17 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 sysbus_connect_irq(SYS_BUS_DEVICE(>mmc), 0,
 npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
 
+/* PSPI */
+QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pspi_addr) != ARRAY_SIZE(s->pspi));
+for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
+SysBusDevice *sbd = SYS_BUS_DEVICE(>pspi[i]);
+int irq = (i == 0) ? NPCM7XX_PSPI1_IRQ : NPCM7XX_PSPI2_IRQ;
+
+sysbus_realize(sbd, _abort);
+sysbus_mmio_map(sbd, 0, npcm7xx_pspi_addr[i]);
+sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
+}
+
 create_unimplemented_device("npcm7xx.shm",  0xc0001000,   4 * KiB);
 create_unimplemented_device("npcm7xx.vdmx", 0xe080,   4 * KiB);
 create_unimplemented_device("npcm7xx.pcierc",   0xe100,  64 * KiB);
@@ -724,8 +747,6 @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
 create_unimplemented_device("npcm7xx.peci", 0xf010,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[1]",  0xf0101000,   4 * KiB);
 create_unimplemented_device("npcm7xx.siox[2]",  0xf0102000,   4 * KiB);
-create_unimplemented_device("npcm7xx.pspi1",0xf020,   4 * KiB);
-create_unimplemented_device("npcm7xx.pspi2",0xf0201000,   4 * KiB);
 create_unimplemented_device("npcm7xx.ahbpci",   0xf040,   1 * MiB);
 create_unimplemented_device("npcm7xx.mcphy",0xf05f,  64 * KiB);
 create_unimplemented_device("npcm7xx.gmac1",0xf0802000,   8 * KiB);
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
index f1b7e4a48d..72c7722096 100644
--- a/include/hw/arm/npcm7xx.h
+++ b/include/hw/arm/npcm7xx.h
@@ -32,6 +32,7 @@
 #include "hw/nvram/npcm7xx_otp.h"
 #include "hw/timer/npcm7xx_timer.h"
 #include "hw/ssi/npcm7xx_fiu.h"
+#include "hw/ssi/npcm_pspi.h"
 #include "hw/usb/hcd-ehci.h"
 #include "hw/usb/hcd-ohci.h"
 #include "target/arm/cpu.h"
@@ -104,6 +105,7 @@ struct NPCM7xxState {
 NPCM7xxFIUState fiu[2];
 NPCM7xxEMCState emc[2];
 NPCM7xxSDHCIState   mmc;
+NPCMPSPIState   pspi[2];
 };
 
 #define TYPE_NPCM7XX"npcm7xx"
-- 
2.39.1.519.gcb327c4b5f-goog




[PATCH v3 1/3] MAINTAINERS: Add myself to maintainers and remove Havard

2023-02-08 Thread Hao Wu
Havard is no longer working on the Nuvoton systems for a while
and won't be able to do any work on it in the future. So I'll
take over maintaining the Nuvoton system from him.

Signed-off-by: Hao Wu 
Acked-by: Havard Skinnemoen 
Reviewed-by: Philippe Mathieu-Daude 
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index fa10ecaeb9..347936e41c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -799,8 +799,8 @@ F: include/hw/net/mv88w8618_eth.h
 F: docs/system/arm/musicpal.rst
 
 Nuvoton NPCM7xx
-M: Havard Skinnemoen 
 M: Tyrone Ting 
+M: Hao Wu 
 L: qemu-...@nongnu.org
 S: Supported
 F: hw/*/npcm7xx*
-- 
2.39.1.519.gcb327c4b5f-goog




[PATCH v3 0/3] Nuvoton Peripheral SPI (PSPI) Module

2023-02-08 Thread Hao Wu
This patch set adds peripheral SPI (PSPI) modules
to NPCM7XX SoCs. These modules can be used to
connect any SPI peripheral devices to the SoC.

This module will also be used in the next generation
NPCM8XX SoCs which haven't been merged yet.

-- Changes from v2 --
Change max_access_size to 2 to match the datasheet.

-- Changes from v1 --
A few minor updates for npcm-pspi.c according to
Phillipe Mathieu-Daude's review.

Thanks!

Hao Wu (3):
  MAINTAINERS: Add myself to maintainers and remove Havard
  hw/ssi: Add Nuvoton PSPI Module
  hw/arm: Attach PSPI module to NPCM7XX SoC

 MAINTAINERS |   8 +-
 docs/system/arm/nuvoton.rst |   2 +-
 hw/arm/npcm7xx.c|  25 +++-
 hw/ssi/meson.build  |   2 +-
 hw/ssi/npcm_pspi.c  | 221 
 hw/ssi/trace-events |   5 +
 include/hw/arm/npcm7xx.h|   2 +
 include/hw/ssi/npcm_pspi.h  |  53 +
 8 files changed, 310 insertions(+), 8 deletions(-)
 create mode 100644 hw/ssi/npcm_pspi.c
 create mode 100644 include/hw/ssi/npcm_pspi.h

-- 
2.39.1.519.gcb327c4b5f-goog




Re: [PATCH v2 2/3] hw/ssi: Add Nuvoton PSPI Module

2023-02-08 Thread Hao Wu
Thanks for pointing that out. I'll send another version to fix that.

On Tue, Feb 7, 2023 at 11:48 PM Philippe Mathieu-Daudé 
wrote:

> On 7/2/23 20:45, Hao Wu wrote:
> > Nuvoton's PSPI is a general purpose SPI module which enables
> > connections to SPI-based peripheral devices.
> >
> > Signed-off-by: Hao Wu 
> > Reviewed-by: Chris Rauer 
> > Reviewed-by: Philippe Mathieu-Daude 
> > ---
> >   MAINTAINERS|   6 +-
> >   hw/ssi/meson.build |   2 +-
> >   hw/ssi/npcm_pspi.c | 221 +
> >   hw/ssi/trace-events|   5 +
> >   include/hw/ssi/npcm_pspi.h |  53 +
> >   5 files changed, 283 insertions(+), 4 deletions(-)
> >   create mode 100644 hw/ssi/npcm_pspi.c
> >   create mode 100644 include/hw/ssi/npcm_pspi.h
>
>
> > +static const MemoryRegionOps npcm_pspi_ctrl_ops = {
> > +.read = npcm_pspi_ctrl_read,
> > +.write = npcm_pspi_ctrl_write,
> > +.endianness = DEVICE_LITTLE_ENDIAN,
> > +.valid = {
> > +.min_access_size = 1,
> > +.max_access_size = 4,
>
> You said in v1 "The datasheet suggests it's either 8-bit or
> 16-bit accesses.", so we want max_access_size = 2 here, right?
>
> > +.unaligned = false,
> > +},
> > +.impl = {
> > +.min_access_size = 2,
> > +.max_access_size = 2,
> > +.unaligned = false,
> > +},
> > +};
>
>
>


[PATCH 1/2] configure: Add 'mkdir build' check

2023-02-08 Thread Dinah Baum
QEMU configure script goes into an infinite error printing loop
when in read only directory due to 'build' dir never being created.

Checking if 'mkdir dir' succeeds prevents this error.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/321
---
 configure | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/configure b/configure
index 64960c6000..3b384914ce 100755
--- a/configure
+++ b/configure
@@ -31,10 +31,11 @@ then
 fi
 fi
 
-mkdir build
-touch $MARKER
+if mkdir build
+then
+touch $MARKER
 
-cat > GNUmakefile <<'EOF'
+cat > GNUmakefile <<'EOF'
 # This file is auto-generated by configure to support in-source tree
 # 'make' command invocation
 
@@ -56,8 +57,12 @@ force: ;
 GNUmakefile: ;
 
 EOF
-cd build
-exec "$source_path/configure" "$@"
+cd build
+exec "$source_path/configure" "$@"
+else
+echo "ERROR: Unable to use ./build dir, try using a ../qemu/configure 
build"
+exit 1
+fi
 fi
 
 # Temporary directory used for files created while
-- 
2.30.2




[PATCH 2/2] configure: './configure --help' should work

2023-02-08 Thread Dinah Baum
Always initialize --help display option

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/321
---
 configure | 676 +++---
 1 file changed, 338 insertions(+), 338 deletions(-)

diff --git a/configure b/configure
index 3b384914ce..1fb4d145f1 100755
--- a/configure
+++ b/configure
@@ -14,6 +14,344 @@ export CCACHE_RECACHE=yes
 # make source path absolute
 source_path=$(cd "$(dirname -- "$0")"; pwd)
 
+werror=""
+
+print_error() {
+(echo
+echo "ERROR: $1"
+while test -n "$2"; do
+echo "   $2"
+shift
+done
+echo) >&2
+}
+
+error_exit() {
+print_error "$@"
+exit 1
+}
+
+meson_option_build_array() {
+  printf '['
+  (if test "$targetos" = windows; then
+IFS=\;
+  else
+IFS=:
+  fi
+  for e in $1; do
+printf '"""'
+# backslash escape any '\' and '"' characters
+printf "%s" "$e" | sed -e 's/\([\"]\)/\\\1/g'
+printf '""",'
+  done)
+  printf ']\n'
+}
+
+. "$source_path/scripts/meson-buildoptions.sh"
+
+quote_sh() {
+printf "%s" "$1" | sed "s,',''',g; s,.*,'&',"
+}
+
+meson_options=
+meson_option_add() {
+  meson_options="$meson_options $(quote_sh "$1")"
+}
+meson_option_parse() {
+  meson_options="$meson_options $(_meson_option_parse "$@")"
+  if test $? -eq 1; then
+echo "ERROR: unknown option $1"
+echo "Try '$0 --help' for more information"
+exit 1
+  fi
+}
+
+for opt do
+  optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
+  case "$opt" in
+  --help|-h) show_help=yes
+  ;;
+  --version|-V) exec cat "$source_path/VERSION"
+  ;;
+  --prefix=*) prefix="$optarg"
+  ;;
+  --cross-prefix=*)
+  ;;
+  --cc=*)
+  ;;
+  --host-cc=*) host_cc="$optarg"
+  ;;
+  --cxx=*)
+  ;;
+  --objcc=*) objcc="$optarg"
+  ;;
+  --make=*) make="$optarg"
+  ;;
+  --install=*)
+  ;;
+  --python=*) python="$optarg" ; explicit_python=yes
+  ;;
+  --skip-meson) skip_meson=yes
+  ;;
+  --meson=*) meson="$optarg"
+  ;;
+  --ninja=*) ninja="$optarg"
+  ;;
+  --smbd=*) smbd="$optarg"
+  ;;
+  --extra-cflags=*)
+  ;;
+  --extra-cxxflags=*)
+  ;;
+  --extra-objcflags=*)
+  ;;
+  --extra-ldflags=*)
+  ;;
+  --cross-cc-*)
+  ;;
+  --cross-prefix-*)
+  ;;
+  --enable-debug-info) meson_option_add -Ddebug=true
+  ;;
+  --disable-debug-info) meson_option_add -Ddebug=false
+  ;;
+  --enable-modules)
+  modules="yes"
+  ;;
+  --disable-modules)
+  modules="no"
+  ;;
+  --cpu=*)
+  ;;
+  --target-list=*) target_list="$optarg"
+   if test "$target_list_exclude"; then
+   error_exit "Can't mix --target-list with 
--target-list-exclude"
+   fi
+  ;;
+  --target-list-exclude=*) target_list_exclude="$optarg"
+   if test "$target_list"; then
+   error_exit "Can't mix --target-list-exclude with 
--target-list"
+   fi
+  ;;
+  --with-default-devices) meson_option_add -Ddefault_devices=true
+  ;;
+  --without-default-devices) meson_option_add -Ddefault_devices=false
+  ;;
+  --with-devices-*[!a-zA-Z0-9_-]*=*) error_exit "Passed bad --with-devices-FOO 
option"
+  ;;
+  --with-devices-*) device_arch=${opt#--with-devices-};
+device_arch=${device_arch%%=*}
+
cf=$source_path/configs/devices/$device_arch-softmmu/$optarg.mak
+if test -f "$cf"; then
+device_archs="$device_archs $device_arch"
+eval "devices_${device_arch}=\$optarg"
+else
+error_exit "File $cf does not exist"
+fi
+  ;;
+  --without-default-features) # processed above
+  ;;
+  --static)
+static="yes"
+QEMU_PKG_CONFIG_FLAGS="--static $QEMU_PKG_CONFIG_FLAGS"
+  ;;
+  --bindir=*) bindir="$optarg"
+  ;;
+  --with-suffix=*) qemu_suffix="$optarg"
+  ;;
+  --host=*|--build=*|\
+  --disable-dependency-tracking|\
+  --sbindir=*|--sharedstatedir=*|\
+  --oldincludedir=*|--datarootdir=*|--infodir=*|\
+  --htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
+# These switches are silently ignored, for compatibility with
+# autoconf-generated configure scripts. This allows QEMU's
+# configure to be used by RPM and similar macros that set
+# lots of directory switches by default.
+  ;;
+  --enable-debug-tcg) debug_tcg="yes"
+  ;;
+  --disable-debug-tcg) debug_tcg="no"
+  ;;
+  --enable-debug)
+  # Enable debugging options that aren't excessively noisy
+  debug_tcg="yes"
+  meson_option_parse --enable-debug-mutex ""
+  meson_option_add -Doptimization=0
+  fortify_source="no"
+  ;;
+  --enable-sanitizers) sanitizers="yes"
+  ;;
+  --disable-sanitizers) sanitizers="no"
+  ;;
+  --enable-tsan) tsan="yes"
+  ;;
+  --disable-tsan) tsan="no"
+  ;;
+  --disable-tcg) tcg="disabled"
+ plugins="no"
+  ;;
+  --enable-tcg) tcg="enabled"
+  ;;
+  --disable-system) softmmu="no"
+  ;;
+  --enable-system) softmmu="yes"
+  ;;
+  --disable-user)
+  linux_user="no" ;
+  

[PATCH 0/2] *** configure: Add 'mkdir build' check ***

2023-02-08 Thread Dinah Baum
QEMU configure script goes into an infinite error printing loop
when in read only directory due to 'build' dir never being created.

1 - Checking if 'mkdir dir' succeeds and if the directory is
writeable prevents this error.

2 - Since we exit early on error in (1), code for reading in
arguments has been moved before that

Changes since v1:
- Fix review comments from Peter Maydell 

Dinah Baum (2):
  configure: Add 'mkdir build' check
  configure: './configure --help' should work

 configure | 691 +++---
 1 file changed, 348 insertions(+), 343 deletions(-)

-- 
2.30.2




Re: [RFC PATCH 0/5] Deprecate/rename singlestep command line option

2023-02-08 Thread Warner Losh
On Tue, Feb 7, 2023 at 8:56 AM Markus Armbruster  wrote:

> Peter Maydell  writes:
>
> > The command line option '-singlestep' and its HMP equivalent
> > the 'singlestep' command are very confusingly named, because
> > they have nothing to do with single-stepping the guest (either
> > via the gdb stub or by emulation of guest CPU architectural
> > debug facilities). What they actually do is put TCG into a
> > mode where it puts only one guest instruction into each
> > translation block. This is useful for some circumstances
> > such as when you want the -d debug logging to be easier to
> > interpret, or if you have a finicky guest binary that wants
> > to see interrupts delivered at something other than the end
> > of a basic block.
> >
> > The confusing name is made worse by the fact that our
> > documentation for these is so minimal as to be useless
> > for telling users what they really do.
> >
> > This series:
> >  * renames the 'singlestep' global variable to 'one_insn_per_tb'
> >  * Adds new '-one-insn-per-tb' command line options and a
> >HMP 'one-insn-per-tb' command
> >  * Documents the '-singlestep' options and 'singlestep'
> >HMP command as deprecated synonyms for the new ones
> >
> > It does not do anything about the other place where we surface
> > 'singlestep', which is in the QMP StatusInfo object returned by the
> > 'query-status' command.  This is incorrectly documented as "true if
> > VCPUs are in single-step mode" and "singlestep is enabled through
> > the GDB stub", because what it's actually returning is the
> > one-insn-per-tb state.
> >
> > Things I didn't bother with because this is only an RFC but
> > will do if it turns into a non-RFC patchset:
> >  * test the bsd-user changes :-)
> >  * add text to deprecated.rst
> >
> > So, questions:
> >
> > (1) is this worth bothering with at all? We could just
> > name our global variable etc better, and document what
> > -singlestep actually does, and not bother with the new
> > names for the options/commands.
>
> The feature is kind of esoteric.  Rather weak excuse for not fixing bad
> UI, in my opinion.  Weaker still since you already did a good part of
> the actual work.
>
> > (2) if we do do it, do we retain the old name indefinitely,
> > or actively put it on the deprecate-and-drop list?
>
> By "the old name", you mean the CLI option name, right?
>
> I'd prefer deprecate and drop.
>
> > (3) what should we do about the HMP StatusInfo object?
> > I'm not sure how we handle compatibility for HMP.
>
> Uh, you mean *QMP*, don't you?
>
> As you wrote above, StatusInfo is returned by query-status, which is a
> stable interface.  Changes to members therefore require the usual
> deprecation grace period.  We'd add a new member with a sane name, and
> deprecate the old one.
>
> The matching HMP command is "info status".  It shows member @singlestep
> as " (single step mode)".  Changing that is fine; HMP is not a stable
> interface.
>

We don't use this feature on bsd-user, so I'm happy to follow whatever is
decided
here. I can test things once the suggestion in this and other threads have
played out
and there's another RFC set of patches.

Warner


Re: Call for GSoC and Outreachy project ideas for summer 2023

2023-02-08 Thread Warner Losh
On Fri, Jan 27, 2023 at 3:02 PM Stefan Hajnoczi  wrote:

> On Fri, 27 Jan 2023 at 12:10, Warner Losh  wrote:
> >
> > [[ cc list trimmed to just qemu-devel ]]
> >
> > On Fri, Jan 27, 2023 at 8:18 AM Stefan Hajnoczi 
> wrote:
> >>
> >> Dear QEMU, KVM, and rust-vmm communities,
> >> QEMU will apply for Google Summer of Code 2023
> >> (https://summerofcode.withgoogle.com/) and has been accepted into
> >> Outreachy May 2023 (https://www.outreachy.org/). You can now
> >> submit internship project ideas for QEMU, KVM, and rust-vmm!
> >>
> >> Please reply to this email by February 6th with your project ideas.
> >>
> >> If you have experience contributing to QEMU, KVM, or rust-vmm you can
> >> be a mentor. Mentors support interns as they work on their project.
> It's a
> >> great way to give back and you get to work with people who are just
> >> starting out in open source.
> >>
> >> Good project ideas are suitable for remote work by a competent
> >> programmer who is not yet familiar with the codebase. In
> >> addition, they are:
> >> - Well-defined - the scope is clear
> >> - Self-contained - there are few dependencies
> >> - Uncontroversial - they are acceptable to the community
> >> - Incremental - they produce deliverables along the way
> >>
> >> Feel free to post ideas even if you are unable to mentor the project.
> >> It doesn't hurt to share the idea!
> >
> >
> > I've been a GSoC mentor for the FreeBSD project on and off for maybe
> > 10-15 years now. I thought I'd share this for feedback here.
> >
> > My project idea falls between the two projects. I've been trying
> > to get bsd-user reviewed and upstreamed for some time now and my
> > time available to do the upstreaming has been greatly diminished lately.
> > It got me thinking: upstreaming is more than just getting patches
> reviewed
> > often times. While there is a rather mechanical aspect to it (and I
> could likely
> > automate that aspect more), the real value of going through the review
> process
> > is that it points out things that had been done wrong, things that need
> to be
> > redone or refactored, etc. It's often these suggestions that lead to the
> biggest
> > investment of time on my part: Is this idea good? if I do it, does it
> break things?
> > Is the feedback right about what's wrong, but wrong about how to fix it?
> etc.
> > Plus the inevitable, I thought this was a good idea, implemented it only
> to find
> > it broke other things, and how do I explain that and provide feedback to
> the
> > reviewer about that breakage to see if it is worth pursuing further or
> not?
> >
> > So my idea for a project is two fold: First, to create scripts to
> automate the
> > upstreaming process: to break big files into bite-sized chunks for
> review on
> > this list. git publish does a great job from there. The current backlog
> to upstream
> > is approximately " 175 files changed, 30270 insertions(+), 640
> deletions(-)" which
> > is 300-600 patches at the 50-100 line patch guidance I've been given. So
> even
> > at .1hr (6 minutes) per patch (which is about 3x faster than I can do it
> by hand),
> > that's ~60 hours just to create the patches. Writing automation should
> take
> > much less time. Realistically, this is on the order of 10-20 hours to
> get done.
> >
> > Second, it's to take feedback from the reviews for refactoring
> > the bsd-user code base (which will eventually land in upstream). I often
> spend
> > a few hours creating my patches each quarter, then about 10 or so hours
> for the
> > 30ish patches that I do processing the review feedback by refactoring
> other things
> > (typically other architectures), checking details of other architectures
> (usually by
> > looking at the FreeBSD kernel), or looking for ways to refactor to share
> code with
> > linux-user  (though so far only the safe signals is upstream: elf could
> be too), or
> > chatting online about the feedback to better understand it, to see what
> I can mine
> > from linux-user (since the code is derived from that, but didn't pick up
> all the changes
> > linus-user has), etc. This would be on the order of 100 hours.
> >
> > Third, the testing infrastructure that exists for linux-user is not well
> leveraged to test
> > bsd-user. I've done some tests from time to time with it, but it's not
> in a state that it
> > can be used as, say, part of a CI pipeline. In addition, the FreeBSD
> project has some
> > very large jobs, a subset of which could be used to further ensure that
> critical bits of
> > infrastructure don't break (or are working if not in a CI pipeline).
> Things like building
> > and using go, rust and the like are constantly breaking for reasons too
> long to enumerate
> > here. This job could be as little as 50 hours to do a minimal but
> complete enough for CI job,
> > or as much as 200 hours to do a more complete jobs that could be used to
> bisect breakage
> > more quickly and give good assurance that at any given time bsd-user is
> useful and 

[PATCH v2 1/4] hw/gpio: add PCA6416 i2c GPIO expander

2023-02-08 Thread Titus Rwantare
The PCA6416 is an i2c device with 16 GPIOs.

Reviewed-by: Hao Wu 
Signed-off-by: Titus Rwantare 
---
 hw/arm/Kconfig  |   1 +
 hw/gpio/Kconfig |   4 +
 hw/gpio/meson.build |   1 +
 hw/gpio/pca_i2c_gpio.c  | 388 
 hw/gpio/trace-events|   5 +
 include/hw/gpio/pca_i2c_gpio.h  |  69 ++
 tests/lcitool/libvirt-ci|   2 +-
 tests/qtest/meson.build |   1 +
 tests/qtest/pca_i2c_gpio-test.c | 169 ++
 9 files changed, 639 insertions(+), 1 deletion(-)
 create mode 100644 hw/gpio/pca_i2c_gpio.c
 create mode 100644 include/hw/gpio/pca_i2c_gpio.h
 create mode 100644 tests/qtest/pca_i2c_gpio-test.c

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 2d157de9b8..1b533ddd76 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -418,6 +418,7 @@ config NPCM7XX
 select SSI
 select UNIMP
 select PCA954X
+select PCA_I2C_GPIO
 
 config FSL_IMX25
 bool
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
index d2cf3accc8..1c01d9744a 100644
--- a/hw/gpio/Kconfig
+++ b/hw/gpio/Kconfig
@@ -16,3 +16,7 @@ config GPIO_PWR
 
 config SIFIVE_GPIO
 bool
+
+config PCA_I2C_GPIO
+bool
+depends on I2C
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
index b726e6d27a..1e5b602002 100644
--- a/hw/gpio/meson.build
+++ b/hw/gpio/meson.build
@@ -12,3 +12,4 @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true: 
files('omap_gpio.c'))
 softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_gpio.c'))
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))
 softmmu_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
+softmmu_ss.add(when: 'CONFIG_PCA_I2C_GPIO', if_true: files('pca_i2c_gpio.c'))
diff --git a/hw/gpio/pca_i2c_gpio.c b/hw/gpio/pca_i2c_gpio.c
new file mode 100644
index 00..434a759453
--- /dev/null
+++ b/hw/gpio/pca_i2c_gpio.c
@@ -0,0 +1,388 @@
+/*
+ * NXP PCA I2C GPIO Expanders
+ *
+ * Low-voltage translating 16-bit I2C/SMBus GPIO expander with interrupt 
output,
+ * reset, and configuration registers
+ *
+ * Datasheet: https://www.nxp.com/docs/en/data-sheet/PCA6416A.pdf
+ *
+ * Copyright 2023 Google LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * To assert some input pins before boot, use the following in the board file 
of
+ * the machine:
+ *  object_property_set_uint(Object *obj, const char *name,
+ *   uint64_t value, Error **errp);
+ * specifying name as "gpio_config" and the value as a bitfield of the inputs
+ * e.g. for the pca6416, a value of 0xFFF0, configures pins 0-3 as outputs and
+ * 4-15 as inputs.
+ * Then using name "gpio_input" with value "0x0F00" would raise GPIOs 8-11.
+ *
+ * This value can also be set at runtime through qmp externally, or by
+ * writing to the config register using i2c. The guest driver should generally
+ * control the config register, but exposing it via qmp allows external 
testing.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/gpio/pca_i2c_gpio.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "migration/vmstate.h"
+#include "qapi/visitor.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+
+/*
+ * compare new_output to curr_output and update irq to match new_output
+ *
+ * The Input port registers (registers 0 and 1) reflect the incoming logic
+ * levels of the pins, regardless of whether the pin is defined as an input or
+ * an output by the Configuration register.
+ */
+static void pca_i2c_update_irqs(PCAGPIOState *ps)
+{
+PCAGPIOClass *pc = PCA_I2C_GPIO_GET_CLASS(ps);
+uint16_t out_diff = ps->new_output ^ ps->curr_output;
+uint16_t in_diff = ps->new_input ^ ps->curr_input;
+uint16_t mask, pin_i;
+
+if (in_diff || out_diff) {
+for (int i = 0; i < pc->num_pins; i++) {
+mask = BIT(i);
+/* pin must be configured as an output to be set here */
+if (out_diff & ~ps->config & mask) {
+pin_i = mask & ps->new_output;
+qemu_set_irq(ps->output[i], pin_i > 0);
+ps->curr_output &= ~mask;
+ps->curr_output |= pin_i;
+}
+
+if (in_diff & mask) {
+ps->curr_input &= ~mask;
+ps->curr_input |= mask & ps->new_input;
+}
+}
+/* make diff = 0 */
+ps->new_input = ps->curr_input;
+}
+}
+
+static void pca_i2c_irq_handler(void *opaque, int n, int level)
+{
+PCAGPIOState *ps = opaque;
+PCAGPIOClass *pc = PCA_I2C_GPIO_GET_CLASS(opaque);
+uint16_t mask = BIT(n);
+
+g_assert(n < pc->num_pins);
+g_assert(n >= 0);
+
+ps->new_input &= ~mask;
+
+if (level > 0) {
+ps->new_input |= BIT(n);
+}
+
+pca_i2c_update_irqs(ps);
+}
+
+/* slave to master */
+static uint8_t pca6416_recv(I2CSlave *i2c)
+{
+PCAGPIOState *ps = PCA_I2C_GPIO(i2c);
+uint8_t data;
+
+switch (ps->command) {
+

[PATCH v2 3/4] hw/gpio: add PCA9536 i2c gpio expander

2023-02-08 Thread Titus Rwantare
This device has the same register layout as the pca9538, but 4 fewer
gpio pins. This commit lowers the number of pins initialised, and reuses
the pca9538 logic.

Reviewed-by: Hao Wu 
Signed-off-by: Titus Rwantare 
---
 hw/gpio/pca_i2c_gpio.c | 18 ++
 include/hw/gpio/pca_i2c_gpio.h |  2 ++
 2 files changed, 20 insertions(+)

diff --git a/hw/gpio/pca_i2c_gpio.c b/hw/gpio/pca_i2c_gpio.c
index fa69523556..8e30064990 100644
--- a/hw/gpio/pca_i2c_gpio.c
+++ b/hw/gpio/pca_i2c_gpio.c
@@ -426,6 +426,19 @@ static void pca9538_gpio_class_init(ObjectClass *klass, 
void *data)
 k->send = pca9538_send;
 }
 
+static void pca9536_gpio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+PCAGPIOClass *pc = PCA_I2C_GPIO_CLASS(klass);
+
+dc->desc = "PCA9536 4-bit I/O expander";
+pc->num_pins = PCA9536_NUM_PINS;
+
+k->recv = pca9538_recv;
+k->send = pca9538_send;
+}
+
 static void pca_i2c_gpio_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -477,6 +490,11 @@ static const TypeInfo pca_gpio_types[] = {
 .parent = TYPE_PCA_I2C_GPIO,
 .class_init = pca9538_gpio_class_init,
 },
+{
+.name = TYPE_PCA9536_GPIO,
+.parent = TYPE_PCA_I2C_GPIO,
+.class_init = pca9536_gpio_class_init,
+},
 };
 
 DEFINE_TYPES(pca_gpio_types);
diff --git a/include/hw/gpio/pca_i2c_gpio.h b/include/hw/gpio/pca_i2c_gpio.h
index 3ab7d19a97..6f8260a8c6 100644
--- a/include/hw/gpio/pca_i2c_gpio.h
+++ b/include/hw/gpio/pca_i2c_gpio.h
@@ -20,6 +20,7 @@
 #define PCA_I2C_MAX_PINS 16
 #define PCA6416_NUM_PINS 16
 #define PCA9538_NUM_PINS 8
+#define PCA9536_NUM_PINS 4
 
 typedef struct PCAGPIOClass {
 I2CSlaveClass parent;
@@ -72,5 +73,6 @@ OBJECT_DECLARE_TYPE(PCAGPIOState, PCAGPIOClass, PCA_I2C_GPIO)
 
 #define TYPE_PCA6416_GPIO "pca6416"
 #define TYPE_PCA9538_GPIO "pca9538"
+#define TYPE_PCA9536_GPIO "pca9536"
 
 #endif
-- 
2.39.1.581.gbfd45094c4-goog




[PATCH v2 2/4] hw/gpio: add PCA9538 8-bit GPIO expander

2023-02-08 Thread Titus Rwantare
  The 8-bit expander has different register offsets than the 16-bit one,
  making them incompatible.

Reviewed-by: Hao Wu 
Signed-off-by: Titus Rwantare 
---
 hw/gpio/pca_i2c_gpio.c | 94 ++
 include/hw/gpio/pca_i2c_gpio.h |  7 +++
 2 files changed, 101 insertions(+)

diff --git a/hw/gpio/pca_i2c_gpio.c b/hw/gpio/pca_i2c_gpio.c
index 434a759453..fa69523556 100644
--- a/hw/gpio/pca_i2c_gpio.c
+++ b/hw/gpio/pca_i2c_gpio.c
@@ -143,6 +143,41 @@ static uint8_t pca6416_recv(I2CSlave *i2c)
 return data;
 }
 
+/* slave to master */
+static uint8_t pca9538_recv(I2CSlave *i2c)
+{
+PCAGPIOState *ps = PCA_I2C_GPIO(i2c);
+uint8_t data;
+
+switch (ps->command) {
+case PCA9538_INPUT_PORT:
+data = ps->curr_input;
+break;
+
+case PCA9538_OUTPUT_PORT:
+data = ps->new_output;
+break;
+
+case PCA9538_POLARITY_INVERSION_PORT:
+data = ps->polarity_inv;
+break;
+
+case PCA9538_CONFIGURATION_PORT:
+data = ps->config;
+break;
+
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: reading from unsupported register 0x%02x",
+  __func__, ps->command);
+data = 0xFF;
+break;
+}
+
+trace_pca_i2c_recv(DEVICE(ps)->canonical_path, ps->command, data);
+return data;
+}
+
 /* master to slave */
 static int pca6416_send(I2CSlave *i2c, uint8_t data)
 {
@@ -203,6 +238,47 @@ static int pca6416_send(I2CSlave *i2c, uint8_t data)
 return 0;
 }
 
+/* master to slave */
+static int pca9538_send(I2CSlave *i2c, uint8_t data)
+{
+PCAGPIOState *ps = PCA_I2C_GPIO(i2c);
+if (ps->i2c_cmd) {
+ps->command = data;
+ps->i2c_cmd = false;
+return 0;
+}
+
+trace_pca_i2c_send(DEVICE(ps)->canonical_path, ps->command, data);
+
+switch (ps->command) {
+case PCA9538_INPUT_PORT:
+qemu_log_mask(LOG_GUEST_ERROR, "%s: writing to read only reg: 0x%02x",
+  __func__, ps->command);
+break;
+case PCA9538_OUTPUT_PORT:
+ps->new_output = data;
+break;
+
+case PCA9538_POLARITY_INVERSION_PORT:
+ps->polarity_inv = data;
+break;
+
+case PCA9538_CONFIGURATION_PORT:
+ps->config = data;
+break;
+
+default:
+qemu_log_mask(LOG_GUEST_ERROR,
+  "%s: writing to unsupported register\n",
+  __func__);
+return -1;
+}
+
+pca_i2c_update_irqs(ps);
+
+return 0;
+}
+
 static int pca_i2c_event(I2CSlave *i2c, enum i2c_event event)
 {
 PCAGPIOState *ps = PCA_I2C_GPIO(i2c);
@@ -337,6 +413,19 @@ static void pca6416_gpio_class_init(ObjectClass *klass, 
void *data)
 k->send = pca6416_send;
 }
 
+static void pca9538_gpio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
+PCAGPIOClass *pc = PCA_I2C_GPIO_CLASS(klass);
+
+dc->desc = "PCA9538 8-bit I/O expander";
+pc->num_pins = PCA9538_NUM_PINS;
+
+k->recv = pca9538_recv;
+k->send = pca9538_send;
+}
+
 static void pca_i2c_gpio_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
@@ -383,6 +472,11 @@ static const TypeInfo pca_gpio_types[] = {
 .parent = TYPE_PCA_I2C_GPIO,
 .class_init = pca6416_gpio_class_init,
 },
+{
+.name = TYPE_PCA9538_GPIO,
+.parent = TYPE_PCA_I2C_GPIO,
+.class_init = pca9538_gpio_class_init,
+},
 };
 
 DEFINE_TYPES(pca_gpio_types);
diff --git a/include/hw/gpio/pca_i2c_gpio.h b/include/hw/gpio/pca_i2c_gpio.h
index 99322959e1..3ab7d19a97 100644
--- a/include/hw/gpio/pca_i2c_gpio.h
+++ b/include/hw/gpio/pca_i2c_gpio.h
@@ -19,6 +19,7 @@
 
 #define PCA_I2C_MAX_PINS 16
 #define PCA6416_NUM_PINS 16
+#define PCA9538_NUM_PINS 8
 
 typedef struct PCAGPIOClass {
 I2CSlaveClass parent;
@@ -62,8 +63,14 @@ OBJECT_DECLARE_TYPE(PCAGPIOState, PCAGPIOClass, PCA_I2C_GPIO)
 #define PCA6416_CONFIGURATION_PORT_0 0x06 /* read/write */
 #define PCA6416_CONFIGURATION_PORT_1 0x07 /* read/write */
 
+#define PCA9538_INPUT_PORT   0x00 /* read */
+#define PCA9538_OUTPUT_PORT  0x01 /* read/write */
+#define PCA9538_POLARITY_INVERSION_PORT  0x02 /* read/write */
+#define PCA9538_CONFIGURATION_PORT   0x03 /* read/write */
+
 #define PCA_I2C_CONFIG_DEFAULT   0
 
 #define TYPE_PCA6416_GPIO "pca6416"
+#define TYPE_PCA9538_GPIO "pca9538"
 
 #endif
-- 
2.39.1.581.gbfd45094c4-goog




[PATCH v2 0/4] PCA I2C GPIO expanders

2023-02-08 Thread Titus Rwantare
This patch series contains a set of i2c GPIO expanders,
with support for 4, 8, and 16 GPIO connections.

The devices are configured as GPIO *inputs by default, but can have pins
configured to be inputs with qmp commands.

For example, the following snippet in a board file for a system,
configures a 16 bit pca6416 to have pins 8-11 as inputs, then asserts
them.

dev = DEVICE(i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 3), 
"pca6416", 0x72));
object_property_set_uint(OBJECT(dev), "gpio_config", 0x0F00, _abort);
object_property_set_uint(OBJECT(dev), "gpio_input", 0x0F00, _abort);

We currently use these to test hardware presence and LEDs in simulation.

Thanks

Since v1:
- addressed comments
- fixed typos in commit messages

Titus Rwantare (4):
  hw/gpio: add PCA6416 i2c GPIO expander
  hw/gpio: add PCA9538 8-bit GPIO expander
  hw/gpio: add PCA9536 i2c gpio expander
  hw/i2c: add canonical path to i2c event traces

 hw/arm/Kconfig  |   1 +
 hw/gpio/Kconfig |   4 +
 hw/gpio/meson.build |   1 +
 hw/gpio/pca_i2c_gpio.c  | 500 
 hw/gpio/trace-events|   5 +
 hw/i2c/core.c   |   8 +-
 hw/i2c/trace-events |   2 +-
 include/hw/gpio/pca_i2c_gpio.h  |  78 +
 tests/lcitool/libvirt-ci|   2 +-
 tests/qtest/meson.build |   1 +
 tests/qtest/pca_i2c_gpio-test.c | 169 +++
 11 files changed, 766 insertions(+), 5 deletions(-)
 create mode 100644 hw/gpio/pca_i2c_gpio.c
 create mode 100644 include/hw/gpio/pca_i2c_gpio.h
 create mode 100644 tests/qtest/pca_i2c_gpio-test.c

-- 
2.39.1.581.gbfd45094c4-goog




[PATCH v2 4/4] hw/i2c: add canonical path to i2c event traces

2023-02-08 Thread Titus Rwantare
Signed-off-by: Titus Rwantare 
---
 hw/i2c/core.c   | 8 +---
 hw/i2c/trace-events | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index d4ba8146bf..c583c1497a 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -161,7 +161,8 @@ static int i2c_do_start_transfer(I2CBus *bus, uint8_t 
address,
start condition.  */
 
 if (sc->event) {
-trace_i2c_event(event == I2C_START_SEND ? "start" : "start_async",
+trace_i2c_event(DEVICE(s)->canonical_path,
+event == I2C_START_SEND ? "start" : "start_async",
 s->address);
 rv = sc->event(s, event);
 if (rv && !bus->broadcast) {
@@ -227,7 +228,7 @@ void i2c_end_transfer(I2CBus *bus)
 I2CSlave *s = node->elt;
 sc = I2C_SLAVE_GET_CLASS(s);
 if (sc->event) {
-trace_i2c_event("finish", s->address);
+trace_i2c_event(DEVICE(s)->canonical_path, "finish", s->address);
 sc->event(s, I2C_FINISH);
 }
 QLIST_REMOVE(node, next);
@@ -314,7 +315,8 @@ void i2c_nack(I2CBus *bus)
 QLIST_FOREACH(node, >current_devs, next) {
 sc = I2C_SLAVE_GET_CLASS(node->elt);
 if (sc->event) {
-trace_i2c_event("nack", node->elt->address);
+trace_i2c_event(DEVICE(node->elt)->canonical_path,
+"nack", node->elt->address);
 sc->event(node->elt, I2C_NACK);
 }
 }
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
index 8e88aa24c1..f42a1ff539 100644
--- a/hw/i2c/trace-events
+++ b/hw/i2c/trace-events
@@ -9,7 +9,7 @@ bitbang_i2c_data(unsigned dat, unsigned clk, unsigned old_out, 
unsigned new_out)
 
 # core.c
 
-i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
+i2c_event(const char *id, const char *event, uint8_t address) "%s: 
%s(addr:0x%02x)"
 i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
 i2c_send_async(uint8_t address, uint8_t data) "send_async(addr:0x%02x) 
data:0x%02x"
 i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
-- 
2.39.1.581.gbfd45094c4-goog




Re: [PATCH 1/3] hw/gpio: add PCA6414 i2c GPIO expander

2023-02-08 Thread Titus Rwantare
On Mon, 6 Feb 2023 at 14:27, Corey Minyard  wrote:
>
> On Mon, Feb 06, 2023 at 07:49:34PM +, Titus Rwantare wrote:
> > This is a simple i2c device that allows i2c capable devices to have
> > GPIOs.
> >
> > Reviewed-by: Hao Wu 
> > Signed-off-by: Titus Rwantare 
> > ---
> >  hw/arm/Kconfig  |   1 +
> >  hw/gpio/meson.build |   1 +
> >  hw/gpio/pca_i2c_gpio.c  | 362 
> >  hw/gpio/trace-events|   5 +
> >  hw/i2c/Kconfig  |   4 +
> >  include/hw/gpio/pca_i2c_gpio.h  |  72 +++
> >  tests/qtest/meson.build |   1 +
> >  tests/qtest/pca_i2c_gpio-test.c | 169 +++
> >  8 files changed, 615 insertions(+)
> >  create mode 100644 hw/gpio/pca_i2c_gpio.c
> >  create mode 100644 include/hw/gpio/pca_i2c_gpio.h
> >  create mode 100644 tests/qtest/pca_i2c_gpio-test.c
> >
> > diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> > index 2d157de9b8..1b533ddd76 100644
> > --- a/hw/arm/Kconfig
> > +++ b/hw/arm/Kconfig
> > @@ -418,6 +418,7 @@ config NPCM7XX
> >  select SSI
> >  select UNIMP
> >  select PCA954X
> > +select PCA_I2C_GPIO
> >
> >  config FSL_IMX25
> >  bool
> > diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
> > index b726e6d27a..1e5b602002 100644
> > --- a/hw/gpio/meson.build
> > +++ b/hw/gpio/meson.build
> > @@ -12,3 +12,4 @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true: 
> > files('omap_gpio.c'))
> >  softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_gpio.c'))
> >  softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))
> >  softmmu_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
> > +softmmu_ss.add(when: 'CONFIG_PCA_I2C_GPIO', if_true: 
> > files('pca_i2c_gpio.c'))
> > diff --git a/hw/gpio/pca_i2c_gpio.c b/hw/gpio/pca_i2c_gpio.c
> > new file mode 100644
> > index 00..afae497a22
> > --- /dev/null
> > +++ b/hw/gpio/pca_i2c_gpio.c
> > @@ -0,0 +1,362 @@
> > +/*
> > + * NXP PCA I2C GPIO Expanders
> > + *
> > + * Low-voltage translating 16-bit I2C/SMBus GPIO expander with interrupt 
> > output,
> > + * reset, and configuration registers
> > + *
> > + * Datasheet: https://www.nxp.com/docs/en/data-sheet/PCA6416A.pdf
> > + *
> > + * Copyright 2023 Google LLC
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + *
> > + * These devices, by default, are configured to input only. The 
> > configuration is
>
> Yout initial email set they are output only by default


Oops, over the course of writing this I changed my mind on what the
default should be.
I've now checked it's all consistent.

>
>
> > + * settable through qom/qmp, or i2c.To set some pins as inputs before 
> > boot, use
> > + * the following in the board file of the machine:
> > + *  object_property_set_uint(Object *obj, const char *name,
> > + *   uint64_t value, Error **errp);
> > + * specifying name as "gpio_config" and the value as a bitfield of the 
> > inputs
> > + * e.g. for the pca6416, a value of 0xFFF0, sets pins 0-3 as outputs and
> > + * 4-15 as inputs.
> > + * This value can also be set at runtime through qmp externally, or by
> > + * writing to the config register using i2c.
>
> When the real hardware comes up, can it be configured in some way
> before the software access it through I2C?  It seems odd to me that you
> have a qemu configuration for something that wouldn't normally be
> configurable by something at power up time.
>
> Philippe mentioned some things, too, but this looks good to me beyond
> that.
>
> -corey


Right, my intention is to not have an implicit dependency on the default
configuration, I've re-written this section to be less confusing.

Thanks for the review, I've sent v2.

-Titus



Re: [PATCH 1/3] hw/gpio: add PCA6414 i2c GPIO expander

2023-02-08 Thread Titus Rwantare
On Mon, 6 Feb 2023 at 13:38, Philippe Mathieu-Daudé  wrote:
>
> Hi Titus,
>
> On 6/2/23 20:49, Titus Rwantare wrote:
> > This is a simple i2c device that allows i2c capable devices to have
> > GPIOs.
> >
> > Reviewed-by: Hao Wu 
> > Signed-off-by: Titus Rwantare 
> > ---
> >   hw/arm/Kconfig  |   1 +
> >   hw/gpio/meson.build |   1 +
> >   hw/gpio/pca_i2c_gpio.c  | 362 
> >   hw/gpio/trace-events|   5 +
> >   hw/i2c/Kconfig  |   4 +
> >   include/hw/gpio/pca_i2c_gpio.h  |  72 +++
> >   tests/qtest/meson.build |   1 +
> >   tests/qtest/pca_i2c_gpio-test.c | 169 +++
> >   8 files changed, 615 insertions(+)
> >   create mode 100644 hw/gpio/pca_i2c_gpio.c
> >   create mode 100644 include/hw/gpio/pca_i2c_gpio.h
> >   create mode 100644 tests/qtest/pca_i2c_gpio-test.c
>
>
> > +/* slave to master */
> > +static uint8_t pca6416_recv(I2CSlave *i2c)
> > +{
> > +PCAGPIOState *ps = PCA_I2C_GPIO(i2c);
> > +uint8_t data;

> > +default:
> > +qemu_log_mask(LOG_GUEST_ERROR,
> > +  "%s: reading from unsupported register 0x%02x",
>
> Some of your qemu_log_mask() calls miss the trailing newline.


Fixed.

>
>
> > +static int pca_i2c_event(I2CSlave *i2c, enum i2c_event event)
> > +{
> > +PCAGPIOState *ps = PCA_I2C_GPIO(i2c);
> > +
> > +switch (event) {
> > +case I2C_START_RECV:
> > +trace_pca_i2c_event(DEVICE(ps)->canonical_path, "START_RECV");
>
> Maybe add the canonical_path to trace_i2c_event() so this is useful
> for all I2C devices.

I've added a patch that does this.

>
>
> > +static void pca_i2c_realize(DeviceState *dev, Error **errp)
> > +{
> > +PCAGPIOState *ps = PCA_I2C_GPIO(dev);
> > +pca_i2c_update_irqs(ps);
>
> There is no reset() handler, is that on purpose?

No, I've added one.

>
> > +static void pca6416_gpio_class_init(ObjectClass *klass, void *data)
> > +{
> > +DeviceClass *dc = DEVICE_CLASS(klass);
> > +I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
> > +PCAGPIOClass *pc = PCA_I2C_GPIO_CLASS(klass);
> > +
> > +dc->desc = "PCA6416 16-bit I/O expander";
>
> Why not set these 3 ...:
>
> > +dc->realize = pca_i2c_realize;
> > +dc->vmsd = _pca_i2c_gpio;
> > +
> > +k->event = pca_i2c_event;
>
> ... in a base abstract class pca_i2c_gpio_class_init()?
>

Right, the code evolved. This makes more sense to do now.


>
> > diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
> > index 14886b35da..b59a79fddf 100644
> > --- a/hw/i2c/Kconfig
> > +++ b/hw/i2c/Kconfig
> > @@ -42,6 +42,10 @@ config PCA954X
> >   bool
> >   select I2C
> >
> > +config PCA_I2C_GPIO
> > +bool
> > +select I2C
>
> This should be 'depends on I2C'.
>
> Apparently various entries are incorrect in this file.
>
> Per docs/devel/kconfig.rst:
>
>Devices *depend on* the bus that they lie on, for example a PCI
>device would specify ``depends on PCI``.  An MMIO device will likely
>have no ``depends on`` directive.  Devices also *select* the buses
>that the device provides, for example a SCSI adapter would specify
>``select SCSI``.

I've moved the entry to hw/gpio and fixed it.

> > diff --git a/include/hw/gpio/pca_i2c_gpio.h b/include/hw/gpio/pca_i2c_gpio.h
> > new file mode 100644
> > index 00..a10897c0e0
> > --- /dev/null
> > +++ b/include/hw/gpio/pca_i2c_gpio.h
> > @@ -0,0 +1,72 @@
> > +/*
> > + * NXP PCA6416A
> > + * Low-voltage translating 16-bit I2C/SMBus GPIO expander with interrupt 
> > output,
> > + * reset, and configuration registers
> > + *
> > + * Datasheet: https://www.nxp.com/docs/en/data-sheet/PCA6416A.pdf
> > + *
> > + * Note: Polarity inversion emulation not implemented
> > + *
> > + * Copyright 2021 Google LLC
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + */
> > +#ifndef PCA_I2C_GPIO_H
> > +#define PCA_I2C_GPIO_H
> > +
> > +#include "hw/i2c/i2c.h"
> > +#include "qom/object.h"
> > +
> > +#define PCA6416_NUM_PINS 16
>
> ^ This is specific to TYPE_PCA6416_GPIO, and you set
> PCAGPIOClass::num_pins to it in pca6416_gpio_class_init(), ...
>
> > +
> > +typedef struct PCAGPIOClass {
> > +I2CSlaveClass parent;
> > +
> > +uint8_t num_pins;
> > +} PCAGPIOClass;
> > +
> > +typedef struct PCAGPIOState {
>
> ... but this defines the generic TYPE_PCA_I2C_GPIO ...
>
> > +I2CSlave parent;
> > +
> > +uint16_t polarity_inv;
> > +uint16_t config;
> > +
> > +/* the values of the gpio pins are mirrored in these integers */
> > +uint16_t curr_input;
> > +uint16_t curr_output;
> > +uint16_t new_input;
> > +uint16_t new_output;
> > +
> > +/*
> > + * Note that these outputs need to be consumed by some other input
> > + * to be useful, qemu ignores writes to disconnected gpio pins
> > + */
> > +qemu_irq output[PCA6416_NUM_PINS];
>
> ... which is now clamped to 16 pins.
>
> Maybe define/use PCA_I2C_GPIO_MAX_PINS instead here, and assert
> 

Re: [PATCH 1/3] hw/gpio: add PCA6414 i2c GPIO expander

2023-02-08 Thread Titus Rwantare
On Mon, 6 Feb 2023 at 17:29, Dong, Eddie  wrote:
> > -Original Message-
> > From: qemu-devel-bounces+eddie.dong=intel@nongnu.org  > devel-bounces+eddie.dong=intel@nongnu.org> On Behalf Of Titus
> > Rwantare
> > Sent: Monday, February 6, 2023 11:50 AM
> > To: peter.mayd...@linaro.org
> > Cc: qemu-...@nongnu.org; qemu-devel@nongnu.org; Titus Rwantare
> > ; Hao Wu 
> > Subject: [PATCH 1/3] hw/gpio: add PCA6414 i2c GPIO expander
> >
> > This is a simple i2c device that allows i2c capable devices to have GPIOs.
>
> This patch is to implement a device model of I2C to GPIO for PCA_xxx, right?
> Or do you implement a general/common I2C to GPIO device?
> I think it is for the former one. In this case, the commit message is not 
> clear.

I've redone the commit message.

>
> >
> > Reviewed-by: Hao Wu 
> > Signed-off-by: Titus Rwantare 
> > ---
> >  hw/arm/Kconfig  |   1 +
> >  hw/gpio/meson.build |   1 +
> >  hw/gpio/pca_i2c_gpio.c  | 362 
> >  hw/gpio/trace-events|   5 +
> >  hw/i2c/Kconfig  |   4 +
> >  include/hw/gpio/pca_i2c_gpio.h  |  72 +++
> >  tests/qtest/meson.build |   1 +
> >  tests/qtest/pca_i2c_gpio-test.c | 169 +++
> >  8 files changed, 615 insertions(+)
> >  create mode 100644 hw/gpio/pca_i2c_gpio.c  create mode 100644
> > include/hw/gpio/pca_i2c_gpio.h  create mode 100644
> > tests/qtest/pca_i2c_gpio-test.c
> >
> > diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index
> > 2d157de9b8..1b533ddd76 100644
> > --- a/hw/arm/Kconfig
> > +++ b/hw/arm/Kconfig
> > @@ -418,6 +418,7 @@ config NPCM7XX
> >  select SSI
> >  select UNIMP
> >  select PCA954X
> > +select PCA_I2C_GPIO
> >
> >  config FSL_IMX25
> >  bool
> > diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build index
> > b726e6d27a..1e5b602002 100644
> > --- a/hw/gpio/meson.build
> > +++ b/hw/gpio/meson.build
> > @@ -12,3 +12,4 @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true:
> > files('omap_gpio.c'))
> >  softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_gpio.c'))
> >  softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true:
> > files('aspeed_gpio.c'))
> >  softmmu_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
> > +softmmu_ss.add(when: 'CONFIG_PCA_I2C_GPIO', if_true:
> > +files('pca_i2c_gpio.c'))
> > diff --git a/hw/gpio/pca_i2c_gpio.c b/hw/gpio/pca_i2c_gpio.c new file
> > mode 100644 index 00..afae497a22
> > --- /dev/null
> > +++ b/hw/gpio/pca_i2c_gpio.c
>
> Should this file be located under hw/i2c ?

I think there's a case to be made for either location. However, there
already exists an i2c device in hw/gpio.

> > @@ -0,0 +1,362 @@
> > +/*
> > + * NXP PCA I2C GPIO Expanders
> > + *
> > + * Low-voltage translating 16-bit I2C/SMBus GPIO expander with
> > +interrupt output,
> > + * reset, and configuration registers
> > + *
> > + * Datasheet: https://www.nxp.com/docs/en/data-sheet/PCA6416A.pdf
> > + *
> > + * Copyright 2023 Google LLC
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + *
> > + * These devices, by default, are configured to input only. The
> > +configuration is
> > + * settable through qom/qmp, or i2c.To set some pins as inputs before
> > +boot, use
> > + * the following in the board file of the machine:
> > + *  object_property_set_uint(Object *obj, const char *name,
> > + *   uint64_t value, Error **errp);
> > + * specifying name as "gpio_config" and the value as a bitfield of the
> > +inputs
> > + * e.g. for the pca6416, a value of 0xFFF0, sets pins 0-3 as outputs
> > +and
> > + * 4-15 as inputs.
> > + * This value can also be set at runtime through qmp externally, or by
> > + * writing to the config register using i2c.
> > + *
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/gpio/pca_i2c_gpio.h"
> > +#include "hw/irq.h"
> > +#include "hw/qdev-properties.h"
> > +#include "migration/vmstate.h"
> > +#include "qapi/visitor.h"
> > +#include "qemu/log.h"
> > +#include "qemu/module.h"
> > +#include "trace.h"
> > +
> > +/*
> > + * compare new_output to curr_output and update irq to match
> > new_output
> > + *
> > + * The Input port registers (registers 0 and 1) reflect the incoming
> > +logic
> > + * levels of the pins, regardless of whether the pin is defined as an
> > +input or
> > + * an output by the Configuration register.
> > + */
> > +static void pca_i2c_update_irqs(PCAGPIOState *ps) {
> > +PCAGPIOClass *pc = PCA_I2C_GPIO_GET_CLASS(ps);
> > +uint16_t out_diff = ps->new_output ^ ps->curr_output;
> > +uint16_t in_diff = ps->new_input ^ ps->curr_input;
> > +uint16_t mask, pin_i;
> > +
> > +if (in_diff || out_diff) {
> The spec says " A pin configured as an output cannot cause an interrupt".
> Do we need to check out_diff here?

This is confusing, as I understand it, qemu_set_irq doesn't
necessarily send an interrupt to the guest. A qemu_irq can be
connected to another device 

Re: [PATCH 1/3] hw/gpio: add PCA6414 i2c GPIO expander

2023-02-08 Thread Titus Rwantare
On Mon, 6 Feb 2023 at 19:43, Joel Stanley  wrote:
>
> On Mon, 6 Feb 2023 at 19:51, Titus Rwantare  wrote:
> >
> > This is a simple i2c device that allows i2c capable devices to have
> > GPIOs.
>
> Nice.
>
> In Linux this is supported by a driver called pca953x.  Would it make
> sense to name your model similarly (both the file and the prefixes you
> use)?
>
> If we do that then it looks like other devices from the same family
> could be easily supported. (I'm not suggesting you do that work up
> front)

Thanks to NXP's naming, pca could mean anything, so I opted
for i2c_gpio.
For example, we use pca954{3,6,8} i2c muxes that are entirely unrelated.
Looking at the driver, most of the devices there seem like they would
work with this qemu model. Someone more familiar would need to
validate them.

> >  hw/gpio/pca_i2c_gpio.c  | 362 
> >  hw/gpio/trace-events|   5 +
> >  hw/i2c/Kconfig  |   4 +
> >  include/hw/gpio/pca_i2c_gpio.h  |  72 +++
> >  tests/qtest/meson.build |   1 +
> >  tests/qtest/pca_i2c_gpio-test.c | 169 +++
> >  8 files changed, 615 insertions(+)
> >  create mode 100644 hw/gpio/pca_i2c_gpio.c
> >  create mode 100644 include/hw/gpio/pca_i2c_gpio.h
> >  create mode 100644 tests/qtest/pca_i2c_gpio-test.c
> >
> > diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
> > index 2d157de9b8..1b533ddd76 100644
> > --- a/hw/arm/Kconfig
> > +++ b/hw/arm/Kconfig
> > @@ -418,6 +418,7 @@ config NPCM7XX
> >  select SSI
> >  select UNIMP
> >  select PCA954X
> > +select PCA_I2C_GPIO
> >
> >  config FSL_IMX25
> >  bool
> > diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
> > index b726e6d27a..1e5b602002 100644
> > --- a/hw/gpio/meson.build
> > +++ b/hw/gpio/meson.build
> > @@ -12,3 +12,4 @@ softmmu_ss.add(when: 'CONFIG_OMAP', if_true: 
> > files('omap_gpio.c'))
> >  softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_gpio.c'))
> >  softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))
> >  softmmu_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
> > +softmmu_ss.add(when: 'CONFIG_PCA_I2C_GPIO', if_true: 
> > files('pca_i2c_gpio.c'))
> > diff --git a/hw/gpio/pca_i2c_gpio.c b/hw/gpio/pca_i2c_gpio.c
> > new file mode 100644
> > index 00..afae497a22
> > --- /dev/null
> > +++ b/hw/gpio/pca_i2c_gpio.c
> > @@ -0,0 +1,362 @@
> > +/*
> > + * NXP PCA I2C GPIO Expanders
> > + *
> > + * Low-voltage translating 16-bit I2C/SMBus GPIO expander with interrupt 
> > output,
> > + * reset, and configuration registers
> > + *
> > + * Datasheet: https://www.nxp.com/docs/en/data-sheet/PCA6416A.pdf
>
> +1
>
> > + *
> > + * Copyright 2023 Google LLC
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + *
> > + * These devices, by default, are configured to input only. The 
> > configuration is
> > + * settable through qom/qmp, or i2c.To set some pins as inputs before 
> > boot, use
> > + * the following in the board file of the machine:
> > + *  object_property_set_uint(Object *obj, const char *name,
> > + *   uint64_t value, Error **errp);
> > + * specifying name as "gpio_config" and the value as a bitfield of the 
> > inputs
> > + * e.g. for the pca6416, a value of 0xFFF0, sets pins 0-3 as outputs and
> > + * 4-15 as inputs.
> > + * This value can also be set at runtime through qmp externally, or by
> > + * writing to the config register using i2c.
>
> Nice docs. I'm sure someone else will tell you if there's a better
> spot, but I like that you've written this down.

Thanks,
-Titus



Re: [PATCH RFCv1 8/8] kvm: Enable dirty ring for arm64

2023-02-08 Thread Juan Quintela
Gavin Shan  wrote:
> arm64 has different capability from x86 to enable the dirty ring, which
> is KVM_CAP_DIRTY_LOG_RING_ACQ_REL. To enable it in kvm_dirty_ring_init()
> when KVM_CAP_DIRTY_LOG_RING isn't supported.
>
> Signed-off-by: Gavin Shan 

Reviewed-by: Juan Quintela 




Re: [PATCH RFCv1 7/8] hw/arm/virt: Enable backup bitmap for dirty ring

2023-02-08 Thread Juan Quintela
Gavin Shan  wrote:
> When KVM device "kvm-arm-gicv3" or "arm-its-kvm" is used, we have to
> enable the backup bitmap for the dirty ring. Otherwise, the migration
> will fail because those two devices are using the backup bitmap to track
> dirty guest memory, corresponding to various hardware tables.
>
> Signed-off-by: Gavin Shan 

Reviewed-by: Juan Quintela 




Re: [PATCH 08/22] include/exec/memattrs: Add two bits of space to MemTxAttrs

2023-02-08 Thread Richard Henderson

On 2/7/23 05:05, Peter Maydell wrote:

On Tue, 24 Jan 2023 at 00:01, Richard Henderson
 wrote:


We will need 2 bits to represent ARMSecurityState.

Do not attempt to replace or widen secure, even though it
logically overlaps the new field -- there are uses within
e.g. hw/block/pflash_cfi01.c, which don't know anything
specific about ARM.

Signed-off-by: Richard Henderson 
---
  include/exec/memattrs.h | 9 -
  1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
index 9fb98bc1ef..d04170aa27 100644
--- a/include/exec/memattrs.h
+++ b/include/exec/memattrs.h
@@ -29,10 +29,17 @@ typedef struct MemTxAttrs {
   * "didn't specify" if necessary.
   */
  unsigned int unspecified:1;
-/* ARM/AMBA: TrustZone Secure access
+/*
+ * ARM/AMBA: TrustZone Secure access
   * x86: System Management Mode access
   */
  unsigned int secure:1;
+/*
+ * ARM: ArmSecuritySpace.  This partially overlaps secure, but it is
+ * easier to have both fields to assist code that does not understand
+ * ARMv9 RME, or no specific knowledge of ARM at all (e.g. pflash).
+ */
+unsigned int space:2;
  /* Memory access is usermode (unprivileged) */
  unsigned int user:1;


Reviewed-by: Peter Maydell 

I guess we aren't so tight on bits in this struct as to
warrant keeping the extra RME info in a single bit (which
should in theory be possible).


Indeed not.  And the 3 target_* bits at the end are unused after recent changes.


r~



Re: [PATCH RFCv1 6/8] kvm: Add helper kvm_dirty_ring_init()

2023-02-08 Thread Juan Quintela
Gavin Shan  wrote:
> Due to multiple capabilities associated with the dirty ring for different
> architectures: KVM_CAP_DIRTY_{LOG_RING, LOG_RING_ACQ_REL} for x86 and
> arm64 separately. There will be more to be done in order to support the
> dirty ring for arm64.
>
> Lets add helper kvm_dirty_ring_init() to enable the dirty ring. With this,
> the code looks a bit clean.
>
> No functional change intended.
>
> Signed-off-by: Gavin Shan 
> ---
>  accel/kvm/kvm-all.c | 73 -
>  1 file changed, 46 insertions(+), 27 deletions(-)
>
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index 9ec117c441..399ef0f7e6 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -1476,6 +1476,49 @@ static int kvm_dirty_ring_reaper_init(KVMState *s)
>  return 0;
>  }
>  
> +static int kvm_dirty_ring_init(KVMState *s)
> +{
> +uint64_t ring_bytes;
> +int ret;
> +
> +/*
> + * Read the max supported pages. Fall back to dirty logging mode
> + * if the dirty ring isn't supported.
> + */
> +ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
> +if (ret <= 0) {
> +warn_report("KVM dirty ring not available, using bitmap method");
> +s->kvm_dirty_ring_size = 0;
> +return 0;
> +}
> +
> +ring_bytes = s->kvm_dirty_ring_size * sizeof(struct kvm_dirty_gfn);
> +if (ring_bytes > ret) {
> +error_report("KVM dirty ring size %" PRIu32 " too big "
> + "(maximum is %ld).  Please use a smaller value.",
> + s->kvm_dirty_ring_size,
> + (long)ret / sizeof(struct kvm_dirty_gfn));
> +ret = -EINVAL;
> +goto out;
> +}
> +
> +ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, ring_bytes);
> +if (ret) {
> +error_report("Enabling of KVM dirty ring failed: %s. "
> + "Suggested minimum value is 1024.", strerror(-ret));
> +ret = -EIO;
> +}
> +
> +out:
> +if (ret) {
> +s->kvm_dirty_ring_size = 0;
> +} else {
> +s->kvm_dirty_ring_bytes = ring_bytes;
> +}
> +
> +return ret;
> +}

If you split it, you don't need the goto.

static int kvm_dirty_ring_init(KVMState *s)
{
s->kvm_dirty_ring_size = 0;
/*
 * Read the max supported pages. Fall back to dirty logging mode
 * if the dirty ring isn't supported.
 */
int ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
if (ret <= 0) {
warn_report("KVM dirty ring not available, using bitmap method");
return 0;
}

uint64_t ring_bytes = s->kvm_dirty_ring_size * sizeof(struct kvm_dirty_gfn);
if (ring_bytes > ret) {
error_report("KVM dirty ring size %" PRIu32 " too big "
 "(maximum is %ld).  Please use a smaller value.",
 s->kvm_dirty_ring_size,
 (long)ret / sizeof(struct kvm_dirty_gfn));
return -EINVAL;
}

ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, ring_bytes);
if (ret) {
error_report("Enabling of KVM dirty ring failed: %s. "
 "Suggested minimum value is 1024.", strerror(-ret));
return -EIO;
}

s->kvm_dirty_ring_bytes = ring_bytes;
return ret;
}



> +
>  static void kvm_region_add(MemoryListener *listener,
> MemoryRegionSection *section)
>  {
> @@ -2545,33 +2588,9 @@ static int kvm_init(MachineState *ms)
>   * dirty logging mode
>   */
>  if (s->kvm_dirty_ring_size > 0) {
> -uint64_t ring_bytes;
> -
> -ring_bytes = s->kvm_dirty_ring_size * sizeof(struct kvm_dirty_gfn);
> -
> -/* Read the max supported pages */
> -ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING);
> -if (ret > 0) {
> -if (ring_bytes > ret) {
> -error_report("KVM dirty ring size %" PRIu32 " too big "
> - "(maximum is %ld).  Please use a smaller 
> value.",
> - s->kvm_dirty_ring_size,
> - (long)ret / sizeof(struct kvm_dirty_gfn));
> -ret = -EINVAL;
> -goto err;
> -}
> -
> -ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING, 0, 
> ring_bytes);
> -if (ret) {
> -error_report("Enabling of KVM dirty ring failed: %s. "
> - "Suggested minimum value is 1024.", 
> strerror(-ret));
> -goto err;
> -}
> -
> -s->kvm_dirty_ring_bytes = ring_bytes;
> - } else {
> - warn_report("KVM dirty ring not available, using bitmap 
> method");
> - s->kvm_dirty_ring_size = 0;
> +ret = kvm_dirty_ring_init(s);
> +if (ret < 0) {
> +goto err;
>  }
>  }




Re: [PATCH RFCv1 4/8] kvm: Introduce secondary dirty bitmap

2023-02-08 Thread Juan Quintela
Gavin Shan  wrote:
> When dirty ring is enabled on ARM64, the backup bitmap may be used
> to track the dirty pages in no-running-vcpu situations. The original
> bitmap is the primary one, used for the dirty ring buffer. We need
> the secondary bitmap to collect the backup bitmap for ARM64.
>
> No functional change intended.
>
> Signed-off-by: Gavin Shan 
> ---
>  accel/kvm/kvm-all.c  | 50 ++--
>  include/sysemu/kvm_int.h |  1 +
>  2 files changed, 39 insertions(+), 12 deletions(-)
>
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index 01a6a026af..1a93985574 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -553,13 +553,29 @@ static void kvm_log_stop(MemoryListener *listener,
>  }
>  }
>  
> +static unsigned long *kvm_slot_dirty_bitmap(KVMSlot *slot, bool primary)
> +{
> +if (primary) {
> +return slot->dirty_bmap;
> +}
> +
> +return slot->dirty_bmap +
> +   slot->dirty_bmap_size / sizeof(slot->dirty_bmap[0]);
> +}


Why?
Just use two bitmaps and call it a day.

Later, Juan.




Re: [PATCH 07/22] target/arm: Introduce ARMSecuritySpace

2023-02-08 Thread Richard Henderson

On 2/7/23 05:00, Peter Maydell wrote:

  static inline bool arm_is_secure(CPUARMState *env)
  {
-if (arm_is_el3_or_mon(env)) {
-return true;
-}
-return arm_is_secure_below_el3(env);
+ARMSecuritySpace ss = arm_security_space(env);
+return ss == ARMSS_Secure || ss == ARMSS_Root;


maybe
   return arm_space_is_secure(arm_security_space(env));


Quite right; arm_space_is_secure was something I added later, and failed to propagate 
completely.



+#ifndef CONFIG_USER_ONLY
+ARMSecuritySpace arm_security_space(CPUARMState *env)
+{
+if (!arm_feature(env, ARM_FEATURE_EL3)) {


The old code had a comment
-/* If EL3 is not supported then the secure state is implementation
- * defined, in which case QEMU defaults to non-secure.
which should probably go here I guess.


Ok.


r~



Re: [PATCH 06/22] target/arm: Add RME cpregs

2023-02-08 Thread Richard Henderson

On 2/7/23 04:53, Peter Maydell wrote:

On Tue, 24 Jan 2023 at 00:01, Richard Henderson
 wrote:


This includes GPCCR, GPTBR, MFAR, the TLB flush insns PAALL,
PAALLOS, RPALOS, RPAOS, and the cache flush insn CIPAPA.

Signed-off-by: Richard Henderson 
---
  target/arm/cpu.h| 19 
  target/arm/helper.c | 74 +
  2 files changed, 93 insertions(+)



Reviewed-by: Peter Maydell 

as far as it goes, but don't we also need DC CIGDPAPA when
FEAT_MTE2 is also implemented?


Quite right.


r~




Re: [PATCH v2 15/23] vfio-user: forward msix BAR accesses to server

2023-02-08 Thread Alex Williamson
On Wed, 8 Feb 2023 06:38:30 +
John Johnson  wrote:

> > On Feb 6, 2023, at 12:33 PM, Alex Williamson  
> > wrote:
> > 
> > On Wed,  1 Feb 2023 21:55:51 -0800
> > John Johnson  wrote:
> >   
> >> Server holds device current device pending state
> >> Use irq masking commands in socket case
> >> 
> >> Signed-off-by: John G Johnson 
> >> Signed-off-by: Elena Ufimtseva 
> >> Signed-off-by: Jagannathan Raman 
> >> ---
> >> hw/vfio/pci.h |  1 +
> >> include/hw/vfio/vfio-common.h |  3 ++
> >> hw/vfio/ccw.c |  1 +
> >> hw/vfio/common.c  | 26 ++
> >> hw/vfio/pci.c | 23 +++-
> >> hw/vfio/platform.c|  1 +
> >> hw/vfio/user-pci.c| 64 
> >> +++
> >> 7 files changed, 118 insertions(+), 1 deletion(-)
> >> 
> >> diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
> >> index 4f70664..d3e5d5f 100644
> >> --- a/hw/vfio/pci.h
> >> +++ b/hw/vfio/pci.h
> >> @@ -113,6 +113,7 @@ typedef struct VFIOMSIXInfo {
> >> uint32_t table_offset;
> >> uint32_t pba_offset;
> >> unsigned long *pending;
> >> +MemoryRegion *pba_region;
> >> } VFIOMSIXInfo;
> >> 
> >> /*
> >> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> >> index bbc4b15..2c58d7d 100644
> >> --- a/include/hw/vfio/vfio-common.h
> >> +++ b/include/hw/vfio/vfio-common.h
> >> @@ -143,6 +143,7 @@ typedef struct VFIODevice {
> >> bool ram_block_discard_allowed;
> >> bool enable_migration;
> >> bool use_regfds;
> >> +bool can_mask_irq;  
> > 
> > How can this be a device level property?  vfio-pci (kernel) supports
> > masking of INTx.  It seems like there needs to be a per-index info or
> > probe here to to support this.
> >   
> 
>   It is only used for MSIX masking.  MSI masking is done with
> config space stores, and vfio-kernel and vfio-user handle them the
> same by forwarding the config space writes to the server so it can
> mask interrupts.

I suppose this does slip through on vfio-kernel, though support via
SET_IRQS would really be the uAPI mechanism we'd expect to use for
masking, just as it is for enabling/disabling MSI.  MSI is not well
used enough to have flushed that out and it seems harmless, but is not
the intended API.

>   MSIX is trickier because the mask bits are in a memory region.
> vfio-kernel doesn’t support SET_IRQS on MSIX vectors, so if the host
> doesn’t allow client mapping of the MSIX table to do the masking, vfio
> switches a masked vector’s event FD destination from KVM to QEMU, then
> uses the QEMU PCI emulation to mask the vector.

Lack of support for MSIX ACTION_[UN]MASK is not an API limitation, it's
an implementation issue in the kernel.  Same for MSI.  I believe this
is resolved now, that there are mask/unmask APIs available within the
kernel, as well as mechanisms to avoid the NORESIZE behavior now, so
the intention would be to implement that support, along with a
mechanism for the user to know the support is present.  We already have
that for NORESIZE via IRQ_INFO, so I suspect the right answer might be
to add a new VFIO_IRQ_INFO_MSI_MASK to advertise masking support.
 
>   vfio-user has to use messages to mask MSIX vectors, since there
> is no host config space to map.  I originally forwarded the MSIX table
> writes to the server to do the masking, but the feedback on the vfio-user
> server changes was to add SET_IRQS support.

Which is what I'm describing above, QEMU should know via the VFIO uAPI
whether MSI/X masking is supported and use that to configure the code
to make use of it rather than some inferred value based on the
interface type.  Thanks,

Alex




Re: [PATCH 3/3] target: Set `CF_PCREL` for arm and i386 frontends

2023-02-08 Thread Richard Henderson

On 2/7/23 00:43, Anton Johansson wrote:

Signed-off-by: Anton Johansson 
---
  target/arm/cpu-param.h  | 2 --
  target/arm/cpu.c| 5 +
  target/i386/cpu-param.h | 4 
  target/i386/cpu.c   | 5 +
  4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
index 53cac9c89b..b7bde18986 100644
--- a/target/arm/cpu-param.h
+++ b/target/arm/cpu-param.h
@@ -31,8 +31,6 @@
  # define TARGET_PAGE_BITS_VARY
  # define TARGET_PAGE_BITS_MIN  10
  
-# define TARGET_TB_PCREL 1

-
  /*
   * Cache the attrs and shareability fields from the page table entry.
   *
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 31dc595e11..62b876e0f0 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1551,6 +1551,11 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
  Error *local_err = NULL;
  bool no_aa32 = false;
  
+/* Use pc-relative instructions in system-mode */

+#ifndef CONFIG_USER_ONLY
+cs->tcg_cflags |= CF_PCREL;
+#endif


To fix bisection problems, the hunks setting CF_PCREL need to precede removal of the 
TARGET_TB_PCREL tests.  The removal of TARGET_TB_PCREL can happen all at once at the end.



r~



Re: [PATCH 2/3] Replace `TARGET_TB_PCREL` with `CF_PCREL`

2023-02-08 Thread Richard Henderson

On 2/7/23 00:43, Anton Johansson wrote:

diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
index b3f6e78835..083939b302 100644
--- a/accel/tcg/tb-jmp-cache.h
+++ b/accel/tcg/tb-jmp-cache.h
  static inline TranslationBlock *
-tb_jmp_cache_get_tb(CPUJumpCache *jc, uint32_t hash)
+tb_jmp_cache_get_tb(CPUJumpCache *jc, uint32_t cflags, uint32_t hash)
  {
-#if TARGET_TB_PCREL
-/* Use acquire to ensure current load of pc from jc. */
-return qatomic_load_acquire(>array[hash].tb);
-#else
-/* Use rcu_read to ensure current load of pc from *tb. */
-return qatomic_rcu_read(>array[hash].tb);
-#endif
+if (cflags & CF_PCREL) {
+/* Use acquire to ensure current load of pc from jc. */
+return qatomic_load_acquire(>array[hash].tb);
+} else {
+/* Use rcu_read to ensure current load of pc from *tb. */
+return qatomic_rcu_read(>array[hash].tb);
+}
  }
  
  static inline target_ulong

  tb_jmp_cache_get_pc(CPUJumpCache *jc, uint32_t hash, TranslationBlock *tb)
  {
-#if TARGET_TB_PCREL
-return jc->array[hash].pc;
-#else
-return tb_pc(tb);
-#endif
+if (tb_cflags(tb) & CF_PCREL) {
+return jc->array[hash].pc;
+} else {
+return tb_pc(tb);
+}
  }
  
  static inline void

  tb_jmp_cache_set(CPUJumpCache *jc, uint32_t hash,
   TranslationBlock *tb, target_ulong pc)
  {
-#if TARGET_TB_PCREL
-jc->array[hash].pc = pc;
-/* Use store_release on tb to ensure pc is written first. */
-qatomic_store_release(>array[hash].tb, tb);
-#else
-/* Use the pc value already stored in tb->pc. */
-qatomic_set(>array[hash].tb, tb);
-#endif
+if (tb_cflags(tb) & CF_PCREL) {
+jc->array[hash].pc = pc;
+/* Use store_release on tb to ensure pc is written first. */
+qatomic_store_release(>array[hash].tb, tb);
+} else{
+/* Use the pc value already stored in tb->pc. */
+qatomic_set(>array[hash].tb, tb);
+}
  }


These little functions made sense when they were isolating ifdefs.
When they protect a sequence of conditions,

if (CF_PCREL) {
a
} else {
b
}
if (CF_PCREL) {
c
} else {
d
}
if (CF_PCREL) {
e
} else {
f
}

we probably want to hoist one check in the callers.


+return ((tb_cflags(a) & CF_PCREL || tb_pc(a) == tb_pc(b)) &&


Similarly things like this, where we have a PCREL test here, and also within 
tb_pc().


-h = tb_hash_func(phys_pc, (TARGET_TB_PCREL ? 0 : tb_pc(tb)),
+h = tb_hash_func(phys_pc, (orig_cflags & CF_PCREL ? 0 : tb_pc(tb)),


etc.

This does too much at once, and also disables TARGET_TB_PCREL for one patch, changing 
behaviour during bisection.



r~



[PATCH RFC 5/7] Revert "x86: use typedef for SetupData struct"

2023-02-08 Thread Michael S. Tsirkin
This reverts commit eebb38a5633a77f5fa79d6486d5b2fcf8fbe3c07.

Fixes: eebb38a563 ("x86: use typedef for SetupData struct")
Signed-off-by: Michael S. Tsirkin 
---
 hw/i386/x86.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 32f37ab7c2..76b12108b4 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -657,12 +657,12 @@ DeviceState *ioapic_init_secondary(GSIState *gsi_state)
 return dev;
 }
 
-typedef struct SetupData {
+struct setup_data {
 uint64_t next;
 uint32_t type;
 uint32_t len;
 uint8_t data[];
-} __attribute__((packed)) SetupData;
+} __attribute__((packed));
 
 
 /*
@@ -803,7 +803,7 @@ void x86_load_linux(X86MachineState *x86ms,
 FILE *f;
 char *vmode;
 MachineState *machine = MACHINE(x86ms);
-SetupData *setup_data;
+struct setup_data *setup_data;
 const char *kernel_filename = machine->kernel_filename;
 const char *initrd_filename = machine->initrd_filename;
 const char *dtb_filename = machine->dtb;
@@ -1086,11 +1086,11 @@ void x86_load_linux(X86MachineState *x86ms,
 }
 
 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
-kernel_size = setup_data_offset + sizeof(SetupData) + dtb_size;
+kernel_size = setup_data_offset + sizeof(struct setup_data) + dtb_size;
 kernel = g_realloc(kernel, kernel_size);
 
 
-setup_data = (SetupData *)(kernel + setup_data_offset);
+setup_data = (struct setup_data *)(kernel + setup_data_offset);
 setup_data->next = cpu_to_le64(first_setup_data);
 first_setup_data = prot_addr + setup_data_offset;
 setup_data->type = cpu_to_le32(SETUP_DTB);
@@ -1101,9 +1101,9 @@ void x86_load_linux(X86MachineState *x86ms,
 
 if (!legacy_no_rng_seed) {
 setup_data_offset = QEMU_ALIGN_UP(kernel_size, 16);
-kernel_size = setup_data_offset + sizeof(SetupData) + RNG_SEED_LENGTH;
+kernel_size = setup_data_offset + sizeof(struct setup_data) + 
RNG_SEED_LENGTH;
 kernel = g_realloc(kernel, kernel_size);
-setup_data = (SetupData *)(kernel + setup_data_offset);
+setup_data = (struct setup_data *)(kernel + setup_data_offset);
 setup_data->next = cpu_to_le64(first_setup_data);
 first_setup_data = prot_addr + setup_data_offset;
 setup_data->type = cpu_to_le32(SETUP_RNG_SEED);
-- 
MST




  1   2   3   4   >