Re: [RFC PATCH 11/17] hw/sd: Add eMMC support

2022-05-30 Thread Cédric Le Goater

On 5/30/22 19:40, Philippe Mathieu-Daudé wrote:

On 18/3/22 14:28, Cédric Le Goater wrote:

The initial eMMC support from Vincent Palatin was largely reworked to
match the current SD framework. The parameters mimick a real 4GB eMMC,
but it can be set to various sizes.

This adds a new QOM object class for EMMC devices.

Signed-off-by: Vincent Palatin 
Link: 
https://lore.kernel.org/r/1311635951-11047-5-git-send-email-vpala...@chromium.org
[ jms: - Forward ported to QEMU 5.2 ]
Signed-off-by: Joel Stanley 
[ clg: - ported on aspeed-7.0 patchset
    - HPI activation ]
Signed-off-by: Cédric Le Goater 
---
  hw/sd/sdmmc-internal.h |  97 +++
  include/hw/sd/sd.h |   9 ++
  hw/sd/sd.c | 205 -
  hw/sd/sdmmc-internal.c |   2 +-
  4 files changed, 311 insertions(+), 2 deletions(-)




+static void emmc_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SDCardClass *sc = SD_CARD_CLASS(klass);
+
+    dc->desc = "eMMC";
+    sc->proto = _proto_emmc;
+    sc->spec_version = SD_PHY_SPECv3_01_VERS; /* eMMC requirement */
+    sc->set_csd = sd_emmc_set_csd;
+}
+
+static const TypeInfo emmc_info = {
+    .name = TYPE_EMMC,
+    .parent = TYPE_SD_CARD,


Hmm this is odd to have the model inheriting features from SD_CARD but then 
behaving differently (one could enumerate QDEV objects implementing
TYPE_SD_CARD then use them expecting they match the SD card protocol).

Why do you need to have TYPE_SD_CARD as parent?


Simply for the initialization.

Could we simply duplicate sd_class_init() assignations instead? That
would likely make it easier to modify eMMC handlers.


May be we lack a base abstract class ?

It would clean up this section in the realize routine :

   sd->proto = sd->spi ? _proto_spi : _proto_sd;

if (sc->proto) {
sd->proto = sc->proto;
}

Thanks,

C.


+    .class_init = emmc_class_init,
+ };





Re: [RFC PATCH 11/17] hw/sd: Add eMMC support

2022-05-30 Thread Cédric Le Goater

On 5/30/22 19:02, Philippe Mathieu-Daudé wrote:

Hi Cédric,

On 18/3/22 14:28, Cédric Le Goater wrote:

The initial eMMC support from Vincent Palatin was largely reworked to
match the current SD framework. The parameters mimick a real 4GB eMMC,
but it can be set to various sizes.

This adds a new QOM object class for EMMC devices.

Signed-off-by: Vincent Palatin 
Link: 
https://lore.kernel.org/r/1311635951-11047-5-git-send-email-vpala...@chromium.org
[ jms: - Forward ported to QEMU 5.2 ]
Signed-off-by: Joel Stanley 
[ clg: - ported on aspeed-7.0 patchset
    - HPI activation ]
Signed-off-by: Cédric Le Goater 
---
  hw/sd/sdmmc-internal.h |  97 +++
  include/hw/sd/sd.h |   9 ++
  hw/sd/sd.c | 205 -
  hw/sd/sdmmc-internal.c |   2 +-
  4 files changed, 311 insertions(+), 2 deletions(-)



+static const SDProto sd_proto_emmc = {


What about renaming as:

     ... emmc_proto = {


yes. These are internal functions. Fine with me.

Thanks,

C.




+    .name = "eMMC",
+    .cmd = {
+    [0] = sd_cmd_GO_IDLE_STATE,
+    [1] = sd_emmc_cmd_SEND_OP_CMD,


    = emmc_cmd_SEND_OP_CMD,


+    [2] = sd_emmc_cmd_ALL_SEND_CID,


  ...

?


+    [3] = sd_emmc_cmd_SEND_RELATIVE_ADDR,
+    [5] = sd_cmd_illegal,
+    [8] = sd_emmc_cmd_SEND_EXT_CSD,
+    [19]    = sd_cmd_SEND_TUNING_BLOCK,
+    [21]    = sd_emmc_cmd_SEND_TUNING_BLOCK,
+    [41]    = sd_cmd_illegal,
+    [52 ... 54] = sd_cmd_illegal,
+    [55]    = sd_emmc_cmd_APP_CMD,
+    [58]    = sd_cmd_illegal,
+    [59]    = sd_cmd_illegal,
+    },
+};





Re: [PATCH 2/2] hw/vhost-user-scsi|blk: set `supports_config` flag correctly

2022-05-30 Thread Raphael Norwitz
On Wed, May 25, 2022 at 08:55:40PM +0800, Changpeng Liu wrote:
> Currently vhost-user-scsi driver doesn't allow to change
> the configuration space of virtio_scsi, while vhost-user-blk
> support that, so here we set the flag in vhost-user-blk driver
> and unset it in vhost-user-scsi.
> 
> Signed-off-by: Changpeng Liu 

Reviewed-by: Raphael Norwitz 

> ---
>  hw/block/vhost-user-blk.c | 1 +
>  hw/scsi/vhost-user-scsi.c | 1 -
>  2 files changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
> index 5dca4eab09..9117222456 100644
> --- a/hw/block/vhost-user-blk.c
> +++ b/hw/block/vhost-user-blk.c
> @@ -337,6 +337,7 @@ static int vhost_user_blk_connect(DeviceState *dev, Error 
> **errp)
>  
>  vhost_dev_set_config_notifier(>dev, _ops);
>  
> +s->vhost_user.supports_config = true;
>  ret = vhost_dev_init(>dev, >vhost_user, VHOST_BACKEND_TYPE_USER, 0,
>   errp);
>  if (ret < 0) {
> diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
> index 9be21d07ee..1b2f7eed98 100644
> --- a/hw/scsi/vhost-user-scsi.c
> +++ b/hw/scsi/vhost-user-scsi.c
> @@ -121,7 +121,6 @@ static void vhost_user_scsi_realize(DeviceState *dev, 
> Error **errp)
>  vsc->dev.backend_features = 0;
>  vqs = vsc->dev.vqs;
>  
> -s->vhost_user.supports_config = true;
>  ret = vhost_dev_init(>dev, >vhost_user,
>   VHOST_BACKEND_TYPE_USER, 0, errp);
>  if (ret < 0) {
> -- 
> 2.21.3
> 
> 


RE: [PATCH] ebpf: replace deprecated bpf_program__set_socket_filter

2022-05-30 Thread Zhang, Chen



> -Original Message-
> From: Qemu-devel  bounces+chen.zhang=intel@nongnu.org> On Behalf Of Haochen Tong
> Sent: Saturday, May 28, 2022 3:07 AM
> To: qemu-devel@nongnu.org
> Cc: qemu-triv...@nongnu.org; Haochen Tong 
> Subject: [PATCH] ebpf: replace deprecated bpf_program__set_socket_filter
> 
> bpf_program__set_ functions have been deprecated since libbpf 0.8.
> Replace with the equivalent bpf_program__set_type call to avoid a
> deprecation warning.
> 
> Signed-off-by: Haochen Tong 

It looks good to me.
By the way, add eBPF maintainers.
Reviewed-by: Zhang Chen 

Thanks
Chen

> ---
>  ebpf/ebpf_rss.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c index 118c68da83..cee658c158
> 100644
> --- a/ebpf/ebpf_rss.c
> +++ b/ebpf/ebpf_rss.c
> @@ -49,7 +49,7 @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx)
>  goto error;
>  }
> 
> -bpf_program__set_socket_filter(rss_bpf_ctx-
> >progs.tun_rss_steering_prog);
> +bpf_program__set_type(rss_bpf_ctx->progs.tun_rss_steering_prog,
> + BPF_PROG_TYPE_SOCKET_FILTER);
> 
>  if (rss_bpf__load(rss_bpf_ctx)) {
>  trace_ebpf_error("eBPF RSS", "can not load RSS program");
> --
> 2.36.1
> 




Re: [PATCH 1/2] hw/virtio/vhost-user: don't use uninitialized variable

2022-05-30 Thread Raphael Norwitz
On Wed, May 25, 2022 at 08:55:39PM +0800, Changpeng Liu wrote:
> Variable `vdev` in `struct vhost_dev` will not be ready
> until start the device, so let's not use it for the error
> output here.
> 
> Fixes: 5653493 ("hw/virtio/vhost-user: don't suppress F_CONFIG when 
> supported")
> 
> Signed-off-by: Changpeng Liu 

Reviewed-by: Raphael Norwitz 

> ---
>  hw/virtio/vhost-user.c | 8 +++-
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index b040c1ad2b..0594178224 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -2031,18 +2031,16 @@ static int vhost_user_backend_init(struct vhost_dev 
> *dev, void *opaque,
>  if (supports_f_config) {
>  if (!virtio_has_feature(protocol_features,
>  VHOST_USER_PROTOCOL_F_CONFIG)) {
> -error_setg(errp, "vhost-user device %s expecting "
> +error_setg(errp, "vhost-user device expecting "
> "VHOST_USER_PROTOCOL_F_CONFIG but the vhost-user 
> backend does "
> -   "not support it.", dev->vdev->name);
> +   "not support it.");
>  return -EPROTO;
>  }
>  } else {
>  if (virtio_has_feature(protocol_features,
> VHOST_USER_PROTOCOL_F_CONFIG)) {
>  warn_reportf_err(*errp, "vhost-user backend supports "
> - "VHOST_USER_PROTOCOL_F_CONFIG for "
> - "device %s but QEMU does not.",
> - dev->vdev->name);
> + "VHOST_USER_PROTOCOL_F_CONFIG but QEMU does 
> not.");
>  protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_CONFIG);
>  }
>  }
> -- 
> 2.21.3
> 
> 


Re: [PATCH v2 01/15] contrib/vhost-user-blk: fix 32 bit build and enable

2022-05-30 Thread Raphael Norwitz
On Tue, May 24, 2022 at 04:40:42PM +0100, Alex Bennée wrote:
> We were not building the vhost-user-blk server due to 32 bit
> compilation problems. The problem was due to format string types so
> fix that and then enable the build. Tweak the rule to follow the same
> rules as other vhost-user daemons.
> 
> Signed-off-by: Alex Bennée 
> Message-Id: <20220321153037.3622127-12-alex.ben...@linaro.org>

Reviewed-by: Raphael Norwitz 

> ---
>  meson.build | 2 +-
>  contrib/vhost-user-blk/vhost-user-blk.c | 6 +++---
>  contrib/vhost-user-blk/meson.build  | 3 +--
>  3 files changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/meson.build b/meson.build
> index 9ebc00f032..a33ed52b7a 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1489,7 +1489,7 @@ have_vhost_user_blk_server = 
> get_option('vhost_user_blk_server') \
> error_message: 'vhost_user_blk_server requires linux') \
>.require(have_vhost_user,
> error_message: 'vhost_user_blk_server requires vhost-user 
> support') \
> -  .disable_auto_if(not have_system) \
> +  .disable_auto_if(not have_tools and not have_system) \
>.allowed()
>  
>  if get_option('fuse').disabled() and get_option('fuse_lseek').enabled()
> diff --git a/contrib/vhost-user-blk/vhost-user-blk.c 
> b/contrib/vhost-user-blk/vhost-user-blk.c
> index cd4a5d7335..9cb78ca1d0 100644
> --- a/contrib/vhost-user-blk/vhost-user-blk.c
> +++ b/contrib/vhost-user-blk/vhost-user-blk.c
> @@ -146,7 +146,7 @@ vub_readv(VubReq *req, struct iovec *iov, uint32_t iovcnt)
>  req->size = vub_iov_size(iov, iovcnt);
>  rc = preadv(vdev_blk->blk_fd, iov, iovcnt, req->sector_num * 512);
>  if (rc < 0) {
> -fprintf(stderr, "%s, Sector %"PRIu64", Size %lu failed with %s\n",
> +fprintf(stderr, "%s, Sector %"PRIu64", Size %zu failed with %s\n",
>  vdev_blk->blk_name, req->sector_num, req->size,
>  strerror(errno));
>  return -1;
> @@ -169,7 +169,7 @@ vub_writev(VubReq *req, struct iovec *iov, uint32_t 
> iovcnt)
>  req->size = vub_iov_size(iov, iovcnt);
>  rc = pwritev(vdev_blk->blk_fd, iov, iovcnt, req->sector_num * 512);
>  if (rc < 0) {
> -fprintf(stderr, "%s, Sector %"PRIu64", Size %lu failed with %s\n",
> +fprintf(stderr, "%s, Sector %"PRIu64", Size %zu failed with %s\n",
>  vdev_blk->blk_name, req->sector_num, req->size,
>  strerror(errno));
>  return -1;
> @@ -188,7 +188,7 @@ vub_discard_write_zeroes(VubReq *req, struct iovec *iov, 
> uint32_t iovcnt,
>  
>  size = vub_iov_size(iov, iovcnt);
>  if (size != sizeof(*desc)) {
> -fprintf(stderr, "Invalid size %ld, expect %ld\n", size, 
> sizeof(*desc));
> +fprintf(stderr, "Invalid size %zd, expect %zd\n", size, 
> sizeof(*desc));
>  return -1;
>  }
>  buf = g_new0(char, size);
> diff --git a/contrib/vhost-user-blk/meson.build 
> b/contrib/vhost-user-blk/meson.build
> index 601ea15ef5..dcb9e2ffcd 100644
> --- a/contrib/vhost-user-blk/meson.build
> +++ b/contrib/vhost-user-blk/meson.build
> @@ -1,5 +1,4 @@
> -# FIXME: broken on 32-bit architectures
>  executable('vhost-user-blk', files('vhost-user-blk.c'),
> dependencies: [qemuutil, vhost_user],
> -   build_by_default: false,
> +   build_by_default: targetos == 'linux',
> install: false)
> -- 
> 2.30.2
> 


Re: Re: [PATCH 0/3] recover hardware corrupted page by virtio balloon

2022-05-30 Thread Jue Wang
On Mon, May 30, 2022 at 8:49 AM Peter Xu  wrote:
>
> On Mon, May 30, 2022 at 07:33:35PM +0800, zhenwei pi wrote:
> > A VM uses RAM of 2M huge page. Once a MCE(@HVAy in [HVAx,HVAz)) occurs, the
> > 2M([HVAx,HVAz)) of hypervisor becomes unaccessible, but the guest poisons 4K
> > (@GPAy in [GPAx, GPAz)) only, it may hit another 511 MCE ([GPAx, GPAz)
> > except GPAy). This is the worse case, so I want to add
> >  '__le32 corrupted_pages' in struct virtio_balloon_config, it is used in the
> > next step: reporting 512 * 4K 'corrupted_pages' to the guest, the guest has
> > a chance to isolate the other 511 pages ahead of time. And the guest
> > actually loses 2M, fixing 512*4K seems to help significantly.
>
> It sounds hackish to teach a virtio device to assume one page will always
> be poisoned in huge page granule.  That's only a limitation to host kernel
> not virtio itself.
>
> E.g. there're upstream effort ongoing with enabling doublemap on hugetlbfs
> pages so hugetlb pages can be mapped in 4k with it.  It provides potential
> possibility to do page poisoning with huge pages in 4k too.  When that'll
> be ready the assumption can go away, and that does sound like a better
> approach towards this problem.

+1.

A hypervisor should always strive to minimize the guest memory loss.

The HugeTLB double mapping enlightened memory poisoning behavior (only
poison 4K out of a 2MB huge page and 4K in guest) is a much better
solution here. To be completely transparent, it's not _strictly_
required to poison the page (whatever the granularity it is) on the
host side, as long as the following are true:

1. A hypervisor can emulate the _minimized_ (e.g., 4K) the poison to the guest.
2. The host page with the UC error is "isolated" (could be PG_HWPOISON
or in some other way) and prevented from being reused by other
processes.

For #2, PG_HWPOISON and HugeTLB double mapping enlightened memory
poisoning is a good solution.

>
> >
> > >
> > > I assume when talking about "the performance memory drops a lot", you
> > > imply that this patch set can mitigate that performance drop?
> > >
> > > But why do you see a performance drop? Because we might lose some
> > > possible THP candidates (in the host or the guest) and you want to plug
> > > does holes? I assume you'll see a performance drop simply because
> > > poisoning memory is expensive, including migrating pages around on CE.
> > >
> > > If you have some numbers to share, especially before/after this change,
> > > that would be great.
> > >
> >
> > The CE storm leads 2 problems I have even seen:
> > 1, the memory bandwidth slows down to 10%~20%, and the cycles per
> > instruction of CPU increases a lot.
> > 2, the THR (/proc/interrupts) interrupts frequently, the CPU has to use a
> > lot time to handle IRQ.
>
> Totally no good knowledge on CMCI, but if 2) is true then I'm wondering
> whether it's necessary to handle the interrupts that frequently.  When I
> was reading the Intel CMCI vector handler I stumbled over this comment:
>
> /*
>  * The interrupt handler. This is called on every event.
>  * Just call the poller directly to log any events.
>  * This could in theory increase the threshold under high load,
>  * but doesn't for now.
>  */
> static void intel_threshold_interrupt(void)
>
> I think that matches with what I was thinking..  I mean for 2) not sure
> whether it can be seen as a CMCI problem and potentially can be optimized
> by adjust the cmci threshold dynamically.

The CE storm caused performance drop is caused by the extra cycles
spent by the ECC steps in memory controller, not in CMCI handling.
This is observed in the Google fleet as well. A good solution is to
monitor the CE rate closely in user space via /dev/mcelog and migrate
all VMs to another host once the CE rate exceeds some threshold.

CMCI is a _background_ interrupt that is not handled in the process
execution context and its handler is setup to switch to poll (1 / 5
min) mode if there are more than ~ a dozen CEs reported via CMCI per
second.
>
> --
> Peter Xu
>



Re: [PATCH v5 40/43] hw/loongarch: Add LoongArch ls7a acpi device support

2022-05-30 Thread maobibo

Ignor,

Thanks for guidance, I reply inline.

在 2022/5/30 下午6:21, Igor Mammedov 写道:

On Fri, 27 May 2022 06:18:43 +0800
maobibo  wrote:


On 5/26/22 16:42, Igor Mammedov wrote:

On Tue, 24 May 2022 16:18:01 +0800
Xiaojuan Yang  wrote:

commit message needs pointers to specification,
+ in patch comments that point to specific chapters
within the spec for newly introduced  registers

Igor,

Thanks for reviewing the patch and guidance, ls7A acpi registers has
minimium registers required by ACPI spec, including pm1a stat/en/cnt,
pm_tmr and GPE stat/enable registers, there is no smi mode in loongarch


those only required for legacy 'Fixed Hardware Programming Model'
which is historically used on x86.
For new platforms if you don't have hardware yet it's better to use
'Hardware-Reduced ACPI' approach and reuse code we already have for
aarch64.
The real loongarch hardware has hw acpi registers like x86, 
'Hardware-Reduced ACPI' approach is a good choice for loongarch virt 
platform and we will investigate this method. Previously we only 
consider to emulate real hardware, anyway the general method is ok for 
virt machine.



architecture. The  LS7A acpi driver is copied from acpi core driver
since register layout of pm1a/pm_tmr/gpe is different from x86 acpi
registers.


sorry, I couldn't parse above sentence.
The real loongarch ACPI hw registers has PM1a_EVT_BLK/PM1a_CNT_BLK, only 
that PM1_EVT_LEN is 8 bytes, and PM1a_STS/PM1a_EN register width is 4 
bytes, which is different legacy acpi registers on x86, this causes 
different acpi register size and offset. So we do not use original 
driver hw/acpi/core.c, and partly copy and modify from it.





By the ACPI spec, there is no specific requirement for layout of ACPI
registers, later we will reuse acpi core driver if the acpi registers
layout can be set dynamically. And we will send the second patch with
detailed description with LS7A ACPI module.


regardless of a separate doc patch, this patch should have a minimal
documentation as it have been pointed earlier, otherwise reviewer or
someone who will later have to look on this code, will have no point
of reference and have no idea if this code is correct or not.

Well we will add document about acpi module.




Also introducing ACPI hardware without an ACPI tables to complement
it is rather pointless as OSPM won't be able to discover/use it.
It might be better to drop this patch until you have corresponding
ACPI tables to describe it.
Originally there is ACPI table and fw_cfg table, in order to speed up 
merging progrss it is dropped. We add acpi driver since the testcases 
need to shutdown machine. How about dropping the acpi patch and adding 
simple virt pm device with shutdown machine function?


After this patch is merged, linux booting function will be added 
incluing acpi driver/table and fw_cfg table also etc.


regards
bibo,mao

   

From: Song Gao 

Signed-off-by: Xiaojuan Yang 
Signed-off-by: Song Gao 
---
   MAINTAINERS|   2 +
   hw/acpi/Kconfig|   4 +
   hw/acpi/ls7a.c | 374 +
   hw/acpi/meson.build|   1 +
   hw/loongarch/Kconfig   |   2 +
   hw/loongarch/loongson3.c   |  19 +-
   include/hw/acpi/ls7a.h |  53 ++
   include/hw/pci-host/ls7a.h |   6 +
   8 files changed, 458 insertions(+), 3 deletions(-)
   create mode 100644 hw/acpi/ls7a.c
   create mode 100644 include/hw/acpi/ls7a.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6e03a8bca8..6f861dec0a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1138,6 +1138,8 @@ F: include/hw/intc/loongarch_*.h
   F: hw/intc/loongarch_*.c
   F: include/hw/pci-host/ls7a.h
   F: hw/rtc/ls7a_rtc.c
+F: include/hw/acpi/ls7a.h
+F: hw/acpi/ls7a.c
   
   M68K Machines

   -
diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
index 3703aca212..c65965c9b9 100644
--- a/hw/acpi/Kconfig
+++ b/hw/acpi/Kconfig
@@ -13,6 +13,10 @@ config ACPI_X86
   select ACPI_PCIHP
   select ACPI_ERST
   
+config ACPI_LOONGARCH

+bool
+select ACPI
+
   config ACPI_X86_ICH
   bool
   select ACPI_X86
diff --git a/hw/acpi/ls7a.c b/hw/acpi/ls7a.c
new file mode 100644
index 00..cc658422dd
--- /dev/null
+++ b/hw/acpi/ls7a.c
@@ -0,0 +1,374 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch ACPI implementation
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/sysemu.h"
+#include "hw/hw.h"
+#include "hw/irq.h"
+#include "sysemu/reset.h"
+#include "sysemu/runstate.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/ls7a.h"
+#include "hw/nvram/fw_cfg.h"
+#include "qemu/config-file.h"
+#include "qapi/opts-visitor.h"
+#include "qapi/qapi-events-run-state.h"
+#include "qapi/error.h"
+#include "hw/pci-host/ls7a.h"
+#include "hw/mem/pc-dimm.h"
+#include "hw/mem/nvdimm.h"
+#include "migration/vmstate.h"
+
+static void ls7a_pm_update_sci_fn(ACPIREGS *regs)
+{
+LS7APMState *pm = 

[PATCH] tcg: Add tcg_gen_mov_ptr

2022-05-30 Thread Richard Henderson
Add an interface to perform moves between TCGv_ptr.

Signed-off-by: Richard Henderson 
---

This will be required for target/arm FEAT_SME.

r~

---
 include/tcg/tcg-op.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/tcg/tcg-op.h b/include/tcg/tcg-op.h
index b09b8b4a05..209e168305 100644
--- a/include/tcg/tcg-op.h
+++ b/include/tcg/tcg-op.h
@@ -1288,6 +1288,11 @@ static inline void tcg_gen_addi_ptr(TCGv_ptr r, TCGv_ptr 
a, intptr_t b)
 glue(tcg_gen_addi_,PTR)((NAT)r, (NAT)a, b);
 }
 
+static inline void tcg_gen_mov_ptr(TCGv_ptr d, TCGv_ptr s)
+{
+glue(tcg_gen_mov_,PTR)((NAT)d, (NAT)s);
+}
+
 static inline void tcg_gen_brcondi_ptr(TCGCond cond, TCGv_ptr a,
intptr_t b, TCGLabel *label)
 {
-- 
2.34.1




[PATCH v3] target/riscv: add support for zmmul extension v0.1

2022-05-30 Thread Weiwei Li
 - includes all multiplication operations for M extension

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Víctor Colombo 
Reviewed-by: Alistair Francis 

v2:
* disable M when both M and Zmmul are enabled

v3:
* add reviewed-by info, rebase to upstream/master

---
 target/riscv/cpu.c  |  7 +++
 target/riscv/cpu.h  |  1 +
 target/riscv/insn_trans/trans_rvm.c.inc | 18 --
 3 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a91253d4bd..bcbba3fbd5 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -600,6 +600,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 cpu->cfg.ext_ifencei = true;
 }
 
+if (cpu->cfg.ext_m && cpu->cfg.ext_zmmul) {
+warn_report("Zmmul will override M");
+cpu->cfg.ext_m = false;
+}
+
 if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
 error_setg(errp,
"I and E extensions are incompatible");
@@ -905,6 +910,7 @@ static Property riscv_cpu_properties[] = {
 
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
+DEFINE_PROP_BOOL("x-zmmul", RISCVCPU, cfg.ext_zmmul, false),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
 DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false),
@@ -1031,6 +1037,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char 
**isa_str, int max_str_len)
 struct isa_ext_data isa_edata_arr[] = {
 ISA_EDATA_ENTRY(zicsr, ext_icsr),
 ISA_EDATA_ENTRY(zifencei, ext_ifencei),
+ISA_EDATA_ENTRY(zmmul, ext_zmmul),
 ISA_EDATA_ENTRY(zfh, ext_zfh),
 ISA_EDATA_ENTRY(zfhmin, ext_zfhmin),
 ISA_EDATA_ENTRY(zfinx, ext_zfinx),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f08c3e8813..890d33cebb 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -411,6 +411,7 @@ struct RISCVCPUConfig {
 bool ext_zhinxmin;
 bool ext_zve32f;
 bool ext_zve64f;
+bool ext_zmmul;
 
 uint32_t mvendorid;
 uint64_t marchid;
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc 
b/target/riscv/insn_trans/trans_rvm.c.inc
index 16b029edf0..ec7f705aab 100644
--- a/target/riscv/insn_trans/trans_rvm.c.inc
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
@@ -18,6 +18,12 @@
  * this program.  If not, see .
  */
 
+#define REQUIRE_M_OR_ZMMUL(ctx) do {  \
+if (!ctx->cfg_ptr->ext_zmmul && !has_ext(ctx, RVM)) { \
+return false; \
+} \
+} while (0)
+
 static void gen_mulhu_i128(TCGv r2, TCGv r3, TCGv al, TCGv ah, TCGv bl, TCGv 
bh)
 {
 TCGv tmpl = tcg_temp_new();
@@ -65,7 +71,7 @@ static void gen_mul_i128(TCGv rl, TCGv rh,
 
 static bool trans_mul(DisasContext *ctx, arg_mul *a)
 {
-REQUIRE_EXT(ctx, RVM);
+REQUIRE_M_OR_ZMMUL(ctx);
 return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, gen_mul_i128);
 }
 
@@ -109,7 +115,7 @@ static void gen_mulh_w(TCGv ret, TCGv s1, TCGv s2)
 
 static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
 {
-REQUIRE_EXT(ctx, RVM);
+REQUIRE_M_OR_ZMMUL(ctx);
 return gen_arith_per_ol(ctx, a, EXT_SIGN, gen_mulh, gen_mulh_w,
 gen_mulh_i128);
 }
@@ -161,7 +167,7 @@ static void gen_mulhsu_w(TCGv ret, TCGv arg1, TCGv arg2)
 
 static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
 {
-REQUIRE_EXT(ctx, RVM);
+REQUIRE_M_OR_ZMMUL(ctx);
 return gen_arith_per_ol(ctx, a, EXT_NONE, gen_mulhsu, gen_mulhsu_w,
 gen_mulhsu_i128);
 }
@@ -176,7 +182,7 @@ static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2)
 
 static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
 {
-REQUIRE_EXT(ctx, RVM);
+REQUIRE_M_OR_ZMMUL(ctx);
 /* gen_mulh_w works for either sign as input. */
 return gen_arith_per_ol(ctx, a, EXT_ZERO, gen_mulhu, gen_mulh_w,
 gen_mulhu_i128);
@@ -349,7 +355,7 @@ static bool trans_remu(DisasContext *ctx, arg_remu *a)
 static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
 {
 REQUIRE_64_OR_128BIT(ctx);
-REQUIRE_EXT(ctx, RVM);
+REQUIRE_M_OR_ZMMUL(ctx);
 ctx->ol = MXL_RV32;
 return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL);
 }
@@ -389,7 +395,7 @@ static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
 static bool trans_muld(DisasContext *ctx, arg_muld *a)
 {
 REQUIRE_128BIT(ctx);
-REQUIRE_EXT(ctx, RVM);
+REQUIRE_M_OR_ZMMUL(ctx);
 ctx->ol = MXL_RV64;
 return gen_arith(ctx, a, EXT_SIGN, tcg_gen_mul_tl, NULL);
 }
-- 
2.17.1




Re: Accelerating non-standard disk types

2022-05-30 Thread Raphael Norwitz
On Wed, May 25, 2022 at 05:00:04PM +0100, Stefan Hajnoczi wrote:
> On Thu, May 19, 2022 at 06:39:39PM +, Raphael Norwitz wrote:
> > On Tue, May 17, 2022 at 03:53:52PM +0200, Paolo Bonzini wrote:
> > > On 5/16/22 19:38, Raphael Norwitz wrote:
> > > > [1] Keep using the SCSI translation in QEMU but back vDisks with a
> > > > vhost-user-scsi or vhost-user-blk backend device.
> > > > [2] Implement SATA and IDE emulation with vfio-user (likely with an SPDK
> > > > client?).
> > > > [3] We've also been looking at your libblkio library. From your
> > > > description in
> > > > https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.gnu.org_archive_html_qemu-2Ddevel_2021-2D04_msg06146.html=DwICaQ=s883GpUCOChKOHiocYtGcg=In4gmR1pGzKB8G5p6LUrWqkSMec2L5EtXZow_FZNJZk=wBSqcw0cal3wPP87YIKgFgmqMHjGCC3apYf4wCn1SIrX6GW_FR-J9wO68v-cyrpn=CP-6ZY-gqgQ2zLAJdR8WVTrMBoqmFHilGvW_qnf2myU=
> > > >it
> > > > sounds like it may definitely play a role here, and possibly provide the
> > > > nessesary abstractions to back I/O from these emulated disks to any
> > > > backends we may want?
> > > 
> > > First of all: have you benchmarked it?  How much time is spent on MMIO vs.
> > > disk I/O?
> > >
> > 
> > Good point - we haven’t benchmarked the emulation, exit and translation
> > overheads - it is very possible speeding up disk I/O may not have a huge
> > impact. We would definitely benchmark this before exploring any of the
> > options seriously, but as you rightly note, performance is not the only
> > motivation here.
> > 
> > > Of the options above, the most interesting to me is to implement a
> > > vhost-user-blk/vhost-user-scsi backend in QEMU, similar to the NVMe one,
> > > that would translate I/O submissions to virtqueue (including polling and 
> > > the
> > > like) and could be used with SATA.
> > >
> > 
> > We were certainly eyeing [1] as the most viable in the immediate future.
> > That said, since a vhost-user-blk driver has been added to libblkio, [3]
> > also sounds like a strong option. Do you see any long term benefit to
> > translating SATA/IDE submissions to virtqueues in a world where libblkio
> > is to be adopted?
> >
> > > For IDE specifically, I'm not sure how much it can be sped up since it has
> > > only 1 in-flight operation.  I think using KVM coalesced I/O could provide
> > > an interesting boost (assuming instant or near-instant reply from the
> > > backend).  If all you're interested in however is not really performance,
> > > but rather having a single "connection" to your back end, vhost-user is
> > > certainly an option.
> > > 
> > 
> > Interesting - I will take a look at KVM coalesced I/O.
> > 
> > You’re totally right though, performance is not our main interest for
> > these disk types. I should have emphasized offload rather than
> > acceleration and performance. We would prefer to QA and support as few
> > data paths as possible, and a vhost-user offload mechanism would allow
> > us to use the same path for all I/O. I imagine other QEMU users who
> > offload to backends like SPDK and use SATA/IDE disk types may feel
> > similarly?
> 
> It's nice to have a single target (e.g. vhost-user-blk in SPDK) that
> handles all disk I/O. On the other hand, QEMU would still have the
> IDE/SATA emulation and libblkio vhost-user-blk driver, so in the end it
> may not reduce the amount of code that you need to support.
> 

Apologies for the late reply - I was on PTO.

For us it’s not so much about the overall LOC we support. We have our
own iSCSI client implementation with embedded business logic which we
use for SCSI disks. Continuing to support SATA and IDE disks without our
implementation has been really troublesome so, even if it means more
LOC, we would really like to unify our data path at least at the iSCSI
layer.

While the overall code may not be reduced so much for many others today,
it may make a significant difference in the future. I can imagine some
QEMU users may want to deprecate (or not implement) iSCSI target support
in favor of NVMe over fabrics and still support these disk types. Being
able to offload the transport layer via vhost-user-blk (either with some
added logic on top of the existing SCSI translation layer or with
libblkio) would make this easy.

Does that sound reasonable?

> Stefan



Re: [RFC PATCH v4 22/36] i386/tdx: Track RAM entries for TDX VM

2022-05-30 Thread Xiaoyao Li

On 5/30/2022 7:59 PM, Gerd Hoffmann wrote:

   Hi,


tdx_add_ram_entry() increments tdx_guest->nr_ram_entries.  I think it's worth
for comments why this is safe regarding to this for-loop.


The for-loop is to find the valid existing RAM entry (from E820 table).
It will update the RAM entry and increment tdx_guest->nr_ram_entries when
the initial RAM entry needs to be split. However, once find, the for-loop is
certainly stopped since it returns unconditionally.


Add a comment saying so would be good.

Or move the code block doing the update out of the loop.  That will
likewise make clear that finding the entry which must be updated is
the only purpose of the loop.


Good idea. I'll go this way.


take care,
   Gerd






Re: RE: [PATCH v8 1/1] crypto: Introduce RSA algorithm

2022-05-30 Thread zhenwei pi

On 5/30/22 21:31, Gonglei (Arei) wrote:




-Original Message-
From: zhenwei pi [mailto:pizhen...@bytedance.com]
Sent: Friday, May 27, 2022 4:48 PM
To: m...@redhat.com; Gonglei (Arei) 
Cc: qemu-devel@nongnu.org; virtualizat...@lists.linux-foundation.org;
helei.si...@bytedance.com; berra...@redhat.com; zhenwei pi

Subject: [PATCH v8 1/1] crypto: Introduce RSA algorithm



Skip...


+static int64_t
+virtio_crypto_create_asym_session(VirtIOCrypto *vcrypto,
+   struct virtio_crypto_akcipher_create_session_req
*sess_req,
+   uint32_t queue_id, uint32_t opcode,
+   struct iovec *iov, unsigned int out_num) {
+VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+CryptoDevBackendSessionInfo info = {0};
+CryptoDevBackendAsymSessionInfo *asym_info;
+int64_t session_id;
+int queue_index;
+uint32_t algo, keytype, keylen;
+g_autofree uint8_t *key = NULL;
+Error *local_err = NULL;
+
+algo = ldl_le_p(_req->para.algo);
+keytype = ldl_le_p(_req->para.keytype);
+keylen = ldl_le_p(_req->para.keylen);
+
+if ((keytype != VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PUBLIC)
+ && (keytype != VIRTIO_CRYPTO_AKCIPHER_KEY_TYPE_PRIVATE)) {
+error_report("unsupported asym keytype: %d", keytype);
+return -VIRTIO_CRYPTO_NOTSUPP;
+}
+
+if (keylen) {
+key = g_malloc(keylen);
+if (iov_to_buf(iov, out_num, 0, key, keylen) != keylen) {
+virtio_error(vdev, "virtio-crypto asym key incorrect");
+return -EFAULT;


Memory leak.


+}
+iov_discard_front(, _num, keylen);
+}
+
+info.op_code = opcode;
+asym_info = _sess_info;
+asym_info->algo = algo;
+asym_info->keytype = keytype;
+asym_info->keylen = keylen;
+asym_info->key = key;
+switch (asym_info->algo) {
+case VIRTIO_CRYPTO_AKCIPHER_RSA:
+asym_info->u.rsa.padding_algo =
+ldl_le_p(_req->para.u.rsa.padding_algo);
+asym_info->u.rsa.hash_algo =
+ldl_le_p(_req->para.u.rsa.hash_algo);
+break;
+
+/* TODO DSA handling */
+
+default:
+return -VIRTIO_CRYPTO_ERR;
+}
+
+queue_index = virtio_crypto_vq2q(queue_id);
+session_id = cryptodev_backend_create_session(vcrypto->cryptodev,
,
+ queue_index, _err);
+if (session_id < 0) {
+if (local_err) {
+error_report_err(local_err);
+}
+return -VIRTIO_CRYPTO_ERR;
+}
+
+return session_id;


Where to free the key at both normal and exceptional paths?



Hi, Lei

The key is declared with g_autofree:
g_autofree uint8_t *key = NULL;



Regards,
-Gonglei




--
zhenwei pi



Re: [PATCH] MAINTAINERS: Add myself as hw/core/uboot_image.h maintainer

2022-05-30 Thread Alistair Francis
On Tue, May 31, 2022 at 1:38 AM Philippe Mathieu-Daudé  wrote:
>
> On 9/5/22 11:13, Alistair Francis via wrote:
> > Signed-off-by: Alistair Francis 
> > ---
> >   MAINTAINERS | 1 +
> >   1 file changed, 1 insertion(+)
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 662ec47246..9ba30cec8a 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -2173,6 +2173,7 @@ Generic Loader
> >   M: Alistair Francis 
> >   S: Maintained
> >   F: hw/core/generic-loader.c
> > +F: hw/core/uboot_image.h
> >   F: include/hw/core/generic-loader.h
> >   F: docs/system/generic-loader.rst
> >
>
> Alternative patch subject:
>
> "MAINTAINERS: Cover hw/core/uboot_image.h within Generic Loader section"

Thanks!

Applied to riscv-to-apply.next with the updated commit message

Alistair

>
> Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v1 01/33] .gitlab-ci.d/container-cross: Fix RISC-V container dependencies / stages

2022-05-30 Thread Alistair Francis
On Sat, May 28, 2022 at 1:36 AM Alex Bennée  wrote:
>
> From: Thomas Huth 
>
> The "riscv64-debian-cross-container" job does not depend on any other
> container job from the first stage, so we can move it to the first
> stage, too.
>
> The "riscv64-debian-test-cross-container" job needs the debian11
> container, so we should add a proper "needs:" statement here.
>
> Signed-off-by: Thomas Huth 
> Message-Id: <20220524093141.91012-1-th...@redhat.com>
> Signed-off-by: Alex Bennée 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  .gitlab-ci.d/container-cross.yml | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/.gitlab-ci.d/container-cross.yml 
> b/.gitlab-ci.d/container-cross.yml
> index e622ac2d21..ac15fce9b6 100644
> --- a/.gitlab-ci.d/container-cross.yml
> +++ b/.gitlab-ci.d/container-cross.yml
> @@ -125,7 +125,7 @@ ppc64el-debian-cross-container:
>
>  riscv64-debian-cross-container:
>extends: .container_job_template
> -  stage: containers-layer2
> +  stage: containers
># as we are currently based on 'sid/unstable' we may break so...
>allow_failure: true
>variables:
> @@ -135,6 +135,7 @@ riscv64-debian-cross-container:
>  riscv64-debian-test-cross-container:
>extends: .container_job_template
>stage: containers-layer2
> +  needs: ['amd64-debian11-container']
>variables:
>  NAME: debian-riscv64-test-cross
>
> --
> 2.30.2
>
>



Re: [PATCH v2] target/riscv: add support for zmmul extension v0.1

2022-05-30 Thread Alistair Francis
On Tue, May 24, 2022 at 2:54 PM Weiwei Li  wrote:
>
>  - includes all multiplication operations for M extension
>
> Signed-off-by: Weiwei Li 
> Signed-off-by: Junqiang Wang 

Do you mind rebasing this on the latest master branch and sending a v3?

Alistair

>
> v2:
> * disable M when both M and Zmmul are enabled
>
> ---
>  target/riscv/cpu.c  |  7 +++
>  target/riscv/cpu.h  |  1 +
>  target/riscv/insn_trans/trans_rvm.c.inc | 18 --
>  3 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index e373c61ba2..aec6882c5f 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -598,6 +598,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> **errp)
>  cpu->cfg.ext_ifencei = true;
>  }
>
> +if (cpu->cfg.ext_m && cpu->cfg.ext_zmmul) {
> +warn_report("Zmmul will override M");
> +cpu->cfg.ext_m = false;
> +}
> +
>  if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
>  error_setg(errp,
> "I and E extensions are incompatible");
> @@ -903,6 +908,7 @@ static Property riscv_cpu_properties[] = {
>
>  /* These are experimental so mark with 'x-' */
>  DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
> +DEFINE_PROP_BOOL("x-zmmul", RISCVCPU, cfg.ext_zmmul, false),
>  /* ePMP 0.9.3 */
>  DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
>  DEFINE_PROP_BOOL("x-aia", RISCVCPU, cfg.aia, false),
> @@ -1027,6 +1033,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char 
> **isa_str, int max_str_len)
>   *extensions by an underscore.
>   */
>  struct isa_ext_data isa_edata_arr[] = {
> +ISA_EDATA_ENTRY(zmmul, ext_zmmul),
>  ISA_EDATA_ENTRY(zfh, ext_zfh),
>  ISA_EDATA_ENTRY(zfhmin, ext_zfhmin),
>  ISA_EDATA_ENTRY(zfinx, ext_zfinx),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index f5ff7294c6..68177eae12 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -405,6 +405,7 @@ struct RISCVCPUConfig {
>  bool ext_zhinxmin;
>  bool ext_zve32f;
>  bool ext_zve64f;
> +bool ext_zmmul;
>
>  uint32_t mvendorid;
>  uint64_t marchid;
> diff --git a/target/riscv/insn_trans/trans_rvm.c.inc 
> b/target/riscv/insn_trans/trans_rvm.c.inc
> index 16b029edf0..ec7f705aab 100644
> --- a/target/riscv/insn_trans/trans_rvm.c.inc
> +++ b/target/riscv/insn_trans/trans_rvm.c.inc
> @@ -18,6 +18,12 @@
>   * this program.  If not, see .
>   */
>
> +#define REQUIRE_M_OR_ZMMUL(ctx) do {  \
> +if (!ctx->cfg_ptr->ext_zmmul && !has_ext(ctx, RVM)) { \
> +return false; \
> +} \
> +} while (0)
> +
>  static void gen_mulhu_i128(TCGv r2, TCGv r3, TCGv al, TCGv ah, TCGv bl, TCGv 
> bh)
>  {
>  TCGv tmpl = tcg_temp_new();
> @@ -65,7 +71,7 @@ static void gen_mul_i128(TCGv rl, TCGv rh,
>
>  static bool trans_mul(DisasContext *ctx, arg_mul *a)
>  {
> -REQUIRE_EXT(ctx, RVM);
> +REQUIRE_M_OR_ZMMUL(ctx);
>  return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, gen_mul_i128);
>  }
>
> @@ -109,7 +115,7 @@ static void gen_mulh_w(TCGv ret, TCGv s1, TCGv s2)
>
>  static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
>  {
> -REQUIRE_EXT(ctx, RVM);
> +REQUIRE_M_OR_ZMMUL(ctx);
>  return gen_arith_per_ol(ctx, a, EXT_SIGN, gen_mulh, gen_mulh_w,
>  gen_mulh_i128);
>  }
> @@ -161,7 +167,7 @@ static void gen_mulhsu_w(TCGv ret, TCGv arg1, TCGv arg2)
>
>  static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
>  {
> -REQUIRE_EXT(ctx, RVM);
> +REQUIRE_M_OR_ZMMUL(ctx);
>  return gen_arith_per_ol(ctx, a, EXT_NONE, gen_mulhsu, gen_mulhsu_w,
>  gen_mulhsu_i128);
>  }
> @@ -176,7 +182,7 @@ static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2)
>
>  static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
>  {
> -REQUIRE_EXT(ctx, RVM);
> +REQUIRE_M_OR_ZMMUL(ctx);
>  /* gen_mulh_w works for either sign as input. */
>  return gen_arith_per_ol(ctx, a, EXT_ZERO, gen_mulhu, gen_mulh_w,
>  gen_mulhu_i128);
> @@ -349,7 +355,7 @@ static bool trans_remu(DisasContext *ctx, arg_remu *a)
>  static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
>  {
>  REQUIRE_64_OR_128BIT(ctx);
> -REQUIRE_EXT(ctx, RVM);
> +REQUIRE_M_OR_ZMMUL(ctx);
>  ctx->ol = MXL_RV32;
>  return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl, NULL);
>  }
> @@ -389,7 +395,7 @@ static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
>  static bool trans_muld(DisasContext *ctx, arg_muld *a)
>  {
>  REQUIRE_128BIT(ctx);
> -REQUIRE_EXT(ctx, RVM);
> +REQUIRE_M_OR_ZMMUL(ctx);
>  ctx->ol = MXL_RV64;
>  return gen_arith(ctx, a, EXT_SIGN, tcg_gen_mul_tl, NULL);
>  }
> --
> 2.17.1
>

Re: [PATCH v9 12/12] target/riscv: Update the privilege field for sscofpmf CSRs

2022-05-30 Thread Alistair Francis
On Tue, May 24, 2022 at 9:59 AM Atish Patra  wrote:
>
> The sscofpmf extension was ratified as a part of priv spec v1.12.
> Mark the csr_ops accordingly.
>
> Signed-off-by: Atish Patra 

Reviewed-by: Alistair Francis 

Alistair

> ---
>  target/riscv/csr.c | 90 ++
>  1 file changed, 60 insertions(+), 30 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index e229f53c674d..c6105edd7a1a 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -4012,63 +4012,92 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> write_mhpmevent },
>
>  [CSR_MHPMEVENT3H]= { "mhpmevent3h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +  write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT4H]= { "mhpmevent4h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +  write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT5H]= { "mhpmevent5h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +  write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT6H]= { "mhpmevent6h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +  write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT7H]= { "mhpmevent7h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +  write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT8H]= { "mhpmevent8h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +  write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT9H]= { "mhpmevent9h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +  write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT10H]   = { "mhpmevent10h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +   write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT11H]   = { "mhpmevent11h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +   write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT12H]   = { "mhpmevent12h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +   write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT13H]   = { "mhpmevent13h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +   write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT14H]   = { "mhpmevent14h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +   write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT15H]   = { "mhpmevent15h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> +   write_mhpmeventh,
> + .min_priv_ver = PRIV_VERSION_1_12_0 
> },
>  [CSR_MHPMEVENT16H]   = { "mhpmevent16h",sscofpmf,  read_mhpmeventh,
> -   write_mhpmeventh},
> 

Re: [PATCH v9 11/12] hw/riscv: virt: Add PMU DT node to the device tree

2022-05-30 Thread Alistair Francis
On Tue, May 24, 2022 at 10:10 AM Atish Patra  wrote:
>
> Qemu virt machine can support few cache events and cycle/instret counters.
> It also supports counter overflow for these events.
>
> Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
> capabilities. There are some dummy nodes added for testing as well.
>
> Signed-off-by: Atish Patra 
> Signed-off-by: Atish Patra 

Acked-by: Alistair Francis 

Alistair

> ---
>  hw/riscv/virt.c| 28 +++
>  target/riscv/cpu.c |  1 +
>  target/riscv/pmu.c | 57 ++
>  target/riscv/pmu.h |  1 +
>  4 files changed, 87 insertions(+)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 3326f4db96a2..1b17ba7f8059 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -29,6 +29,7 @@
>  #include "hw/char/serial.h"
>  #include "target/riscv/cpu.h"
>  #include "hw/core/sysbus-fdt.h"
> +#include "target/riscv/pmu.h"
>  #include "hw/riscv/riscv_hart.h"
>  #include "hw/riscv/virt.h"
>  #include "hw/riscv/boot.h"
> @@ -715,6 +716,32 @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
>  aplic_phandles[socket] = aplic_s_phandle;
>  }
>
> +static void create_fdt_socket_pmu(RISCVVirtState *s,
> +  int socket, uint32_t *phandle,
> +  uint32_t *intc_phandles)
> +{
> +int cpu;
> +char *pmu_name;
> +uint32_t *pmu_cells;
> +MachineState *mc = MACHINE(s);
> +RISCVCPU hart = s->soc[socket].harts[0];
> +
> +pmu_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
> +
> +for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
> +pmu_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
> +pmu_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_PMU_OVF);
> +}
> +
> +pmu_name = g_strdup_printf("/soc/pmu");
> +qemu_fdt_add_subnode(mc->fdt, pmu_name);
> +qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
> +riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
> +
> +g_free(pmu_name);
> +g_free(pmu_cells);
> +}
> +
>  static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
> bool is_32_bit, uint32_t *phandle,
> uint32_t *irq_mmio_phandle,
> @@ -760,6 +787,7 @@ static void create_fdt_sockets(RISCVVirtState *s, const 
> MemMapEntry *memmap,
>  _phandles[phandle_pos]);
>  }
>  }
> +create_fdt_socket_pmu(s, socket, phandle, intc_phandles);
>  }
>
>  if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index a8f156a66eba..b51ad7496f71 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1032,6 +1032,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char 
> **isa_str, int max_str_len)
>  ISA_EDATA_ENTRY(zkt, ext_zkt),
>  ISA_EDATA_ENTRY(zve32f, ext_zve32f),
>  ISA_EDATA_ENTRY(zve64f, ext_zve64f),
> +ISA_EDATA_ENTRY(sscofpmf, ext_sscofpmf),
>  ISA_EDATA_ENTRY(svinval, ext_svinval),
>  ISA_EDATA_ENTRY(svnapot, ext_svnapot),
>  ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
> diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> index 7bb85d8d6ad7..0163758297c4 100644
> --- a/target/riscv/pmu.c
> +++ b/target/riscv/pmu.c
> @@ -20,11 +20,68 @@
>  #include "cpu.h"
>  #include "pmu.h"
>  #include "sysemu/cpu-timers.h"
> +#include "sysemu/device_tree.h"
>
>  #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */
>  #define MAKE_32BIT_MASK(shift, length) \
>  (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
>
> +/**
> + * To keep it simple, any event can be mapped to any programmable counters in
> + * QEMU. The generic cycle & instruction count events can also be monitored
> + * using programmable counters. In that case, mcycle & minstret must continue
> + * to provide the correct value as well. Heterogeneous PMU per hart is not
> + * supported yet. Thus, number of counters are same across all harts.
> + */
> +void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name)
> +{
> +uint32_t fdt_event_ctr_map[20] = {};
> +uint32_t cmask;
> +
> +/* All the programmable counters can map to any event */
> +cmask = MAKE_32BIT_MASK(3, num_ctrs);
> +
> +   /**
> +* The event encoding is specified in the SBI specification
> +* Event idx is a 20bits wide number encoded as follows:
> +* event_idx[19:16] = type
> +* event_idx[15:0] = code
> +* The code field in cache events are encoded as follows:
> +* event_idx.code[15:3] = cache_id
> +* event_idx.code[2:1] = op_id
> +* event_idx.code[0:0] = result_id
> +*/
> +
> +   /* SBI_PMU_HW_CPU_CYCLES: 0x01 : type(0x00) */
> +   fdt_event_ctr_map[0] = cpu_to_be32(0x0001);
> +   fdt_event_ctr_map[1] = cpu_to_be32(0x0001);
> +   fdt_event_ctr_map[2] = cpu_to_be32(cmask | 1 << 0);
> +
> +   /* 

Re: [PATCH v5 05/10] cutils: add functions for IEC and SI prefixes

2022-05-30 Thread Philippe Mathieu-Daudé via

On 30/5/22 17:07, Paolo Bonzini wrote:

Extract the knowledge of IEC and SI prefixes out of size_to_str and
freq_to_str, so that it can be reused when printing statistics.

Signed-off-by: Paolo Bonzini 
---
  include/qemu/cutils.h| 18 ++
  tests/unit/test-cutils.c | 32 
  util/cutils.c| 34 +-
  3 files changed, 75 insertions(+), 9 deletions(-)



diff --git a/util/cutils.c b/util/cutils.c
index 19fb4d04f8..485e9b0cea 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -872,6 +872,25 @@ int parse_debug_env(const char *name, int max, int initial)
  return debug;
  }
  
+const char *si_prefix(unsigned int exp10)

+{
+static const char *prefixes[] = {
+"a", "f", "p", "n", "u", "m", "", "k", "M", "G", "T", "P", "E"
+};
+
+exp10 += 18;
+assert(exp10 % 3 == 0 && exp10 / 3 < ARRAY_SIZE(prefixes));


Can we add parenthesis to ease code review?


+return prefixes[exp10 / 3];
+}
+
+const char *iec_binary_prefix(unsigned int exp2)
+{
+static const char *prefixes[] = { "", "ki", "Mi", "Gi", "Ti", "Pi", "Ei" };
+
+assert(exp2 % 10 == 0 && exp2 / 10 < ARRAY_SIZE(prefixes));


Ditto.


+return prefixes[exp2 / 10];
+}


Reviewed-by: Philippe Mathieu-Daudé 



Re: [PATCH v5 04/10] cutils: fix case for "kilo" and "kibi"

2022-05-30 Thread Philippe Mathieu-Daudé via

On 30/5/22 17:07, Paolo Bonzini wrote:

The correct abbreviations use a lowercase k, so adjust freq_to_str
and size_to_str accordingly and add tests.

Signed-off-by: Paolo Bonzini 
---
  tests/unit/test-cutils.c | 20 
  util/cutils.c|  6 +++---
  2 files changed, 23 insertions(+), 3 deletions(-)


Reviewed-by: Philippe Mathieu-Daudé 



Re: [PULL 0/2] Add myself as the maintainer for Hyper-V VMBus

2022-05-30 Thread Richard Henderson

On 5/30/22 11:41, Maciej S. Szmigiero wrote:

The following changes since commit f7a1ea403e0282a7f57edd4298c4f65f24165da5:

   Merge tag 'misc-pull-request' of gitlab.com:marcandre.lureau/qemu into 
staging (2022-05-29 16:34:56 -0700)

are available in the Git repository at:

   https://github.com/maciejsszmigiero/qemu.git tags/vmbus-maint-20220530

for you to fetch changes up to 6ede46b910ac66fd10bc169fb0a6f681429a9c5c:

   hw/hyperv/vmbus: Remove unused vmbus_load/save_req() (2022-05-30 19:49:42 
+0200)



As discussed in 
https://lore.kernel.org/qemu-devel/4e03945d-fb92-494d-53a8-f22ee9150...@redhat.com/
I am adding myself as the maintainer for Hyper-V VMBus, so there is some
contact point for incoming patches and somebody to review and pick up them.

The VMBus code is currently in a good shape, this pull request also
includes a single patch that has been waiting for being picked up since
November last year.


Applied, thanks.  Please update https://wiki.qemu.org/ChangeLog/7.1 as 
appropriate.


r~






Maciej S. Szmigiero (1):
   MAINTAINERS: Add myself as the maintainer for Hyper-V VMBus

Philippe Mathieu-Daudé (1):
   hw/hyperv/vmbus: Remove unused vmbus_load/save_req()

  MAINTAINERS   |  6 +++
  hw/hyperv/vmbus.c | 99 ---
  include/hw/hyperv/vmbus.h |  3 --
  3 files changed, 6 insertions(+), 102 deletions(-)






Re: [PATCH v2 09/11] scsi-disk: allow MODE SELECT block descriptor to set the ROM device block size

2022-05-30 Thread Mark Cave-Ayland

On 26/05/2022 13:08, Paolo Bonzini wrote:


On 4/24/22 18:49, Mark Cave-Ayland wrote:

Whilst CDROM drives usually have a 2048 byte sector size, older drives have the
ability to switch between 2048 byte and 512 byte sector sizes by specifying a
block descriptor in the MODE SELECT command.

If a MODE SELECT block descriptor is provided, update the scsi-cd device block
size with the provided value accordingly.

This allows CDROMs to be used with A/UX whose driver only works with a 512 byte
sector size.

Signed-off-by: Mark Cave-Ayland 


Why do this only for MMC?


No good reason other than I only have an guest OS that does this for CDROMs :)  I can 
easily drop the TYPE_ROM check if you don't think it will cause any unexpected issues 
with other SCSI devices?



Paolo


---
  hw/scsi/scsi-disk.c  | 7 +++
  hw/scsi/trace-events | 1 +
  2 files changed, 8 insertions(+)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 6991493cf4..41ebbe3045 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -1583,6 +1583,13 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, 
uint8_t *inbuf)

  goto invalid_param;
  }
+    /* Allow changing the block size of ROM devices */
+    if (s->qdev.type == TYPE_ROM && bd_len &&
+    p[6] != (s->qdev.blocksize >> 8)) {
+    s->qdev.blocksize = p[6] << 8;
+    trace_scsi_disk_mode_select_rom_set_blocksize(s->qdev.blocksize);
+    }
+
  len -= bd_len;
  p += bd_len;
diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events
index 25eae9f307..1a021ddae9 100644
--- a/hw/scsi/trace-events
+++ b/hw/scsi/trace-events
@@ -340,6 +340,7 @@ scsi_disk_dma_command_WRITE(const char *cmd, uint64_t lba, int 
len) "Write %s(se
  scsi_disk_new_request(uint32_t lun, uint32_t tag, const char *line) "Command: 
lun=%d tag=0x%x data=%s"
  scsi_disk_aio_sgio_command(uint32_t tag, uint8_t cmd, uint64_t lba, int len, 
uint32_t timeout) "disk aio sgio: tag=0x%x cmd=0x%x (sector %" PRId64 ", count %d) 
timeout=%u"
  scsi_disk_mode_select_page_truncated(int page, int len, int page_len) "page %d 
expected length %d but received length %d"

+scsi_disk_mode_select_rom_set_blocksize(int blocksize) "set ROM block size to 
%d"
  # scsi-generic.c
  scsi_generic_command_complete_noio(void *req, uint32_t tag, int statuc) "Command 
complete %p tag=0x%x status=%d"



ATB,

Mark.



Re: [PATCH v2 07/11] scsi-disk: allow truncated MODE SELECT requests

2022-05-30 Thread Mark Cave-Ayland

On 26/05/2022 13:06, Paolo Bonzini wrote:


On 4/24/22 18:49, Mark Cave-Ayland wrote:

According to [1] this truncated request is accepted on real hardware whereas in
QEMU it generates an INVALID_PARAM_LEN sense code which causes A/UX to get stuck
in a loop retrying the command in an attempt to succeed.


That's for MODE SENSE, not MODE SELECT.

Truncated MODE SELECT is a bit more iffy, so I'd rather have a quirk for this 
as well.


Okay let me double-check this again to confirm whether the issue is with MODE SENSE, 
MODE SELECT or both. Adding a quirk to control the behaviour is fairly easy to do.



Paolo


Alter the mode page request length check so that truncated requests are allowed
as per real hardware, adding a trace event to enable the condition to be 
detected.

[1]https://68kmla.org/bb/index.php?threads/scsi2sd-project-anyone-interested.29040/page-7#post-316444 



Signed-off-by: Mark Cave-Ayland
---
  hw/scsi/scsi-disk.c  | 2 +-
  hw/scsi/trace-events | 1 +
  2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 71fdf132c1..c657e4f5da 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -1525,7 +1525,7 @@ static int mode_select_pages(SCSIDiskReq *r, uint8_t *p, int 
len, bool change)

  goto invalid_param;
  }
  if (page_len > len) {
-    goto invalid_param_len;
+    trace_scsi_disk_mode_select_page_truncated(page, page_len, len);
  }




