From: Stefan Hajnoczi <stefanha@redhat.com>
To: Alexander Graf <graf@amazon.com>
Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org,
qemu-arm@nongnu.org, "Cameron Esfahani" <dirty@apple.com>,
"Michael S . Tsirkin" <mst@redhat.com>,
"Kevin Wolf" <kwolf@redhat.com>,
"Hanna Reitz" <hreitz@redhat.com>,
"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Mads Ynddal" <mads@ynddal.dk>,
"Daniel P . Berrangé" <berrange@redhat.com>,
"Bernhard Beschow" <shentey@gmail.com>,
"Gerd Hoffmann" <kraxel@redhat.com>
Subject: Re: [PATCH v2 08/12] hw/vmapple/bdif: Introduce vmapple backdoor interface
Date: Thu, 31 Aug 2023 15:46:24 -0400 [thread overview]
Message-ID: <20230831194624.GE532982@fedora> (raw)
In-Reply-To: <20230830161425.91946-9-graf@amazon.com>
[-- Attachment #1: Type: text/plain, Size: 11292 bytes --]
On Wed, Aug 30, 2023 at 04:14:21PM +0000, Alexander Graf wrote:
> The VMApple machine exposes AUX and ROOT block devices (as well as USB OTG
> emulation) via virtio-pci as well as a special, simple backdoor platform
> device.
>
> This patch implements this backdoor platform device to the best of my
> understanding. I left out any USB OTG parts; they're only needed for
> guest recovery and I don't understand the protocol yet.
Out of curiosity: This interface has no way to check the size of the
block device? I guess that's not necessary in a boot loader that just
parses a boot record and then loads the next stage...
I posted comments below. Otherwise:
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
>
> Signed-off-by: Alexander Graf <graf@amazon.com>
>
> ---
>
> v1 -> v2:
>
> - Adapt to system_ss meson.build target
> ---
> include/hw/vmapple/bdif.h | 31 +++++
> hw/vmapple/bdif.c | 245 ++++++++++++++++++++++++++++++++++++++
> hw/vmapple/Kconfig | 2 +
> hw/vmapple/meson.build | 1 +
> hw/vmapple/trace-events | 5 +
> 5 files changed, 284 insertions(+)
> create mode 100644 include/hw/vmapple/bdif.h
> create mode 100644 hw/vmapple/bdif.c
>
> diff --git a/include/hw/vmapple/bdif.h b/include/hw/vmapple/bdif.h
> new file mode 100644
> index 0000000000..65ee43457b
> --- /dev/null
> +++ b/include/hw/vmapple/bdif.h
> @@ -0,0 +1,31 @@
> +/*
> + * VMApple Backdoor Interface
> + *
> + * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#ifndef HW_VMAPPLE_BDIF_H
> +#define HW_VMAPPLE_BDIF_H
> +
> +#include "hw/sysbus.h"
> +#include "qom/object.h"
> +
> +#define TYPE_VMAPPLE_BDIF "vmapple-bdif"
> +OBJECT_DECLARE_SIMPLE_TYPE(VMAppleBdifState, VMAPPLE_BDIF)
> +
> +struct VMAppleBdifState {
> + /* <private> */
> + SysBusDevice parent_obj;
> +
> + /* <public> */
> + BlockBackend *aux;
> + BlockBackend *root;
> + MemoryRegion mmio;
> +};
> +
> +#define VMAPPLE_BDIF_SIZE 0x00200000
> +
> +#endif /* HW_VMAPPLE_BDIF_H */
> diff --git a/hw/vmapple/bdif.c b/hw/vmapple/bdif.c
> new file mode 100644
> index 0000000000..36b5915ff3
> --- /dev/null
> +++ b/hw/vmapple/bdif.c
> @@ -0,0 +1,245 @@
> +/*
> + * VMApple Backdoor Interface
> + *
> + * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/vmapple/bdif.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "qapi/error.h"
> +#include "trace.h"
> +#include "hw/block/block.h"
> +#include "sysemu/block-backend.h"
> +
> +#define REG_DEVID_MASK 0xffff0000
> +#define DEVID_ROOT 0x00000000
> +#define DEVID_AUX 0x00010000
> +#define DEVID_USB 0x00100000
> +
> +#define REG_STATUS 0x0
> +#define REG_STATUS_ACTIVE BIT(0)
> +#define REG_CFG 0x4
> +#define REG_CFG_ACTIVE BIT(1)
> +#define REG_UNK1 0x8
> +#define REG_BUSY 0x10
> +#define REG_BUSY_READY BIT(0)
> +#define REG_UNK2 0x400
> +#define REG_CMD 0x408
> +#define REG_NEXT_DEVICE 0x420
> +#define REG_UNK3 0x434
> +
> +typedef struct vblk_sector {
> + uint32_t pad;
> + uint32_t pad2;
> + uint32_t sector;
> + uint32_t pad3;
> +} VblkSector;
> +
> +typedef struct vblk_req_cmd {
> + uint64_t addr;
> + uint32_t len;
> + uint32_t flags;
> +} VblkReqCmd;
> +
> +typedef struct vblk_req {
> + VblkReqCmd sector;
> + VblkReqCmd data;
> + VblkReqCmd retval;
> +} VblkReq;
> +
> +#define VBLK_DATA_FLAGS_READ 0x00030001
> +#define VBLK_DATA_FLAGS_WRITE 0x00010001
> +
> +#define VBLK_RET_SUCCESS 0
> +#define VBLK_RET_FAILED 1
> +
> +static uint64_t bdif_read(void *opaque, hwaddr offset, unsigned size)
> +{
> + uint64_t ret = -1;
> + uint64_t devid = (offset & REG_DEVID_MASK);
> +
> + switch (offset & ~REG_DEVID_MASK) {
> + case REG_STATUS:
> + ret = REG_STATUS_ACTIVE;
> + break;
> + case REG_CFG:
> + ret = REG_CFG_ACTIVE;
> + break;
> + case REG_UNK1:
> + ret = 0x420;
> + break;
> + case REG_BUSY:
> + ret = REG_BUSY_READY;
> + break;
> + case REG_UNK2:
> + ret = 0x1;
> + break;
> + case REG_UNK3:
> + ret = 0x0;
> + break;
> + case REG_NEXT_DEVICE:
> + switch (devid) {
> + case DEVID_ROOT:
> + ret = 0x8000000;
> + break;
> + case DEVID_AUX:
> + ret = 0x10000;
> + break;
> + }
> + break;
> + }
> +
> + trace_bdif_read(offset, size, ret);
> + return ret;
> +}
> +
> +static void le2cpu_sector(VblkSector *sector)
> +{
> + sector->sector = le32_to_cpu(sector->sector);
> +}
> +
> +static void le2cpu_reqcmd(VblkReqCmd *cmd)
> +{
> + cmd->addr = le64_to_cpu(cmd->addr);
> + cmd->len = le32_to_cpu(cmd->len);
> + cmd->flags = le32_to_cpu(cmd->flags);
> +}
> +
> +static void le2cpu_req(VblkReq *req)
> +{
> + le2cpu_reqcmd(&req->sector);
> + le2cpu_reqcmd(&req->data);
> + le2cpu_reqcmd(&req->retval);
> +}
> +
> +static void vblk_cmd(uint64_t devid, BlockBackend *blk, uint64_t value,
> + uint64_t static_off)
> +{
> + VblkReq req;
> + VblkSector sector;
> + uint64_t off = 0;
> + char *buf = NULL;
> + uint8_t ret = VBLK_RET_FAILED;
> + int r;
> +
> + cpu_physical_memory_read(value, &req, sizeof(req));
Please zero req first so that when value is bogus and
cpu_physical_memory_read() does not store to &req, we don't process
req's uninitialized stack memory:
VblkReq req = {};
> + le2cpu_req(&req);
> +
> + if (req.sector.len != sizeof(sector)) {
> + ret = VBLK_RET_FAILED;
> + goto out;
> + }
> +
> + /* Read the vblk command */
> + cpu_physical_memory_read(req.sector.addr, §or, sizeof(sector));
Same here:
VblkSectors sector = {};
> + le2cpu_sector(§or);
> +
> + off = sector.sector * 512ULL + static_off;
> +
> + /* Sanity check that we're not allocating bogus sizes */
> + if (req.data.len > (128 * 1024 * 1024)) {
> + goto out;
> + }
> +
> + buf = g_malloc0(req.data.len);
> + switch (req.data.flags) {
> + case VBLK_DATA_FLAGS_READ:
> + r = blk_pread(blk, off, req.data.len, buf, 0);
> + trace_bdif_vblk_read(devid == DEVID_AUX ? "aux" : "root",
> + req.data.addr, off, req.data.len, r);
> + if (r < 0) {
> + goto out;
> + }
> + cpu_physical_memory_write(req.data.addr, buf, req.data.len);
> + ret = VBLK_RET_SUCCESS;
> + break;
> + case VBLK_DATA_FLAGS_WRITE:
> + /* Not needed, iBoot only reads */
> + break;
> + default:
> + break;
> + }
> +
> +out:
> + g_free(buf);
> + cpu_physical_memory_write(req.retval.addr, &ret, 1);
> +}
> +
> +static void bdif_write(void *opaque, hwaddr offset,
> + uint64_t value, unsigned size)
> +{
> + VMAppleBdifState *s = opaque;
> + uint64_t devid = (offset & REG_DEVID_MASK);
> +
> + trace_bdif_write(offset, size, value);
> +
> + switch (offset & ~REG_DEVID_MASK) {
> + case REG_CMD:
> + switch (devid) {
> + case DEVID_ROOT:
> + vblk_cmd(devid, s->root, value, 0x0);
> + break;
> + case DEVID_AUX:
> + vblk_cmd(devid, s->aux, value, 0x0);
> + break;
> + }
> + break;
> + }
> +}
> +
> +static const MemoryRegionOps bdif_ops = {
> + .read = bdif_read,
> + .write = bdif_write,
> + .endianness = DEVICE_NATIVE_ENDIAN,
> + .valid = {
> + .min_access_size = 1,
> + .max_access_size = 8,
> + },
> + .impl = {
> + .min_access_size = 1,
> + .max_access_size = 8,
> + },
> +};
> +
> +static void bdif_init(Object *obj)
> +{
> + VMAppleBdifState *s = VMAPPLE_BDIF(obj);
> +
> + memory_region_init_io(&s->mmio, obj, &bdif_ops, obj,
> + "VMApple Backdoor Interface", VMAPPLE_BDIF_SIZE);
> + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
> +}
> +
> +static Property bdif_properties[] = {
> + DEFINE_PROP_DRIVE("aux", VMAppleBdifState, aux),
> + DEFINE_PROP_DRIVE("root", VMAppleBdifState, root),
> + DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void bdif_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> +
> + dc->desc = "VMApple Backdoor Interface";
> + device_class_set_props(dc, bdif_properties);
> +}
> +
> +static const TypeInfo bdif_info = {
> + .name = TYPE_VMAPPLE_BDIF,
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(VMAppleBdifState),
> + .instance_init = bdif_init,
> + .class_init = bdif_class_init,
> +};
> +
> +static void bdif_register_types(void)
> +{
> + type_register_static(&bdif_info);
> +}
> +
> +type_init(bdif_register_types)
> diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
> index a73504d599..388a2bc60c 100644
> --- a/hw/vmapple/Kconfig
> +++ b/hw/vmapple/Kconfig
> @@ -1,3 +1,5 @@
> config VMAPPLE_AES
> bool
>
> +config VMAPPLE_BDIF
> + bool
> diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
> index bcd4dcb28d..d4624713de 100644
> --- a/hw/vmapple/meson.build
> +++ b/hw/vmapple/meson.build
> @@ -1 +1,2 @@
> system_ss.add(when: 'CONFIG_VMAPPLE_AES', if_true: files('aes.c'))
> +system_ss.add(when: 'CONFIG_VMAPPLE_BDIF', if_true: files('bdif.c'))
> diff --git a/hw/vmapple/trace-events b/hw/vmapple/trace-events
> index 03585cdf0f..45c69de2e0 100644
> --- a/hw/vmapple/trace-events
> +++ b/hw/vmapple/trace-events
> @@ -18,3 +18,8 @@ aes_2_read(uint64_t offset, uint64_t res) "offset=0x%"PRIx64" res=0x%"PRIx64
> aes_2_write_unknown(uint64_t offset) "offset=0x%"PRIx64
> aes_2_write(uint64_t offset, uint64_t val) "offset=0x%"PRIx64" val=0x%"PRIx64
> aes_dump_data(const char *desc, const char *hex) "%s%s"
> +
> +# bdif.c
> +bdif_read(uint64_t offset, uint32_t size, uint64_t value) "offset=0x%"PRIx64" size=0x%x value=0x%"PRIx64
> +bdif_write(uint64_t offset, uint32_t size, uint64_t value) "offset=0x%"PRIx64" size=0x%x value=0x%"PRIx64
> +bdif_vblk_read(const char *dev, uint64_t addr, uint64_t offset, uint32_t len, int r) "dev=%s addr=0x%"PRIx64" off=0x%"PRIx64" size=0x%x r=%d"
> --
> 2.39.2 (Apple Git-143)
>
>
>
>
> Amazon Development Center Germany GmbH
> Krausenstr. 38
> 10117 Berlin
> Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
> Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
> Sitz: Berlin
> Ust-ID: DE 289 237 879
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 484 bytes --]
next prev parent reply other threads:[~2023-08-31 19:47 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-30 16:14 [PATCH v2 00/12] Introduce new vmapple machine type Alexander Graf
2023-08-30 16:14 ` [PATCH v2 01/12] build: Only define OS_OBJECT_USE_OBJC with gcc Alexander Graf
2023-08-31 8:12 ` Philippe Mathieu-Daudé
2023-08-31 8:53 ` Akihiko Odaki
2023-08-31 8:59 ` Alexander Graf
2023-08-31 10:45 ` Akihiko Odaki
2023-08-30 16:14 ` [PATCH v2 02/12] hw/misc/pvpanic: Add MMIO interface Alexander Graf
2023-09-01 5:19 ` Mark Cave-Ayland
2023-08-30 16:14 ` [PATCH v2 03/12] hvf: Increase number of possible memory slots Alexander Graf
2023-08-30 16:14 ` [PATCH v2 04/12] hvf: arm: Ignore writes to CNTP_CTL_EL0 Alexander Graf
2023-08-31 8:13 ` Philippe Mathieu-Daudé
2023-08-30 16:14 ` [PATCH v2 05/12] hw: Add vmapple subdir Alexander Graf
2023-08-30 16:14 ` [PATCH v2 06/12] gpex: Allow more than 4 legacy IRQs Alexander Graf
2023-08-30 16:14 ` [PATCH v2 07/12] hw/vmapple/aes: Introduce aes engine Alexander Graf
2023-09-01 5:34 ` Mark Cave-Ayland
2023-08-30 16:14 ` [PATCH v2 08/12] hw/vmapple/bdif: Introduce vmapple backdoor interface Alexander Graf
2023-08-31 19:46 ` Stefan Hajnoczi [this message]
2023-09-01 5:40 ` Mark Cave-Ayland
2023-08-30 16:14 ` [PATCH v2 09/12] hw/vmapple/cfg: Introduce vmapple cfg region Alexander Graf
2023-09-01 5:46 ` Mark Cave-Ayland
2023-08-30 16:14 ` [PATCH v2 10/12] hw/vmapple/apple-gfx: Introduce ParavirtualizedGraphics.Framework support Alexander Graf
2023-09-23 21:04 ` Phil Dennis-Jordan
2023-08-30 16:14 ` [PATCH v2 11/12] hw/vmapple/virtio-blk: Add support for apple virtio-blk Alexander Graf
2023-08-31 20:03 ` Stefan Hajnoczi
2023-08-31 20:34 ` Philippe Mathieu-Daudé
2023-09-01 6:53 ` Mark Cave-Ayland
2023-08-30 16:14 ` [PATCH v2 12/12] hw/vmapple/vmapple: Add vmapple machine type Alexander Graf
2023-09-01 7:07 ` Mark Cave-Ayland
2023-10-12 11:46 ` Francesco Cagnin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230831194624.GE532982@fedora \
--to=stefanha@redhat.com \
--cc=berrange@redhat.com \
--cc=dirty@apple.com \
--cc=graf@amazon.com \
--cc=hreitz@redhat.com \
--cc=kraxel@redhat.com \
--cc=kwolf@redhat.com \
--cc=mads@ynddal.dk \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=shentey@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.