ATB,

Mark.



Re: [PATCH v3 4/7] hw/isa/piix{3,4}: QOM'ify PCI device creation and wiring

2022-05-30 Thread Bernhard Beschow
Am 30. Mai 2022 13:17:12 UTC schrieb "Philippe Mathieu-Daudé" :
>Hi Bernhard,

Hi Philippe,

>On 28/5/22 21:20, Bernhard Beschow wrote:
>> PCI interrupt wiring and device creation (piix4 only) were performed
>> in create() functions which are obsolete. Move these tasks into QOM
>> functions to modernize the code.
>> 
>> In order to avoid duplicate checking for xen_enabled() the piix3 realize
>> methods are now split.
>> 
>> Signed-off-by: Bernhard Beschow 
>> ---
>>   hw/isa/piix3.c | 67 +-
>>   hw/isa/piix4.c | 30 --
>>   2 files changed, 67 insertions(+), 30 deletions(-)
>
>While this is the same chipset family, these models are maintained by
>different people... Do you mind splitting?

Will do. I'd split the whole series then.

>For PIIX4 part:
>Reviewed-by: Philippe Mathieu-Daudé 
>




Re: [PATCH 07/12] hw/acpi/piix4: introduce piix4_pm_init() instance init function

2022-05-30 Thread Mark Cave-Ayland

On 29/05/2022 20:06, Bernhard Beschow wrote:


Am 28. Mai 2022 09:19:29 UTC schrieb Mark Cave-Ayland 
:

Use the new piix4_pm_init() instance init function to initialise 2 separate qdev
gpios for the SCI and SMI IRQs.

Signed-off-by: Mark Cave-Ayland 
---
hw/acpi/piix4.c | 9 +
1 file changed, 9 insertions(+)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index d897d2dee6..454fa34df1 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -497,6 +497,14 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
 piix4_pm_add_properties(s);
}

+static void piix4_pm_init(Object *obj)
+{
+PIIX4PMState *s = PIIX4_PM(obj);
+
+qdev_init_gpio_out(DEVICE(obj), >irq, 1);
+qdev_init_gpio_out_named(DEVICE(obj), >smi_irq, "smi-irq", 1);
+}


The two IRQs still get connected internally. Doesn't this create the risk of 
double connections until patches 8 and 9 are applied?


No, that should be fine. Here the address of the IRQ is being made available as a 
qdev gpio for use by qdev_connect_gpio_out(). Since that isn't being used yet, and 
the 2 IRQs are still being set afterwards in piix4_pm_initfn(), everything should 
still work just as before.



+
PIIX4PMState *piix4_pm_initfn(PCIBus *bus, int devfn, uint32_t smb_io_base,
   qemu_irq sci_irq, qemu_irq smi_irq,
   int smm_enabled)
@@ -663,6 +671,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void 
*data)
static const TypeInfo piix4_pm_info = {
 .name  = TYPE_PIIX4_PM,
 .parent= TYPE_PCI_DEVICE,
+.instance_init  = piix4_pm_init,
 .instance_size = sizeof(PIIX4PMState),
 .class_init= piix4_pm_class_init,
 .interfaces = (InterfaceInfo[]) {


ATB,

Mark.



Re: [PATCH v3 6/7] hw/isa/piix4: QOM'ify PIIX4 PM creation

2022-05-30 Thread Mark Cave-Ayland

On 29/05/2022 19:05, Bernhard Beschow wrote:


On Sun, May 29, 2022 at 11:25 AM Mark Cave-Ayland <
mark.cave-ayl...@ilande.co.uk> wrote:


On 28/05/2022 20:20, Bernhard Beschow wrote:


Just like the real hardware, create the PIIX4 ACPI controller as part of
the PIIX4 southbridge. This also mirrors how the IDE and USB functions
are already created.

Signed-off-by: Bernhard Beschow 
---
   hw/isa/piix4.c| 25 ++---
   hw/mips/malta.c   |  3 ++-
   include/hw/southbridge/piix.h |  2 +-
   3 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 96df21a610..217989227d 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -49,6 +49,7 @@ struct PIIX4State {
   RTCState rtc;
   PCIIDEState ide;
   UHCIState uhci;
+PIIX4PMState pm;
   /* Reset Control Register */
   MemoryRegion rcr_mem;
   uint8_t rcr;
@@ -261,6 +262,14 @@ static void piix4_realize(PCIDevice *dev, Error

**errp)

   return;
   }

+/* ACPI controller */
+qdev_prop_set_int32(DEVICE(>pm), "addr", dev->devfn + 3);
+if (!qdev_realize(DEVICE(>pm), BUS(pci_bus), errp)) {
+return;
+}
+qdev_connect_gpio_out(DEVICE(>pm), 0, s->isa[9]);
+object_property_add_alias(OBJECT(s), "smbus", OBJECT(>pm),

"i2c");

Now that the PM device is QOMified you don't actually need this alias
anymore (see
below). In general aliasing parts of contained devices onto the container
isn't
recommended, since it starts to blur the line between individual devices
and then you
find some wiring gets done to the container, some directly to the
contained device
and then it starts to get confusing quite quickly.


   pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s,

PIIX_NUM_PIRQS);

   }

@@ -271,6 +280,10 @@ static void piix4_init(Object *obj)
   object_initialize_child(obj, "rtc", >rtc, TYPE_MC146818_RTC);
   object_initialize_child(obj, "ide", >ide, "piix4-ide");
   object_initialize_child(obj, "uhci", >uhci, "piix4-usb-uhci");
+
+object_initialize_child(obj, "pm", >pm, TYPE_PIIX4_PM);
+qdev_prop_set_uint32(DEVICE(>pm), "smb_io_base", 0x1100);
+qdev_prop_set_bit(DEVICE(>pm), "smm-enabled", 0);
   }

   static void piix4_class_init(ObjectClass *klass, void *data)
@@ -312,7 +325,7 @@ static void piix4_register_types(void)

   type_init(piix4_register_types)

-DeviceState *piix4_create(PCIBus *pci_bus, I2CBus **smbus)
+DeviceState *piix4_create(PCIBus *pci_bus)
   {
   PCIDevice *pci;
   DeviceState *dev;
@@ -322,15 +335,5 @@ DeviceState *piix4_create(PCIBus *pci_bus, I2CBus

**smbus)

 TYPE_PIIX4_PCI_DEVICE);
   dev = DEVICE(pci);

-if (smbus) {
-pci = pci_new(devfn + 3, TYPE_PIIX4_PM);
-qdev_prop_set_uint32(DEVICE(pci), "smb_io_base", 0x1100);
-qdev_prop_set_bit(DEVICE(pci), "smm-enabled", 0);
-pci_realize_and_unref(pci, pci_bus, _fatal);
-qdev_connect_gpio_out(DEVICE(pci), 0,
-  qdev_get_gpio_in_named(dev, "isa", 9));
-*smbus = I2C_BUS(qdev_get_child_bus(DEVICE(pci), "i2c"));
-}
-
   return dev;
   }
diff --git a/hw/mips/malta.c b/hw/mips/malta.c
index e446b25ad0..b0fc84ccbb 100644
--- a/hw/mips/malta.c
+++ b/hw/mips/malta.c
@@ -1399,8 +1399,9 @@ void mips_malta_init(MachineState *machine)
   empty_slot_init("GT64120", 0, 0x2000);

   /* Southbridge */
-dev = piix4_create(pci_bus, );
+dev = piix4_create(pci_bus);
   isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
+smbus = I2C_BUS(qdev_get_child_bus(dev, "smbus"));


It should now be possible to do something like this:

  pm_dev = DEVICE(object_resolve_path_component(OBJECT(dev), "pm"));
  smbus = I2C_BUS(qdev_get_child_bus(pm_dev, "i2c"));

whereby we grab the reference to the PIIX4_PM device by resolving the "pm"
child
object and then use that to obtain the reference to smbus.



Imagining the container device to be an abstraction layer for the
contained functionality I actually prefer the alias. Having it one
doesn't need to know that there is an internal device named "pm" and
one doesn't need to care about how many levels deep it is buried
inside the implementation. This allows for further refactoring the
PIIX4 without breaking its contract to its users.

Also, this reflects how the real hardware works: The Malta board can
wire up the PIIX4 southbridge without worrying about its inner
details. One can look into the datasheets, see the exposed interfaces
and pins, and connect them. By QOM'ifying PIIX4 we now have the
opportunity to mirror the real hardware by exposing it to the Malta
board as a black box which exposes dedicated pins and buses.


It's a bit trickier in this particular case because here the PIIX4 device acts as 
both a container and PCI device instance - and certainly the distinction can be 
blurred when modelling integrated devices.



Re: [PATCH 00/12] hw/acpi/piix4: remove legacy piix4_pm_init() function

2022-05-30 Thread Mark Cave-Ayland

On 29/05/2022 19:05, Philippe Mathieu-Daudé via wrote:


On 28/5/22 11:19, Mark Cave-Ayland wrote:

Whilst reviewing Bernhard's PIIX Southbridge QOMifcation patches at
https://lists.gnu.org/archive/html/qemu-devel/2022-05/msg04329.html, I
noticed that we should first eliminate the legacy device init function
piix4_pm_init().

This series moves the outstanding logic from piix4_pm_init() into the
relevant instance init() and realize() functions, changes the IRQs to
use qdev gpios, and then finally removes the now-unused piix4_pm_initfn()
function.

Signed-off-by: Mark Cave-Ayland 


Mark Cave-Ayland (12):
   hw/acpi/piix4: move xen_enabled() logic from piix4_pm_init() to
 piix4_pm_realize()
   hw/acpi/piix4: change smm_enabled from int to bool
   hw/acpi/piix4: convert smm_enabled bool to qdev property
   hw/acpi/piix4: move PIIX4PMState into separate piix4.h header
   hw/acpi/piix4: alter piix4_pm_init() to return PIIX4PMState
   hw/acpi/piix4: rename piix4_pm_init() to piix4_pm_initfn()
   hw/acpi/piix4: introduce piix4_pm_init() instance init function
   hw/acpi/piix4: use qdev gpio to wire up sci_irq
   hw/acpi/piix4: use qdev gpio to wire up smi_irq
   hw/i386/pc_piix: create PIIX4_PM device directly instead of using
 piix4_pm_initfn()
   hw/isa/piix4.c: create PIIX4_PM device directly instead of using
 piix4_pm_initfn()
   hw/acpi/piix4: remove unused piix4_pm_initfn() function


Nitpicking, SCI could also be a named GPIO :)


FWIW I used the SCI irq as the "primary" GPIO since it was referenced as just "irq" 
within PIIX4PMState which is typical for a single output IRQ (my guess would be that 
"smi_irq" came along later).



Series:
Reviewed-by: Philippe Mathieu-Daudé 


Thanks!


ATB,

Mark.



Re: [PATCH 05/12] hw/acpi/piix4: alter piix4_pm_init() to return PIIX4PMState

2022-05-30 Thread Mark Cave-Ayland

On 29/05/2022 19:24, Bernhard Beschow wrote:


Am 28. Mai 2022 09:19:27 UTC schrieb Mark Cave-Ayland 
:

This exposes the PIIX4_PM device to the caller to allow any qdev gpios to be
mapped outside of piix4_pm_init().

Signed-off-by: Mark Cave-Ayland 
---
hw/acpi/piix4.c   | 11 ---
hw/i386/pc_piix.c | 10 +-
hw/isa/piix4.c|  8 +---
include/hw/southbridge/piix.h |  7 ---
4 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 7ee65b1bff..05c129b6af 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -497,9 +497,9 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp)
 piix4_pm_add_properties(s);
}

-I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-  qemu_irq sci_irq, qemu_irq smi_irq,
-  int smm_enabled, DeviceState **piix4_pm)
+PIIX4PMState *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+qemu_irq sci_irq, qemu_irq smi_irq,
+int smm_enabled)
{
 PCIDevice *pci_dev;
 DeviceState *dev;
@@ -509,9 +509,6 @@ I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t 
smb_io_base,
 dev = DEVICE(pci_dev);
 qdev_prop_set_uint32(dev, "smb_io_base", smb_io_base);
 qdev_prop_set_bit(dev, "smm-enabled", smm_enabled);
-if (piix4_pm) {
-*piix4_pm = dev;
-}

 s = PIIX4_PM(dev);
 s->irq = sci_irq;
@@ -519,7 +516,7 @@ I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t 
smb_io_base,

 pci_realize_and_unref(pci_dev, bus, _fatal);

-return s->smb.smbus;
+return s;
}

static uint64_t gpe_readb(void *opaque, hwaddr addr, unsigned width)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 578e537b35..0300be5ef4 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -281,14 +281,14 @@ static void pc_init1(MachineState *machine,
 }

 if (pcmc->pci_enabled && x86_machine_is_acpi_enabled(X86_MACHINE(pcms))) {
-DeviceState *piix4_pm;
+PIIX4PMState *piix4_pm;

 smi_irq = qemu_allocate_irq(pc_acpi_smi_interrupt, first_cpu, 0);
 /* TODO: Populate SPD eeprom data.  */


While at it: Perhaps move this comment...


-pcms->smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
-x86ms->gsi[9], smi_irq,
-x86_machine_is_smm_enabled(x86ms),
-_pm);
+piix4_pm = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
+ x86ms->gsi[9], smi_irq,
+ x86_machine_is_smm_enabled(x86ms));
+pcms->smbus = I2C_BUS(qdev_get_child_bus(DEVICE(piix4_pm), "i2c"));


... here? At least the Malta board seems to do this business here.


Possibly, although it was still close enough to smbus_eeprom_init() to be useful when 
working on the series. I could do this if there were enough comments to spin out a v2 
though.



 smbus_eeprom_init(pcms->smbus, 8, NULL, 0);

 object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 8607e0ac36..7d9bedd1bb 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -293,6 +293,7 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int 
irq_num)
DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus, I2CBus **smbus)
{
 PIIX4State *s;
+PIIX4PMState *pms;
 PCIDevice *pci;
 DeviceState *dev;
 int devfn = PCI_DEVFN(10, 0);
@@ -310,9 +311,10 @@ DeviceState *piix4_create(PCIBus *pci_bus, ISABus 
**isa_bus, I2CBus **smbus)

 pci_create_simple(pci_bus, devfn + 2, "piix4-usb-uhci");
 if (smbus) {
-*smbus = piix4_pm_init(pci_bus, devfn + 3, 0x1100,
-   qdev_get_gpio_in_named(dev, "isa", 9),
-   NULL, 0, NULL);
+pms = piix4_pm_init(pci_bus, devfn + 3, 0x1100,
+qdev_get_gpio_in_named(dev, "isa", 9),
+NULL, 0);
+*smbus = I2C_BUS(qdev_get_child_bus(DEVICE(pms), "i2c"));
 }

 pci_bus_irqs(pci_bus, piix4_set_irq, pci_slot_get_pirq, s, PIIX_NUM_PIRQS);
diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index c5b842b45d..108800ab06 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -14,10 +14,11 @@

#include "hw/pci/pci.h"
#include "qom/object.h"
+#include "hw/acpi/piix4.h"

-I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-  qemu_irq sci_irq, qemu_irq smi_irq,
-  int smm_enabled, DeviceState **piix4_pm);
+PIIX4PMState *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
+qemu_irq sci_irq, qemu_irq smi_irq,
+int smm_enabled);

/* PIRQRC[A:D]: PIRQx Route Control Registers */
#define 

Re: [PATCH 01/18] target/arm: Allow raise_exception to handle finding target EL

2022-05-30 Thread Richard Henderson

On 5/30/22 12:01, Peter Maydell wrote:

I'll have another go at this reorg this week.  If it still doesn't feel 
cleaner, we can
drop it, and I'll make some changes to the SME patch set building on this.


I was wondering if it would work better the other way around, so that
raise_exception() doesn't mess with the target_el at all, and all the
"work out which EL to take the exception to" is done in
target_exception_el() and similar ?


We need some place to put the EC_ADVSIMDFPACCESSTRAP special case, and it has to be done 
at the same time we're handling HCR_EL2.TGE.  Perhaps that can be separated out to its own 
helper.



r~



Re: [PATCH v3 0/7] QOM'ify PIIX southbridge creation

2022-05-30 Thread Philippe Mathieu-Daudé via

On 30/5/22 21:11, Mark Cave-Ayland wrote:

On 29/05/2022 14:02, Bernhard Beschow wrote:


    Oh wait - I see now it's just the cover letter which is missing 
the additional
    maintainer addresses :)  If you could add them into the cover 
letter for your next
    revision that would be great, since it gives context for 
maintainers to help with

    the
    review process.


Hi Mark,

Thanks for your great work you put into reviews and the useful 
insights! It seems to me that the time it takes for patches to be 
queued depends on the subsystem - some are faster, some are slower...


I've automated my setup as described in [1]. However, it doesn't seem 
to work for the cover letter which I'd expect to be sent to the union 
of all reviewers of all patches. Any idea how to fix this?


Best regards,
Bernhard

[1] 
https://www.qemu.org/docs/master/devel/submitting-a-patch.html#cc-the-relevant-maintainer 
 



Good question. I tend to do "git format-patch -o /tmp/foo 
--cover-letter" to generate the series, fill in the cover letter, and 
then use "git send-email /tmp/foo" to send out the emails (entering in 
the results of get_maintainer.pl by hand). I'm not sure why the cover 
letter isn't being generated correctly in your case I'm afraid.


Or try git-publish :) It does a first pass collecting Cc for each patch
(calling get_maintainer.pl) then use that set on the cover.

https://github.com/stefanha/git-publish



[PATCH v2 25/25] hw/sd: Add boot config support

2022-05-30 Thread Philippe Mathieu-Daudé
From: Joel Stanley 

Introduced "boot-config" property to set CSD 179, the boot config
register.

With this correctly set we can use the enable bit to detect if partition
support is enabled.

Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 26ddf3e92d..da909ec59f 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -116,6 +116,7 @@ struct SDState {
 uint8_t spec_version;
 BlockBackend *blk;
 bool spi;
+uint8_t boot_config;
 
 /* Runtime changeables */
 
@@ -453,6 +454,8 @@ static void mmc_set_ext_csd(SDState *sd, uint64_t size)
 sd->ext_csd[159] = 0x00; /* Max enhanced area size */
 sd->ext_csd[158] = 0x00; /* ... */
 sd->ext_csd[157] = 0xEC; /* ... */
+
+sd->ext_csd[EXT_CSD_PART_CONFIG] = sd->boot_config;
 }
 
 static void sd_emmc_set_csd(SDState *sd, uint64_t size)
@@ -878,8 +881,14 @@ static uint32_t sd_emmc_bootpart_offset(SDState *sd)
 {
 unsigned int access = sd->ext_csd[EXT_CSD_PART_CONFIG] &
 EXT_CSD_PART_CONFIG_ACC_MASK;
+unsigned int enable = sd->ext_csd[EXT_CSD_PART_CONFIG] &
+ EXT_CSD_PART_CONFIG_EN_MASK;
 unsigned int boot_capacity = sd_boot_capacity_bytes(sd);
 
+if (!enable) {
+return 0;
+}
+
 switch (access) {
 case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
 return boot_capacity * 2;
@@ -2548,6 +2557,7 @@ static Property sd_properties[] = {
  * board to ensure that ssi transfers only occur when the chip select
  * is asserted.  */
 DEFINE_PROP_BOOL("spi", SDState, spi, false),
+DEFINE_PROP_UINT8("boot-config", SDState, boot_config, 0x0),
 DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.36.1




[PATCH v2 22/25] hw/sd: Add sd_emmc_cmd_SEND_EXT_CSD() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Cédric Le Goater 

The parameters mimick a real 4GB eMMC, but it can be set to various
sizes. Initially from Vincent Palatin 

Signed-off-by: Cédric Le Goater 
[PMD: Remove CMD8 (SEND_EXT_CSD) case in sd_read_byte()]
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 101 -
 hw/sd/sdmmc-internal.h |  97 +++
 include/hw/sd/sd.h |   1 +
 3 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 907d4f5760..6722003cda 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -142,6 +142,7 @@ struct SDState {
 uint64_t data_start;
 uint32_t data_offset;
 uint8_t data[512];
+uint8_t ext_csd[512];
 qemu_irq readonly_cb;
 qemu_irq inserted_cb;
 QEMUTimer *ocr_power_timer;
@@ -408,8 +409,85 @@ static const uint8_t sd_csd_rw_mask[16] = {
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe,
 };
 
+static void mmc_set_ext_csd(SDState *sd, uint64_t size)
+{
+uint32_t sectcount = size >> HWBLOCK_SHIFT;
+
+memset(sd->ext_csd, 0, sizeof(sd->ext_csd));
+
+sd->ext_csd[EXT_CSD_S_CMD_SET] = 0x1; /* supported command sets */
+sd->ext_csd[EXT_CSD_HPI_FEATURES] = 0x3; /* HPI features  */
+sd->ext_csd[EXT_CSD_BKOPS_SUPPORT] = 0x1; /* Background operations */
+sd->ext_csd[241] = 0xA; /* 1st initialization time after partitioning */
+sd->ext_csd[EXT_CSD_TRIM_MULT] = 0x1; /* Trim multiplier */
+sd->ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] = 0x15; /* Secure feature */
+sd->ext_csd[EXT_CSD_SEC_ERASE_MULT] = 0x96; /* Secure erase support */
+sd->ext_csd[EXT_CSD_SEC_TRIM_MULT] = 0x96; /* Secure TRIM multiplier */
+sd->ext_csd[EXT_CSD_BOOT_INFO] = 0x7; /* Boot information */
+sd->ext_csd[EXT_CSD_BOOT_MULT] = 0x8; /* Boot partition size. 128KB unit */
+sd->ext_csd[EXT_CSD_ACC_SIZE] = 0x6; /* Access size */
+sd->ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] = 0x4; /* HC Erase unit size */
+sd->ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] = 0x1; /* HC erase timeout */
+sd->ext_csd[EXT_CSD_REL_WR_SEC_C] = 0x1; /* Reliable write sector count */
+sd->ext_csd[EXT_CSD_HC_WP_GRP_SIZE] = 0x4; /* HC write protect group size 
*/
+sd->ext_csd[EXT_CSD_S_C_VCC] = 0x8; /* Sleep current VCC  */
+sd->ext_csd[EXT_CSD_S_C_VCCQ] = 0x7; /* Sleep current VCCQ */
+sd->ext_csd[EXT_CSD_S_A_TIMEOUT] = 0x11; /* Sleep/Awake timeout */
+sd->ext_csd[215] = (sectcount >> 24) & 0xff; /* Sector count */
+sd->ext_csd[214] = (sectcount >> 16) & 0xff; /* ... */
+sd->ext_csd[213] = (sectcount >> 8) & 0xff;  /* ... */
+sd->ext_csd[EXT_CSD_SEC_CNT] = (sectcount & 0xff);   /* ... */
+sd->ext_csd[210] = 0xa; /* Min write perf for 8bit@52Mhz */
+sd->ext_csd[209] = 0xa; /* Min read perf for 8bit@52Mhz  */
+sd->ext_csd[208] = 0xa; /* Min write perf for 4bit@52Mhz */
+sd->ext_csd[207] = 0xa; /* Min read perf for 4bit@52Mhz */
+sd->ext_csd[206] = 0xa; /* Min write perf for 4bit@26Mhz */
+sd->ext_csd[205] = 0xa; /* Min read perf for 4bit@26Mhz */
+sd->ext_csd[EXT_CSD_PART_SWITCH_TIME] = 0x1;
+sd->ext_csd[EXT_CSD_OUT_OF_INTERRUPT_TIME] = 0x1;
+sd->ext_csd[EXT_CSD_CARD_TYPE] = 0x7;
+sd->ext_csd[EXT_CSD_STRUCTURE] = 0x2;
+sd->ext_csd[EXT_CSD_REV] = 0x5;
+sd->ext_csd[EXT_CSD_RPMB_MULT] = 0x1; /* RPMB size */
+sd->ext_csd[EXT_CSD_PARTITION_SUPPORT] = 0x3;
+sd->ext_csd[159] = 0x00; /* Max enhanced area size */
+sd->ext_csd[158] = 0x00; /* ... */
+sd->ext_csd[157] = 0xEC; /* ... */
+}
+
+static void sd_emmc_set_csd(SDState *sd, uint64_t size)
+{
+sd->csd[0] = 0xd0;
+sd->csd[1] = 0x0f;
+sd->csd[2] = 0x00;
+sd->csd[3] = 0x32;
+sd->csd[4] = 0x0f;
+if (size <= 2 * GiB) {
+/* use 1k blocks */
+uint32_t csize1k = (size >> (CMULT_SHIFT + 10)) - 1;
+sd->csd[5] = 0x5a;
+sd->csd[6] = 0x80 | ((csize1k >> 10) & 0xf);
+sd->csd[7] = (csize1k >> 2) & 0xff;
+} else { /* >= 2GB : size stored in ext CSD, block addressing */
+sd->csd[5] = 0x59;
+sd->csd[6] = 0x8f;
+sd->csd[7] = 0xff;
+sd->ocr = FIELD_DP32(sd->ocr, OCR, CARD_CAPACITY, 1);
+}
+sd->csd[8] = 0xff;
+sd->csd[9] = 0xff;
+sd->csd[10] = 0xf7;
+sd->csd[11] = 0xfe;
+sd->csd[12] = 0x49;
+sd->csd[13] = 0x10;
+sd->csd[14] = 0x00;
+sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
+mmc_set_ext_csd(sd, size);
+}
+
 static void sd_set_csd(SDState *sd, uint64_t size)
 {
+SDCardClass *sc = SD_CARD_GET_CLASS(sd);
 int hwblock_shift = HWBLOCK_SHIFT;
 uint32_t csize;
 uint32_t sectsize = (1 << (SECTOR_SHIFT + 1)) - 1;
@@ -421,7 +499,9 @@ static void sd_set_csd(SDState *sd, uint64_t size)
 }
 csize = (size >> (CMULT_SHIFT + hwblock_shift)) - 1;
 
-if (size <= SDSC_MAX_CAPACITY) { /* Standard Capacity SD */
+if (sc->set_csd) {
+sc->set_csd(sd, size);
+} else if (size <= SDSC_MAX_CAPACITY) { /* 

[PATCH v2 23/25] hw/sd: Support boot area in emmc image

2022-05-30 Thread Philippe Mathieu-Daudé
From: Joel Stanley 

This assumes a specially constructued image:

  dd if=/dev/zero of=mmc-bootarea.img count=2 bs=1M
  dd if=u-boot-spl.bin of=mmc-bootarea.img conv=notrunc
  dd if=u-boot.bin of=mmc-bootarea.img conv=notrunc count=64 bs=1K
  cat mmc-bootarea.img obmc-phosphor-image.wic > mmc.img
  truncate --size 16GB mmc.img
  truncate --size 128MB mmc-bootarea.img

For now this still requires a mtd image to load the SPL:

  qemu-system-arm -M tacoma-bmc -nographic \
   -global driver=sd-card,property=emmc,value=true \
   -drive file=mmc.img,if=sd,index=2 \
   -drive file=mmc-bootarea.img,if=mtd,format=raw

Signed-off-by: Joel Stanley 
[clg: - definition renames
  - Introduced bootpart_offset
  - Introduced sd_boot_capacity_bytes() helper (Philippe) ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 39 +++
 include/hw/sd/sd.h |  1 +
 2 files changed, 40 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 6722003cda..05e77f128f 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -659,6 +659,12 @@ static inline uint64_t sd_addr_to_wpnum(uint64_t addr)
 return addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
 }
 
+
+static unsigned sd_boot_capacity_bytes(SDState *sd)
+{
+return sd->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+}
+
 static void sd_reset(DeviceState *dev)
 {
 SDState *sd = SD_CARD(dev);
@@ -857,9 +863,40 @@ void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq 
insert)
 qemu_set_irq(insert, sd->blk ? blk_is_inserted(sd->blk) : 0);
 }
 
+/*
+ * This requires a disk image that has two boot partitions inserted at the
+ * beginning of it. The size of the boot partitions are configured in the
+ * ext_csd structure, which is hardcoded in qemu. They are currently set to
+ * 1MB each.
+ */
+static uint32_t sd_emmc_bootpart_offset(SDState *sd)
+{
+unsigned int access = sd->ext_csd[EXT_CSD_PART_CONFIG] &
+EXT_CSD_PART_CONFIG_ACC_MASK;
+unsigned int boot_capacity = sd_boot_capacity_bytes(sd);
+
+switch (access) {
+case EXT_CSD_PART_CONFIG_ACC_DEFAULT:
+return boot_capacity * 2;
+case EXT_CSD_PART_CONFIG_ACC_BOOT0:
+return 0;
+case EXT_CSD_PART_CONFIG_ACC_BOOT0 + 1:
+return boot_capacity * 1;
+default:
+ g_assert_not_reached();
+}
+}
+
+static uint32_t sd_bootpart_offset(SDState *sd)
+{
+SDCardClass *sc = SD_CARD_GET_CLASS(sd);
+return sc->bootpart_offset ? sc->bootpart_offset(sd) : 0;
+}
+
 static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len)
 {
 trace_sdcard_read_block(addr, len);
+addr += sd_bootpart_offset(sd);
 if (!sd->blk || blk_pread(sd->blk, addr, sd->data, len) < 0) {
 fprintf(stderr, "sd_blk_read: read error on host side\n");
 }
@@ -868,6 +905,7 @@ static void sd_blk_read(SDState *sd, uint64_t addr, 
uint32_t len)
 static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len)
 {
 trace_sdcard_write_block(addr, len);
+addr += sd_bootpart_offset(sd);
 if (!sd->blk || blk_pwrite(sd->blk, addr, sd->data, len, 0) < 0) {
 fprintf(stderr, "sd_blk_write: write error on host side\n");
 }
@@ -2564,6 +2602,7 @@ static void emmc_class_init(ObjectClass *klass, void 
*data)
 dc->realize = emmc_realize;
 sc->proto = _proto_emmc;
 sc->set_csd = sd_emmc_set_csd;
+sc->bootpart_offset = sd_emmc_bootpart_offset;
 }
 
 static const TypeInfo emmc_info = {
diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index 8a0f2e75da..36d3cba08e 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -130,6 +130,7 @@ struct SDCardClass {
 
 const struct SDProto *proto;
 void (*set_csd)(SDState *sd, uint64_t size);
+uint32_t (*bootpart_offset)(SDState *sd);
 };
 
 #define TYPE_SD_BUS "sd-bus"
-- 
2.36.1




[PATCH v2 20/25] hw/sd: Add CMD21 tuning sequence

2022-05-30 Thread Philippe Mathieu-Daudé
From: Sai Pavan Boddu 

MMC cards support different tuning sequence for entering HS200 mode.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
[ clg: - ported on QEMU 7.0 ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index d38ee5094d..672af1e839 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2012,6 +2012,30 @@ static const uint8_t 
sd_tuning_block_pattern[SD_TUNING_BLOCK_SIZE] = {
 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
 };
 
+#define EXCSD_BUS_WIDTH_OFFSET 183
+#define BUS_WIDTH_8_MASK0x4
+#define BUS_WIDTH_4_MASK0x2
+#define MMC_TUNING_BLOCK_SIZE   128
+
+static const uint8_t mmc_tuning_block_pattern[128] = {
+   0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+   0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
+   0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
+   0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
+   0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
+   0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
+   0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
+   0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
+   0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
+   0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
+   0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
+   0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
+   0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
+   0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
+   0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
+   0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
+};
+
 uint8_t sd_read_byte(SDState *sd)
 {
 /* TODO: Append CRCs */
@@ -2098,6 +2122,21 @@ uint8_t sd_read_byte(SDState *sd)
 ret = sd_tuning_block_pattern[sd->data_offset++];
 break;
 
+case 21:/* CMD21: SEND_TUNING_BLOCK (MMC) */
+if (sd->data_offset >= MMC_TUNING_BLOCK_SIZE - 1) {
+sd->state = sd_transfer_state;
+}
+if (sd->ext_csd[EXCSD_BUS_WIDTH_OFFSET] & BUS_WIDTH_8_MASK) {
+ret = mmc_tuning_block_pattern[sd->data_offset++];
+} else {
+/* Return LSB Nibbles of two byte from the 8bit tuning block
+ * for 4bit mode
+ */
+ret = mmc_tuning_block_pattern[sd->data_offset++] & 0x0F;
+ret |= (mmc_tuning_block_pattern[sd->data_offset++] & 0x0F) << 4;
+}
+break;
+
 case 22:   /* ACMD22: SEND_NUM_WR_BLOCKS */
 ret = sd->data[sd->data_offset ++];
 
-- 
2.36.1




[PATCH v2 21/25] hw/sd: Add mmc switch function support

2022-05-30 Thread Philippe Mathieu-Daudé
From: Sai Pavan Boddu 

switch operation in mmc cards, updated the ext_csd register to
request changes in card operations. Here we implement similar
sequence but requests are mostly dummy and make no change.

Implement SWITCH_ERROR if the write operation offset goes beyond length
of ext_csd.

Signed-off-by: Sai Pavan Boddu 
Signed-off-by: Edgar E. Iglesias 
[ clg: - ported on SDProto framework ]
Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 52 
 1 file changed, 52 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 672af1e839..907d4f5760 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -476,6 +476,7 @@ static void sd_set_rca(SDState *sd)
 FIELD(CSR, AKE_SEQ_ERROR,   3,  1)
 FIELD(CSR, APP_CMD, 5,  1)
 FIELD(CSR, FX_EVENT,6,  1)
+FIELD(CSR, SWITCH_ERROR,7,  1)
 FIELD(CSR, READY_FOR_DATA,  8,  1)
 FIELD(CSR, CURRENT_STATE,   9,  4)
 FIELD(CSR, ERASE_RESET,13,  1)
@@ -873,6 +874,43 @@ static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
 return ret;
 }
 
+enum {
+MMC_CMD6_ACCESS_COMMAND_SET = 0,
+MMC_CMD6_ACCESS_SET_BITS,
+MMC_CMD6_ACCESS_CLEAR_BITS,
+MMC_CMD6_ACCESS_WRITE_BYTE,
+};
+
+static void mmc_function_switch(SDState *sd, uint32_t arg)
+{
+uint32_t access = extract32(arg, 24, 2);
+uint32_t index = extract32(arg, 16, 8);
+uint32_t value = extract32(arg, 8, 8);
+uint8_t b = sd->ext_csd[index];
+
+switch (access) {
+case MMC_CMD6_ACCESS_COMMAND_SET:
+qemu_log_mask(LOG_UNIMP, "MMC Command set switching not supported\n");
+return;
+case MMC_CMD6_ACCESS_SET_BITS:
+b |= value;
+break;
+case MMC_CMD6_ACCESS_CLEAR_BITS:
+b &= ~value;
+break;
+case MMC_CMD6_ACCESS_WRITE_BYTE:
+b = value;
+break;
+}
+
+if (index >= 192) {
+sd->card_status |= R_CSR_SWITCH_ERROR_MASK;
+return;
+}
+
+sd->ext_csd[index] = b;
+}
+
 static void sd_function_switch(SDState *sd, uint32_t arg)
 {
 int i, mode, new_func;
@@ -2257,6 +2295,19 @@ static sd_rsp_type_t 
sd_emmc_cmd_SEND_TUNING_BLOCK(SDState *sd, SDRequest req)
 return sd_r1;
 }
 
+static sd_rsp_type_t sd_emmc_cmd_SWITCH_FUNCTION(SDState *sd, SDRequest req)
+{
+switch (sd->state) {
+case sd_transfer_state:
+sd->state = sd_programming_state;
+mmc_function_switch(sd, req.arg);
+sd->state = sd_transfer_state;
+return sd_r1b;
+default:
+return sd_invalid_state_for_cmd(sd, req);
+}
+}
+
 static const SDProto sd_proto_emmc = {
 .name = "eMMC",
 .cmd = {
@@ -2265,6 +2316,7 @@ static const SDProto sd_proto_emmc = {
 [2] = sd_emmc_cmd_ALL_SEND_CID,
 [3] = sd_emmc_cmd_SEND_RELATIVE_ADDR,
 [5] = sd_cmd_illegal,
+[6] = sd_emmc_cmd_SWITCH_FUNCTION,
 [19]= sd_cmd_SEND_TUNING_BLOCK,
 [21]= sd_emmc_cmd_SEND_TUNING_BLOCK,
 [41]= sd_cmd_illegal,
-- 
2.36.1




[PATCH v2 19/25] hw/sd: add sd_emmc_cmd_SEND_TUNING_BLOCK() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Cédric Le Goater 

Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 90da24ad2d..d38ee5094d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2207,6 +2207,17 @@ static sd_rsp_type_t sd_emmc_cmd_APP_CMD(SDState *sd, 
SDRequest req)
 return sd_r0;
 }
 
+static sd_rsp_type_t sd_emmc_cmd_SEND_TUNING_BLOCK(SDState *sd, SDRequest req)
+{
+if (sd->state != sd_transfer_state) {
+sd_invalid_state_for_cmd(sd, req);
+}
+
+sd->state = sd_sendingdata_state;
+sd->data_offset = 0;
+return sd_r1;
+}
+
 static const SDProto sd_proto_emmc = {
 .name = "eMMC",
 .cmd = {
@@ -2216,6 +2227,7 @@ static const SDProto sd_proto_emmc = {
 [3] = sd_emmc_cmd_SEND_RELATIVE_ADDR,
 [5] = sd_cmd_illegal,
 [19]= sd_cmd_SEND_TUNING_BLOCK,
+[21]= sd_emmc_cmd_SEND_TUNING_BLOCK,
 [41]= sd_cmd_illegal,
 [52 ... 54] = sd_cmd_illegal,
 [55]= sd_emmc_cmd_APP_CMD,
-- 
2.36.1




[PATCH v2 17/25] hw/sd: Add sd_emmc_cmd_SEND_RELATIVE_ADDR() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Cédric Le Goater 

Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 5e315f171c..100fe191a7 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1048,6 +1048,25 @@ static sd_rsp_type_t sd_cmd_ALL_SEND_CID(SDState *sd, 
SDRequest req)
 return sd_r2_i;
 }
 
+static void sd_emmc_set_rca(SDState *sd, uint16_t value)
+{
+sd->rca = value;
+}
+
+static sd_rsp_type_t sd_emmc_cmd_SEND_RELATIVE_ADDR(SDState *sd, SDRequest req)
+{
+switch (sd->state) {
+case sd_identification_state:
+case sd_standby_state:
+sd->state = sd_standby_state;
+sd_emmc_set_rca(sd, req.arg >> 16);
+return sd_r1;
+
+default:
+return sd_invalid_state_for_cmd(sd, req);
+}
+}
+
 static sd_rsp_type_t sd_cmd_SEND_RELATIVE_ADDR(SDState *sd, SDRequest req)
 {
 switch (sd->state) {
@@ -2189,6 +2208,7 @@ static const SDProto sd_proto_emmc = {
 [0] = sd_cmd_GO_IDLE_STATE,
 [1] = sd_emmc_cmd_SEND_OP_CMD,
 [2] = sd_emmc_cmd_ALL_SEND_CID,
+[3] = sd_emmc_cmd_SEND_RELATIVE_ADDR,
 [5] = sd_cmd_illegal,
 [19]= sd_cmd_SEND_TUNING_BLOCK,
 [41]= sd_cmd_illegal,
-- 
2.36.1




[PATCH v2 16/25] hw/sd: Add sd_emmc_cmd_ALL_SEND_CID() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Cédric Le Goater 

Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 538231dbab..5e315f171c 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2172,11 +2172,23 @@ static sd_rsp_type_t sd_emmc_cmd_SEND_OP_CMD(SDState 
*sd, SDRequest req)
 return sd_r3;
 }
 
+static sd_rsp_type_t sd_emmc_cmd_ALL_SEND_CID(SDState *sd, SDRequest req)
+{
+if (sd->state != sd_ready_state && sd->state != sd_idle_state) {
+return sd_invalid_state_for_cmd(sd, req);
+}
+
+sd->state = sd_identification_state;
+
+return sd_r2_i;
+}
+
 static const SDProto sd_proto_emmc = {
 .name = "eMMC",
 .cmd = {
 [0] = sd_cmd_GO_IDLE_STATE,
 [1] = sd_emmc_cmd_SEND_OP_CMD,
+[2] = sd_emmc_cmd_ALL_SEND_CID,
 [5] = sd_cmd_illegal,
 [19]= sd_cmd_SEND_TUNING_BLOCK,
 [41]= sd_cmd_illegal,
-- 
2.36.1




[PATCH v2 18/25] hw/sd: Add sd_emmc_cmd_APP_CMD() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Cédric Le Goater 

Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 100fe191a7..90da24ad2d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2202,6 +2202,11 @@ static sd_rsp_type_t sd_emmc_cmd_ALL_SEND_CID(SDState 
*sd, SDRequest req)
 return sd_r2_i;
 }
 
+static sd_rsp_type_t sd_emmc_cmd_APP_CMD(SDState *sd, SDRequest req)
+{
+return sd_r0;
+}
+
 static const SDProto sd_proto_emmc = {
 .name = "eMMC",
 .cmd = {
@@ -2213,6 +2218,7 @@ static const SDProto sd_proto_emmc = {
 [19]= sd_cmd_SEND_TUNING_BLOCK,
 [41]= sd_cmd_illegal,
 [52 ... 54] = sd_cmd_illegal,
+[55]= sd_emmc_cmd_APP_CMD,
 [58]= sd_cmd_illegal,
 [59]= sd_cmd_illegal,
 },
-- 
2.36.1




[PATCH v2 09/25] hw/sd: Add sd_cmd_SEND_OP_CMD() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
[ clg: Update cmd_abbrev ]
Message-Id: <20210624142209.1193073-9-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 18 +-
 hw/sd/sdmmc-internal.c |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 22405e8bb6..ac81e1c667 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1030,6 +1030,13 @@ static sd_rsp_type_t sd_cmd_GO_IDLE_STATE(SDState *sd, 
SDRequest req)
 return sd->spi ? sd_r1 : sd_r0;
 }
 
+static sd_rsp_type_t sd_cmd_SEND_OP_CMD(SDState *sd, SDRequest req)
+{
+sd->state = sd_transfer_state;
+
+return sd_r1;
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1069,10 +1076,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 switch (req.cmd) {
 /* Basic commands (Class 0 and Class 1) */
-case 1:/* CMD1:   SEND_OP_CMD */
-sd->state = sd_transfer_state;
-return sd_r1;
-
 case 2:/* CMD2:   ALL_SEND_CID */
 switch (sd->state) {
 case sd_ready_state:
@@ -1622,11 +1625,6 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
 break;
 
 case 41:   /* ACMD41: SD_APP_OP_COND */
-if (sd->spi) {
-/* SEND_OP_CMD */
-sd->state = sd_transfer_state;
-return sd_r1;
-}
 if (sd->state != sd_idle_state) {
 break;
 }
@@ -2131,6 +2129,7 @@ static const SDProto sd_proto_spi = {
 .name = "SPI",
 .cmd = {
 [0] = sd_cmd_GO_IDLE_STATE,
+[1] = sd_cmd_SEND_OP_CMD,
 [2 ... 4]   = sd_cmd_illegal,
 [5] = sd_cmd_illegal,
 [7] = sd_cmd_illegal,
@@ -2140,6 +2139,7 @@ static const SDProto sd_proto_spi = {
 },
 .acmd = {
 [6] = sd_cmd_unimplemented,
+[41]= sd_cmd_SEND_OP_CMD,
 },
 };
 
diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
index 2053def3f1..8648a7808d 100644
--- a/hw/sd/sdmmc-internal.c
+++ b/hw/sd/sdmmc-internal.c
@@ -14,7 +14,7 @@
 const char *sd_cmd_name(uint8_t cmd)
 {
 static const char *cmd_abbrev[SDMMC_CMD_MAX] = {
- [0]= "GO_IDLE_STATE",
+ [0]= "GO_IDLE_STATE",   [1]= "SEND_OP_CMD",
  [2]= "ALL_SEND_CID",[3]= "SEND_RELATIVE_ADDR",
  [4]= "SET_DSR", [5]= "IO_SEND_OP_COND",
  [6]= "SWITCH_FUNC", [7]= "SELECT/DESELECT_CARD",
-- 
2.36.1




[PATCH v2 24/25] hw/sd: Subtract bootarea size from blk

2022-05-30 Thread Philippe Mathieu-Daudé
From: Joel Stanley 

The userdata size is derived from the file the user passes on the
command line, but we must take into account the boot areas.

Signed-off-by: Joel Stanley 
Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 05e77f128f..26ddf3e92d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -668,6 +668,7 @@ static unsigned sd_boot_capacity_bytes(SDState *sd)
 static void sd_reset(DeviceState *dev)
 {
 SDState *sd = SD_CARD(dev);
+SDCardClass *sc = SD_CARD_GET_CLASS(sd);
 uint64_t size;
 uint64_t sect;
 
@@ -679,6 +680,10 @@ static void sd_reset(DeviceState *dev)
 }
 size = sect << 9;
 
+if (sc->bootpart_offset) {
+size -= sd_boot_capacity_bytes(sd) * 2;
+}
+
 sect = sd_addr_to_wpnum(size) + 1;
 
 sd->state = sd_idle_state;
-- 
2.36.1




[PATCH v2 12/25] hw/sd: Add sd_cmd_SEND_TUNING_BLOCK() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Joel Stanley 

Signed-off-by: Joel Stanley 
Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Cédric Le Goater 
[PMD: Rebased]
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 28 +---
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 2fe05c5a3d..a9130155be 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1062,6 +1062,22 @@ static sd_rsp_type_t sd_cmd_SEND_RELATIVE_ADDR(SDState 
*sd, SDRequest req)
 }
 }
 
+static sd_rsp_type_t sd_cmd_SEND_TUNING_BLOCK(SDState *sd, SDRequest req)
+{
+if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
+return sd_cmd_illegal(sd, req);
+}
+
+if (sd->state != sd_transfer_state) {
+return sd_invalid_state_for_cmd(sd, req);
+}
+
+sd->state = sd_sendingdata_state;
+sd->data_offset = 0;
+
+return sd_r1;
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1305,17 +1321,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 break;
 
-case 19:/* CMD19: SEND_TUNING_BLOCK (SD) */
-if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
-return sd_invalid_state_for_cmd(sd, req);
-}
-if (sd->state == sd_transfer_state) {
-sd->state = sd_sendingdata_state;
-sd->data_offset = 0;
-return sd_r1;
-}
-break;
-
 case 23:/* CMD23: SET_BLOCK_COUNT */
 if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
 return sd_invalid_state_for_cmd(sd, req);
@@ -2152,6 +2157,7 @@ static const SDProto sd_proto_sd = {
 [2] = sd_cmd_ALL_SEND_CID,
 [3] = sd_cmd_SEND_RELATIVE_ADDR,
 [5] = sd_cmd_illegal,
+[19]= sd_cmd_SEND_TUNING_BLOCK,
 [52 ... 54] = sd_cmd_illegal,
 [58]= sd_cmd_illegal,
 [59]= sd_cmd_illegal,
-- 
2.36.1




[PATCH v2 15/25] hw/sd: Add sd_emmc_cmd_SEND_OP_CMD() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Cédric Le Goater 

Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8b178aa261..538231dbab 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2166,10 +2166,17 @@ static const SDProto sd_proto_sd = {
 },
 };
 
+static sd_rsp_type_t sd_emmc_cmd_SEND_OP_CMD(SDState *sd, SDRequest req)
+{
+sd->state = sd_ready_state;
+return sd_r3;
+}
+
 static const SDProto sd_proto_emmc = {
 .name = "eMMC",
 .cmd = {
 [0] = sd_cmd_GO_IDLE_STATE,
+[1] = sd_emmc_cmd_SEND_OP_CMD,
 [5] = sd_cmd_illegal,
 [19]= sd_cmd_SEND_TUNING_BLOCK,
 [41]= sd_cmd_illegal,
-- 
2.36.1




Re: [PULL 000/117] target-arm queue

2022-05-30 Thread Richard Henderson

On 5/30/22 09:05, Peter Maydell wrote:

Massive pullreq but almost all of that is RTH's SVE
refactoring patchset. The other interesting thing here is
the fix for compiling on aarch64 macos.

thanks
-- PMM

The following changes since commit f7a1ea403e0282a7f57edd4298c4f65f24165da5:

   Merge tag 'misc-pull-request' of gitlab.com:marcandre.lureau/qemu into 
staging (2022-05-29 16:34:56 -0700)

are available in the Git repository at:

   https://git.linaro.org/people/pmaydell/qemu-arm.git 
tags/pull-target-arm-20220530

for you to fetch changes up to b1071174d2a2ab371082b7d4b5f19e98edc61ac6:

   target/arm: Remove aa64_sve check from before disas_sve (2022-05-30 17:05:12 
+0100)


target-arm queue:
  * docs/system/arm: Add FEAT_HCX to list of emulated features
  * target/arm/hvf: Include missing "cpregs.h"
  * hw/sd/allwinner-sdhost: report FIFO water level as 1 when data ready
  * SVE: refactor to use TRANS/TRANS_FEAT macros and push
SVE feature check down to individual insn level


Applied, thanks.  Please update https://wiki.qemu.org/ChangeLog/7.1 as 
appropriate.


r~





Icenowy Zheng (1):
   hw/sd/allwinner-sdhost: report FIFO water level as 1 when data ready

Peter Maydell (1):
   docs/system/arm: Add FEAT_HCX to list of emulated features

Philippe Mathieu-Daudé (1):
   target/arm/hvf: Include missing "cpregs.h"

Richard Henderson (114):
   target/arm: Introduce TRANS, TRANS_FEAT
   target/arm: Move null function and sve check into gen_gvec_ool_zz
   target/arm: Use TRANS_FEAT for gen_gvec_ool_zz
   target/arm: Move null function and sve check into gen_gvec_ool_zzz
   target/arm: Introduce gen_gvec_ool_arg_zzz
   target/arm: Use TRANS_FEAT for gen_gvec_ool_arg_zzz
   target/arm: Use TRANS_FEAT for do_sve2_zzz_ool
   target/arm: Move null function and sve check into gen_gvec_ool_
   target/arm: Use TRANS_FEAT for gen_gvec_ool_
   target/arm: Introduce gen_gvec_ool_arg_
   target/arm: Use TRANS_FEAT for do_sve2__ool
   target/arm: Use TRANS_FEAT for gen_gvec_ool_arg_
   target/arm: Rename do_zzxz_ool to gen_gvec_ool_arg_zzxz
   target/arm: Use TRANS_FEAT for gen_gvec_ool_arg_zzxz
   target/arm: Use TRANS_FEAT for do_sve2_zzz_data
   target/arm: Use TRANS_FEAT for do_sve2__data
   target/arm: Use TRANS_FEAT for do_sve2_zzw_data
   target/arm: Use TRANS_FEAT for USDOT_
   target/arm: Move null function and sve check into gen_gvec_ool_zzp
   target/arm: Introduce gen_gvec_ool_arg_zpz
   target/arm: Use TRANS_FEAT for gen_gvec_ool_arg_zpz
   target/arm: Use TRANS_FEAT for do_sve2_zpz_data
   target/arm: Rename do_zpzi_ool to gen_gvec_ool_arg_zpzi
   target/arm: Use TRANS_FEAT for gen_gvec_ool_arg_zpzi
   target/arm: Move null function and sve check into gen_gvec_ool_zzzp
   target/arm: Introduce gen_gvec_ool_arg_zpzz
   target/arm: Use TRANS_FEAT for gen_gvec_ool_arg_zpzz
   target/arm: Use TRANS_FEAT for do_sve2_zpzz_ool
   target/arm: Merge gen_gvec_fn_zz into do_mov_z
   target/arm: Move null function and sve check into gen_gvec_fn_zzz
   target/arm: Rename do_zzz_fn to gen_gvec_fn_arg_zzz
   target/arm: More use of gen_gvec_fn_arg_zzz
   target/arm: Use TRANS_FEAT for gen_gvec_fn_arg_zzz
   target/arm: Use TRANS_FEAT for do_sve2_fn_zzz
   target/arm: Use TRANS_FEAT for RAX1
   target/arm: Introduce gen_gvec_fn_arg_
   target/arm: Use TRANS_FEAT for do_sve2__fn
   target/arm: Introduce gen_gvec_fn_zzi
   target/arm: Use TRANS_FEAT for do_zz_dbm
   target/arm: Hoist sve access check through do_sel_z
   target/arm: Introduce gen_gvec_fn_arg_zzi
   target/arm: Use TRANS_FEAT for do_sve2_fn2i
   target/arm: Use TRANS_FEAT for do_vpz_ool
   target/arm: Use TRANS_FEAT for do_shift_imm
   target/arm: Introduce do_shift_zpzi
   target/arm: Use TRANS_FEAT for do_shift_zpzi
   target/arm: Use TRANS_FEAT for do_zpzzz_ool
   target/arm: Move sve check into do_index
   target/arm: Use TRANS_FEAT for do_index
   target/arm: Use TRANS_FEAT for do_adr
   target/arm: Use TRANS_FEAT for do_predset
   target/arm: Use TRANS_FEAT for RDFFR, WRFFR
   target/arm: Use TRANS_FEAT for do_pfirst_pnext
   target/arm: Use TRANS_FEAT for do_EXT
   target/arm: Use TRANS_FEAT for do_perm_pred3
   target/arm: Use TRANS_FEAT for do_perm_pred2
   target/arm: Move sve zip high_ofs into simd_data
   target/arm: Use gen_gvec_ool_arg_zzz for do_zip, do_zip_q
   target/arm: Use TRANS_FEAT for do_zip, do_zip_q
   target/arm: Use TRANS_FEAT for do_clast_vector
   target/arm: Use TRANS_FEAT for do_clast_fp
   target/arm: Use TRANS_FEAT for do_clast_general
   target/arm: Use TRANS_FEAT for do_last_

[PATCH v2 11/25] hw/sd: Add sd_cmd_SEND_RELATIVE_ADDR() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Message-Id: <20210624142209.1193073-11-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 28 +++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index b56b8fea41..2fe05c5a3d 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1048,6 +1048,20 @@ static sd_rsp_type_t sd_cmd_ALL_SEND_CID(SDState *sd, 
SDRequest req)
 return sd_r2_i;
 }
 
+static sd_rsp_type_t sd_cmd_SEND_RELATIVE_ADDR(SDState *sd, SDRequest req)
+{
+switch (sd->state) {
+case sd_identification_state:
+case sd_standby_state:
+sd->state = sd_standby_state;
+sd_set_rca(sd);
+return sd_r6;
+
+default:
+return sd_invalid_state_for_cmd(sd, req);
+}
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1087,19 +1101,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 switch (req.cmd) {
 /* Basic commands (Class 0 and Class 1) */
-case 3:/* CMD3:   SEND_RELATIVE_ADDR */
-switch (sd->state) {
-case sd_identification_state:
-case sd_standby_state:
-sd->state = sd_standby_state;
-sd_set_rca(sd);
-return sd_r6;
-
-default:
-break;
-}
-break;
-
 case 4:/* CMD4:   SEND_DSR */
 switch (sd->state) {
 case sd_standby_state:
@@ -2149,6 +2150,7 @@ static const SDProto sd_proto_sd = {
 [0] = sd_cmd_GO_IDLE_STATE,
 [1] = sd_cmd_illegal,
 [2] = sd_cmd_ALL_SEND_CID,
+[3] = sd_cmd_SEND_RELATIVE_ADDR,
 [5] = sd_cmd_illegal,
 [52 ... 54] = sd_cmd_illegal,
 [58]= sd_cmd_illegal,
-- 
2.36.1




[PATCH v2 13/25] hw/sd: Add sd_cmd_SET_BLOCK_COUNT() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 30 --
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a9130155be..b2f16dbb73 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1078,6 +1078,21 @@ static sd_rsp_type_t sd_cmd_SEND_TUNING_BLOCK(SDState 
*sd, SDRequest req)
 return sd_r1;
 }
 
+static sd_rsp_type_t sd_cmd_SET_BLOCK_COUNT(SDState *sd, SDRequest req)
+{
+if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
+return sd_cmd_illegal(sd, req);
+}
+
+if (sd->state != sd_transfer_state) {
+return sd_invalid_state_for_cmd(sd, req);
+}
+
+sd->multi_blk_cnt = req.arg;
+
+return sd_r1;
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1321,20 +1336,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 break;
 
-case 23:/* CMD23: SET_BLOCK_COUNT */
-if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
-return sd_invalid_state_for_cmd(sd, req);
-}
-switch (sd->state) {
-case sd_transfer_state:
-sd->multi_blk_cnt = req.arg;
-return sd_r1;
-
-default:
-break;
-}
-break;
-
 /* Block write commands (Class 4) */
 case 24:   /* CMD24:  WRITE_SINGLE_BLOCK */
 case 25:   /* CMD25:  WRITE_MULTIPLE_BLOCK */
@@ -2158,6 +2159,7 @@ static const SDProto sd_proto_sd = {
 [3] = sd_cmd_SEND_RELATIVE_ADDR,
 [5] = sd_cmd_illegal,
 [19]= sd_cmd_SEND_TUNING_BLOCK,
+[23]= sd_cmd_SET_BLOCK_COUNT,
 [52 ... 54] = sd_cmd_illegal,
 [58]= sd_cmd_illegal,
 [59]= sd_cmd_illegal,
-- 
2.36.1




[PATCH v2 06/25] hw/sd: Add sd_cmd_illegal() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Log illegal commands as GUEST_ERROR.

Note: we are logging back the SDIO commands (CMD5, CMD52-54).

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Message-Id: <20210624142209.1193073-6-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 62 +++---
 1 file changed, 26 insertions(+), 36 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index ed63528615..bda24bc042 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1002,6 +1002,15 @@ static sd_rsp_type_t sd_invalid_state_for_cmd(SDState 
*sd, SDRequest req)
 return sd_illegal;
 }
 
+static sd_rsp_type_t sd_cmd_illegal(SDState *sd, SDRequest req)
+{
+qemu_log_mask(LOG_GUEST_ERROR, "%s: Unknown CMD%i for spec %s\n",
+  sd_proto(sd)->name, req.cmd,
+  sd_version_str(sd->spec_version));
+
+return sd_illegal;
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1054,15 +1063,10 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 1:/* CMD1:   SEND_OP_CMD */
-if (!sd->spi)
-goto bad_cmd;
-
 sd->state = sd_transfer_state;
 return sd_r1;
 
 case 2:/* CMD2:   ALL_SEND_CID */
-if (sd->spi)
-goto bad_cmd;
 switch (sd->state) {
 case sd_ready_state:
 sd->state = sd_identification_state;
@@ -1074,8 +1078,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 3:/* CMD3:   SEND_RELATIVE_ADDR */
-if (sd->spi)
-goto bad_cmd;
 switch (sd->state) {
 case sd_identification_state:
 case sd_standby_state:
@@ -1089,8 +1091,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 4:/* CMD4:   SEND_DSR */
-if (sd->spi)
-goto bad_cmd;
 switch (sd->state) {
 case sd_standby_state:
 break;
@@ -1100,9 +1100,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 break;
 
-case 5: /* CMD5: reserved for SDIO cards */
-return sd_illegal;
-
 case 6:/* CMD6:   SWITCH_FUNCTION */
 switch (sd->mode) {
 case sd_data_transfer_mode:
@@ -1118,8 +1115,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 7:/* CMD7:   SELECT/DESELECT_CARD */
-if (sd->spi)
-goto bad_cmd;
 switch (sd->state) {
 case sd_standby_state:
 if (sd->rca != rca)
@@ -1249,8 +1244,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 15:   /* CMD15:  GO_INACTIVE_STATE */
-if (sd->spi)
-goto bad_cmd;
 switch (sd->mode) {
 case sd_data_transfer_mode:
 if (sd->rca != rca)
@@ -1303,7 +1296,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 case 19:/* CMD19: SEND_TUNING_BLOCK (SD) */
 if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
-goto bad_cmd;
+return sd_invalid_state_for_cmd(sd, req);
 }
 if (sd->state == sd_transfer_state) {
 sd->state = sd_sendingdata_state;
@@ -1314,7 +1307,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 case 23:/* CMD23: SET_BLOCK_COUNT */
 if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
-goto bad_cmd;
+return sd_invalid_state_for_cmd(sd, req);
 }
 switch (sd->state) {
 case sd_transfer_state:
@@ -1357,8 +1350,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 26:   /* CMD26:  PROGRAM_CID */
-if (sd->spi)
-goto bad_cmd;
 switch (sd->state) {
 case sd_transfer_state:
 sd->state = sd_receivingdata_state;
@@ -1508,15 +1499,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 }
 break;
 
-case 52 ... 54:
-/* CMD52, CMD53, CMD54: reserved for SDIO cards
- * (see the SDIO Simplified Specification V2.0)
- * Handle as illegal command but do not complain
- * on stderr, as some OSes may use these in their
- * probing for presence of an SDIO card.
- */
-return sd_illegal;
-
 /* Application specific commands (Class 8) */
 case 55:   /* CMD55:  APP_CMD */
 switch (sd->state) {
@@ -1557,19 +1539,12 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 break;
 
 case 58:/* CMD58:   READ_OCR (SPI) */
-if (!sd->spi) {
-goto bad_cmd;
-}
 return sd_r3;
 
 case 59:/* CMD59:   CRC_ON_OFF (SPI) */
-if (!sd->spi) {
-goto bad_cmd;
-}
 return 

[PATCH v2 14/25] hw/sd: Basis for eMMC support

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

The initial eMMC support from Vincent Palatin was largely reworked to
match the current SD framework.

Signed-off-by: Cédric Le Goater 
Signed-off-by: Philippe Mathieu-Daudé 
---
TODO: Do not inherit TYPE_SD_CARD, duplicate sd_class_init()
---
 hw/sd/sd.c | 42 ++
 include/hw/sd/sd.h |  3 +++
 2 files changed, 45 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index b2f16dbb73..8b178aa261 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2166,6 +2166,19 @@ static const SDProto sd_proto_sd = {
 },
 };
 
+static const SDProto sd_proto_emmc = {
+.name = "eMMC",
+.cmd = {
+[0] = sd_cmd_GO_IDLE_STATE,
+[5] = sd_cmd_illegal,
+[19]= sd_cmd_SEND_TUNING_BLOCK,
+[41]= sd_cmd_illegal,
+[52 ... 54] = sd_cmd_illegal,
+[58]= sd_cmd_illegal,
+[59]= sd_cmd_illegal,
+},
+};
+
 static void sd_instance_init(Object *obj)
 {
 SDState *sd = SD_CARD(obj);
@@ -2284,9 +2297,38 @@ static const TypeInfo sd_info = {
 .instance_finalize = sd_instance_finalize,
 };
 
+static void emmc_realize(DeviceState *dev, Error **errp)
+{
+SDState *sd = SD_CARD(dev);
+
+if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
+error_setg(errp, "Minimum spec for eMMC is v3.01");
+return;
+}
+
+sd_realize(dev, errp);
+}
+
+static void emmc_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+SDCardClass *sc = SD_CARD_CLASS(klass);
+
+dc->desc = "eMMC";
+dc->realize = emmc_realize;
+sc->proto = _proto_emmc;
+}
+
+static const TypeInfo emmc_info = {
+.name = TYPE_EMMC,
+.parent = TYPE_SD_CARD,
+.class_init = emmc_class_init,
+ };
+
 static void sd_register_types(void)
 {
 type_register_static(_info);
+type_register_static(_info);
 }
 
 type_init(sd_register_types)
diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index 0d94e1f346..e52436b7a5 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -93,6 +93,9 @@ typedef struct {
 #define TYPE_SD_CARD "sd-card"
 OBJECT_DECLARE_TYPE(SDState, SDCardClass, SD_CARD)
 
+#define TYPE_EMMC "emmc"
+DECLARE_INSTANCE_CHECKER(SDState, EMMC, TYPE_EMMC)
+
 struct SDCardClass {
 /*< private >*/
 DeviceClass parent_class;
-- 
2.36.1




[PATCH v2 10/25] hw/sd: Add sd_cmd_ALL_SEND_CID() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Message-Id: <20210624142209.1193073-10-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index ac81e1c667..b56b8fea41 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1037,6 +1037,17 @@ static sd_rsp_type_t sd_cmd_SEND_OP_CMD(SDState *sd, 
SDRequest req)
 return sd_r1;
 }
 
+static sd_rsp_type_t sd_cmd_ALL_SEND_CID(SDState *sd, SDRequest req)
+{
+if (sd->state != sd_ready_state) {
+return sd_invalid_state_for_cmd(sd, req);
+}
+
+sd->state = sd_identification_state;
+
+return sd_r2_i;
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1076,17 +1087,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 switch (req.cmd) {
 /* Basic commands (Class 0 and Class 1) */
-case 2:/* CMD2:   ALL_SEND_CID */
-switch (sd->state) {
-case sd_ready_state:
-sd->state = sd_identification_state;
-return sd_r2_i;
-
-default:
-break;
-}
-break;
-
 case 3:/* CMD3:   SEND_RELATIVE_ADDR */
 switch (sd->state) {
 case sd_identification_state:
@@ -2148,6 +2148,7 @@ static const SDProto sd_proto_sd = {
 .cmd = {
 [0] = sd_cmd_GO_IDLE_STATE,
 [1] = sd_cmd_illegal,
+[2] = sd_cmd_ALL_SEND_CID,
 [5] = sd_cmd_illegal,
 [52 ... 54] = sd_cmd_illegal,
 [58]= sd_cmd_illegal,
-- 
2.36.1




[PATCH v2 08/25] hw/sd: Add sd_cmd_GO_IDLE_STATE() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Message-Id: <20210624142209.1193073-8-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index e018498b10..22405e8bb6 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1020,6 +1020,16 @@ static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, 
SDRequest req)
 return sd_illegal;
 }
 
+static sd_rsp_type_t sd_cmd_GO_IDLE_STATE(SDState *sd, SDRequest req)
+{
+if (sd->state != sd_inactive_state) {
+sd->state = sd_idle_state;
+sd_reset(DEVICE(sd));
+}
+
+return sd->spi ? sd_r1 : sd_r0;
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1059,18 +1069,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 switch (req.cmd) {
 /* Basic commands (Class 0 and Class 1) */
-case 0:/* CMD0:   GO_IDLE_STATE */
-switch (sd->state) {
-case sd_inactive_state:
-return sd->spi ? sd_r1 : sd_r0;
-
-default:
-sd->state = sd_idle_state;
-sd_reset(DEVICE(sd));
-return sd->spi ? sd_r1 : sd_r0;
-}
-break;
-
 case 1:/* CMD1:   SEND_OP_CMD */
 sd->state = sd_transfer_state;
 return sd_r1;
@@ -2132,6 +2130,7 @@ void sd_enable(SDState *sd, bool enable)
 static const SDProto sd_proto_spi = {
 .name = "SPI",
 .cmd = {
+[0] = sd_cmd_GO_IDLE_STATE,
 [2 ... 4]   = sd_cmd_illegal,
 [5] = sd_cmd_illegal,
 [7] = sd_cmd_illegal,
@@ -2147,6 +2146,7 @@ static const SDProto sd_proto_spi = {
 static const SDProto sd_proto_sd = {
 .name = "SD",
 .cmd = {
+[0] = sd_cmd_GO_IDLE_STATE,
 [1] = sd_cmd_illegal,
 [5] = sd_cmd_illegal,
 [52 ... 54] = sd_cmd_illegal,
-- 
2.36.1




[PATCH v2 04/25] hw/sd: Move proto_name to SDProto structure

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Introduce a new structure to hold the bus protocol specific
fields: SDProto. The first field is the protocol name.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Message-Id: <20210624142209.1193073-4-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 35 +++
 include/hw/sd/sd.h |  2 ++
 2 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index b3e61b9f84..953dbbd7ae 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -87,6 +87,10 @@ enum SDCardStates {
 sd_disconnect_state,
 };
 
+typedef struct SDProto {
+const char *name;
+} SDProto;
+
 struct SDState {
 DeviceState parent_obj;
 
@@ -137,7 +141,6 @@ struct SDState {
 qemu_irq readonly_cb;
 qemu_irq inserted_cb;
 QEMUTimer *ocr_power_timer;
-const char *proto_name;
 bool enable;
 uint8_t dat_lines;
 bool cmd_line;
@@ -145,6 +148,13 @@ struct SDState {
 
 static void sd_realize(DeviceState *dev, Error **errp);
 
+static const struct SDProto *sd_proto(SDState *sd)
+{
+SDCardClass *sc = SD_CARD_GET_CLASS(sd);
+
+return sc->proto;
+}
+
 static const char *sd_version_str(enum SDPhySpecificationVersion version)
 {
 static const char *sdphy_version[] = {
@@ -981,8 +991,8 @@ static bool address_in_range(SDState *sd, const char *desc,
 
 static sd_rsp_type_t sd_invalid_state_for_cmd(SDState *sd, SDRequest req)
 {
-qemu_log_mask(LOG_GUEST_ERROR, "SD: CMD%i in a wrong state: %s (spec 
%s)\n",
-  req.cmd, sd_state_name(sd->state),
+qemu_log_mask(LOG_GUEST_ERROR, "%s: CMD%i in a wrong state: %s (spec 
%s)\n",
+  sd_proto(sd)->name, req.cmd, sd_state_name(sd->state),
   sd_version_str(sd->spec_version));
 
 return sd_illegal;
@@ -997,7 +1007,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
  * However there is no ACMD55, so we want to trace this particular case.
  */
 if (req.cmd != 55 || sd->expecting_acmd) {
-trace_sdcard_normal_command(sd->proto_name,
+trace_sdcard_normal_command(sd_proto(sd)->name,
 sd_cmd_name(req.cmd), req.cmd,
 req.arg, sd_state_name(sd->state));
 }
@@ -1562,7 +1572,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 static sd_rsp_type_t sd_app_command(SDState *sd,
 SDRequest req)
 {
-trace_sdcard_app_command(sd->proto_name, sd_acmd_name(req.cmd),
+trace_sdcard_app_command(sd_proto(sd)->name, sd_acmd_name(req.cmd),
  req.cmd, req.arg, sd_state_name(sd->state));
 sd->card_status |= APP_CMD;
 switch (req.cmd) {
@@ -1856,7 +1866,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
 if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
 return;
 
-trace_sdcard_write_data(sd->proto_name,
+trace_sdcard_write_data(sd_proto(sd)->name,
 sd_acmd_name(sd->current_cmd),
 sd->current_cmd, value);
 switch (sd->current_cmd) {
@@ -2012,7 +2022,7 @@ uint8_t sd_read_byte(SDState *sd)
 
 io_len = (sd->ocr & (1 << 30)) ? 512 : sd->blk_len;
 
-trace_sdcard_read_data(sd->proto_name,
+trace_sdcard_read_data(sd_proto(sd)->name,
sd_acmd_name(sd->current_cmd),
sd->current_cmd, io_len);
 switch (sd->current_cmd) {
@@ -2131,6 +2141,14 @@ void sd_enable(SDState *sd, bool enable)
 sd->enable = enable;
 }
 
+static const SDProto sd_proto_spi = {
+.name = "SPI",
+};
+
+static const SDProto sd_proto_sd = {
+.name = "SD",
+};
+
 static void sd_instance_init(Object *obj)
 {
 SDState *sd = SD_CARD(obj);
@@ -2149,9 +2167,10 @@ static void sd_instance_finalize(Object *obj)
 static void sd_realize(DeviceState *dev, Error **errp)
 {
 SDState *sd = SD_CARD(dev);
+SDCardClass *sc = SD_CARD_GET_CLASS(sd);
 int ret;
 
-sd->proto_name = sd->spi ? "SPI" : "SD";
+sc->proto = sd->spi ? _proto_spi : _proto_sd;
 
 switch (sd->spec_version) {
 case SD_PHY_SPECv1_10_VERS
diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index 47360ba4ee..0d94e1f346 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -124,6 +124,8 @@ struct SDCardClass {
 void (*enable)(SDState *sd, bool enable);
 bool (*get_inserted)(SDState *sd);
 bool (*get_readonly)(SDState *sd);
+
+const struct SDProto *proto;
 };
 
 #define TYPE_SD_BUS "sd-bus"
-- 
2.36.1




[PATCH v2 05/25] hw/sd: Introduce sd_cmd_handler type

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Add 2 command handler arrays in SDProto, for CMD and ACMD.
Have sd_normal_command() / sd_app_command() use these arrays:
if an command handler is registered, call it, otherwise fall
back to current code base.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Message-Id: <20210624142209.1193073-5-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 953dbbd7ae..ed63528615 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -87,8 +87,12 @@ enum SDCardStates {
 sd_disconnect_state,
 };
 
+typedef sd_rsp_type_t (*sd_cmd_handler)(SDState *sd, SDRequest req);
+
 typedef struct SDProto {
 const char *name;
+sd_cmd_handler cmd[SDMMC_CMD_MAX];
+sd_cmd_handler acmd[SDMMC_CMD_MAX];
 } SDProto;
 
 struct SDState {
@@ -1031,6 +1035,10 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_illegal;
 }
 
+if (sd_proto(sd)->cmd[req.cmd]) {
+return sd_proto(sd)->cmd[req.cmd](sd, req);
+}
+
 switch (req.cmd) {
 /* Basic commands (Class 0 and Class 1) */
 case 0:/* CMD0:   GO_IDLE_STATE */
@@ -1575,6 +1583,11 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
 trace_sdcard_app_command(sd_proto(sd)->name, sd_acmd_name(req.cmd),
  req.cmd, req.arg, sd_state_name(sd->state));
 sd->card_status |= APP_CMD;
+
+if (sd_proto(sd)->acmd[req.cmd]) {
+return sd_proto(sd)->acmd[req.cmd](sd, req);
+}
+
 switch (req.cmd) {
 case 6:/* ACMD6:  SET_BUS_WIDTH */
 if (sd->spi) {
-- 
2.36.1




[PATCH v2 02/25] hw/sd: When card is in wrong state, log which state it is

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

We report the card is in an inconsistent state, but don't precise
in which state it is. Add this information, as it is useful when
debugging problems.

Since we will reuse this code, extract as sd_invalid_state_for_cmd()
helper.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Message-Id: <20210624142209.1193073-2-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 7e3bb12b1a..b0e7a7e6d0 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -966,6 +966,14 @@ static bool address_in_range(SDState *sd, const char *desc,
 return true;
 }
 
+static sd_rsp_type_t sd_invalid_state_for_cmd(SDState *sd, SDRequest req)
+{
+qemu_log_mask(LOG_GUEST_ERROR, "SD: CMD%i in a wrong state: %s\n",
+  req.cmd, sd_state_name(sd->state));
+
+return sd_illegal;
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1534,9 +1542,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 return sd_illegal;
 }
 
-qemu_log_mask(LOG_GUEST_ERROR, "SD: CMD%i in a wrong state: %s\n",
-  req.cmd, sd_state_name(sd->state));
-return sd_illegal;
+return sd_invalid_state_for_cmd(sd, req);
 }
 
 static sd_rsp_type_t sd_app_command(SDState *sd,
-- 
2.36.1




[PATCH v2 07/25] hw/sd: Add sd_cmd_unimplemented() handler

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
[ clg: Fix redundant assignment of .cmd ]
Message-Id: <20210624142209.1193073-7-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
 hw/sd/sd.c | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index bda24bc042..e018498b10 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1011,6 +1011,15 @@ static sd_rsp_type_t sd_cmd_illegal(SDState *sd, 
SDRequest req)
 return sd_illegal;
 }
 
+/* Commands that are recognised but not yet implemented. */
+static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, SDRequest req)
+{
+qemu_log_mask(LOG_UNIMP, "%s: CMD%i not implemented\n",
+  sd_proto(sd)->name, req.cmd);
+
+return sd_illegal;
+}
+
 static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
 {
 uint32_t rca = 0x;
@@ -1565,9 +1574,6 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
 
 switch (req.cmd) {
 case 6:/* ACMD6:  SET_BUS_WIDTH */
-if (sd->spi) {
-goto unimplemented_spi_cmd;
-}
 switch (sd->state) {
 case sd_transfer_state:
 sd->sd_status[0] &= 0x3f;
@@ -1698,12 +1704,6 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
 default:
 /* Fall back to standard commands.  */
 return sd_normal_command(sd, req);
-
-unimplemented_spi_cmd:
-/* Commands that are recognised but not yet implemented in SPI mode.  
*/
-qemu_log_mask(LOG_UNIMP, "SD: CMD%i not implemented in SPI mode\n",
-  req.cmd);
-return sd_illegal;
 }
 
 qemu_log_mask(LOG_GUEST_ERROR, "SD: ACMD%i in a wrong state\n", req.cmd);
@@ -2139,6 +2139,9 @@ static const SDProto sd_proto_spi = {
 [26]= sd_cmd_illegal,
 [52 ... 54] = sd_cmd_illegal,
 },
+.acmd = {
+[6] = sd_cmd_unimplemented,
+},
 };
 
 static const SDProto sd_proto_sd = {
-- 
2.36.1




[PATCH v2 03/25] hw/sd: When card is in wrong state, log which spec version is used

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Add the sd_version_str() helper.

Signed-off-by: Philippe Mathieu-Daudé 
---
 hw/sd/sd.c | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index b0e7a7e6d0..b3e61b9f84 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -145,6 +145,19 @@ struct SDState {
 
 static void sd_realize(DeviceState *dev, Error **errp);
 
+static const char *sd_version_str(enum SDPhySpecificationVersion version)
+{
+static const char *sdphy_version[] = {
+[SD_PHY_SPECv1_10_VERS] = "v1.10",
+[SD_PHY_SPECv2_00_VERS] = "v2.00",
+[SD_PHY_SPECv3_01_VERS] = "v3.01",
+};
+if (version >= ARRAY_SIZE(sdphy_version)) {
+return "unsupported version";
+}
+return sdphy_version[version];
+}
+
 static const char *sd_state_name(enum SDCardStates state)
 {
 static const char *state_name[] = {
@@ -968,8 +981,9 @@ static bool address_in_range(SDState *sd, const char *desc,
 
 static sd_rsp_type_t sd_invalid_state_for_cmd(SDState *sd, SDRequest req)
 {
-qemu_log_mask(LOG_GUEST_ERROR, "SD: CMD%i in a wrong state: %s\n",
-  req.cmd, sd_state_name(sd->state));
+qemu_log_mask(LOG_GUEST_ERROR, "SD: CMD%i in a wrong state: %s (spec 
%s)\n",
+  req.cmd, sd_state_name(sd->state),
+  sd_version_str(sd->spec_version));
 
 return sd_illegal;
 }
-- 
2.36.1




[PATCH v2 01/25] hw/sd/sdcard: Return ILLEGAL for CMD19/CMD23 prior SD spec v3.01

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

CMD19 (SEND_TUNING_BLOCK) and CMD23 (SET_BLOCK_COUNT) were
added in the Physical Layer Simplified Specification v3.01.
When earlier spec version is requested, we should return ILLEGAL.

Signed-off-by: Philippe Mathieu-Daudé 
Reviewed-by: Bin Meng 
Message-Id: <20220509141320.98374-1-philippe.mathieu.da...@gmail.com>
---
 hw/sd/sd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 8e6fa09151..7e3bb12b1a 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1263,7 +1263,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 case 19:/* CMD19: SEND_TUNING_BLOCK (SD) */
 if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
-break;
+goto bad_cmd;
 }
 if (sd->state == sd_transfer_state) {
 sd->state = sd_sendingdata_state;
@@ -1274,7 +1274,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, 
SDRequest req)
 
 case 23:/* CMD23: SET_BLOCK_COUNT */
 if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
-break;
+goto bad_cmd;
 }
 switch (sd->state) {
 case sd_transfer_state:
-- 
2.36.1




[PATCH v2 00/25] hw/sd: Rework models for eMMC support

2022-05-30 Thread Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé 

Rebase/respin of Cédric RFC:
https://lore.kernel.org/qemu-devel/20220318132824.1134400-1-...@kaod.org/
(sorry it took me so long guys...)

Pushed at https://gitlab.com/philmd/qemu/-/commits/emmc-v2

I plan to queue patches 1-12 via sdmmc-next later this week.

Cédric, if you are happy with this series, it should be easy to rebase
your other patches on top and address the comments I left on the RFC :)

Regards,

Phil.

Cédric Le Goater (6):
  hw/sd: Add sd_emmc_cmd_SEND_OP_CMD() handler
  hw/sd: Add sd_emmc_cmd_ALL_SEND_CID() handler
  hw/sd: Add sd_emmc_cmd_SEND_RELATIVE_ADDR() handler
  hw/sd: Add sd_emmc_cmd_APP_CMD() handler
  hw/sd: add sd_emmc_cmd_SEND_TUNING_BLOCK() handler
  hw/sd: Add sd_emmc_cmd_SEND_EXT_CSD() handler

Joel Stanley (4):
  hw/sd: Add sd_cmd_SEND_TUNING_BLOCK() handler
  hw/sd: Support boot area in emmc image
  hw/sd: Subtract bootarea size from blk
  hw/sd: Add boot config support

Philippe Mathieu-Daudé (13):
  hw/sd/sdcard: Return ILLEGAL for CMD19/CMD23 prior SD spec v3.01
  hw/sd: When card is in wrong state, log which state it is
  hw/sd: When card is in wrong state, log which spec version is used
  hw/sd: Move proto_name to SDProto structure
  hw/sd: Introduce sd_cmd_handler type
  hw/sd: Add sd_cmd_illegal() handler
  hw/sd: Add sd_cmd_unimplemented() handler
  hw/sd: Add sd_cmd_GO_IDLE_STATE() handler
  hw/sd: Add sd_cmd_SEND_OP_CMD() handler
  hw/sd: Add sd_cmd_ALL_SEND_CID() handler
  hw/sd: Add sd_cmd_SEND_RELATIVE_ADDR() handler
  hw/sd: Add sd_cmd_SET_BLOCK_COUNT() handler
  hw/sd: Basis for eMMC support

Sai Pavan Boddu (2):
  hw/sd: Add CMD21 tuning sequence
  hw/sd: Add mmc switch function support

 hw/sd/sd.c | 645 +
 hw/sd/sdmmc-internal.c |   2 +-
 hw/sd/sdmmc-internal.h |  97 +++
 include/hw/sd/sd.h |   7 +
 4 files changed, 627 insertions(+), 124 deletions(-)

-- 
2.36.1




Re: [PATCH] hw/nvme: deprecate the use-intel-id compatibility parameter

2022-05-30 Thread Klaus Jensen
On May 30 16:37, Philippe Mathieu-Daudé wrote:
> On 29/4/22 07:41, Klaus Jensen wrote:
> > From: Klaus Jensen 
> > 
> > Since version 5.2 commit 6eb7a071292a ("hw/block/nvme: change controller
> > pci id"), the emulated NVMe controller has defaulted to a non-Intel PCI
> > identifier.
> > 
> > Deprecate the compatibility parameter so we can get rid of it once and
> > for all.
> > 
> > Signed-off-by: Klaus Jensen 
> > ---
> >   docs/about/deprecated.rst | 8 
> >   1 file changed, 8 insertions(+)
> > 
> > diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> > index 896e5a97abbd..450f945ac25f 100644
> > --- a/docs/about/deprecated.rst
> > +++ b/docs/about/deprecated.rst
> > @@ -356,6 +356,14 @@ contains native support for this feature and thus use 
> > of the option
> >   ROM approach is obsolete. The native SeaBIOS support can be activated
> >   by using ``-machine graphics=off``.
> > +``-device nvme,use-intel-id=on|off`` (since 7.1)
> > +
> > +
> > +The ``nvme`` device originally used a PCI Vendor/Device Identifier 
> > combination
> > +from Intel that was not properly allocated. Since version 5.2, the 
> > controller
> > +has used a properly allocated identifier. Deprecate the ``use-intel-id``
> > +machine compatibility parameter.
> > +
> >   Block device options
> >   
> 
> Reviewed-by: Philippe Mathieu-Daudé 

Thanks!

Applied to nvme-next.


signature.asc
Description: PGP signature


Re: [PATCH] tests/tcg/s390x: Test overflow conditions

2022-05-30 Thread Gautam Agrawal
Hi,
On Mon, 30 May 2022 at 16:05, Thomas Huth  wrote:
>
>   Hi!
>
> On 30/05/2022 11.50, David Hildenbrand wrote:
> > On 27.05.22 12:11, Gautam Agrawal wrote:
> >> Add a test to check for overflow conditions in s390x.
> >> This patch is based on the following patches :
> >> * https://git.qemu.org/?p=qemu.git;a=commitdiff;h=5a2e67a691501
> >> * https://git.qemu.org/?p=qemu.git;a=commitdiff;h=fc6e0d0f2db51
> >>
> >> Signed-off-by: Gautam Agrawal 
> >> ---
> >>   tests/tcg/s390x/Makefile.target |  1 +
> >>   tests/tcg/s390x/overflow.c  | 58 +
> >>   2 files changed, 59 insertions(+)
> >>   create mode 100644 tests/tcg/s390x/overflow.c
> >>
> >> diff --git a/tests/tcg/s390x/Makefile.target 
> >> b/tests/tcg/s390x/Makefile.target
> >> index 3124172736..7f86de85b9 100644
> >> --- a/tests/tcg/s390x/Makefile.target
> >> +++ b/tests/tcg/s390x/Makefile.target
> >> @@ -16,6 +16,7 @@ TESTS+=shift
> >>   TESTS+=trap
> >>   TESTS+=signals-s390x
> >>   TESTS+=branch-relative-long
> >> +TESTS+=overflow
> >>
> >>   VECTOR_TESTS=vxeh2_vs
> >>   VECTOR_TESTS+=vxeh2_vcvt
> >> diff --git a/tests/tcg/s390x/overflow.c b/tests/tcg/s390x/overflow.c
> >> new file mode 100644
> >> index 00..ea8a410b1a
> >> --- /dev/null
> >> +++ b/tests/tcg/s390x/overflow.c
> >> @@ -0,0 +1,58 @@
> >> +#include 
> >> +
> >> +int overflow_add_32(int x, int y)
> >> +{
> >> +int sum;
> >> +return __builtin_add_overflow(x, y, );
> >> +}
> >> +
> >> +int overflow_add_64(long long x, long long y)
> >> +{
> >> +long sum;
> >
> > Just wondering, why "long long" in input and "long" in output?

> It's been like this in the original test program that has been supplied in
> https://gitlab.com/qemu-project/qemu/-/issues/616 and .../618 - but I agree
> it likely makes more sense to use the same type everywhere (i.e. switch sum
> from long to long long).

I will correct the type in next patch.

>
> >> +return __builtin_add_overflow(x, y, );
> >> +}
> >> +
> >> +int overflow_sub_32(int x, int y)
> >> +{
> >> +int sum;
> >> +return __builtin_sub_overflow(x, y, );
> >> +}
> >> +
> >> +int overflow_sub_64(long long x, long long y)
> >> +{
> >> +long sum;
> >> +return __builtin_sub_overflow(x, y, );
> >
> > nit: I'd call all local variables "ret" or "res".
>
> Well, "sum" is not the return value here, so "ret" could be confusing, too.
> "res" or "diff" might be a good choice here, though. Gautam, what do you 
> think?

I agree "res" sounds better.

Regards,
Gautam Agrawal



Re: Help: How do I make a machine with 2 separate ARM SoC's?

2022-05-30 Thread Peter Delevoryas


> On May 30, 2022, at 11:15 AM, Cédric Le Goater  wrote:
> 
> On 5/30/22 18:53, Peter Maydell wrote:
>> On Thu, 26 May 2022 at 23:14, Peter Delevoryas  wrote:
>>> Hey QEMU developers,
>>> 
>>> Cedric mentioned here[1] that QEMU can support emulating a
>>> more complete board, e.g. a machine with an AST2600 *and* an AST1030.
>> This is true, as long as all the CPUs are the same
>> architecture family, e.g. all Arm CPUs. (Mixing A- and
>> R- or A- and M-profile is OK, they just all have to be
>> available in the same qemu-system-whatever binary.)
>>> I read through the memory API docs[2] and it mostly makes sense to me,
>>> but what I don’t understand is, what does system_memory represent?
>> So, system_memory is something of a legacy from when QEMU was
>> much older. Before the MemoryRegion and AddressSpace APIs were
>> added to QEMU, everything that could initiate a memory transaction
>> (CPUs, DMA-capable devices, etc) always saw the same view of
>> memory. The functions to do memory accesses just operated on
>> that view implicitly. (We still have some of them, for instance
>> cpu_physical_memory_read() and cpu_physical_memory_write().) The
>> MemoryRegion/AddressSpace APIs are much more flexible and allow
>> different memory transaction initiators to see different views, as
>> real hardware does. But for backwards compatibility we still have
>> the old assumes-one-view APIs. The view those APIs use is the
>> "system memory". We also have some device models which have been
>> converted to use an AddressSpace to do their DMA operations, but
>> which assume they want to use address_space_memory (which is the AS
>> corresponding to the system_memory MR) instead of taking a
>> MemoryRegion as a QOM pointer and creating an AddressSpace for it.
>> In the modern view of the world, you can build up a system with
>> a set of MemoryRegions. Typically you can start with an empty
>> container, and the board code fills it with board-level devices,
>> then passes it to the SoC code, which fills it with SoC devices,
>> and passes it again to the CPU object, which creates an AddressSpace
>> so it can initiate transactions into it. By making that initial
>> "empty container" be the global system_memory MemoryRegion, this
>> makes the legacy APIs and devices that still use it basically work.
>>> Or, what should the layout be for a situation like I’m interested in,
>>> where you have an AST2600 and an AST1030 (and actually, maybe even
>>> an x86 CPU too? idk if that would be possible).
>> Cross-architecture heterogenous board models can't be done today:
>> the qemu-system-foo binaries compile-time build in some assumptions
>> about specifics of the guest architecture. (This is something it would
>> be nice to fix, but the amount of work is pretty big and hairy, and
>> thus far nobody's had a pressing enough need for it to try to tackle it.)
>>> I need to make sure each SoC runs in a different address space, right?
>>> But, how do I actually do that? Do I model it as two containers inside
>>> the large system_memory container, or as two different containers
>>> that get swapped in for system_memory when executing their associated
>>> CPU?
>> The best way to think about QEMU's AddressSpace type is that it is
>> the interface you use to initiate memory transactions. You create
>> one from a MemoryRegion. When SoC and board code is building up its
>> view of the world, what it is really creating and passing around is
>> a hierarchy of MemoryRegions. It's only when the SoC code hands a
>> MemoryRegion to a CPU or a DMA-capable device that that device says
>> "I will need to make transactions to this, let me create the
>> corresponding AddressSpace".
>>> I was having trouble figuring out what the Xilinx boards are actually
>>> doing in this case. Does each CPU share peripherals, or are the
>>> A + R cpu’s actually in separate address spaces? I’m very confused lol.
>> xlnx-versal-virt is a virtual board, so ignore that one: it's
>> probably more confusing than helpful. The xlnx-zcu102 board
>> uses the xlnx-zynqmp SoC, and that SoC has both R and A profile
>> CPUs in it, but they both see basically the same view of the
>> world because they're in the same SoC.

I see, I started to suspect as much.

>> Another device that does some moderately complicated things with
>> MemoryRegions is the hw/arm/armsse.c SoC, which has several CPUs
>> and has some per-CPU devices.
>> 
>> I think we have not thus far had a model of a board where different
>> CPUs see radically different things (only ones where they can see
>> minor differences), so you'll probably run into places where the
>> APIs are a bit clunky (and we can perhaps have a go at making
>> them a bit less so). What I would do is make the system_memory
>> container be used by whatever is the "main" application processor
>> SoC in your board. 
> 
> I think Peter D. wants to emulate a machine with a BMC board (ast2600)
> and a SCP-like SoC (ast1030) running zephir. Correct me if I 

Re: [PATCH v3 0/7] QOM'ify PIIX southbridge creation

2022-05-30 Thread Mark Cave-Ayland

On 29/05/2022 14:02, Bernhard Beschow wrote:

On Sun, May 29, 2022 at 12:06 PM Mark Cave-Ayland > wrote:


On 29/05/2022 10:46, Mark Cave-Ayland wrote:

 > On 28/05/2022 20:20, Bernhard Beschow wrote:
 >
 >> v3:
 >> * Rebase onto 'hw/acpi/piix4: remove legacy piix4_pm_init() function' 
(Mark) [1]
 >> * Use embedded structs for touched PCI devices (Mark)
 >> * Fix piix4's rtc embedded struct to be initialized by
 >>    object_initialize_child() (Peter) [2]
 >>
 >> Testing done:
 >>
 >> 1)
 >> `make check-avocado` for --target-list=x86_64-softmmu,mips-softmmu
 >> Result: All pass.
 >>
 >> 2)
 >> * `qemu-system-x86_64 -M pc -m 2G -cdrom 
archlinux-2022.05.01-x86_64.iso`
 >> * `qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda
 >>    debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 
console=tty0"`
 >>
 >> In both cases the system booted successfully and it was possible to 
shut down
 >> the system using the `poweroff` command.
 >>
 >>
 >> v2:
 >> * Preserve `DeviceState *` as return value of piix4_create() (Mark)
 >> * Aggregate all type name movements into first commit (Mark)
 >> * Have piix4 southbridge rather than malta board instantiate piix4 pm 
(me)
 >>
 >> Testing done:
 >>
 >> 1)
 >> `make check-avocado` for --target-list=x86_64-softmmu,mips-softmmu
 >> Result: All pass.
 >>
 >> 2)
 >> Modify pci_piix3_realize() to start with
 >>  error_setg(errp, "This is a test");
 >> Then start `qemu-system-x86_64 -M pc -m 1G -accel kvm -cpu host -cdrom
 >> archlinux-2022.05.01-x86_64.iso`.
 >> Result: qemu-system-x86_64 aborts with: "This is a test"
 >>
 >>
 >> v1:
 >> The piix3 and piix4 southbridge devices still rely on create() 
functions which
 >> are deprecated. This series resolves these functions piece by piece to
 >> modernize the code.
 >>
 >> Both devices are modified in lockstep where possible to provide more 
context.
 >>
 >> Testing done:
 >> * `qemu-system-x86_64 -M pc -m 2G -cdrom 
archlinux-2022.05.01-x86_64.iso`
 >> * `qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda
 >>    debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 
console=tty0"`
 >>
 >> In both cases the system booted successfully and it was possible to 
shut down
 >> the system using the `poweroff` command.
 >>
 >> [1] https://lists.gnu.org/archive/html/qemu-devel/2022-05/msg05686.html

 >> [2] https://lists.gnu.org/archive/html/qemu-devel/2022-02/msg01128.html

 >>
 >> Bernhard Beschow (7):
 >>    include/hw/southbridge/piix: Aggregate all PIIX soughbridge type 
names
 >>    hw/isa/piix4: Use object_initialize_child() for embedded struct
 >>    hw/isa/piix{3,4}: Move pci_map_irq_fn's near pci_set_irq_fn's
 >>    hw/isa/piix{3,4}: QOM'ify PCI device creation and wiring
 >>    hw/isa/piix{3,4}: Factor out ISABus retrieval from create() functions
 >>    hw/isa/piix4: QOM'ify PIIX4 PM creation
 >>    hw/isa/piix{3,4}: Inline and remove create() functions
 >>
 >>   hw/i386/pc_piix.c |   7 +-
 >>   hw/isa/piix3.c    |  98 ++-
 >>   hw/isa/piix4.c    | 120 +-
 >>   hw/mips/malta.c   |   7 +-
 >>   include/hw/isa/isa.h  |   2 -
 >>   include/hw/southbridge/piix.h |   6 +-
 >>   6 files changed, 127 insertions(+), 113 deletions(-)
 >
 > Hi Bernhard,
 >
 > I've spotted a couple of small things, but once those are fixed this 
series looks
 > good to me so I'm happy to give a:
 >
 > Reviewed-by: Mark Cave-Ayland mailto:mark.cave-ayl...@ilande.co.uk>>
 >
 > Thanks for your patience with these series too: you've done some good 
work here,
 > however patchsets like this can sometimes take a while to get reviewed 
because
they
 > both i) touch legacy code/APIs and ii) cut across multiple machines and
maintainers.
 > I'd really like to get this work, along with your RTC updates, merged 
soon as
it is a
 > great improvement.
 >
 > One reason that you may not get many reviews is because you've not added 
the
relevant
 > maintainers on To/CC. Due to the large volume of emails on qemu-devel, 
quite a
few
 > maintainers will filter based upon their own email address so it is 
definitely
worth
 > adding them in.
 >
 > Fortunately you can easily find the relevant maintainer email addresses 
by
running
 > "./scripts/get_maintainer.pl 
" on your git format-patch
 > 

Re: [PATCH 01/18] target/arm: Allow raise_exception to handle finding target EL

2022-05-30 Thread Peter Maydell
On Mon, 30 May 2022 at 17:39, Richard Henderson
 wrote:
>
> On 5/30/22 05:44, Peter Maydell wrote:
> >>   G_NORETURN void raise_exception(CPUARMState *env, uint32_t excp,
> >> -uint32_t syndrome, uint32_t target_el);
> >> +uint32_t syndrome, uint32_t 
> >> cur_or_target_el);
> >
> > "cur_or_target_el" is odd, because it's mixing what the architecture
> > sets up as two distinct things: the state the exception is
> > "taken from", and the state the exception is "taken to". I was
> > hoping this was just a temporary thing for the purposes of the
> > refactoring and it would go away near the end of the series, but
> > it doesn't seem to.
>
> No, sorry.  Most of the time it's cur_el, except from cpregs, where we get 
> directed to a
> specific higher el.  There may be some way to split the helpers...
>
> I'll have another go at this reorg this week.  If it still doesn't feel 
> cleaner, we can
> drop it, and I'll make some changes to the SME patch set building on this.

I was wondering if it would work better the other way around, so that
raise_exception() doesn't mess with the target_el at all, and all the
"work out which EL to take the exception to" is done in
target_exception_el() and similar ?

-- PMM



[PULL 2/2] hw/hyperv/vmbus: Remove unused vmbus_load/save_req()

2022-05-30 Thread Maciej S. Szmigiero
From: Philippe Mathieu-Daudé 

vmbus_save_req() and vmbus_load_req() are not used.
Remove them to avoid maintaining dead code.

This essentially reverts commit 4dd8a7064b8a6527f99a62be11
("vmbus: add infrastructure to save/load vmbus requests").

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20211106134155.582312-2-phi...@redhat.com>
[MSS: Remove also corresponding variables, which are now unused]
Signed-off-by: Maciej S. Szmigiero 
---
 hw/hyperv/vmbus.c | 99 ---
 include/hw/hyperv/vmbus.h |  3 --
 2 files changed, 102 deletions(-)

diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c
index 8aad29f1bb..30bc04e1c4 100644
--- a/hw/hyperv/vmbus.c
+++ b/hw/hyperv/vmbus.c
@@ -1273,105 +1273,6 @@ void vmbus_free_req(void *req)
 g_free(req);
 }
 
-static const VMStateDescription vmstate_sgent = {
-.name = "vmbus/sgentry",
-.version_id = 0,
-.minimum_version_id = 0,
-.fields = (VMStateField[]) {
-VMSTATE_UINT64(base, ScatterGatherEntry),
-VMSTATE_UINT64(len, ScatterGatherEntry),
-VMSTATE_END_OF_LIST()
-}
-};
-
-typedef struct VMBusChanReqSave {
-uint16_t chan_idx;
-uint16_t pkt_type;
-uint32_t msglen;
-void *msg;
-uint64_t transaction_id;
-bool need_comp;
-uint32_t num;
-ScatterGatherEntry *sgl;
-} VMBusChanReqSave;
-
-static const VMStateDescription vmstate_vmbus_chan_req = {
-.name = "vmbus/vmbus_chan_req",
-.version_id = 0,
-.minimum_version_id = 0,
-.fields = (VMStateField[]) {
-VMSTATE_UINT16(chan_idx, VMBusChanReqSave),
-VMSTATE_UINT16(pkt_type, VMBusChanReqSave),
-VMSTATE_UINT32(msglen, VMBusChanReqSave),
-VMSTATE_VBUFFER_ALLOC_UINT32(msg, VMBusChanReqSave, 0, NULL, msglen),
-VMSTATE_UINT64(transaction_id, VMBusChanReqSave),
-VMSTATE_BOOL(need_comp, VMBusChanReqSave),
-VMSTATE_UINT32(num, VMBusChanReqSave),
-VMSTATE_STRUCT_VARRAY_POINTER_UINT32(sgl, VMBusChanReqSave, num,
- vmstate_sgent, 
ScatterGatherEntry),
-VMSTATE_END_OF_LIST()
-}
-};
-
-void vmbus_save_req(QEMUFile *f, VMBusChanReq *req)
-{
-VMBusChanReqSave req_save;
-
-req_save.chan_idx = req->chan->subchan_idx;
-req_save.pkt_type = req->pkt_type;
-req_save.msglen = req->msglen;
-req_save.msg = req->msg;
-req_save.transaction_id = req->transaction_id;
-req_save.need_comp = req->need_comp;
-req_save.num = req->sgl.nsg;
-req_save.sgl = g_memdup(req->sgl.sg,
-req_save.num * sizeof(ScatterGatherEntry));
-
-vmstate_save_state(f, _vmbus_chan_req, _save, NULL);
-
-g_free(req_save.sgl);
-}
-
-void *vmbus_load_req(QEMUFile *f, VMBusDevice *dev, uint32_t size)
-{
-VMBusChanReqSave req_save;
-VMBusChanReq *req = NULL;
-VMBusChannel *chan = NULL;
-uint32_t i;
-
-vmstate_load_state(f, _vmbus_chan_req, _save, 0);
-
-if (req_save.chan_idx >= dev->num_channels) {
-error_report("%s: %u(chan_idx) > %u(num_channels)", __func__,
- req_save.chan_idx, dev->num_channels);
-goto out;
-}
-chan = >channels[req_save.chan_idx];
-
-if (vmbus_channel_reserve(chan, 0, req_save.msglen)) {
-goto out;
-}
-
-req = vmbus_alloc_req(chan, size, req_save.pkt_type, req_save.msglen,
-  req_save.transaction_id, req_save.need_comp);
-if (req_save.msglen) {
-memcpy(req->msg, req_save.msg, req_save.msglen);
-}
-
-for (i = 0; i < req_save.num; i++) {
-qemu_sglist_add(>sgl, req_save.sgl[i].base, req_save.sgl[i].len);
-}
-
-out:
-if (req_save.msglen) {
-g_free(req_save.msg);
-}
-if (req_save.num) {
-g_free(req_save.sgl);
-}
-return req;
-}
-
 static void channel_event_cb(EventNotifier *e)
 {
 VMBusChannel *chan = container_of(e, VMBusChannel, notifier);
diff --git a/include/hw/hyperv/vmbus.h b/include/hw/hyperv/vmbus.h
index f98bea3888..8ea660dd8e 100644
--- a/include/hw/hyperv/vmbus.h
+++ b/include/hw/hyperv/vmbus.h
@@ -223,7 +223,4 @@ int vmbus_map_sgl(VMBusChanReq *req, DMADirection dir, 
struct iovec *iov,
 void vmbus_unmap_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov,
  unsigned iov_cnt, size_t accessed);
 
-void vmbus_save_req(QEMUFile *f, VMBusChanReq *req);
-void *vmbus_load_req(QEMUFile *f, VMBusDevice *dev, uint32_t size);
-
 #endif



[PULL 1/2] MAINTAINERS: Add myself as the maintainer for Hyper-V VMBus

2022-05-30 Thread Maciej S. Szmigiero
From: "Maciej S. Szmigiero" 

This way there is some contact point for incoming patches,
and somebody to review and pick up them.

Signed-off-by: Maciej S. Szmigiero 
---
 MAINTAINERS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index dff0200f70..00dc4a8ecb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1777,6 +1777,12 @@ F: include/hw/block/fdc.h
 F: tests/qtest/fdc-test.c
 T: git https://gitlab.com/jsnow/qemu.git ide
 
+Hyper-V VMBus
+M: Maciej S. Szmigiero 
+S: Odd Fixes
+F: hw/hyperv/vmbus.c
+F: include/hw/hyperv/vmbus*.h
+
 OMAP
 M: Peter Maydell 
 L: qemu-...@nongnu.org



[PULL 0/2] Add myself as the maintainer for Hyper-V VMBus

2022-05-30 Thread Maciej S. Szmigiero
The following changes since commit f7a1ea403e0282a7f57edd4298c4f65f24165da5:

  Merge tag 'misc-pull-request' of gitlab.com:marcandre.lureau/qemu into 
staging (2022-05-29 16:34:56 -0700)

are available in the Git repository at:

  https://github.com/maciejsszmigiero/qemu.git tags/vmbus-maint-20220530

for you to fetch changes up to 6ede46b910ac66fd10bc169fb0a6f681429a9c5c:

  hw/hyperv/vmbus: Remove unused vmbus_load/save_req() (2022-05-30 19:49:42 
+0200)



As discussed in 
https://lore.kernel.org/qemu-devel/4e03945d-fb92-494d-53a8-f22ee9150...@redhat.com/
I am adding myself as the maintainer for Hyper-V VMBus, so there is some
contact point for incoming patches and somebody to review and pick up them.

The VMBus code is currently in a good shape, this pull request also
includes a single patch that has been waiting for being picked up since
November last year.



Maciej S. Szmigiero (1):
  MAINTAINERS: Add myself as the maintainer for Hyper-V VMBus

Philippe Mathieu-Daudé (1):
  hw/hyperv/vmbus: Remove unused vmbus_load/save_req()

 MAINTAINERS   |  6 +++
 hw/hyperv/vmbus.c | 99 ---
 include/hw/hyperv/vmbus.h |  3 --
 3 files changed, 6 insertions(+), 102 deletions(-)



Re: Help: How do I make a machine with 2 separate ARM SoC's?

2022-05-30 Thread Cédric Le Goater

On 5/30/22 18:53, Peter Maydell wrote:

On Thu, 26 May 2022 at 23:14, Peter Delevoryas  wrote:

Hey QEMU developers,

Cedric mentioned here[1] that QEMU can support emulating a
more complete board, e.g. a machine with an AST2600 *and* an AST1030.


This is true, as long as all the CPUs are the same
architecture family, e.g. all Arm CPUs. (Mixing A- and
R- or A- and M-profile is OK, they just all have to be
available in the same qemu-system-whatever binary.)


I read through the memory API docs[2] and it mostly makes sense to me,
but what I don’t understand is, what does system_memory represent?


So, system_memory is something of a legacy from when QEMU was
much older. Before the MemoryRegion and AddressSpace APIs were
added to QEMU, everything that could initiate a memory transaction
(CPUs, DMA-capable devices, etc) always saw the same view of
memory. The functions to do memory accesses just operated on
that view implicitly. (We still have some of them, for instance
cpu_physical_memory_read() and cpu_physical_memory_write().) The
MemoryRegion/AddressSpace APIs are much more flexible and allow
different memory transaction initiators to see different views, as
real hardware does. But for backwards compatibility we still have
the old assumes-one-view APIs. The view those APIs use is the
"system memory". We also have some device models which have been
converted to use an AddressSpace to do their DMA operations, but
which assume they want to use address_space_memory (which is the AS
corresponding to the system_memory MR) instead of taking a
MemoryRegion as a QOM pointer and creating an AddressSpace for it.

In the modern view of the world, you can build up a system with
a set of MemoryRegions. Typically you can start with an empty
container, and the board code fills it with board-level devices,
then passes it to the SoC code, which fills it with SoC devices,
and passes it again to the CPU object, which creates an AddressSpace
so it can initiate transactions into it. By making that initial
"empty container" be the global system_memory MemoryRegion, this
makes the legacy APIs and devices that still use it basically work.


Or, what should the layout be for a situation like I’m interested in,
where you have an AST2600 and an AST1030 (and actually, maybe even
an x86 CPU too? idk if that would be possible).


Cross-architecture heterogenous board models can't be done today:
the qemu-system-foo binaries compile-time build in some assumptions
about specifics of the guest architecture. (This is something it would
be nice to fix, but the amount of work is pretty big and hairy, and
thus far nobody's had a pressing enough need for it to try to tackle it.)


I need to make sure each SoC runs in a different address space, right?
But, how do I actually do that? Do I model it as two containers inside
the large system_memory container, or as two different containers
that get swapped in for system_memory when executing their associated
CPU?


The best way to think about QEMU's AddressSpace type is that it is
the interface you use to initiate memory transactions. You create
one from a MemoryRegion. When SoC and board code is building up its
view of the world, what it is really creating and passing around is
a hierarchy of MemoryRegions. It's only when the SoC code hands a
MemoryRegion to a CPU or a DMA-capable device that that device says
"I will need to make transactions to this, let me create the
corresponding AddressSpace".


I was having trouble figuring out what the Xilinx boards are actually
doing in this case. Does each CPU share peripherals, or are the
A + R cpu’s actually in separate address spaces? I’m very confused lol.


xlnx-versal-virt is a virtual board, so ignore that one: it's
probably more confusing than helpful. The xlnx-zcu102 board
uses the xlnx-zynqmp SoC, and that SoC has both R and A profile
CPUs in it, but they both see basically the same view of the
world because they're in the same SoC.

Another device that does some moderately complicated things with
MemoryRegions is the hw/arm/armsse.c SoC, which has several CPUs
and has some per-CPU devices.

I think we have not thus far had a model of a board where different
CPUs see radically different things (only ones where they can see
minor differences), so you'll probably run into places where the
APIs are a bit clunky (and we can perhaps have a go at making
them a bit less so). What I would do is make the system_memory
container be used by whatever is the "main" application processor
SoC in your board. 


I think Peter D. wants to emulate a machine with a  BMC board (ast2600)
and a SCP-like SoC (ast1030) running zephir. Correct me if I am wrong.
That's a first step.


If the two SoCs really see absolutely different
worlds with no shared devices at all, then you'll want to create
a new empty container for the second SoC. 


yes.


If they do have some
board-level shared devices, then you'll want to do something a little
more complicated with aliases.


The 

Re: [RFC PATCH 11/17] hw/sd: Add eMMC support

2022-05-30 Thread Philippe Mathieu-Daudé via

On 18/3/22 14:28, Cédric Le Goater wrote:

The initial eMMC support from Vincent Palatin was largely reworked to
match the current SD framework. The parameters mimick a real 4GB eMMC,
but it can be set to various sizes.

This adds a new QOM object class for EMMC devices.

Signed-off-by: Vincent Palatin 
Link: 
https://lore.kernel.org/r/1311635951-11047-5-git-send-email-vpala...@chromium.org
[ jms: - Forward ported to QEMU 5.2 ]
Signed-off-by: Joel Stanley 
[ clg: - ported on aspeed-7.0 patchset
- HPI activation ]
Signed-off-by: Cédric Le Goater 
---
  hw/sd/sdmmc-internal.h |  97 +++
  include/hw/sd/sd.h |   9 ++
  hw/sd/sd.c | 205 -
  hw/sd/sdmmc-internal.c |   2 +-
  4 files changed, 311 insertions(+), 2 deletions(-)



  static void sd_instance_init(Object *obj)
  {
  SDState *sd = SD_CARD(obj);
@@ -2162,10 +2338,19 @@ static void sd_instance_finalize(Object *obj)
  static void sd_realize(DeviceState *dev, Error **errp)
  {
  SDState *sd = SD_CARD(dev);
+SDCardClass *sc = SD_CARD_GET_CLASS(sd);
  int ret;
  
  sd->proto = sd->spi ? _proto_spi : _proto_sd;
  
+if (sc->proto) {

+sd->proto = sc->proto;
+}
+
+if (sc->spec_version) {
+sd->spec_version = sc->spec_version;
+}
+
  switch (sd->spec_version) {
  case SD_PHY_SPECv1_10_VERS
   ... SD_PHY_SPECv3_01_VERS:



Instead I'd use:

-- >8 --
@@ -2301,14 +2297,26 @@ static const TypeInfo sd_info = {
 .instance_finalize = sd_instance_finalize,
 };

+static void emmc_realize(DeviceState *dev, Error **errp)
+{
+SDState *sd = SD_CARD(dev);
+
+if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
+error_setg(errp, "Minimum spec for eMMC is v3.01");
+return;
+}
+
+sd_realize(dev, errp);
+}
+
 static void emmc_class_init(ObjectClass *klass, void *data)
 {
 DeviceClass *dc = DEVICE_CLASS(klass);
 SDCardClass *sc = SD_CARD_CLASS(klass);

 dc->desc = "eMMC";
+dc->realize = emmc_realize;
 sc->proto = _proto_emmc;
 }

---





Re: [RFC PATCH 11/17] hw/sd: Add eMMC support

2022-05-30 Thread Philippe Mathieu-Daudé via

On 18/3/22 14:28, Cédric Le Goater wrote:

The initial eMMC support from Vincent Palatin was largely reworked to
match the current SD framework. The parameters mimick a real 4GB eMMC,
but it can be set to various sizes.

This adds a new QOM object class for EMMC devices.

Signed-off-by: Vincent Palatin 
Link: 
https://lore.kernel.org/r/1311635951-11047-5-git-send-email-vpala...@chromium.org
[ jms: - Forward ported to QEMU 5.2 ]
Signed-off-by: Joel Stanley 
[ clg: - ported on aspeed-7.0 patchset
- HPI activation ]
Signed-off-by: Cédric Le Goater 
---
  hw/sd/sdmmc-internal.h |  97 +++
  include/hw/sd/sd.h |   9 ++
  hw/sd/sd.c | 205 -
  hw/sd/sdmmc-internal.c |   2 +-
  4 files changed, 311 insertions(+), 2 deletions(-)




+static void emmc_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+SDCardClass *sc = SD_CARD_CLASS(klass);
+
+dc->desc = "eMMC";
+sc->proto = _proto_emmc;
+sc->spec_version = SD_PHY_SPECv3_01_VERS; /* eMMC requirement */
+sc->set_csd = sd_emmc_set_csd;
+}
+
+static const TypeInfo emmc_info = {
+.name = TYPE_EMMC,
+.parent = TYPE_SD_CARD,


Hmm this is odd to have the model inheriting features from SD_CARD but 
then behaving differently (one could enumerate QDEV objects implementing

TYPE_SD_CARD then use them expecting they match the SD card protocol).

Why do you need to have TYPE_SD_CARD as parent?

Could we simply duplicate sd_class_init() assignations instead? That
would likely make it easier to modify eMMC handlers.


+.class_init = emmc_class_init,
+ };




Re: [PATCH v10 02/45] hw/cxl/component: Introduce CXL components (8.1.x, 8.2.5)

2022-05-30 Thread Jonathan Cameron via
On Fri, 29 Apr 2022 15:40:27 +0100
Jonathan Cameron  wrote:

> From: Ben Widawsky 
> 
> A CXL 2.0 component is any entity in the CXL topology. All components
> have a analogous function in PCIe. Except for the CXL host bridge, all
> have a PCIe config space that is accessible via the common PCIe
> mechanisms. CXL components are enumerated via DVSEC fields in the
> extended PCIe header space. CXL components will minimally implement some
> subset of CXL.mem and CXL.cache registers defined in 8.2.5 of the CXL
> 2.0 specification. Two headers and a utility library are introduced to
> support the minimum functionality needed to enumerate components.
> 
> The cxl_pci header manages bits associated with PCI, specifically the
> DVSEC and related fields. The cxl_component.h variant has data
> structures and APIs that are useful for drivers implementing any of the
> CXL 2.0 components. The library takes care of making use of the DVSEC
> bits and the CXL.[mem|cache] registers. Per spec, the registers are
> little endian.
> 
> None of the mechanisms required to enumerate a CXL capable hostbridge
> are introduced at this point.
> 
> Note that the CXL.mem and CXL.cache registers used are always 4B wide.
> It's possible in the future that this constraint will not hold.
> 
> Signed-off-by: Ben Widawsky 
> Signed-off-by: Jonathan Cameron 
> Reviewed-by: Alex Bennée 
> Reviewed-by: Adam Manzanares 

FYI on a bug, in case anyone else hits it.

> +static void hdm_init_common(uint32_t *reg_state, uint32_t *write_msk)
> +{
> +int decoder_count = 1;
> +int i;
> +
> +ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, DECODER_COUNT,
> + cxl_decoder_count_enc(decoder_count));
> +ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, TARGET_COUNT, 1);
> +ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_256B, 
> 1);
> +ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_4K, 
> 1);
> +ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, 
> POISON_ON_ERR_CAP, 0);
> +ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_GLOBAL_CONTROL,
> + HDM_DECODER_ENABLE, 0);
> +write_msk[R_CXL_HDM_DECODER_GLOBAL_CONTROL] = 0x3;
> +for (i = 0; i < decoder_count; i++) {
> +write_msk[R_CXL_HDM_DECODER0_BASE_LO + i * 0x20] = 0xf000;
> +write_msk[R_CXL_HDM_DECODER0_BASE_HI + i * 0x20] = 0x;
> +write_msk[R_CXL_HDM_DECODER0_SIZE_LO + i * 0x20] = 0xf000;
> +write_msk[R_CXL_HDM_DECODER0_SIZE_HI + i * 0x20] = 0x;
> +write_msk[R_CXL_HDM_DECODER0_CTRL + i * 0x20] = 0x13ff;

For some unknown reason I missed write masks for the target lists in here.
It was hidden from superficial testing by a bug in the kernel code I was using
that mean these were mostly written to 0.

I'll send a fix out tomorrow (just adds 0x masks for each of the
target registers).

Given issues I'm seeing in testing around HDM decoder programming I'll look
to follow that up with a patch adding some more rigorous checking of the
values on commit.

Jonathan



Re: [PATCH 4/4] hw/ide/piix: Ignore writes of hardwired PCI command register bits

2022-05-30 Thread Michael S. Tsirkin
On Mon, May 30, 2022 at 03:33:18PM +0200, Philippe Mathieu-Daudé wrote:
> On 28/5/22 22:47, Lev Kujawski wrote:
> > One method to enable PCI bus mastering for IDE controllers, often used
> > by x86 firmware, is to write 0x7 to the PCI command register.  Neither
> > the PIIX3 specification nor actual hardware (a Tyan S1686D system)
> > permit modification of the Memory Space Enable (MSE) bit, 1, and thus
> > the command register would be left in an unspecified state without
> > this patch.
> > 
> > Signed-off-by: Lev Kujawski 
> > ---
> >   hw/ide/piix.c | 25 +
> >   1 file changed, 25 insertions(+)
> > 
> > diff --git a/hw/ide/piix.c b/hw/ide/piix.c
> > index 76ea8fd9f6..f1d1168ecd 100644
> > --- a/hw/ide/piix.c
> > +++ b/hw/ide/piix.c
> > @@ -25,6 +25,8 @@
> >* References:
> >*  [1] 82371FB (PIIX) AND 82371SB (PIIX3) PCI ISA IDE XCELERATOR,
> >*  290550-002, Intel Corporation, April 1997.
> > + *  [2] 82371AB PCI-TO-ISA / IDE XCELERATOR (PIIX4), 290562-001,
> > + *  Intel Corporation, April 1997.
> >*/
> >   #include "qemu/osdep.h"
> > @@ -32,6 +34,7 @@
> >   #include "migration/vmstate.h"
> >   #include "qapi/error.h"
> >   #include "qemu/module.h"
> > +#include "qemu/range.h"
> >   #include "sysemu/block-backend.h"
> >   #include "sysemu/blockdev.h"
> >   #include "sysemu/dma.h"
> > @@ -220,6 +223,26 @@ static void pci_piix_ide_exitfn(PCIDevice *dev)
> >   }
> >   }
> > +static void piix_pci_config_write(PCIDevice *d, uint32_t addr,
> > +  uint32_t val, int l)
> > +{
> > +/*
> > + * Mask all IDE PCI command register bits except for Bus Master
> > + * Function Enable (bit 2) and I/O Space Enable (bit 1), as the
> > + * remainder are hardwired to 0 [1, p.48] [2, p.89-90].
> > + *
> > + * NOTE: According to the PIIX3 datasheet [1], the Memory Space
> > + * Enable (MSE bit) is hardwired to 1, but this is contradicted by
> > + * actual PIIX3 hardware, the datasheet itself (viz., Default
> > + * Value: h), and the PIIX4 datasheet [2].
> > + */
> > +if (range_covers_byte(addr, l, PCI_COMMAND)) {
> > +val &= ~(0xfffa << ((PCI_COMMAND - addr) << 3));
> 
> Watch out, len can be 1/2/4.


If there are bits hardwired to 0 the right way to do it is
by clearing a bit in wmask. Might need machine compat machinery
for this.

> > +}
> > +
> > +pci_default_write_config(d, addr, val, l);
> > +}
> > +
> >   /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
> >   static void piix3_ide_class_init(ObjectClass *klass, void *data)
> >   {
> > @@ -232,6 +255,7 @@ static void piix3_ide_class_init(ObjectClass *klass, 
> > void *data)
> >   k->vendor_id = PCI_VENDOR_ID_INTEL;
> >   k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1;
> >   k->class_id = PCI_CLASS_STORAGE_IDE;
> > +k->config_write = piix_pci_config_write;
> >   set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> >   dc->hotpluggable = false;
> >   }
> > @@ -260,6 +284,7 @@ static void piix4_ide_class_init(ObjectClass *klass, 
> > void *data)
> >   k->vendor_id = PCI_VENDOR_ID_INTEL;
> >   k->device_id = PCI_DEVICE_ID_INTEL_82371AB;
> >   k->class_id = PCI_CLASS_STORAGE_IDE;
> > +k->config_write = piix_pci_config_write;
> >   set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> >   dc->hotpluggable = false;
> >   }




[PATCH v2 07/11] vfio/migration: Implement VFIO migration protocol v2

2022-05-30 Thread Avihai Horon
Add implementation of VFIO migration protocol v2. The two protocols, v1
and v2, will co-exist and in next patch v1 protocol will be removed.

There are several main differences between v1 and v2 protocols:
- VFIO device state is now represented as a finite state machine instead
  of a bitmap.

- Migration interface with kernel is now done using VFIO_DEVICE_FEATURE
  ioctl and normal read() and write() instead of the migration region.

- VFIO migration protocol v2 currently doesn't support the pre-copy
  phase of migration.

Detailed information about VFIO migration protocol v2 and difference
compared to v1 can be found here [1].

[1]
https://lore.kernel.org/all/20220224142024.147653-10-yish...@nvidia.com/

Signed-off-by: Avihai Horon 
---
 hw/vfio/common.c  |  19 +-
 hw/vfio/migration.c   | 365 ++
 hw/vfio/trace-events  |   2 +
 include/hw/vfio/vfio-common.h |   5 +
 4 files changed, 354 insertions(+), 37 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index a3dd8221ed..5541133ec9 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -355,10 +355,18 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer 
*container)
 return false;
 }
 
-if ((vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF) &&
+if (!migration->v2 &&
+(vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF) &&
 (migration->device_state_v1 & VFIO_DEVICE_STATE_V1_RUNNING)) {
 return false;
 }
+
+if (migration->v2 &&
+(vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF) &&
+(migration->device_state == VFIO_DEVICE_STATE_RUNNING ||
+ migration->device_state == VFIO_DEVICE_STATE_RUNNING_P2P)) {
+return false;
+}
 }
 }
 return true;
@@ -385,7 +393,14 @@ static bool 
vfio_devices_all_running_and_mig_active(VFIOContainer *container)
 return false;
 }
 
-if (migration->device_state_v1 & VFIO_DEVICE_STATE_V1_RUNNING) {
+if (!migration->v2 &&
+migration->device_state_v1 & VFIO_DEVICE_STATE_V1_RUNNING) {
+continue;
+}
+
+if (migration->v2 &&
+(migration->device_state == VFIO_DEVICE_STATE_RUNNING ||
+ migration->device_state == VFIO_DEVICE_STATE_RUNNING_P2P)) {
 continue;
 } else {
 return false;
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index e40aa0ad80..de68eadb09 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -44,8 +44,83 @@
 #define VFIO_MIG_FLAG_DEV_SETUP_STATE   (0xef13ULL)
 #define VFIO_MIG_FLAG_DEV_DATA_STATE(0xef14ULL)
 
+#define VFIO_MIG_DATA_BUFFER_SIZE (1024 * 1024)
+
 static int64_t bytes_transferred;
 
+static const char *mig_state_to_str(enum vfio_device_mig_state state)
+{
+switch (state) {
+case VFIO_DEVICE_STATE_ERROR:
+return "ERROR";
+case VFIO_DEVICE_STATE_STOP:
+return "STOP";
+case VFIO_DEVICE_STATE_RUNNING:
+return "RUNNING";
+case VFIO_DEVICE_STATE_STOP_COPY:
+return "STOP_COPY";
+case VFIO_DEVICE_STATE_RESUMING:
+return "RESUMING";
+case VFIO_DEVICE_STATE_RUNNING_P2P:
+return "RUNNING_P2P";
+default:
+return "UNKNOWN STATE";
+}
+}
+
+static int vfio_migration_set_state(VFIODevice *vbasedev,
+enum vfio_device_mig_state new_state,
+enum vfio_device_mig_state recover_state)
+{
+VFIOMigration *migration = vbasedev->migration;
+uint64_t buf[DIV_ROUND_UP(sizeof(struct vfio_device_feature) +
+  sizeof(struct vfio_device_feature_mig_state),
+  sizeof(uint64_t))] = {};
+struct vfio_device_feature *feature = (void *)buf;
+struct vfio_device_feature_mig_state *mig_state = (void *)feature->data;
+int ret;
+
+feature->argsz = sizeof(buf);
+feature->flags =
+VFIO_DEVICE_FEATURE_SET | VFIO_DEVICE_FEATURE_MIG_DEVICE_STATE;
+mig_state->device_state = new_state;
+ret = ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature);
+if (ret) {
+/* Try to put the device in some good state */
+mig_state->device_state = recover_state;
+if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) {
+hw_error("%s: Device in error state, can't recover",
+ vbasedev->name);
+}
+
+error_report("%s: Failed changing device state to %s", vbasedev->name,
+ mig_state_to_str(new_state));
+migration->device_state = recover_state;
+
+return -1;
+}
+
+if (mig_state->data_fd != -1) {
+if (migration->data_fd != -1) {
+/*
+ * 

Re: [RFC PATCH 11/17] hw/sd: Add eMMC support

2022-05-30 Thread Philippe Mathieu-Daudé via

Hi Cédric,

On 18/3/22 14:28, Cédric Le Goater wrote:

The initial eMMC support from Vincent Palatin was largely reworked to
match the current SD framework. The parameters mimick a real 4GB eMMC,
but it can be set to various sizes.

This adds a new QOM object class for EMMC devices.

Signed-off-by: Vincent Palatin 
Link: 
https://lore.kernel.org/r/1311635951-11047-5-git-send-email-vpala...@chromium.org
[ jms: - Forward ported to QEMU 5.2 ]
Signed-off-by: Joel Stanley 
[ clg: - ported on aspeed-7.0 patchset
- HPI activation ]
Signed-off-by: Cédric Le Goater 
---
  hw/sd/sdmmc-internal.h |  97 +++
  include/hw/sd/sd.h |   9 ++
  hw/sd/sd.c | 205 -
  hw/sd/sdmmc-internal.c |   2 +-
  4 files changed, 311 insertions(+), 2 deletions(-)



+static const SDProto sd_proto_emmc = {


What about renaming as:

... emmc_proto = {


+.name = "eMMC",
+.cmd = {
+[0] = sd_cmd_GO_IDLE_STATE,
+[1] = sd_emmc_cmd_SEND_OP_CMD,


   = emmc_cmd_SEND_OP_CMD,


+[2] = sd_emmc_cmd_ALL_SEND_CID,


 ...

?


+[3] = sd_emmc_cmd_SEND_RELATIVE_ADDR,
+[5] = sd_cmd_illegal,
+[8] = sd_emmc_cmd_SEND_EXT_CSD,
+[19]= sd_cmd_SEND_TUNING_BLOCK,
+[21]= sd_emmc_cmd_SEND_TUNING_BLOCK,
+[41]= sd_cmd_illegal,
+[52 ... 54] = sd_cmd_illegal,
+[55]= sd_emmc_cmd_APP_CMD,
+[58]= sd_cmd_illegal,
+[59]= sd_cmd_illegal,
+},
+};




[PATCH v2 05/11] vfio/migration: Move migration v1 logic to vfio_migration_init()

2022-05-30 Thread Avihai Horon
Move vfio_dev_get_region_info() logic from vfio_migration_probe() to
vfio_migration_init(). This logic is specific to v1 protocol and moving
it will make it easier to add the v2 protocol implementation later.
No functional changes intended.

Signed-off-by: Avihai Horon 
---
 hw/vfio/migration.c  | 30 +++---
 hw/vfio/trace-events |  2 +-
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index d8f9b086c2..8a0deed0e4 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -789,14 +789,14 @@ static void vfio_migration_exit(VFIODevice *vbasedev)
 vbasedev->migration = NULL;
 }
 
-static int vfio_migration_init(VFIODevice *vbasedev,
-   struct vfio_region_info *info)
+static int vfio_migration_init(VFIODevice *vbasedev)
 {
 int ret;
 Object *obj;
 VFIOMigration *migration;
 char id[256] = "";
 g_autofree char *path = NULL, *oid = NULL;
+struct vfio_region_info *info = NULL;
 
 if (!vbasedev->ops->vfio_get_object) {
 return -EINVAL;
@@ -807,6 +807,14 @@ static int vfio_migration_init(VFIODevice *vbasedev,
 return -EINVAL;
 }
 
+ret = vfio_get_dev_region_info(vbasedev,
+   VFIO_REGION_TYPE_MIGRATION_DEPRECATED,
+   VFIO_REGION_SUBTYPE_MIGRATION_DEPRECATED,
+   );
+if (ret) {
+return ret;
+}
+
 vbasedev->migration = g_new0(VFIOMigration, 1);
 
 ret = vfio_region_setup(obj, vbasedev, >migration->region,
@@ -824,6 +832,8 @@ static int vfio_migration_init(VFIODevice *vbasedev,
 goto err;
 }
 
+g_free(info);
+
 migration = vbasedev->migration;
 migration->vbasedev = vbasedev;
 
@@ -846,6 +856,7 @@ static int vfio_migration_init(VFIODevice *vbasedev,
 return 0;
 
 err:
+g_free(info);
 vfio_migration_exit(vbasedev);
 return ret;
 }
@@ -860,7 +871,6 @@ int64_t vfio_mig_bytes_transferred(void)
 int vfio_migration_probe(VFIODevice *vbasedev, Error **errp)
 {
 VFIOContainer *container = vbasedev->group->container;
-struct vfio_region_info *info = NULL;
 int ret = -ENOTSUP;
 
 if (!vbasedev->enable_migration) {
@@ -874,27 +884,17 @@ int vfio_migration_probe(VFIODevice *vbasedev, Error 
**errp)
 migrate_get_current()->skip_precopy = true;
 }
 
-ret = vfio_get_dev_region_info(vbasedev,
-   VFIO_REGION_TYPE_MIGRATION_DEPRECATED,
-   VFIO_REGION_SUBTYPE_MIGRATION_DEPRECATED,
-   );
+ret = vfio_migration_init(vbasedev);
 if (ret) {
 goto add_blocker;
 }
 
-ret = vfio_migration_init(vbasedev, info);
-if (ret) {
-goto add_blocker;
-}
-
-trace_vfio_migration_probe(vbasedev->name, info->index);
-g_free(info);
+trace_vfio_migration_probe(vbasedev->name);
 return 0;
 
 add_blocker:
 error_setg(>migration_blocker,
"VFIO device doesn't support migration");
-g_free(info);
 
 ret = migrate_add_blocker(vbasedev->migration_blocker, errp);
 if (ret < 0) {
diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index 582882db91..438402b619 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -148,7 +148,7 @@ vfio_display_edid_update(uint32_t prefx, uint32_t prefy) 
"%ux%u"
 vfio_display_edid_write_error(void) ""
 
 # migration.c
-vfio_migration_probe(const char *name, uint32_t index) " (%s) Region %d"
+vfio_migration_probe(const char *name) " (%s)"
 vfio_migration_set_state(const char *name, uint32_t state) " (%s) state %d"
 vfio_vmstate_change(const char *name, int running, const char *reason, 
uint32_t dev_state) " (%s) running %d reason %s device state %d"
 vfio_migration_state_notifier(const char *name, const char *state) " (%s) 
state %s"
-- 
2.21.3




[PATCH v2 03/11] migration/qemu-file: Add qemu_file_get_to_fd()

2022-05-30 Thread Avihai Horon
Add new function qemu_file_get_to_fd() that allows reading data from
QEMUFile and writing it straight into a given fd.

This will be used later in VFIO migration code.

Signed-off-by: Avihai Horon 
---
 migration/qemu-file.c | 34 ++
 migration/qemu-file.h |  1 +
 2 files changed, 35 insertions(+)

diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index 1479cddad9..cad3d32eb3 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -867,3 +867,37 @@ QIOChannel *qemu_file_get_ioc(QEMUFile *file)
 {
 return file->has_ioc ? QIO_CHANNEL(file->opaque) : NULL;
 }
+
+/*
+ * Read size bytes from QEMUFile f and write them to fd.
+ */
+int qemu_file_get_to_fd(QEMUFile *f, int fd, size_t size)
+{
+while (size) {
+size_t pending = f->buf_size - f->buf_index;
+ssize_t rc;
+
+if (!pending) {
+rc = qemu_fill_buffer(f);
+if (rc < 0) {
+return rc;
+}
+if (rc == 0) {
+return -1;
+}
+continue;
+}
+
+rc = write(fd, f->buf + f->buf_index, MIN(pending, size));
+if (rc < 0) {
+return rc;
+}
+if (rc == 0) {
+return -1;
+}
+f->buf_index += rc;
+size -= rc;
+}
+
+return 0;
+}
diff --git a/migration/qemu-file.h b/migration/qemu-file.h
index 3f36d4dc8c..dd26037450 100644
--- a/migration/qemu-file.h
+++ b/migration/qemu-file.h
@@ -162,6 +162,7 @@ int qemu_file_shutdown(QEMUFile *f);
 QEMUFile *qemu_file_get_return_path(QEMUFile *f);
 void qemu_fflush(QEMUFile *f);
 void qemu_file_set_blocking(QEMUFile *f, bool block);
+int qemu_file_get_to_fd(QEMUFile *f, int fd, size_t size);
 
 void ram_control_before_iterate(QEMUFile *f, uint64_t flags);
 void ram_control_after_iterate(QEMUFile *f, uint64_t flags);
-- 
2.21.3




[PULL 097/117] target/arm: Move null function and sve check into do_frint_mode

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-95-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 52 +-
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 2a5fbec2d6d..43cfd2818ea 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -4140,62 +4140,56 @@ TRANS_FEAT(FRINTX, aa64_sve, gen_gvec_fpst_arg_zpz, 
frintx_fns[a->esz],
 static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a,
   int mode, gen_helper_gvec_3_ptr *fn)
 {
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_i32 tmode = tcg_const_i32(mode);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
+unsigned vsz;
+TCGv_i32 tmode;
+TCGv_ptr status;
 
-gen_helper_set_rmode(tmode, tmode, status);
-
-tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   pred_full_reg_offset(s, a->pg),
-   status, vsz, vsz, 0, fn);
-
-gen_helper_set_rmode(tmode, tmode, status);
-tcg_temp_free_i32(tmode);
-tcg_temp_free_ptr(status);
+if (fn == NULL) {
+return false;
 }
+if (!sve_access_check(s)) {
+return true;
+}
+
+vsz = vec_full_reg_size(s);
+tmode = tcg_const_i32(mode);
+status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
+
+gen_helper_set_rmode(tmode, tmode, status);
+
+tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
+   vec_full_reg_offset(s, a->rn),
+   pred_full_reg_offset(s, a->pg),
+   status, vsz, vsz, 0, fn);
+
+gen_helper_set_rmode(tmode, tmode, status);
+tcg_temp_free_i32(tmode);
+tcg_temp_free_ptr(status);
 return true;
 }
 
 static bool trans_FRINTN(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_nearest_even, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTP(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_up, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTM(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_down, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTZ(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_to_zero, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_ties_away, frint_fns[a->esz]);
 }
 
-- 
2.25.1




Re: [PATCH v2 02/11] vfio/migration: Skip pre-copy if dirty page tracking is not supported

2022-05-30 Thread Avihai Horon



On 5/30/2022 8:07 PM, Avihai Horon wrote:

Currently, if IOMMU of a VFIO container doesn't support dirty page
tracking, migration is blocked completely. This is because a DMA-able
VFIO device can dirty RAM pages without updating QEMU about it, thus
breaking the migration.

However, this doesn't mean that migration can't be done at all. If
migration pre-copy phase is skipped, the VFIO device doesn't have a
chance to dirty RAM pages that have been migrated already, thus
eliminating the problem previously mentioned.

Hence, in such case allow migration but skip pre-copy phase.

Signed-off-by: Avihai Horon 
---
  hw/vfio/migration.c   | 9 -
  migration/migration.c | 5 +
  migration/migration.h | 3 +++
  3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 34f9f894ed..d8f9b086c2 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -863,10 +863,17 @@ int vfio_migration_probe(VFIODevice *vbasedev, Error 
**errp)
  struct vfio_region_info *info = NULL;
  int ret = -ENOTSUP;
  
-if (!vbasedev->enable_migration || !container->dirty_pages_supported) {

+if (!vbasedev->enable_migration) {
  goto add_blocker;
  }
  
+if (!container->dirty_pages_supported) {

+warn_report_once(
+"%s: IOMMU of the device's VFIO container doesn't support dirty page 
tracking, migration pre-copy phase will be skipped",
+vbasedev->name);
+migrate_get_current()->skip_precopy = true;
+}
+
  ret = vfio_get_dev_region_info(vbasedev,
 VFIO_REGION_TYPE_MIGRATION_DEPRECATED,
 VFIO_REGION_SUBTYPE_MIGRATION_DEPRECATED,
diff --git a/migration/migration.c b/migration/migration.c
index 31739b2af9..217f0e3e94 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -3636,6 +3636,11 @@ static MigIterateState 
migration_iteration_run(MigrationState *s)
  uint64_t pending_size, pend_pre, pend_compat, pend_post;
  bool in_postcopy = s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE;
  
+if (s->skip_precopy) {

+migration_completion(s);
+return MIG_ITERATE_BREAK;
+}
+
  qemu_savevm_state_pending(s->to_dst_file, s->threshold_size, _pre,
_compat, _post);
  pending_size = pend_pre + pend_compat + pend_post;
diff --git a/migration/migration.h b/migration/migration.h
index 485d58b95f..0920a0950e 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -332,6 +332,9 @@ struct MigrationState {
   * This save hostname when out-going migration starts
   */
  char *hostname;
+
+/* Whether to skip pre-copy phase of migration or not */
+bool skip_precopy;
  };
  
  void migrate_set_state(int *state, int old_state, int new_state);


This patch still has the problem that it doesn't respect configured 
downtime limit.


Maybe adding an option to set "no downtime limit" will solve it?
Then we can allow migration with VFIO device that doesn't support dirty 
tracking only if this option is set.
Can we use migration param downtime_limit with value 0 to mark "no 
downtime limit"? Does it make sense?


Do you have other ideas how to solve this issue?

Thanks!




[PULL 089/117] target/arm: Use TRANS_FEAT for DO_FP3

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-87-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 61bf5f57578..d596e7a0277 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3799,14 +3799,11 @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz 
*a)
  */
 
 #define DO_FP3(NAME, name) \
-static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a)   \
-{   \
-static gen_helper_gvec_3_ptr * const fns[4] = { \
+static gen_helper_gvec_3_ptr * const name##_fns[4] = {  \
 NULL, gen_helper_gvec_##name##_h,   \
 gen_helper_gvec_##name##_s, gen_helper_gvec_##name##_d  \
 };  \
-return gen_gvec_fpst_arg_zzz(s, fns[a->esz], a, 0); \
-}
+TRANS_FEAT(NAME, aa64_sve, gen_gvec_fpst_arg_zzz, name##_fns[a->esz], a, 0)
 
 DO_FP3(FADD_zzz, fadd)
 DO_FP3(FSUB_zzz, fsub)
-- 
2.25.1




Re: [RFC PATCH 07/17] hw/sd: Add sd_cmd_SEND_OP_CMD() handler

2022-05-30 Thread Philippe Mathieu-Daudé via

On 10/5/22 08:57, Cédric Le Goater wrote:

On 5/9/22 23:12, Philippe Mathieu-Daudé wrote:

On 18/3/22 14:28, Cédric Le Goater wrote:

From: Philippe Mathieu-Daudé 

Signed-off-by: Philippe Mathieu-Daudé 
Message-Id: <20210624142209.1193073-9-f4...@amsat.org>
Signed-off-by: Cédric Le Goater 
---
  hw/sd/sd.c | 18 +-
  1 file changed, 9 insertions(+), 9 deletions(-)



@@ -2111,6 +2109,7 @@ static const SDProto sd_proto_spi = {
  .name = "SPI",
  .cmd = {
  [0] = sd_cmd_GO_IDLE_STATE,
+    [1] = sd_cmd_SEND_OP_CMD,
  [2 ... 4]   = sd_cmd_illegal,
  [5] = sd_cmd_illegal,
  [7] = sd_cmd_illegal,
@@ -2120,6 +2119,7 @@ static const SDProto sd_proto_spi = {
  },
  .cmd = {
  [6] = sd_cmd_unimplemented,
+    [41]    = sd_cmd_SEND_OP_CMD,
  },
  };


I missed adding the cmd_abbrev[1] entry.


Will you resend ?


Yes.



[PATCH v2 11/11] docs/devel: Align vfio-migration docs to VFIO migration v2

2022-05-30 Thread Avihai Horon
Align the vfio-migration documentation to VFIO migration protocol v2.

Signed-off-by: Avihai Horon 
---
 docs/devel/vfio-migration.rst | 77 +++
 1 file changed, 33 insertions(+), 44 deletions(-)

diff --git a/docs/devel/vfio-migration.rst b/docs/devel/vfio-migration.rst
index 9ff6163c88..09744af5a6 100644
--- a/docs/devel/vfio-migration.rst
+++ b/docs/devel/vfio-migration.rst
@@ -7,46 +7,35 @@ the guest is running on source host and restoring this saved 
state on the
 destination host. This document details how saving and restoring of VFIO
 devices is done in QEMU.
 
-Migration of VFIO devices consists of two phases: the optional pre-copy phase,
-and the stop-and-copy phase. The pre-copy phase is iterative and allows to
-accommodate VFIO devices that have a large amount of data that needs to be
-transferred. The iterative pre-copy phase of migration allows for the guest to
-continue whilst the VFIO device state is transferred to the destination, this
-helps to reduce the total downtime of the VM. VFIO devices can choose to skip
-the pre-copy phase of migration by returning pending_bytes as zero during the
-pre-copy phase.
+Migration of VFIO devices currently consists of a single stop-and-copy phase.
+During the stop-and-copy phase the guest is stopped and the entire VFIO device
+data is transferred to the destination.
+
+The pre-copy phase of migration is currently not supported for VFIO devices,
+so VFIO device data is not transferred during pre-copy phase.
 
 A detailed description of the UAPI for VFIO device migration can be found in
-the comment for the ``vfio_device_migration_info`` structure in the header
-file linux-headers/linux/vfio.h.
+the comment for the ``vfio_device_mig_state`` structure in the header file
+linux-headers/linux/vfio.h.
 
 VFIO implements the device hooks for the iterative approach as follows:
 
-* A ``save_setup`` function that sets up the migration region and sets _SAVING
-  flag in the VFIO device state.
-
-* A ``load_setup`` function that sets up the migration region on the
-  destination and sets _RESUMING flag in the VFIO device state.
-
-* A ``save_live_pending`` function that reads pending_bytes from the vendor
-  driver, which indicates the amount of data that the vendor driver has yet to
-  save for the VFIO device.
+* A ``save_setup`` function that sets up migration on the source.
 
-* A ``save_live_iterate`` function that reads the VFIO device's data from the
-  vendor driver through the migration region during iterative phase.
+* A ``load_setup`` function that sets the VFIO device on the destination in
+  _RESUMING state.
 
 * A ``save_state`` function to save the device config space if it is present.
 
-* A ``save_live_complete_precopy`` function that resets _RUNNING flag from the
-  VFIO device state and iteratively copies the remaining data for the VFIO
-  device until the vendor driver indicates that no data remains (pending bytes
-  is zero).
+* A ``save_live_complete_precopy`` function that sets the VFIO device in
+  _STOP_COPY state and iteratively copies the data for the VFIO device until
+  the vendor driver indicates that no data remains.
 
 * A ``load_state`` function that loads the config section and the data
-  sections that are generated by the save functions above
+  sections that are generated by the save functions above.
 
 * ``cleanup`` functions for both save and load that perform any migration
-  related cleanup, including unmapping the migration region
+  related cleanup.
 
 
 The VFIO migration code uses a VM state change handler to change the VFIO
@@ -71,13 +60,13 @@ tracking can identify dirtied pages, but any page pinned by 
the vendor driver
 can also be written by the device. There is currently no device or IOMMU
 support for dirty page tracking in hardware.
 
-By default, dirty pages are tracked when the device is in pre-copy as well as
-stop-and-copy phase. So, a page pinned by the vendor driver will be copied to
-the destination in both phases. Copying dirty pages in pre-copy phase helps
-QEMU to predict if it can achieve its downtime tolerances. If QEMU during
-pre-copy phase keeps finding dirty pages continuously, then it understands
-that even in stop-and-copy phase, it is likely to find dirty pages and can
-predict the downtime accordingly.
+By default, dirty pages are tracked during pre-copy as well as stop-and-copy
+phase. So, a page pinned by the vendor driver will be copied to the destination
+in both phases. Copying dirty pages in pre-copy phase helps QEMU to predict if
+it can achieve its downtime tolerances. If QEMU during pre-copy phase keeps
+finding dirty pages continuously, then it understands that even in 
stop-and-copy
+phase, it is likely to find dirty pages and can predict the downtime
+accordingly.
 
 QEMU also provides a per device opt-out option ``pre-copy-dirty-page-tracking``
 which disables querying the dirty bitmap during pre-copy phase. If it is set to
@@ -111,23 +100,23 @@ 

[PATCH v2 10/11] vfio: Alphabetize migration section of VFIO trace-events file

2022-05-30 Thread Avihai Horon
Sort the migration section of VFIO trace events file alphabetically
and move two misplaced traces to common.c section.

Signed-off-by: Avihai Horon 
---
 hw/vfio/trace-events | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events
index a24ea7d8b0..d3cba59bfd 100644
--- a/hw/vfio/trace-events
+++ b/hw/vfio/trace-events
@@ -119,6 +119,8 @@ vfio_region_sparse_mmap_header(const char *name, int index, 
int nr_areas) "Devic
 vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) 
"sparse entry %d [0x%lx - 0x%lx]"
 vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t 
subtype) "%s index %d, %08x/%0x8"
 vfio_dma_unmap_overflow_workaround(void) ""
+vfio_get_dirty_bitmap(int fd, uint64_t iova, uint64_t size, uint64_t 
bitmap_size, uint64_t start) "container fd=%d, iova=0x%"PRIx64" size= 
0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64
+vfio_iommu_map_dirty_notify(uint64_t iova_start, uint64_t iova_end) "iommu 
dirty @ 0x%"PRIx64" - 0x%"PRIx64
 
 # platform.c
 vfio_platform_base_device_init(char *name, int groupid) "%s belongs to group 
#%d"
@@ -148,18 +150,16 @@ vfio_display_edid_update(uint32_t prefx, uint32_t prefy) 
"%ux%u"
 vfio_display_edid_write_error(void) ""
 
 # migration.c
+vfio_load_cleanup(const char *name) " (%s)"
+vfio_load_device_config_state(const char *name) " (%s)"
+vfio_load_state(const char *name, uint64_t data) " (%s) data 0x%"PRIx64
+vfio_load_state_device_data(const char *name, uint64_t data_size) " (%s) size 
0x%"PRIx64
 vfio_migration_probe(const char *name) " (%s)"
 vfio_migration_set_state(const char *name, uint32_t state) " (%s) state %d"
-vfio_vmstate_change(const char *name, int running, const char *reason, 
uint32_t dev_state) " (%s) running %d reason %s device state %d"
 vfio_migration_state_notifier(const char *name, const char *state) " (%s) 
state %s"
-vfio_save_setup(const char *name) " (%s)"
+vfio_save_block(const char *name, int data_size) " (%s) data_size %d"
 vfio_save_cleanup(const char *name) " (%s)"
-vfio_save_device_config_state(const char *name) " (%s)"
 vfio_save_complete_precopy(const char *name) " (%s)"
-vfio_load_device_config_state(const char *name) " (%s)"
-vfio_load_state(const char *name, uint64_t data) " (%s) data 0x%"PRIx64
-vfio_load_state_device_data(const char *name, uint64_t data_size) " (%s) size 
0x%"PRIx64
-vfio_load_cleanup(const char *name) " (%s)"
-vfio_get_dirty_bitmap(int fd, uint64_t iova, uint64_t size, uint64_t 
bitmap_size, uint64_t start) "container fd=%d, iova=0x%"PRIx64" size= 
0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64
-vfio_iommu_map_dirty_notify(uint64_t iova_start, uint64_t iova_end) "iommu 
dirty @ 0x%"PRIx64" - 0x%"PRIx64
-vfio_save_block(const char *name, int data_size) " (%s) data_size %d"
+vfio_save_device_config_state(const char *name) " (%s)"
+vfio_save_setup(const char *name) " (%s)"
+vfio_vmstate_change(const char *name, int running, const char *reason, 
uint32_t dev_state) " (%s) running %d reason %s device state %d"
-- 
2.21.3




Re: Help: How do I make a machine with 2 separate ARM SoC's?

2022-05-30 Thread Peter Maydell
On Thu, 26 May 2022 at 23:14, Peter Delevoryas  wrote:
> Hey QEMU developers,
>
> Cedric mentioned here[1] that QEMU can support emulating a
> more complete board, e.g. a machine with an AST2600 *and* an AST1030.

This is true, as long as all the CPUs are the same
architecture family, e.g. all Arm CPUs. (Mixing A- and
R- or A- and M-profile is OK, they just all have to be
available in the same qemu-system-whatever binary.)

> I read through the memory API docs[2] and it mostly makes sense to me,
> but what I don’t understand is, what does system_memory represent?

So, system_memory is something of a legacy from when QEMU was
much older. Before the MemoryRegion and AddressSpace APIs were
added to QEMU, everything that could initiate a memory transaction
(CPUs, DMA-capable devices, etc) always saw the same view of
memory. The functions to do memory accesses just operated on
that view implicitly. (We still have some of them, for instance
cpu_physical_memory_read() and cpu_physical_memory_write().) The
MemoryRegion/AddressSpace APIs are much more flexible and allow
different memory transaction initiators to see different views, as
real hardware does. But for backwards compatibility we still have
the old assumes-one-view APIs. The view those APIs use is the
"system memory". We also have some device models which have been
converted to use an AddressSpace to do their DMA operations, but
which assume they want to use address_space_memory (which is the AS
corresponding to the system_memory MR) instead of taking a
MemoryRegion as a QOM pointer and creating an AddressSpace for it.

In the modern view of the world, you can build up a system with
a set of MemoryRegions. Typically you can start with an empty
container, and the board code fills it with board-level devices,
then passes it to the SoC code, which fills it with SoC devices,
and passes it again to the CPU object, which creates an AddressSpace
so it can initiate transactions into it. By making that initial
"empty container" be the global system_memory MemoryRegion, this
makes the legacy APIs and devices that still use it basically work.

> Or, what should the layout be for a situation like I’m interested in,
> where you have an AST2600 and an AST1030 (and actually, maybe even
> an x86 CPU too? idk if that would be possible).

Cross-architecture heterogenous board models can't be done today:
the qemu-system-foo binaries compile-time build in some assumptions
about specifics of the guest architecture. (This is something it would
be nice to fix, but the amount of work is pretty big and hairy, and
thus far nobody's had a pressing enough need for it to try to tackle it.)

> I need to make sure each SoC runs in a different address space, right?
> But, how do I actually do that? Do I model it as two containers inside
> the large system_memory container, or as two different containers
> that get swapped in for system_memory when executing their associated
> CPU?

The best way to think about QEMU's AddressSpace type is that it is
the interface you use to initiate memory transactions. You create
one from a MemoryRegion. When SoC and board code is building up its
view of the world, what it is really creating and passing around is
a hierarchy of MemoryRegions. It's only when the SoC code hands a
MemoryRegion to a CPU or a DMA-capable device that that device says
"I will need to make transactions to this, let me create the
corresponding AddressSpace".

> I was having trouble figuring out what the Xilinx boards are actually
> doing in this case. Does each CPU share peripherals, or are the
> A + R cpu’s actually in separate address spaces? I’m very confused lol.

xlnx-versal-virt is a virtual board, so ignore that one: it's
probably more confusing than helpful. The xlnx-zcu102 board
uses the xlnx-zynqmp SoC, and that SoC has both R and A profile
CPUs in it, but they both see basically the same view of the
world because they're in the same SoC.

Another device that does some moderately complicated things with
MemoryRegions is the hw/arm/armsse.c SoC, which has several CPUs
and has some per-CPU devices.

I think we have not thus far had a model of a board where different
CPUs see radically different things (only ones where they can see
minor differences), so you'll probably run into places where the
APIs are a bit clunky (and we can perhaps have a go at making
them a bit less so). What I would do is make the system_memory
container be used by whatever is the "main" application processor
SoC in your board. If the two SoCs really see absolutely different
worlds with no shared devices at all, then you'll want to create
a new empty container for the second SoC. If they do have some
board-level shared devices, then you'll want to do something a little
more complicated with aliases.

If you find the SoC device models you're using hardcode use of
system_memory or address_space_memory you should treat those as
bugs to be fixed. Other loose ends (like monitor commands that
assume the 

[PULL 080/117] target/arm: Introduce gen_gvec_{ptr,fpst}_zzzz

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Use these for the several varieties of floating-point
multiply-add instructions.

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-78-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 140 ++---
 1 file changed, 53 insertions(+), 87 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index b8bd1047b0a..a799ce3110a 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -205,6 +205,35 @@ static bool gen_gvec_ool_arg_zzxz(DisasContext *s, 
gen_helper_gvec_4 *fn,
 return gen_gvec_ool_(s, fn, a->rd, a->rn, a->rm, a->ra, a->index);
 }
 
+/* Invoke an out-of-line helper on 4 Zregs, plus a pointer. */
+static bool gen_gvec_ptr_(DisasContext *s, gen_helper_gvec_4_ptr *fn,
+  int rd, int rn, int rm, int ra,
+  int data, TCGv_ptr ptr)
+{
+if (fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   vec_full_reg_offset(s, ra),
+   ptr, vsz, vsz, data, fn);
+}
+return true;
+}
+
+static bool gen_gvec_fpst_(DisasContext *s, gen_helper_gvec_4_ptr *fn,
+   int rd, int rn, int rm, int ra,
+   int data, ARMFPStatusFlavour flavour)
+{
+TCGv_ptr status = fpstatus_ptr(flavour);
+bool ret = gen_gvec_ptr_(s, fn, rd, rn, rm, ra, data, status);
+tcg_temp_free_ptr(status);
+return ret;
+}
+
 /* Invoke an out-of-line helper on 2 Zregs and a predicate. */
 static bool gen_gvec_ool_zzp(DisasContext *s, gen_helper_gvec_3 *fn,
  int rd, int rn, int pg, int data)
@@ -3485,24 +3514,15 @@ DO_SVE2_RRXR_ROT(CDOT_zzxw_d, 
gen_helper_sve2_cdot_idx_d)
 
 static bool do_FMLA_zzxz(DisasContext *s, arg_rrxr_esz *a, bool sub)
 {
-static gen_helper_gvec_4_ptr * const fns[3] = {
+static gen_helper_gvec_4_ptr * const fns[4] = {
+NULL,
 gen_helper_gvec_fmla_idx_h,
 gen_helper_gvec_fmla_idx_s,
 gen_helper_gvec_fmla_idx_d,
 };
-
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vec_full_reg_offset(s, a->ra),
-   status, vsz, vsz, (a->index << 1) | sub,
-   fns[a->esz - 1]);
-tcg_temp_free_ptr(status);
-}
-return true;
+return gen_gvec_fpst_(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra,
+  (a->index << 1) | sub,
+  a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
 }
 
 static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a)
@@ -4040,26 +4060,18 @@ static bool trans_FCMLA_zpzzz(DisasContext *s, 
arg_FCMLA_zpzzz *a)
 
 static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a)
 {
-static gen_helper_gvec_4_ptr * const fns[2] = {
+static gen_helper_gvec_4_ptr * const fns[4] = {
+NULL,
 gen_helper_gvec_fcmlah_idx,
 gen_helper_gvec_fcmlas_idx,
+NULL,
 };
 
-tcg_debug_assert(a->esz == 1 || a->esz == 2);
 tcg_debug_assert(a->rd == a->ra);
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vec_full_reg_offset(s, a->ra),
-   status, vsz, vsz,
-   a->index * 4 + a->rot,
-   fns[a->esz - 1]);
-tcg_temp_free_ptr(status);
-}
-return true;
+
+return gen_gvec_fpst_(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra,
+  a->index * 4 + a->rot,
+  a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
 }
 
 /*
@@ -7327,17 +7339,7 @@ static bool trans_FMMLA(DisasContext *s, arg__esz *a)
 return false;
 }
 
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(FPST_FPCR);
-tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
- 

[PATCH v2 00/11] vfio/migration: Implement VFIO migration protocol v2

2022-05-30 Thread Avihai Horon
Hello,

Following VFIO migration protocol v2 acceptance in kernel, this series
implements VFIO migration according to the new v2 protocol and replaces
the now deprecated v1 implementation.

The main differences between v1 and v2 migration protocols are:
1. VFIO device state is represented as a finite state machine instead of
   a bitmap.

2. The migration interface with kernel is done using VFIO_DEVICE_FEATURE
   ioctl and normal read() and write() instead of the migration region
   used in v1.

3. Migration protocol v2 currently doesn't support the pre-copy phase of
   migration.

Full description of the v2 protocol and the differences from v1 can be
found here [1].

Patches 1-3 are prep patches fixing bugs and adding QEMUFile function
that will be used later.

Patches 4-6 refactor v1 protocol code to make it easier to add v2
protocol.

Patches 7-11 implement v2 protocol and remove v1 protocol.

Thanks.

[1]
https://lore.kernel.org/all/20220224142024.147653-10-yish...@nvidia.com/

Changes from v1: 
https://lore.kernel.org/all/20220512154320.19697-1-avih...@nvidia.com/
- Split the big patch that replaced v1 with v2 into several patches as
  suggested by Joao, to make review easier.
- Change warn_report to warn_report_once when container doesn't support
  dirty tracking.
- Add Reviewed-by tag.

Avihai Horon (11):
  vfio/migration: Fix NULL pointer dereference bug
  vfio/migration: Skip pre-copy if dirty page tracking is not supported
  migration/qemu-file: Add qemu_file_get_to_fd()
  vfio/common: Change vfio_devices_all_running_and_saving() logic to
equivalent one
  vfio/migration: Move migration v1 logic to vfio_migration_init()
  vfio/migration: Rename functions/structs related to v1 protocol
  vfio/migration: Implement VFIO migration protocol v2
  vfio/migration: Remove VFIO migration protocol v1
  vfio/migration: Reset device if setting recover state fails
  vfio: Alphabetize migration section of VFIO trace-events file
  docs/devel: Align vfio-migration docs to VFIO migration v2

 docs/devel/vfio-migration.rst |  77 ++--
 hw/vfio/common.c  |  21 +-
 hw/vfio/migration.c   | 640 --
 hw/vfio/trace-events  |  25 +-
 include/hw/vfio/vfio-common.h |   8 +-
 migration/migration.c |   5 +
 migration/migration.h |   3 +
 migration/qemu-file.c |  34 ++
 migration/qemu-file.h |   1 +
 9 files changed, 252 insertions(+), 562 deletions(-)

-- 
2.21.3




[PULL 076/117] target/arm: Reject copy w/ shifted byte early

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Remove the unparsed extractions in trans_CPY_{m,z}_i which are intended
to reject an 8-bit shift of an 8-bit constant for 8-bit element.

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-74-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/sve.decode  | 10 --
 target/arm/translate-sve.c |  6 --
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index 8cff63cf257..7e79198f5ba 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -528,8 +528,14 @@ DUPM0101 11  dbm:13 rd:5
 FCPY0101 .. 01  110 imm:8 . @rdn_pg4
 
 # SVE copy integer immediate (predicated)
-CPY_m_i 0101 .. 01  01 .  .   @rdn_pg4 imm=%sh8_i8s
-CPY_z_i 0101 .. 01  00 .  .   @rdn_pg4 imm=%sh8_i8s
+{
+  INVALID   0101 00 01  01 1  -
+  CPY_m_i   0101 .. 01  01 .  .   @rdn_pg4 imm=%sh8_i8s
+}
+{
+  INVALID   0101 00 01  00 1  -
+  CPY_z_i   0101 .. 01  00 .  .   @rdn_pg4 imm=%sh8_i8s
+}
 
 ### SVE Permute - Extract Group
 
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index bf988cab3eb..83980f5ee6b 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2024,9 +2024,6 @@ static bool trans_FCPY(DisasContext *s, arg_FCPY *a)
 
 static bool trans_CPY_m_i(DisasContext *s, arg_rpri_esz *a)
 {
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 if (sve_access_check(s)) {
 do_cpy_m(s, a->esz, a->rd, a->rn, a->pg, tcg_constant_i64(a->imm));
 }
@@ -2040,9 +2037,6 @@ static bool trans_CPY_z_i(DisasContext *s, arg_CPY_z_i *a)
 gen_helper_sve_cpy_z_s, gen_helper_sve_cpy_z_d,
 };
 
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 if (sve_access_check(s)) {
 unsigned vsz = vec_full_reg_size(s);
 tcg_gen_gvec_2i_ool(vec_full_reg_offset(s, a->rd),
-- 
2.25.1




[PATCH v2 09/11] vfio/migration: Reset device if setting recover state fails

2022-05-30 Thread Avihai Horon
If vfio_migration_set_state() fails to set the device in the requested
state it tries to put it in a recover state. If setting the device in
the recover state fails as well, hw_error is triggered and the VM is
aborted.

To improve user experience and avoid VM data loss, reset the device with
VFIO_RESET_DEVICE instead of aborting the VM.

Signed-off-by: Avihai Horon 
---
 hw/vfio/migration.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 852759e6ca..6c34502611 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -89,8 +89,16 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 /* Try to put the device in some good state */
 mig_state->device_state = recover_state;
 if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) {
-hw_error("%s: Device in error state, can't recover",
- vbasedev->name);
+if (ioctl(vbasedev->fd, VFIO_DEVICE_RESET)) {
+hw_error("%s: Device in error state, can't recover",
+ vbasedev->name);
+}
+
+error_report(
+"%s: Device was reset due to failure in changing device state 
to recover state %s",
+vbasedev->name, mig_state_to_str(recover_state));
+
+return -1;
 }
 
 error_report("%s: Failed changing device state to %s", vbasedev->name,
-- 
2.21.3




[PATCH v2 06/11] vfio/migration: Rename functions/structs related to v1 protocol

2022-05-30 Thread Avihai Horon
To avoid name collisions, rename functions and structs related to VFIO
migration protocol v1. This will allow the two protocols to co-exist
when v2 protocol is added, until v1 is removed. No functional changes
intended.

Signed-off-by: Avihai Horon 
---
 hw/vfio/common.c  |  6 +--
 hw/vfio/migration.c   | 82 +--
 hw/vfio/trace-events  |  2 +-
 include/hw/vfio/vfio-common.h |  2 +-
 4 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index bbc6d375de..a3dd8221ed 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -355,8 +355,8 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer 
*container)
 return false;
 }
 
-if ((vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF)
-&& (migration->device_state & VFIO_DEVICE_STATE_V1_RUNNING)) {
+if ((vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF) &&
+(migration->device_state_v1 & VFIO_DEVICE_STATE_V1_RUNNING)) {
 return false;
 }
 }
@@ -385,7 +385,7 @@ static bool 
vfio_devices_all_running_and_mig_active(VFIOContainer *container)
 return false;
 }
 
-if (migration->device_state & VFIO_DEVICE_STATE_V1_RUNNING) {
+if (migration->device_state_v1 & VFIO_DEVICE_STATE_V1_RUNNING) {
 continue;
 } else {
 return false;
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 8a0deed0e4..e40aa0ad80 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -107,8 +107,8 @@ static int vfio_mig_rw(VFIODevice *vbasedev, __u8 *buf, 
size_t count,
  * an error is returned.
  */
 
-static int vfio_migration_set_state(VFIODevice *vbasedev, uint32_t mask,
-uint32_t value)
+static int vfio_migration_v1_set_state(VFIODevice *vbasedev, uint32_t mask,
+   uint32_t value)
 {
 VFIOMigration *migration = vbasedev->migration;
 VFIORegion *region = >region;
@@ -145,7 +145,7 @@ static int vfio_migration_set_state(VFIODevice *vbasedev, 
uint32_t mask,
 return ret;
 }
 
-migration->device_state = device_state;
+migration->device_state_v1 = device_state;
 trace_vfio_migration_set_state(vbasedev->name, device_state);
 return 0;
 }
@@ -260,8 +260,8 @@ static int vfio_save_buffer(QEMUFile *f, VFIODevice 
*vbasedev, uint64_t *size)
 return ret;
 }
 
-static int vfio_load_buffer(QEMUFile *f, VFIODevice *vbasedev,
-uint64_t data_size)
+static int vfio_v1_load_buffer(QEMUFile *f, VFIODevice *vbasedev,
+   uint64_t data_size)
 {
 VFIORegion *region = >migration->region;
 uint64_t data_offset = 0, size, report_size;
@@ -288,7 +288,7 @@ static int vfio_load_buffer(QEMUFile *f, VFIODevice 
*vbasedev,
 data_size = 0;
 }
 
-trace_vfio_load_state_device_data(vbasedev->name, data_offset, size);
+trace_vfio_v1_load_state_device_data(vbasedev->name, data_offset, 
size);
 
 while (size) {
 void *buf;
@@ -394,7 +394,7 @@ static int vfio_load_device_config_state(QEMUFile *f, void 
*opaque)
 return qemu_file_get_error(f);
 }
 
-static void vfio_migration_cleanup(VFIODevice *vbasedev)
+static void vfio_migration_v1_cleanup(VFIODevice *vbasedev)
 {
 VFIOMigration *migration = vbasedev->migration;
 
@@ -405,7 +405,7 @@ static void vfio_migration_cleanup(VFIODevice *vbasedev)
 
 /* -- */
 
-static int vfio_save_setup(QEMUFile *f, void *opaque)
+static int vfio_v1_save_setup(QEMUFile *f, void *opaque)
 {
 VFIODevice *vbasedev = opaque;
 VFIOMigration *migration = vbasedev->migration;
@@ -431,8 +431,8 @@ static int vfio_save_setup(QEMUFile *f, void *opaque)
 }
 }
 
-ret = vfio_migration_set_state(vbasedev, VFIO_DEVICE_STATE_MASK,
-   VFIO_DEVICE_STATE_V1_SAVING);
+ret = vfio_migration_v1_set_state(vbasedev, VFIO_DEVICE_STATE_MASK,
+  VFIO_DEVICE_STATE_V1_SAVING);
 if (ret) {
 error_report("%s: Failed to set state SAVING", vbasedev->name);
 return ret;
@@ -448,11 +448,11 @@ static int vfio_save_setup(QEMUFile *f, void *opaque)
 return 0;
 }
 
-static void vfio_save_cleanup(void *opaque)
+static void vfio_v1_save_cleanup(void *opaque)
 {
 VFIODevice *vbasedev = opaque;
 
-vfio_migration_cleanup(vbasedev);
+vfio_migration_v1_cleanup(vbasedev);
 trace_vfio_save_cleanup(vbasedev->name);
 }
 
@@ -524,15 +524,15 @@ static int vfio_save_iterate(QEMUFile *f, void *opaque)
 return 0;
 }
 
-static int vfio_save_complete_precopy(QEMUFile *f, void *opaque)
+static int vfio_v1_save_complete_precopy(QEMUFile *f, void *opaque)
 {
 VFIODevice 

[PULL 075/117] target/arm: Reject add/sub w/ shifted byte early

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Remove the unparsed extractions in trans_ADD_zzi, trans_SUBR_zzi,
and do_zzi_sat which are intended to reject an 8-bit shift of an
8-bit constant for 8-bit element.

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-73-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/sve.decode  | 35 ---
 target/arm/translate-sve.c |  9 -
 2 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index c02da0a0829..8cff63cf257 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -793,13 +793,34 @@ FDUP00100101 esz:2 111 00 1110 imm:8 rd:5
 }
 
 # SVE integer add/subtract immediate (unpredicated)
-ADD_zzi 00100101 .. 100 000 11 .  . @rdn_sh_i8u
-SUB_zzi 00100101 .. 100 001 11 .  . @rdn_sh_i8u
-SUBR_zzi00100101 .. 100 011 11 .  . @rdn_sh_i8u
-SQADD_zzi   00100101 .. 100 100 11 .  . @rdn_sh_i8u
-UQADD_zzi   00100101 .. 100 101 11 .  . @rdn_sh_i8u
-SQSUB_zzi   00100101 .. 100 110 11 .  . @rdn_sh_i8u
-UQSUB_zzi   00100101 .. 100 111 11 .  . @rdn_sh_i8u
+{
+  INVALID   00100101 00 100 000 11 1  -
+  ADD_zzi   00100101 .. 100 000 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 001 11 1  -
+  SUB_zzi   00100101 .. 100 001 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 011 11 1  -
+  SUBR_zzi  00100101 .. 100 011 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 100 11 1  -
+  SQADD_zzi 00100101 .. 100 100 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 101 11 1  -
+  UQADD_zzi 00100101 .. 100 101 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 110 11 1  -
+  SQSUB_zzi 00100101 .. 100 110 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 111 11 1  -
+  UQSUB_zzi 00100101 .. 100 111 11 .  . @rdn_sh_i8u
+}
 
 # SVE integer min/max immediate (unpredicated)
 SMAX_zzi00100101 .. 101 000 110  .  @rdn_i8s
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 14faef05641..bf988cab3eb 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3262,9 +3262,6 @@ static bool trans_DUP_i(DisasContext *s, arg_DUP_i *a)
 
 static bool trans_ADD_zzi(DisasContext *s, arg_rri_esz *a)
 {
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 return gen_gvec_fn_arg_zzi(s, tcg_gen_gvec_addi, a);
 }
 
@@ -3305,9 +3302,6 @@ static bool trans_SUBR_zzi(DisasContext *s, arg_rri_esz 
*a)
   .scalar_first = true }
 };
 
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 if (sve_access_check(s)) {
 unsigned vsz = vec_full_reg_size(s);
 tcg_gen_gvec_2s(vec_full_reg_offset(s, a->rd),
@@ -3321,9 +3315,6 @@ TRANS_FEAT(MUL_zzi, aa64_sve, gen_gvec_fn_arg_zzi, 
tcg_gen_gvec_muli, a)
 
 static bool do_zzi_sat(DisasContext *s, arg_rri_esz *a, bool u, bool d)
 {
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 if (sve_access_check(s)) {
 do_sat_addsub_vec(s, a->esz, a->rd, a->rn,
   tcg_constant_i64(a->imm), u, d);
-- 
2.25.1




[PULL 082/117] target/arm: Move sve check into gen_gvec_fn_ppp

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Combined with the check already present in gen_mov_p,
we can simplify some special cases in trans_AND_
and trans_BIC_.

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-80-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 30 --
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 364e419f3eb..f33bc9d480b 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -370,13 +370,16 @@ static void do_dupi_z(DisasContext *s, int rd, uint64_t 
word)
 }
 
 /* Invoke a vector expander on three Pregs.  */
-static void gen_gvec_fn_ppp(DisasContext *s, GVecGen3Fn *gvec_fn,
+static bool gen_gvec_fn_ppp(DisasContext *s, GVecGen3Fn *gvec_fn,
 int rd, int rn, int rm)
 {
-unsigned psz = pred_gvec_reg_size(s);
-gvec_fn(MO_64, pred_full_reg_offset(s, rd),
-pred_full_reg_offset(s, rn),
-pred_full_reg_offset(s, rm), psz, psz);
+if (sve_access_check(s)) {
+unsigned psz = pred_gvec_reg_size(s);
+gvec_fn(MO_64, pred_full_reg_offset(s, rd),
+pred_full_reg_offset(s, rn),
+pred_full_reg_offset(s, rm), psz, psz);
+}
+return true;
 }
 
 /* Invoke a vector move on two Pregs.  */
@@ -1317,19 +1320,13 @@ static bool trans_AND_(DisasContext *s, arg_rprr_s 
*a)
 };
 
 if (!a->s) {
-if (!sve_access_check(s)) {
-return true;
-}
 if (a->rn == a->rm) {
 if (a->pg == a->rn) {
-do_mov_p(s, a->rd, a->rn);
-} else {
-gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->pg);
+return do_mov_p(s, a->rd, a->rn);
 }
-return true;
+return gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->pg);
 } else if (a->pg == a->rn || a->pg == a->rm) {
-gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->rm);
-return true;
+return gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->rm);
 }
 }
 return do__flags(s, a, );
@@ -1358,10 +1355,7 @@ static bool trans_BIC_(DisasContext *s, arg_rprr_s 
*a)
 };
 
 if (!a->s && a->pg == a->rn) {
-if (sve_access_check(s)) {
-gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->rn, a->rm);
-}
-return true;
+return gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->rn, a->rm);
 }
 return do__flags(s, a, );
 }
-- 
2.25.1




[PATCH v2 08/11] vfio/migration: Remove VFIO migration protocol v1

2022-05-30 Thread Avihai Horon
Now that v2 protocol implementation has been added, remove the
deprecated v1 implementation.

Signed-off-by: Avihai Horon 
---
 hw/vfio/common.c  |  19 +-
 hw/vfio/migration.c   | 698 +-
 hw/vfio/trace-events  |   5 -
 include/hw/vfio/vfio-common.h |   5 -
 4 files changed, 24 insertions(+), 703 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 5541133ec9..00c6cb0ffe 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -355,14 +355,7 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer 
*container)
 return false;
 }
 
-if (!migration->v2 &&
-(vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF) &&
-(migration->device_state_v1 & VFIO_DEVICE_STATE_V1_RUNNING)) {
-return false;
-}
-
-if (migration->v2 &&
-(vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF) &&
+if ((vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF) &&
 (migration->device_state == VFIO_DEVICE_STATE_RUNNING ||
  migration->device_state == VFIO_DEVICE_STATE_RUNNING_P2P)) {
 return false;
@@ -393,14 +386,8 @@ static bool 
vfio_devices_all_running_and_mig_active(VFIOContainer *container)
 return false;
 }
 
-if (!migration->v2 &&
-migration->device_state_v1 & VFIO_DEVICE_STATE_V1_RUNNING) {
-continue;
-}
-
-if (migration->v2 &&
-(migration->device_state == VFIO_DEVICE_STATE_RUNNING ||
- migration->device_state == VFIO_DEVICE_STATE_RUNNING_P2P)) {
+if (migration->device_state == VFIO_DEVICE_STATE_RUNNING ||
+migration->device_state == VFIO_DEVICE_STATE_RUNNING_P2P) {
 continue;
 } else {
 return false;
diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index de68eadb09..852759e6ca 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -121,220 +121,6 @@ static int vfio_migration_set_state(VFIODevice *vbasedev,
 return 0;
 }
 
-static inline int vfio_mig_access(VFIODevice *vbasedev, void *val, int count,
-  off_t off, bool iswrite)
-{
-int ret;
-
-ret = iswrite ? pwrite(vbasedev->fd, val, count, off) :
-pread(vbasedev->fd, val, count, off);
-if (ret < count) {
-error_report("vfio_mig_%s %d byte %s: failed at offset 0x%"
- HWADDR_PRIx", err: %s", iswrite ? "write" : "read", count,
- vbasedev->name, off, strerror(errno));
-return (ret < 0) ? ret : -EINVAL;
-}
-return 0;
-}
-
-static int vfio_mig_rw(VFIODevice *vbasedev, __u8 *buf, size_t count,
-   off_t off, bool iswrite)
-{
-int ret, done = 0;
-__u8 *tbuf = buf;
-
-while (count) {
-int bytes = 0;
-
-if (count >= 8 && !(off % 8)) {
-bytes = 8;
-} else if (count >= 4 && !(off % 4)) {
-bytes = 4;
-} else if (count >= 2 && !(off % 2)) {
-bytes = 2;
-} else {
-bytes = 1;
-}
-
-ret = vfio_mig_access(vbasedev, tbuf, bytes, off, iswrite);
-if (ret) {
-return ret;
-}
-
-count -= bytes;
-done += bytes;
-off += bytes;
-tbuf += bytes;
-}
-return done;
-}
-
-#define vfio_mig_read(f, v, c, o)   vfio_mig_rw(f, (__u8 *)v, c, o, false)
-#define vfio_mig_write(f, v, c, o)  vfio_mig_rw(f, (__u8 *)v, c, o, true)
-
-#define VFIO_MIG_STRUCT_OFFSET(f)   \
- offsetof(struct vfio_device_migration_info, f)
-/*
- * Change the device_state register for device @vbasedev. Bits set in @mask
- * are preserved, bits set in @value are set, and bits not set in either @mask
- * or @value are cleared in device_state. If the register cannot be accessed,
- * the resulting state would be invalid, or the device enters an error state,
- * an error is returned.
- */
-
-static int vfio_migration_v1_set_state(VFIODevice *vbasedev, uint32_t mask,
-   uint32_t value)
-{
-VFIOMigration *migration = vbasedev->migration;
-VFIORegion *region = >region;
-off_t dev_state_off = region->fd_offset +
-  VFIO_MIG_STRUCT_OFFSET(device_state);
-uint32_t device_state;
-int ret;
-
-ret = vfio_mig_read(vbasedev, _state, sizeof(device_state),
-dev_state_off);
-if (ret < 0) {
-return ret;
-}
-
-device_state = (device_state & mask) | value;
-
-if (!VFIO_DEVICE_STATE_VALID(device_state)) {
-return -EINVAL;
-}
-
-ret = vfio_mig_write(vbasedev, _state, sizeof(device_state),
- dev_state_off);
-if (ret < 0) {
-int 

[PATCH v2 01/11] vfio/migration: Fix NULL pointer dereference bug

2022-05-30 Thread Avihai Horon
As part of its error flow, vfio_vmstate_change() accesses
MigrationState->to_dst_file without any checks. This can cause a NULL
pointer dereference if the error flow is taken and
MigrationState->to_dst_file is not set.

For example, this can happen if VM is started or stopped not during
migration and vfio_vmstate_change() error flow is taken, as
MigrationState->to_dst_file is not set at that time.

Fix it by checking that MigrationState->to_dst_file is set before using
it.

Fixes: 02a7e71b1e5b ("vfio: Add VM state change handler to know state of VM")
Signed-off-by: Avihai Horon 
Reviewed-by: Juan Quintela 
---
 hw/vfio/migration.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index a6ad1f8945..34f9f894ed 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -744,7 +744,9 @@ static void vfio_vmstate_change(void *opaque, bool running, 
RunState state)
  */
 error_report("%s: Failed to set device state 0x%x", vbasedev->name,
  (migration->device_state & mask) | value);
-qemu_file_set_error(migrate_get_current()->to_dst_file, ret);
+if (migrate_get_current()->to_dst_file) {
+qemu_file_set_error(migrate_get_current()->to_dst_file, ret);
+}
 }
 vbasedev->migration->vm_running = running;
 trace_vfio_vmstate_change(vbasedev->name, running, RunState_str(state),
-- 
2.21.3




[PULL 064/117] target/arm: Use TRANS_FEAT for do_clast_fp

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-62-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 51358667984..21c2bd099d4 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2542,15 +2542,8 @@ static bool do_clast_fp(DisasContext *s, arg_rpr_esz *a, 
bool before)
 return true;
 }
 
-static bool trans_CLASTA_v(DisasContext *s, arg_rpr_esz *a)
-{
-return do_clast_fp(s, a, false);
-}
-
-static bool trans_CLASTB_v(DisasContext *s, arg_rpr_esz *a)
-{
-return do_clast_fp(s, a, true);
-}
+TRANS_FEAT(CLASTA_v, aa64_sve, do_clast_fp, a, false)
+TRANS_FEAT(CLASTB_v, aa64_sve, do_clast_fp, a, true)
 
 /* Compute CLAST for a Xreg.  */
 static bool do_clast_general(DisasContext *s, arg_rpr_esz *a, bool before)
-- 
2.25.1




[PULL 095/117] target/arm: Expand frint_fns for MO_8

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Simplify indexing of this array.  This will allow folding
of the illegal esz == 0 into the normal fn == NULL check.

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-93-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 2f7651249ad..99e5d896457 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -4167,7 +4167,8 @@ static bool trans_FCVTZU_dd(DisasContext *s, arg_rpr_esz 
*a)
 return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_dd);
 }
 
-static gen_helper_gvec_3_ptr * const frint_fns[3] = {
+static gen_helper_gvec_3_ptr * const frint_fns[] = {
+NULL,
 gen_helper_sve_frint_h,
 gen_helper_sve_frint_s,
 gen_helper_sve_frint_d
@@ -4179,7 +4180,7 @@ static bool trans_FRINTI(DisasContext *s, arg_rpr_esz *a)
 return false;
 }
 return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16,
-  frint_fns[a->esz - 1]);
+  frint_fns[a->esz]);
 }
 
 static bool trans_FRINTX(DisasContext *s, arg_rpr_esz *a)
@@ -4222,7 +4223,7 @@ static bool trans_FRINTN(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_nearest_even, frint_fns[a->esz - 
1]);
+return do_frint_mode(s, a, float_round_nearest_even, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTP(DisasContext *s, arg_rpr_esz *a)
@@ -4230,7 +4231,7 @@ static bool trans_FRINTP(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_up, frint_fns[a->esz - 1]);
+return do_frint_mode(s, a, float_round_up, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTM(DisasContext *s, arg_rpr_esz *a)
@@ -4238,7 +4239,7 @@ static bool trans_FRINTM(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_down, frint_fns[a->esz - 1]);
+return do_frint_mode(s, a, float_round_down, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTZ(DisasContext *s, arg_rpr_esz *a)
@@ -4246,7 +4247,7 @@ static bool trans_FRINTZ(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_to_zero, frint_fns[a->esz - 1]);
+return do_frint_mode(s, a, float_round_to_zero, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a)
@@ -4254,7 +4255,7 @@ static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_ties_away, frint_fns[a->esz - 1]);
+return do_frint_mode(s, a, float_round_ties_away, frint_fns[a->esz]);
 }
 
 static bool trans_FRECPX(DisasContext *s, arg_rpr_esz *a)
-- 
2.25.1




[PATCH v2 04/11] vfio/common: Change vfio_devices_all_running_and_saving() logic to equivalent one

2022-05-30 Thread Avihai Horon
vfio_devices_all_running_and_saving() is used to check if migration is
in pre-copy phase. This is done by checking if migration is in setup or
active states and if all VFIO devices are in pre-copy state, i.e.
_SAVING | _RUNNING.

VFIO migration protocol v2 currently doesn't support pre-copy phase, so
it doesn't have an equivalent VFIO pre-copy state like v1 has.

As preparation for adding the v2 protocol and to make things easier,
change vfio_devices_all_running_and_saving() logic to check if migration
is active and if all VFIO devices are in running state.

The new logic avoids using the VFIO pre-copy state and is equivalent to
the previous one, indicating that migration is in pre-copy phase. No
functional changes intended.

Signed-off-by: Avihai Horon 
---
 hw/vfio/common.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index 29982c7af8..bbc6d375de 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -40,6 +40,7 @@
 #include "trace.h"
 #include "qapi/error.h"
 #include "migration/migration.h"
+#include "migration/misc.h"
 #include "sysemu/tpm.h"
 
 VFIOGroupList vfio_group_list =
@@ -363,13 +364,16 @@ static bool vfio_devices_all_dirty_tracking(VFIOContainer 
*container)
 return true;
 }
 
-static bool vfio_devices_all_running_and_saving(VFIOContainer *container)
+/*
+ * Check if all VFIO devices are running and migration is active, which is
+ * essentially equivalent to the migration being in pre-copy phase.
+ */
+static bool vfio_devices_all_running_and_mig_active(VFIOContainer *container)
 {
 VFIOGroup *group;
 VFIODevice *vbasedev;
-MigrationState *ms = migrate_get_current();
 
-if (!migration_is_setup_or_active(ms->state)) {
+if (!migration_is_active(migrate_get_current())) {
 return false;
 }
 
@@ -381,8 +385,7 @@ static bool 
vfio_devices_all_running_and_saving(VFIOContainer *container)
 return false;
 }
 
-if ((migration->device_state & VFIO_DEVICE_STATE_V1_SAVING) &&
-(migration->device_state & VFIO_DEVICE_STATE_V1_RUNNING)) {
+if (migration->device_state & VFIO_DEVICE_STATE_V1_RUNNING) {
 continue;
 } else {
 return false;
@@ -461,7 +464,7 @@ static int vfio_dma_unmap(VFIOContainer *container,
 };
 
 if (iotlb && container->dirty_pages_supported &&
-vfio_devices_all_running_and_saving(container)) {
+vfio_devices_all_running_and_mig_active(container)) {
 return vfio_dma_unmap_bitmap(container, iova, size, iotlb);
 }
 
-- 
2.21.3




Re: [RESEND PATCH] hw/dma: fix crash caused by race condition

2022-05-30 Thread David Hildenbrand
On 27.04.22 22:51, Tong Zhang wrote:
> assert(dbs->acb) is meant to check the return value of io_func per
> documented in commit 6bee44ea34 ("dma: the passed io_func does not
> return NULL"). However, there is a chance that after calling
> aio_context_release(dbs->ctx); the dma_blk_cb function is called before
> the assertion and dbs->acb is set to NULL again at line 121. Thus when
> we run assert at line 181 it will fail.
> 
>   softmmu/dma-helpers.c:181: dma_blk_cb: Assertion `dbs->acb' failed.
> 
> Reported-by: Francisco Londono 
> Signed-off-by: Tong Zhang 
> ---
>  softmmu/dma-helpers.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
> index 7820fec54c..cb81017928 100644
> --- a/softmmu/dma-helpers.c
> +++ b/softmmu/dma-helpers.c
> @@ -177,8 +177,8 @@ static void dma_blk_cb(void *opaque, int ret)
>  aio_context_acquire(dbs->ctx);
>  dbs->acb = dbs->io_func(dbs->offset, >iov,
>  dma_blk_cb, dbs, dbs->io_func_opaque);
> -aio_context_release(dbs->ctx);
>  assert(dbs->acb);
> +aio_context_release(dbs->ctx);
>  }
>  
>  static void dma_aio_cancel(BlockAIOCB *acb)

I'm fairly new to that code, but I wonder what prevents dma_blk_cb() to
run after you reshuffled the code?

After all, acquire/release is only around the dbs->io_func() call, so I
don't immediately see how it interacts with re-entrance?

-- 
Thanks,

David / dhildenb




[PULL 066/117] target/arm: Use TRANS_FEAT for do_last_fp

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-64-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index f5453e99e15..841c1b56449 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2608,15 +2608,8 @@ static bool do_last_fp(DisasContext *s, arg_rpr_esz *a, 
bool before)
 return true;
 }
 
-static bool trans_LASTA_v(DisasContext *s, arg_rpr_esz *a)
-{
-return do_last_fp(s, a, false);
-}
-
-static bool trans_LASTB_v(DisasContext *s, arg_rpr_esz *a)
-{
-return do_last_fp(s, a, true);
-}
+TRANS_FEAT(LASTA_v, aa64_sve, do_last_fp, a, false)
+TRANS_FEAT(LASTB_v, aa64_sve, do_last_fp, a, true)
 
 /* Compute LAST for a Xreg.  */
 static bool do_last_general(DisasContext *s, arg_rpr_esz *a, bool before)
-- 
2.25.1




[PULL 092/117] target/arm: Move null function and sve check into do_reduce

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-90-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 30 +-
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 11e4b4e1e4a..0d71072f837 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3572,15 +3572,24 @@ TRANS_FEAT(FMUL_zzx, aa64_sve, gen_gvec_fpst_zzz,
 typedef void gen_helper_fp_reduce(TCGv_i64, TCGv_ptr, TCGv_ptr,
   TCGv_ptr, TCGv_i32);
 
-static void do_reduce(DisasContext *s, arg_rpr_esz *a,
+static bool do_reduce(DisasContext *s, arg_rpr_esz *a,
   gen_helper_fp_reduce *fn)
 {
-unsigned vsz = vec_full_reg_size(s);
-unsigned p2vsz = pow2ceil(vsz);
-TCGv_i32 t_desc = tcg_constant_i32(simd_desc(vsz, vsz, p2vsz));
+unsigned vsz, p2vsz;
+TCGv_i32 t_desc;
 TCGv_ptr t_zn, t_pg, status;
 TCGv_i64 temp;
 
+if (fn == NULL) {
+return false;
+}
+if (!sve_access_check(s)) {
+return true;
+}
+
+vsz = vec_full_reg_size(s);
+p2vsz = pow2ceil(vsz);
+t_desc = tcg_constant_i32(simd_desc(vsz, vsz, p2vsz));
 temp = tcg_temp_new_i64();
 t_zn = tcg_temp_new_ptr();
 t_pg = tcg_temp_new_ptr();
@@ -3596,23 +3605,18 @@ static void do_reduce(DisasContext *s, arg_rpr_esz *a,
 
 write_fp_dreg(s, a->rd, temp);
 tcg_temp_free_i64(temp);
+return true;
 }
 
 #define DO_VPZ(NAME, name) \
 static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a)\
 {\
-static gen_helper_fp_reduce * const fns[3] = {   \
-gen_helper_sve_##name##_h,   \
+static gen_helper_fp_reduce * const fns[4] = {   \
+NULL, gen_helper_sve_##name##_h, \
 gen_helper_sve_##name##_s,   \
 gen_helper_sve_##name##_d,   \
 };   \
-if (a->esz == 0) {   \
-return false;\
-}\
-if (sve_access_check(s)) {   \
-do_reduce(s, a, fns[a->esz - 1]);\
-}\
-return true; \
+return do_reduce(s, a, fns[a->esz]); \
 }
 
 DO_VPZ(FADDV, faddv)
-- 
2.25.1




[PATCH v2 02/11] vfio/migration: Skip pre-copy if dirty page tracking is not supported

2022-05-30 Thread Avihai Horon
Currently, if IOMMU of a VFIO container doesn't support dirty page
tracking, migration is blocked completely. This is because a DMA-able
VFIO device can dirty RAM pages without updating QEMU about it, thus
breaking the migration.

However, this doesn't mean that migration can't be done at all. If
migration pre-copy phase is skipped, the VFIO device doesn't have a
chance to dirty RAM pages that have been migrated already, thus
eliminating the problem previously mentioned.

Hence, in such case allow migration but skip pre-copy phase.

Signed-off-by: Avihai Horon 
---
 hw/vfio/migration.c   | 9 -
 migration/migration.c | 5 +
 migration/migration.h | 3 +++
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
index 34f9f894ed..d8f9b086c2 100644
--- a/hw/vfio/migration.c
+++ b/hw/vfio/migration.c
@@ -863,10 +863,17 @@ int vfio_migration_probe(VFIODevice *vbasedev, Error 
**errp)
 struct vfio_region_info *info = NULL;
 int ret = -ENOTSUP;
 
-if (!vbasedev->enable_migration || !container->dirty_pages_supported) {
+if (!vbasedev->enable_migration) {
 goto add_blocker;
 }
 
+if (!container->dirty_pages_supported) {
+warn_report_once(
+"%s: IOMMU of the device's VFIO container doesn't support dirty 
page tracking, migration pre-copy phase will be skipped",
+vbasedev->name);
+migrate_get_current()->skip_precopy = true;
+}
+
 ret = vfio_get_dev_region_info(vbasedev,
VFIO_REGION_TYPE_MIGRATION_DEPRECATED,
VFIO_REGION_SUBTYPE_MIGRATION_DEPRECATED,
diff --git a/migration/migration.c b/migration/migration.c
index 31739b2af9..217f0e3e94 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -3636,6 +3636,11 @@ static MigIterateState 
migration_iteration_run(MigrationState *s)
 uint64_t pending_size, pend_pre, pend_compat, pend_post;
 bool in_postcopy = s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE;
 
+if (s->skip_precopy) {
+migration_completion(s);
+return MIG_ITERATE_BREAK;
+}
+
 qemu_savevm_state_pending(s->to_dst_file, s->threshold_size, _pre,
   _compat, _post);
 pending_size = pend_pre + pend_compat + pend_post;
diff --git a/migration/migration.h b/migration/migration.h
index 485d58b95f..0920a0950e 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -332,6 +332,9 @@ struct MigrationState {
  * This save hostname when out-going migration starts
  */
 char *hostname;
+
+/* Whether to skip pre-copy phase of migration or not */
+bool skip_precopy;
 };
 
 void migrate_set_state(int *state, int old_state, int new_state);
-- 
2.21.3




[PULL 099/117] target/arm: Use TRANS_FEAT for FLOGB

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-97-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 29 ++---
 1 file changed, 6 insertions(+), 23 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 552a551fef3..2f96f52293d 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -7280,29 +7280,12 @@ TRANS_FEAT(FCVTX_ds, aa64_sve2, do_frint_mode, a,
 TRANS_FEAT(FCVTXNT_ds, aa64_sve2, do_frint_mode, a,
float_round_to_odd, gen_helper_sve2_fcvtnt_ds)
 
-static bool trans_FLOGB(DisasContext *s, arg_rpr_esz *a)
-{
-static gen_helper_gvec_3_ptr * const fns[] = {
-NULL,   gen_helper_flogb_h,
-gen_helper_flogb_s, gen_helper_flogb_d
-};
-
-if (!dc_isar_feature(aa64_sve2, s) || fns[a->esz] == NULL) {
-return false;
-}
-if (sve_access_check(s)) {
-TCGv_ptr status =
-fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
-unsigned vsz = vec_full_reg_size(s);
-
-tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   pred_full_reg_offset(s, a->pg),
-   status, vsz, vsz, 0, fns[a->esz]);
-tcg_temp_free_ptr(status);
-}
-return true;
-}
+static gen_helper_gvec_3_ptr * const flogb_fns[] = {
+NULL,   gen_helper_flogb_h,
+gen_helper_flogb_s, gen_helper_flogb_d
+};
+TRANS_FEAT(FLOGB, aa64_sve2, gen_gvec_fpst_arg_zpz, flogb_fns[a->esz],
+   a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
 
 static bool do_FMLAL_zzzw(DisasContext *s, arg__esz *a, bool sub, bool sel)
 {
-- 
2.25.1




[PULL 051/117] target/arm: Move sve check into do_index

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-49-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 53 ++
 1 file changed, 25 insertions(+), 28 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 52bbd1a4faa..44c23429232 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1087,12 +1087,20 @@ TRANS_FEAT(MLS, aa64_sve, do_zpzzz_ool, a, 
mls_fns[a->esz])
  *** SVE Index Generation Group
  */
 
-static void do_index(DisasContext *s, int esz, int rd,
+static bool do_index(DisasContext *s, int esz, int rd,
  TCGv_i64 start, TCGv_i64 incr)
 {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_i32 desc = tcg_constant_i32(simd_desc(vsz, vsz, 0));
-TCGv_ptr t_zd = tcg_temp_new_ptr();
+unsigned vsz;
+TCGv_i32 desc;
+TCGv_ptr t_zd;
+
+if (!sve_access_check(s)) {
+return true;
+}
+
+vsz = vec_full_reg_size(s);
+desc = tcg_constant_i32(simd_desc(vsz, vsz, 0));
+t_zd = tcg_temp_new_ptr();
 
 tcg_gen_addi_ptr(t_zd, cpu_env, vec_full_reg_offset(s, rd));
 if (esz == 3) {
@@ -1115,46 +1123,35 @@ static void do_index(DisasContext *s, int esz, int rd,
 tcg_temp_free_i32(i32);
 }
 tcg_temp_free_ptr(t_zd);
+return true;
 }
 
 static bool trans_INDEX_ii(DisasContext *s, arg_INDEX_ii *a)
 {
-if (sve_access_check(s)) {
-TCGv_i64 start = tcg_constant_i64(a->imm1);
-TCGv_i64 incr = tcg_constant_i64(a->imm2);
-do_index(s, a->esz, a->rd, start, incr);
-}
-return true;
+TCGv_i64 start = tcg_constant_i64(a->imm1);
+TCGv_i64 incr = tcg_constant_i64(a->imm2);
+return do_index(s, a->esz, a->rd, start, incr);
 }
 
 static bool trans_INDEX_ir(DisasContext *s, arg_INDEX_ir *a)
 {
-if (sve_access_check(s)) {
-TCGv_i64 start = tcg_constant_i64(a->imm);
-TCGv_i64 incr = cpu_reg(s, a->rm);
-do_index(s, a->esz, a->rd, start, incr);
-}
-return true;
+TCGv_i64 start = tcg_constant_i64(a->imm);
+TCGv_i64 incr = cpu_reg(s, a->rm);
+return do_index(s, a->esz, a->rd, start, incr);
 }
 
 static bool trans_INDEX_ri(DisasContext *s, arg_INDEX_ri *a)
 {
-if (sve_access_check(s)) {
-TCGv_i64 start = cpu_reg(s, a->rn);
-TCGv_i64 incr = tcg_constant_i64(a->imm);
-do_index(s, a->esz, a->rd, start, incr);
-}
-return true;
+TCGv_i64 start = cpu_reg(s, a->rn);
+TCGv_i64 incr = tcg_constant_i64(a->imm);
+return do_index(s, a->esz, a->rd, start, incr);
 }
 
 static bool trans_INDEX_rr(DisasContext *s, arg_INDEX_rr *a)
 {
-if (sve_access_check(s)) {
-TCGv_i64 start = cpu_reg(s, a->rn);
-TCGv_i64 incr = cpu_reg(s, a->rm);
-do_index(s, a->esz, a->rd, start, incr);
-}
-return true;
+TCGv_i64 start = cpu_reg(s, a->rn);
+TCGv_i64 incr = cpu_reg(s, a->rm);
+return do_index(s, a->esz, a->rd, start, incr);
 }
 
 /*
-- 
2.25.1




[PULL 083/117] target/arm: Implement NOT (prediates) alias

2022-05-30 Thread Peter Maydell
From: Richard Henderson 

This alias is defined on EOR (prediates).  While the
same operation could be performed with NAND or NOR,
only bother with the official alias.

Signed-off-by: Richard Henderson 
Message-id: 20220527181907.189259-81-richard.hender...@linaro.org
Reviewed-by: Peter Maydell 
Signed-off-by: Peter Maydell 
---
 target/arm/translate-sve.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index f33bc9d480b..b6b5980e2db 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1381,6 +1381,11 @@ static bool trans_EOR_(DisasContext *s, arg_rprr_s 
*a)
 .fno = gen_helper_sve_eor_,
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
+
+/* Alias NOT (predicate) is EOR Pd.B, Pg/Z, Pn.B, Pg.B */
+if (!a->s && a->pg == a->rm) {
+return gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->pg, a->rn);
+}
 return do__flags(s, a, );
 }
 
-- 
2.25.1




  1   2   3   4   >