Re: [PATCH v2 01/12] build: Only define OS_OBJECT_USE_OBJC with gcc

2023-08-31 Thread Alexander Graf


On 31.08.23 10:53, Akihiko Odaki wrote:



On 2023/08/31 17:12, Philippe Mathieu-Daudé wrote:

On 30/8/23 18:14, Alexander Graf wrote:
Recent versions of macOS use clang instead of gcc. The 
OS_OBJECT_USE_OBJC
define is only necessary when building with gcc. Let's not define it 
when

building with clang.

With this patch, I can successfully include GCD headers in QEMU when
building with clang.

Signed-off-by: Alexander Graf 
---
  meson.build | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 98e68ef0b1..0d6a0015a1 100644
--- a/meson.build
+++ b/meson.build
@@ -224,7 +224,9 @@ qemu_ldflags = []
  if targetos == 'darwin'
    # Disable attempts to use ObjectiveC features in os/object.h since
they
    # won't work when we're compiling with gcc as a C compiler.
-  qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
+  if compiler.get_id() == 'gcc'
+    qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
+  endif
  elif targetos == 'solaris'
    # needed for CMSG_ macros in sys/socket.h
    qemu_common_flags += '-D_XOPEN_SOURCE=600'


Reviewed-by: Philippe Mathieu-Daudé 



Defining OS_OBJECT_USE_OBJC does not look like a proper solution.
Looking at os/object.h, it seems OS_OBJECT_USE_OBJC is defined as 0 when:
!defined(OS_OBJECT_HAVE_OBJC_SUPPORT) && (!defined(__OBJC__) ||
defined(__OBJC_GC__))

This means OS_OBJECT_USE_OBJC is always 0 if Objective-C is disabled. I
also confirmed os/object.h will not use Objective-C features when
compiled as C code on clang with the following command:

clang -E -x -c - <
EOF

If compilation fails with GCC when not defining OS_OBJECT_USE_OBJC, it
probably means GCC incorrectly treats C code as Objective-C and that is
the problem we should solve. I cannot confirm this theory however since
I have only an Apple Silicon Mac that is incompatible with GCC.



My take on this was to make the gcc hack be a "legacy" thing that we put 
into its own corner, so that in a few years we can just drop it 
altogether. I don't really think it's worth wasting much time on this 
workaround and its potential compatibility with old macOS versions.



Alex





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




[PATCH v2 01/12] build: Only define OS_OBJECT_USE_OBJC with gcc

2023-08-30 Thread Alexander Graf
Recent versions of macOS use clang instead of gcc. The OS_OBJECT_USE_OBJC
define is only necessary when building with gcc. Let's not define it when
building with clang.

With this patch, I can successfully include GCD headers in QEMU when
building with clang.

Signed-off-by: Alexander Graf 
---
 meson.build | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 98e68ef0b1..0d6a0015a1 100644
--- a/meson.build
+++ b/meson.build
@@ -224,7 +224,9 @@ qemu_ldflags = []
 if targetos == 'darwin'
   # Disable attempts to use ObjectiveC features in os/object.h since they
   # won't work when we're compiling with gcc as a C compiler.
-  qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
+  if compiler.get_id() == 'gcc'
+qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
+  endif
 elif targetos == 'solaris'
   # needed for CMSG_ macros in sys/socket.h
   qemu_common_flags += '-D_XOPEN_SOURCE=600'
-- 
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






[PATCH v2 10/12] hw/vmapple/apple-gfx: Introduce ParavirtualizedGraphics.Framework support

2023-08-30 Thread Alexander Graf
MacOS provides a framework (library) that allows any vmm to implement a
paravirtualized 3d graphics passthrough to the host metal stack called
ParavirtualizedGraphics.Framework (PVG). The library abstracts away
almost every aspect of the paravirtualized device model and only provides
and receives callbacks on MMIO access as well as to share memory address
space between the VM and PVG.

This patch implements a QEMU device that drives PVG for the VMApple
variant of it.

Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - Adapt to system_ss meson.build target
---
 meson.build |   4 +
 hw/vmapple/Kconfig  |   3 +
 hw/vmapple/apple-gfx.m  | 578 
 hw/vmapple/meson.build  |   1 +
 hw/vmapple/trace-events |  22 ++
 5 files changed, 608 insertions(+)
 create mode 100644 hw/vmapple/apple-gfx.m

diff --git a/meson.build b/meson.build
index dc5242a5f4..d34310b5eb 100644
--- a/meson.build
+++ b/meson.build
@@ -607,6 +607,8 @@ socket = []
 version_res = []
 coref = []
 iokit = []
+pvg = []
+metal = []
 emulator_link_args = []
 nvmm =not_found
 hvf = not_found
@@ -630,6 +632,8 @@ elif targetos == 'darwin'
   coref = dependency('appleframeworks', modules: 'CoreFoundation')
   iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
   host_dsosuf = '.dylib'
+  pvg = dependency('appleframeworks', modules: 'ParavirtualizedGraphics')
+  metal = dependency('appleframeworks', modules: 'Metal')
 elif targetos == 'sunos'
   socket = [cc.find_library('socket'),
 cc.find_library('nsl'),
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index 542426a740..ba37fc5b81 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -6,3 +6,6 @@ config VMAPPLE_BDIF
 
 config VMAPPLE_CFG
 bool
+
+config VMAPPLE_PVG
+bool
diff --git a/hw/vmapple/apple-gfx.m b/hw/vmapple/apple-gfx.m
new file mode 100644
index 00..97dd2cd9ae
--- /dev/null
+++ b/hw/vmapple/apple-gfx.m
@@ -0,0 +1,578 @@
+/*
+ * QEMU Apple ParavirtualizedGraphics.framework device
+ *
+ * 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.
+ *
+ * ParavirtualizedGraphics.framework is a set of libraries that macOS provides
+ * which implements 3d graphics passthrough to the host as well as a
+ * proprietary guest communication channel to drive it. This device model
+ * implements support to drive that library from within QEMU.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+#include "hw/sysbus.h"
+#include "hw/pci/msi.h"
+#include "crypto/hash.h"
+#include "sysemu/cpus.h"
+#include "ui/console.h"
+#include "monitor/monitor.h"
+#import 
+
+#define TYPE_APPLE_GFX  "apple-gfx"
+
+#define MAX_MRS 512
+
+static const PGDisplayCoord_t apple_gfx_modes[] = {
+{ .x = 1440, .y = 1080 },
+{ .x = 1280, .y = 1024 },
+};
+
+/*
+ * We have to map PVG memory into our address space. Use the one below
+ * as base start address. In normal linker setups it points to a free
+ * memory range.
+ */
+#define APPLE_GFX_BASE_VA ((void *)(uintptr_t)0x5000UL)
+
+/*
+ * ParavirtualizedGraphics.Framework only ships header files for the x86
+ * variant which does not include IOSFC descriptors and host devices. We add
+ * their definitions here so that we can also work with the ARM version.
+ */
+typedef bool(^IOSFCRaiseInterrupt)(uint32_t vector);
+typedef bool(^IOSFCUnmapMemory)(void *a, void *b, void *c, void *d, void *e, 
void *f);
+typedef bool(^IOSFCMapMemory)(uint64_t phys, uint64_t len, bool ro, void **va, 
void *e, void *f);
+
+@interface PGDeviceDescriptorExt : PGDeviceDescriptor
+@property (readwrite, nonatomic) bool usingIOSurfaceMapper;
+@end
+
+@interface PGIOSurfaceHostDeviceDescriptor : NSObject
+-(PGIOSurfaceHostDeviceDescriptor *)init;
+@property (readwrite, nonatomic, copy, nullable) IOSFCMapMemory mapMemory;
+@property (readwrite, nonatomic, copy, nullable) IOSFCUnmapMemory unmapMemory;
+@property (readwrite, nonatomic, copy, nullable) IOSFCRaiseInterrupt 
raiseInterrupt;
+@end
+
+@interface PGIOSurfaceHostDevice : NSObject
+-(void)initWithDescriptor:(PGIOSurfaceHostDeviceDescriptor *) desc;
+-(uint32_t)mmioReadAtOffset:(size_t) offset;
+-(void)mmioWriteAtOffset:(size_t) offset value:(uint32_t)value;
+@end
+
+typedef struct AppleGFXMR {
+QTAILQ_ENTRY(AppleGFXMR) node;
+hwaddr pa;
+void *va;
+uint64_t len;
+} AppleGFXMR;
+
+typedef QTAILQ_HEAD(, AppleGFXMR) AppleGFXMRList;
+
+typedef struct AppleGFXTask {
+QTAILQ_ENTRY(AppleGFXTask) node;
+void *mem;
+uint64_t len;
+} AppleGFXTask;
+
+typedef QTAILQ_HEAD(, AppleGFXTask) AppleGFXTaskList;
+
+typ

[PATCH v2 03/12] hvf: Increase number of possible memory slots

2023-08-30 Thread Alexander Graf
For PVG we will need more than the current 32 possible memory slots.
Bump the limit to 512 instead.

Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - Move max slot number to define
---
 include/sysemu/hvf_int.h  | 4 +++-
 accel/hvf/hvf-accel-ops.c | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
index 718beddcdd..36aa9b4eff 100644
--- a/include/sysemu/hvf_int.h
+++ b/include/sysemu/hvf_int.h
@@ -17,6 +17,8 @@
 #include 
 #endif
 
+#define HVF_MAX_SLOTS 512
+
 /* hvf_slot flags */
 #define HVF_SLOT_LOG (1 << 0)
 
@@ -40,7 +42,7 @@ typedef struct hvf_vcpu_caps {
 
 struct HVFState {
 AccelState parent;
-hvf_slot slots[32];
+hvf_slot slots[HVF_MAX_SLOTS];
 int num_slots;
 
 hvf_vcpu_caps *hvf_caps;
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index 3c94c79747..7aee0d6f72 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -88,7 +88,7 @@ struct mac_slot {
 uint64_t gva;
 };
 
-struct mac_slot mac_slots[32];
+struct mac_slot mac_slots[HVF_MAX_SLOTS];
 
 static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
 {
-- 
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






[PATCH v2 12/12] hw/vmapple/vmapple: Add vmapple machine type

2023-08-30 Thread Alexander Graf
Apple defines a new "vmapple" machine type as part of its proprietary
macOS Virtualization.Framework vmm. This machine type is similar to the
virt one, but with subtle differences in base devices, a few special
vmapple device additions and a vastly different boot chain.

This patch reimplements this machine type in QEMU. To use it, you
have to have a readily installed version of macOS for VMApple,
run on macOS with -accel hvf, pass the Virtualization.Framework
boot rom (AVPBooter) in via -bios, pass the aux and root volume as pflash
and pass aux and root volume as virtio drives. In addition, you also
need to find the machine UUID and pass that as -M vmapple,uuid= parameter:

$ qemu-system-aarch64 -accel hvf -M vmapple,uuid=0x1234 -m 4G \
-bios 
/System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPBooter.vmapple2.bin
-drive file=aux,if=pflash,format=raw \
-drive file=root,if=pflash,format=raw \
-drive file=aux,if=none,id=aux,format=raw \
-device vmapple-virtio-aux,drive=aux \
-drive file=root,if=none,id=root,format=raw \
-device vmapple-virtio-root,drive=root

With all these in place, you should be able to see macOS booting
successfully.

Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - Adapt to system_ss meson.build target
  - Add documentation
---
 MAINTAINERS |   1 +
 docs/system/arm/vmapple.rst |  63 
 docs/system/target-arm.rst  |   1 +
 hw/vmapple/vmapple.c| 661 
 hw/vmapple/Kconfig  |  19 ++
 hw/vmapple/meson.build  |   1 +
 6 files changed, 746 insertions(+)
 create mode 100644 docs/system/arm/vmapple.rst
 create mode 100644 hw/vmapple/vmapple.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3104e58eff..1d3b1e0034 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2578,6 +2578,7 @@ M: Alexander Graf 
 S: Maintained
 F: hw/vmapple/*
 F: include/hw/vmapple/*
+F: docs/system/arm/vmapple.rst
 
 Subsystems
 --
diff --git a/docs/system/arm/vmapple.rst b/docs/system/arm/vmapple.rst
new file mode 100644
index 00..c7486b21d9
--- /dev/null
+++ b/docs/system/arm/vmapple.rst
@@ -0,0 +1,63 @@
+VMApple machine emulation
+
+
+VMApple is the device model that the macOS built-in hypervisor called 
"Virtualization.framework"
+exposes to Apple Silicon macOS guests. The "vmapple" machine model in QEMU 
implements the same
+device model, but does not use any code from Virtualization.Framework.
+
+Prerequisites
+-
+
+To run the vmapple machine model, you need to
+
+ * Run on Apple Silicon
+ * Run on macOS 12.0 or above
+ * Have an already installed copy of a Virtualization.Framework macOS virtual 
machine. I will
+   assume that you installed it using the macosvm CLI.
+
+First, we need to extract the UUID from the virtual machine that you 
installed. You can do this
+by running the following shell script:
+
+.. code-block:: bash
+  :caption: uuid.sh script to extract the UUID from a macosvm.json file
+
+  #!/bin/bash
+
+  MID=$(cat "$1" | python3 -c 'import 
json,sys;obj=json.load(sys.stdin);print(obj["machineId"]);')
+  echo "$MID" | base64 -d | plutil -extract ECID raw -
+
+Now we also need to trim the aux partition. It contains metadata that we can 
just discard:
+
+.. code-block:: bash
+  :caption: Command to trim the aux file
+
+  $ dd if="aux.img" of="aux.img.trimmed" bs=$(( 0x4000 )) skip=1
+
+How to run
+--
+
+Then, we can launch QEMU with the Virtualization.Framework pre-boot 
environment and the readily
+installed target disk images. I recommend to port forward the VM's ssh and vnc 
ports to the host
+to get better interactive access into the target system:
+
+.. code-block:: bash
+  :caption: Example execution command line
+
+  $ UUID=$(uuid.sh macosvm.json)
+  $ 
AVPBOOTER=/System/Library/Frameworks/Virtualization.framework/Resources/AVPBooter.vmapple2.bin
+  $ AUX=aux.img.trimmed
+  $ DISK=disk.img
+  $ qemu-system-aarch64 \
+   -serial mon:stdio \
+   -m 4G \
+   -accel hvf \
+   -M vmapple,uuid=$UUID \
+   -bios $AVPBOOTER \
+-drive file="$AUX",if=pflash,format=raw \
+-drive file="$DISK",if=pflash,format=raw \
+   -drive file="$AUX",if=none,id=aux,format=raw \
+   -drive file="$DISK",if=none,id=root,format=raw \
+   -device vmapple-virtio-aux,drive=aux \
+   -device vmapple-virtio-root,drive=root \
+   -net user,ipv6=off,hostfwd=tcp::-:22,hostfwd=tcp::5901-:5900 \
+   -net nic,model=virtio \
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
index 790ac1b8a2..bf663df4a6 100644
--- a/docs/system/target-arm.rst
+++ b/docs/system/target-arm.rst
@@ -106,6 +106,7 @@ undocumented; you can get a complete list by running
arm/stellaris
arm/stm32
arm/virt

[PATCH v2 07/12] hw/vmapple/aes: Introduce aes engine

2023-08-30 Thread Alexander Graf
VMApple contains an "aes" engine device that it uses to encrypt and
decrypt its nvram. It has trivial hard coded keys it uses for that
purpose.

Add device emulation for this device model.

Signed-off-by: Alexander Graf 
---
 hw/vmapple/aes.c| 583 
 hw/vmapple/Kconfig  |   2 +
 hw/vmapple/meson.build  |   1 +
 hw/vmapple/trace-events |  18 ++
 4 files changed, 604 insertions(+)
 create mode 100644 hw/vmapple/aes.c

diff --git a/hw/vmapple/aes.c b/hw/vmapple/aes.c
new file mode 100644
index 00..eaf1e26abe
--- /dev/null
+++ b/hw/vmapple/aes.c
@@ -0,0 +1,583 @@
+/*
+ * QEMU Apple AES device emulation
+ *
+ * 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/irq.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+#include "hw/sysbus.h"
+#include "crypto/hash.h"
+#include "crypto/aes.h"
+#include "crypto/cipher.h"
+
+#define TYPE_AES  "apple-aes"
+#define MAX_FIFO_SIZE 9
+
+#define CMD_KEY   0x1
+#define CMD_KEY_CONTEXT_SHIFT27
+#define CMD_KEY_CONTEXT_MASK (0x1 << CMD_KEY_CONTEXT_SHIFT)
+#define CMD_KEY_SELECT_SHIFT 24
+#define CMD_KEY_SELECT_MASK  (0x7 << CMD_KEY_SELECT_SHIFT)
+#define CMD_KEY_KEY_LEN_SHIFT22
+#define CMD_KEY_KEY_LEN_MASK (0x3 << CMD_KEY_KEY_LEN_SHIFT)
+#define CMD_KEY_ENCRYPT_SHIFT20
+#define CMD_KEY_ENCRYPT_MASK (0x1 << CMD_KEY_ENCRYPT_SHIFT)
+#define CMD_KEY_BLOCK_MODE_SHIFT 16
+#define CMD_KEY_BLOCK_MODE_MASK  (0x3 << CMD_KEY_BLOCK_MODE_SHIFT)
+#define CMD_IV0x2
+#define CMD_IV_CONTEXT_SHIFT 26
+#define CMD_IV_CONTEXT_MASK  (0x3 << CMD_KEY_CONTEXT_SHIFT)
+#define CMD_DSB   0x3
+#define CMD_SKG   0x4
+#define CMD_DATA  0x5
+#define CMD_DATA_KEY_CTX_SHIFT   27
+#define CMD_DATA_KEY_CTX_MASK(0x1 << CMD_DATA_KEY_CTX_SHIFT)
+#define CMD_DATA_IV_CTX_SHIFT25
+#define CMD_DATA_IV_CTX_MASK (0x3 << CMD_DATA_IV_CTX_SHIFT)
+#define CMD_DATA_LEN_MASK0xff
+#define CMD_STORE_IV  0x6
+#define CMD_STORE_IV_ADDR_MASK   0xff
+#define CMD_WRITE_REG 0x7
+#define CMD_FLAG  0x8
+#define CMD_FLAG_STOP_MASK   BIT(26)
+#define CMD_FLAG_RAISE_IRQ_MASK  BIT(27)
+#define CMD_FLAG_INFO_MASK   0xff
+#define CMD_MAX   0x10
+
+#define CMD_SHIFT 28
+
+#define REG_STATUS0xc
+#define REG_STATUS_DMA_READ_RUNNING BIT(0)
+#define REG_STATUS_DMA_READ_PENDING BIT(1)
+#define REG_STATUS_DMA_WRITE_RUNNINGBIT(2)
+#define REG_STATUS_DMA_WRITE_PENDINGBIT(3)
+#define REG_STATUS_BUSY BIT(4)
+#define REG_STATUS_EXECUTINGBIT(5)
+#define REG_STATUS_READYBIT(6)
+#define REG_STATUS_TEXT_DPA_SEEDED  BIT(7)
+#define REG_STATUS_UNWRAP_DPA_SEEDEDBIT(8)
+
+#define REG_IRQ_STATUS0x18
+#define REG_IRQ_STATUS_INVALID_CMD  BIT(2)
+#define REG_IRQ_STATUS_FLAG BIT(5)
+#define REG_IRQ_ENABLE0x1c
+#define REG_WATERMARK 0x20
+#define REG_Q_STATUS  0x24
+#define REG_FLAG_INFO 0x30
+#define REG_FIFO  0x200
+
+static const uint32_t key_lens[4] = {
+[0] = 16,
+[1] = 24,
+[2] = 32,
+[3] = 64,
+};
+
+struct key {
+uint32_t key_len;
+uint32_t key[8];
+};
+
+struct iv {
+uint32_t iv[4];
+};
+
+struct context {
+struct key key;
+struct iv iv;
+};
+
+static struct key builtin_keys[7] = {
+[1] = {
+.key_len = 32,
+.key = { 0x1 },
+},
+[2] = {
+.key_len = 32,
+.key = { 0x2 },
+},
+[3] = {
+.key_len = 32,
+.key = { 0x3 },
+}
+};
+
+typedef struct AESState {
+/* Private */
+SysBusDevice parent_obj;
+
+/* Public */
+qemu_irq irq;
+MemoryRegion iomem1;
+MemoryRegion iomem2;
+
+uint32_t status;
+uint32_t q_status;
+uint32_t irq_status;
+uint32_t irq_enable;
+uint32_t watermark;
+uint32_t flag_info;
+uint32_t fifo[MAX_FIFO_SIZE];
+uint32_t fifo_idx;
+struct key key[2];
+struct iv iv[4];
+bool is_encrypt;
+QCryptoCipherMode block_mode;
+} AESState;
+
+OBJECT_DECLARE_SIMPLE_TYPE(AESState, AES)
+
+static void aes_update_irq(AESState *s)
+{
+qemu_set_irq(s->irq, !!(s->irq_status & s->irq_enable));
+}
+
+static uint64_t aes1_read(void *opaque, hwaddr offset, unsigned size)
+{
+AESState *s = opaque;
+uint64_t res = 0;
+
+switch (offset) {
+case REG_STATUS:
+res = s->status;
+break;
+case REG_IRQ_STATUS:
+res = s->irq_status;
+break;
+

[PATCH v2 00/12] Introduce new vmapple machine type

2023-08-30 Thread Alexander Graf
This patch set introduces a new ARM and HVF specific machine type
called "vmapple". It mimicks the device model that Apple's proprietary
Virtualization.Framework exposes, but implements it in QEMU.

With this new machine type, you can run macOS guests on Apple Silicon
systems via HVF. To do so, you need to first install macOS using
Virtualization.Framework onto a virtual disk image using a tool like
macosvm (https://github.com/s-u/macosvm)

  $ macosvm --disk disk.img,size=32g --aux aux.img \
--restore UniversalMac_12.0.1_21A559_Restore.ipsw vm.json

Then, extract the ECID from the installed VM:

  $ cat "$DIR/macosvm.json" | python3 -c \
  'import json,sys;obj=json.load(sys.stdin);print(obj["machineId"]) |\
  base64 -d | plutil -extract ECID raw -

In addition, cut off the first 16kb of the aux.img:

  $ dd if=aux.img of=aux.img.trimmed bs=$(( 0x4000 )) skip=1

Now, you can just launch QEMU with the bits generated above:

  $ qemu-system-aarch64 -serial mon:stdio\
  -m 4G  \
  -M vmapple,uuid=6240349656165161789\
  -bios /Sys*/Lib*/Fra*/Virtualization.f*/R*/AVPBooter.vmapple2.bin  \
  -pflash aux.img.trimmed\
  -pflash disk.img   \
  -drive file=disk.img,if=none,id=root   \
  -device vmapple-virtio-root,drive=root \
  -drive file=aux.img.trimmed,if=none,id=aux \
  -device vmapple-virtio-aix,drive=aux   \
  -accel hvf

There are a few limitations with this implementation:

  - Only runs on macOS because it relies on
ParavirtualizesGraphics.Framework
  - Something is not fully correct on interrupt delivery or
similar - the keyboard does not work
  - No Rosetta in the guest because we lack the private
entitlement to enable TSO

Over time, I hope that some of the limitations above could cease to exist.
This device model would enable very nice use cases with KVM on an Asahi
Linux device.

Please beware that the vmapple device model only works with macOS 12 guests
for now. Newer guests run into Hypervisor.Framework incompatibilities.

---

v1 -> v2:

  - Adapt to system_ss meson.build target
  - Add documentation
  - Rework virtio-blk patch to make all vmapple virtio-blk logic subclasses
  - Add log message on write
  - Move max slot number to define
  - Use SPDX header
  - Remove useless includes

Alexander Graf (12):
  build: Only define OS_OBJECT_USE_OBJC with gcc
  hw/misc/pvpanic: Add MMIO interface
  hvf: Increase number of possible memory slots
  hvf: arm: Ignore writes to CNTP_CTL_EL0
  hw: Add vmapple subdir
  gpex: Allow more than 4 legacy IRQs
  hw/vmapple/aes: Introduce aes engine
  hw/vmapple/bdif: Introduce vmapple backdoor interface
  hw/vmapple/cfg: Introduce vmapple cfg region
  hw/vmapple/apple-gfx: Introduce ParavirtualizedGraphics.Framework
support
  hw/vmapple/virtio-blk: Add support for apple virtio-blk
  hw/vmapple/vmapple: Add vmapple machine type

 MAINTAINERS |   7 +
 docs/system/arm/vmapple.rst |  68 
 docs/system/target-arm.rst  |   1 +
 meson.build |   9 +-
 hw/vmapple/trace.h  |   1 +
 include/hw/misc/pvpanic.h   |   1 +
 include/hw/pci-host/gpex.h  |   7 +-
 include/hw/pci/pci_ids.h|   1 +
 include/hw/virtio/virtio-blk.h  |  11 +-
 include/hw/vmapple/bdif.h   |  31 ++
 include/hw/vmapple/cfg.h|  68 
 include/hw/vmapple/virtio-blk.h |  39 ++
 include/sysemu/hvf_int.h|   4 +-
 accel/hvf/hvf-accel-ops.c   |   2 +-
 hw/arm/sbsa-ref.c   |   2 +-
 hw/arm/virt.c   |   2 +-
 hw/block/virtio-blk.c   |  18 +-
 hw/i386/microvm.c   |   2 +-
 hw/loongarch/virt.c |   2 +-
 hw/mips/loongson3_virt.c|   2 +-
 hw/misc/pvpanic-mmio.c  |  61 +++
 hw/openrisc/virt.c  |  12 +-
 hw/pci-host/gpex.c  |  36 +-
 hw/riscv/virt.c |  12 +-
 hw/vmapple/aes.c| 583 
 hw/vmapple/bdif.c   | 245 
 hw/vmapple/cfg.c| 105 +
 hw/vmapple/virtio-blk.c | 212 ++
 hw/vmapple/vmapple.c| 661 
 hw/xtensa/virt.c|   2 +-
 target/arm/hvf/hvf.c|   9 +
 hw/Kconfig  |   1 +
 hw/meson.build  |   1 +
 hw/misc/Kconfig |   4 +
 hw/misc/meson.build |   1 +
 hw/vmapple/Kconfig  |  33 ++
 hw/vmapple/apple-gfx.m  | 578 
 hw/vmapple/meson.build  |   6 +
 hw/vmapple/trace-events   

[PATCH v2 11/12] hw/vmapple/virtio-blk: Add support for apple virtio-blk

2023-08-30 Thread Alexander Graf
Apple has its own virtio-blk PCI device ID where it deviates from the
official virtio-pci spec slightly: It puts a new "apple type"
field at a static offset in config space and introduces a new barrier
command.

This patch first creates a mechanism for virtio-blk downstream classes to
handle unknown commands. It then creates such a downstream class and a new
vmapple-virtio-blk-pci class which support the additional apple type config
identifier as well as the barrier command.

It then exposes 2 subclasses from that that we can use to expose root and
aux virtio-blk devices: "vmapple-virtio-root" and "vmapple-virtio-aux".

Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - Rework to make all vmapple virtio-blk logic a subclass
---
 include/hw/pci/pci_ids.h|   1 +
 include/hw/virtio/virtio-blk.h  |  12 +-
 include/hw/vmapple/virtio-blk.h |  39 ++
 hw/block/virtio-blk.c   |  19 ++-
 hw/vmapple/virtio-blk.c | 212 
 hw/vmapple/Kconfig  |   3 +
 hw/vmapple/meson.build  |   1 +
 7 files changed, 282 insertions(+), 5 deletions(-)
 create mode 100644 include/hw/vmapple/virtio-blk.h
 create mode 100644 hw/vmapple/virtio-blk.c

diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index e4386ebb20..74e589a298 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -188,6 +188,7 @@
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP0x0020
 #define PCI_DEVICE_ID_APPLE_U3_AGP   0x004b
 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC   0x0021
+#define PCI_DEVICE_ID_APPLE_VIRTIO_BLK   0x1a00
 
 #define PCI_VENDOR_ID_SUN0x108e
 #define PCI_DEVICE_ID_SUN_EBUS   0x1000
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index dafec432ce..381a906410 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -23,7 +23,7 @@
 #include "qom/object.h"
 
 #define TYPE_VIRTIO_BLK "virtio-blk-device"
-OBJECT_DECLARE_SIMPLE_TYPE(VirtIOBlock, VIRTIO_BLK)
+OBJECT_DECLARE_TYPE(VirtIOBlock, VirtIOBlkClass, VIRTIO_BLK)
 
 /* This is the last element of the write scatter-gather list */
 struct virtio_blk_inhdr
@@ -91,6 +91,16 @@ typedef struct MultiReqBuffer {
 bool is_write;
 } MultiReqBuffer;
 
+typedef struct VirtIOBlkClass {
+/*< private >*/
+VirtioDeviceClass parent;
+/*< public >*/
+bool (*handle_unknown_request)(VirtIOBlockReq *req, MultiReqBuffer *mrb,
+   uint32_t type);
+} VirtIOBlkClass;
+
 void virtio_blk_handle_vq(VirtIOBlock *s, VirtQueue *vq);
+void virtio_blk_free_request(VirtIOBlockReq *req);
+void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status);
 
 #endif
diff --git a/include/hw/vmapple/virtio-blk.h b/include/hw/vmapple/virtio-blk.h
new file mode 100644
index 00..b23106a3df
--- /dev/null
+++ b/include/hw/vmapple/virtio-blk.h
@@ -0,0 +1,39 @@
+/*
+ * VMApple specific VirtIO Block implementation
+ *
+ * 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_CFG_H
+#define HW_VMAPPLE_CFG_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+#include "hw/virtio/virtio-pci.h"
+#include "hw/virtio/virtio-blk.h"
+
+#define TYPE_VMAPPLE_VIRTIO_BLK "vmapple-virtio-blk"
+#define TYPE_VMAPPLE_VIRTIO_ROOT "vmapple-virtio-root"
+#define TYPE_VMAPPLE_VIRTIO_AUX "vmapple-virtio-aux"
+
+OBJECT_DECLARE_TYPE(VMAppleVirtIOBlk, VMAppleVirtIOBlkClass, 
VMAPPLE_VIRTIO_BLK)
+
+typedef struct VMAppleVirtIOBlkClass {
+/*< private >*/
+VirtIOBlkClass parent;
+/*< public >*/
+void (*get_config)(VirtIODevice *vdev, uint8_t *config);
+} VMAppleVirtIOBlkClass;
+
+typedef struct VMAppleVirtIOBlk {
+/*  */
+VirtIOBlock parent_obj;
+
+/*  */
+uint32_t apple_type;
+} VMAppleVirtIOBlk;
+
+#endif /* HW_VMAPPLE_CFG_H */
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 39e7f23fab..1645cdccbe 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -48,12 +48,12 @@ static void virtio_blk_init_request(VirtIOBlock *s, 
VirtQueue *vq,
 req->mr_next = NULL;
 }
 
-static void virtio_blk_free_request(VirtIOBlockReq *req)
+void virtio_blk_free_request(VirtIOBlockReq *req)
 {
 g_free(req);
 }
 
-static void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
+void virtio_blk_req_complete(VirtIOBlockReq *req, unsigned char status)
 {
 VirtIOBlock *s = req->dev;
 VirtIODevice *vdev = VIRTIO_DEVICE(s);
@@ -1121,8 +1121,18 @@ static int virtio_blk_handle_request(VirtIOBlockReq 
*req, MultiReqBuffer *mrb)
 break;
 }
 default:
-virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
-  

[PATCH v2 09/12] hw/vmapple/cfg: Introduce vmapple cfg region

2023-08-30 Thread Alexander Graf
Instead of device tree or other more standardized means, VMApple passes
platform configuration to the first stage boot loader in a binary encoded
format that resides at a dedicated RAM region in physical address space.

This patch models this configuration space as a qdev device which we can
then map at the fixed location in the address space. That way, we can
influence and annotate all configuration fields easily.

Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - Adapt to system_ss meson.build target
---
 include/hw/vmapple/cfg.h |  68 +
 hw/vmapple/cfg.c | 105 +++
 hw/vmapple/Kconfig   |   3 ++
 hw/vmapple/meson.build   |   1 +
 4 files changed, 177 insertions(+)
 create mode 100644 include/hw/vmapple/cfg.h
 create mode 100644 hw/vmapple/cfg.c

diff --git a/include/hw/vmapple/cfg.h b/include/hw/vmapple/cfg.h
new file mode 100644
index 00..3337064e44
--- /dev/null
+++ b/include/hw/vmapple/cfg.h
@@ -0,0 +1,68 @@
+/*
+ * VMApple Configuration Region
+ *
+ * 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_CFG_H
+#define HW_VMAPPLE_CFG_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+#include "net/net.h"
+
+typedef struct VMAppleCfg {
+uint32_t version; /* 0x000 */
+uint32_t nr_cpus; /* 0x004 */
+uint32_t unk1;/* 0x008 */
+uint32_t unk2;/* 0x00c */
+uint32_t unk3;/* 0x010 */
+uint32_t unk4;/* 0x014 */
+uint64_t ecid;/* 0x018 */
+uint64_t ram_size;/* 0x020 */
+uint32_t run_installer1;  /* 0x028 */
+uint32_t unk5;/* 0x02c */
+uint32_t unk6;/* 0x030 */
+uint32_t run_installer2;  /* 0x034 */
+uint32_t rnd; /* 0x038 */
+uint32_t unk7;/* 0x03c */
+MACAddr mac_en0;  /* 0x040 */
+uint8_t pad1[2];
+MACAddr mac_en1;  /* 0x048 */
+uint8_t pad2[2];
+MACAddr mac_wifi0;/* 0x050 */
+uint8_t pad3[2];
+MACAddr mac_bt0;  /* 0x058 */
+uint8_t pad4[2];
+uint8_t reserved[0xa0];   /* 0x060 */
+uint32_t cpu_ids[0x80];   /* 0x100 */
+uint8_t scratch[0x200];   /* 0x180 */
+char serial[32];  /* 0x380 */
+char unk8[32];/* 0x3a0 */
+char model[32];   /* 0x3c0 */
+uint8_t unk9[32]; /* 0x3e0 */
+uint32_t unk10;   /* 0x400 */
+char soc_name[32];/* 0x404 */
+} VMAppleCfg;
+
+#define TYPE_VMAPPLE_CFG "vmapple-cfg"
+OBJECT_DECLARE_SIMPLE_TYPE(VMAppleCfgState, VMAPPLE_CFG)
+
+struct VMAppleCfgState {
+/*  */
+SysBusDevice parent_obj;
+VMAppleCfg cfg;
+
+/*  */
+MemoryRegion mem;
+char *serial;
+char *model;
+char *soc_name;
+};
+
+#define VMAPPLE_CFG_SIZE 0x0001
+
+#endif /* HW_VMAPPLE_CFG_H */
diff --git a/hw/vmapple/cfg.c b/hw/vmapple/cfg.c
new file mode 100644
index 00..d48e3c3afa
--- /dev/null
+++ b/hw/vmapple/cfg.c
@@ -0,0 +1,105 @@
+/*
+ * VMApple Configuration Region
+ *
+ * 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/cfg.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+
+static void vmapple_cfg_reset(DeviceState *dev)
+{
+VMAppleCfgState *s = VMAPPLE_CFG(dev);
+VMAppleCfg *cfg;
+
+cfg = memory_region_get_ram_ptr(>mem);
+memset((void *)cfg, 0, VMAPPLE_CFG_SIZE);
+*cfg = s->cfg;
+}
+
+static void vmapple_cfg_realize(DeviceState *dev, Error **errp)
+{
+VMAppleCfgState *s = VMAPPLE_CFG(dev);
+uint32_t i;
+
+strncpy(s->cfg.serial, s->serial, sizeof(s->cfg.serial));
+strncpy(s->cfg.model, s->model, sizeof(s->cfg.model));
+strncpy(s->cfg.soc_name, s->soc_name, sizeof(s->cfg.soc_name));
+strncpy(s->cfg.unk8, "D/A", sizeof(s->cfg.soc_name));
+s->cfg.ecid = cpu_to_be64(s->cfg.ecid);
+s->cfg.version = 2;
+s->cfg.unk1 = 1;
+s->cfg.unk2 = 1;
+s->cfg.unk3 = 0x20;
+s->cfg.unk4 = 0;
+s->cfg.unk5 = 1;
+s->cfg.unk6 = 1;
+s->cfg.unk7 = 0;
+s->cfg.unk10 = 1;
+
+g_assert(s->cfg.nr_cpus < ARRAY_SIZE(s->cfg.cpu_ids));
+for (i = 0; i < s->cfg.nr_cpus; i++) {
+s->cfg.cpu_ids[i] = i;
+}
+}
+
+static void vmapple_cfg_init(Object *obj)
+{
+VMAppleCfgState *s = VMAPPLE_CFG(obj);
+
+memory_region_init_ram(>mem, obj, "VMApple Config", VMAPPLE_CFG_S

[PATCH v2 06/12] gpex: Allow more than 4 legacy IRQs

2023-08-30 Thread Alexander Graf
Some boards such as vmapple don't do real legacy PCI IRQ swizzling.
Instead, they just keep allocating more board IRQ lines for each new
legacy IRQ. Let's support that mode by giving instantiators a new
"nr_irqs" property they can use to support more than 4 legacy IRQ lines.
In this mode, GPEX will export more IRQ lines, one for each device.

Signed-off-by: Alexander Graf 
---
 include/hw/pci-host/gpex.h |  7 +++
 hw/arm/sbsa-ref.c  |  2 +-
 hw/arm/virt.c  |  2 +-
 hw/i386/microvm.c  |  2 +-
 hw/loongarch/virt.c|  2 +-
 hw/mips/loongson3_virt.c   |  2 +-
 hw/openrisc/virt.c | 12 ++--
 hw/pci-host/gpex.c | 36 +++-
 hw/riscv/virt.c| 12 ++--
 hw/xtensa/virt.c   |  2 +-
 10 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
index b0240bd768..098dc4d1cc 100644
--- a/include/hw/pci-host/gpex.h
+++ b/include/hw/pci-host/gpex.h
@@ -32,8 +32,6 @@ OBJECT_DECLARE_SIMPLE_TYPE(GPEXHost, GPEX_HOST)
 #define TYPE_GPEX_ROOT_DEVICE "gpex-root"
 OBJECT_DECLARE_SIMPLE_TYPE(GPEXRootState, GPEX_ROOT_DEVICE)
 
-#define GPEX_NUM_IRQS 4
-
 struct GPEXRootState {
 /*< private >*/
 PCIDevice parent_obj;
@@ -51,8 +49,9 @@ struct GPEXHost {
 MemoryRegion io_mmio;
 MemoryRegion io_ioport_window;
 MemoryRegion io_mmio_window;
-qemu_irq irq[GPEX_NUM_IRQS];
-int irq_num[GPEX_NUM_IRQS];
+uint32_t nr_irqs;
+qemu_irq *irq;
+int *irq_num;
 
 bool allow_unmapped_accesses;
 };
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index bc89eb4806..a786849238 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -681,7 +681,7 @@ static void create_pcie(SBSAMachineState *sms)
 /* Map IO port space */
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
qdev_get_gpio_in(sms->gic, irq + i));
 gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a13c658bbf..3a4ef3adc2 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1467,7 +1467,7 @@ static void create_pcie(VirtMachineState *vms)
 /* Map IO port space */
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
qdev_get_gpio_in(vms->gic, irq + i));
 gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 7227a2156c..9ca007b870 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -139,7 +139,7 @@ static void create_gpex(MicrovmMachineState *mms)
 mms->gpex.mmio64.base, mmio64_alias);
 }
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
x86ms->gsi[mms->gpex.irq + i]);
 }
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 2629128aed..36bfcea53b 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -533,7 +533,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, 
LoongArchMachineState *
 memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE,
 pio_alias);
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 sysbus_connect_irq(d, i,
qdev_get_gpio_in(pch_pic, 16 + i));
 gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index b74b358874..6d54f679eb 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -437,7 +437,7 @@ static inline void loongson3_virt_devices_init(MachineState 
*machine,
 virt_memmap[VIRT_PCIE_PIO].base, s->pio_alias);
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, virt_memmap[VIRT_PCIE_PIO].base);
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 irq = qdev_get_gpio_in(pic, PCIE_IRQ_BASE + i);
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
 gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ_BASE + i);
diff --git a/hw/openrisc/virt.c b/hw/openrisc/virt.c
index f8a68a6a6b..16a5676c4b 100644
--- a/hw/openrisc/virt.c
+++ b/hw/openrisc/virt.c
@@ -318,7 +318,7 @@ static void create_pcie_irq_map(void *fdt, char *nodename, 
int irq_base,
 {
 int pin, dev;
 uint32_t irq_map_stride = 0;
-uint32_t full_irq_map[GPEX_NUM_IRQS * GPEX_NUM_IRQS * 6] = {};
+uint32_t full_irq_map[PCI_NUM_PINS * PCI_NUM_PINS * 6] = {};
 uint32_t *irq_map = full_irq_map;

[PATCH v2 08/12] hw/vmapple/bdif: Introduce vmapple backdoor interface

2023-08-30 Thread Alexander Graf
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.

Signed-off-by: Alexander Graf 

---

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 00..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 {
+/*  */
+SysBusDevice parent_obj;
+
+/*  */
+BlockBackend *aux;
+BlockBackend *root;
+MemoryRegion mmio;
+};
+
+#define VMAPPLE_BDIF_SIZE 0x0020
+
+#endif /* HW_VMAPPLE_BDIF_H */
diff --git a/hw/vmapple/bdif.c b/hw/vmapple/bdif.c
new file mode 100644
index 00..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  0x
+#define DEVID_ROOT  0x
+#define DEVID_AUX   0x0001
+#define DEVID_USB   0x0010
+
+#define REG_STATUS  0x0
+#define REG_STATUS_ACTIVE BIT(0)
+#define REG_CFG 0x4
+#define REG_CFG_ACTIVEBIT(1)
+#define REG_UNK10x8
+#define REG_BUSY0x10
+#define REG_BUSY_READYBIT(0)
+#define REG_UNK20x400
+#define REG_CMD 0x408
+#define REG_NEXT_DEVICE 0x420
+#define REG_UNK30x434
+
+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 = 0x800;
+break;
+case DEVID_AUX:
+ret = 0x1;
+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(>sector);
+le2cpu_reqcmd(>data);
+le2cpu_reqcmd(>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

[PATCH v2 05/12] hw: Add vmapple subdir

2023-08-30 Thread Alexander Graf
We will introduce a number of devices that are specific to the vmapple
target machine. To keep them all tidily together, let's put them into
a single target directory.

Signed-off-by: Alexander Graf 
---
 MAINTAINERS | 6 ++
 meson.build | 1 +
 hw/vmapple/trace.h  | 1 +
 hw/Kconfig  | 1 +
 hw/meson.build  | 1 +
 hw/vmapple/Kconfig  | 1 +
 hw/vmapple/meson.build  | 0
 hw/vmapple/trace-events | 2 ++
 8 files changed, 13 insertions(+)
 create mode 100644 hw/vmapple/trace.h
 create mode 100644 hw/vmapple/Kconfig
 create mode 100644 hw/vmapple/meson.build
 create mode 100644 hw/vmapple/trace-events

diff --git a/MAINTAINERS b/MAINTAINERS
index 6111b6b4d9..3104e58eff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2573,6 +2573,12 @@ F: hw/usb/canokey.c
 F: hw/usb/canokey.h
 F: docs/system/devices/canokey.rst
 
+VMapple
+M: Alexander Graf 
+S: Maintained
+F: hw/vmapple/*
+F: include/hw/vmapple/*
+
 Subsystems
 --
 Overall Audio backends
diff --git a/meson.build b/meson.build
index 0d6a0015a1..dc5242a5f4 100644
--- a/meson.build
+++ b/meson.build
@@ -3282,6 +3282,7 @@ if have_system
 'hw/usb',
 'hw/vfio',
 'hw/virtio',
+'hw/vmapple',
 'hw/watchdog',
 'hw/xen',
 'hw/gpio',
diff --git a/hw/vmapple/trace.h b/hw/vmapple/trace.h
new file mode 100644
index 00..572adbefe0
--- /dev/null
+++ b/hw/vmapple/trace.h
@@ -0,0 +1 @@
+#include "trace/trace-hw_vmapple.h"
diff --git a/hw/Kconfig b/hw/Kconfig
index ba62ff6417..d99854afdd 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -41,6 +41,7 @@ source tpm/Kconfig
 source usb/Kconfig
 source virtio/Kconfig
 source vfio/Kconfig
+source vmapple/Kconfig
 source xen/Kconfig
 source watchdog/Kconfig
 
diff --git a/hw/meson.build b/hw/meson.build
index c7ac7d3d75..e156a6618f 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -40,6 +40,7 @@ subdir('tpm')
 subdir('usb')
 subdir('vfio')
 subdir('virtio')
+subdir('vmapple')
 subdir('watchdog')
 subdir('xen')
 subdir('xenpv')
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
new file mode 100644
index 00..8b13789179
--- /dev/null
+++ b/hw/vmapple/Kconfig
@@ -0,0 +1 @@
+
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
new file mode 100644
index 00..e69de29bb2
diff --git a/hw/vmapple/trace-events b/hw/vmapple/trace-events
new file mode 100644
index 00..9ccc579048
--- /dev/null
+++ b/hw/vmapple/trace-events
@@ -0,0 +1,2 @@
+# See docs/devel/tracing.rst for syntax documentation.
+
-- 
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






[PATCH v2 04/12] hvf: arm: Ignore writes to CNTP_CTL_EL0

2023-08-30 Thread Alexander Graf
MacOS unconditionally disables interrupts of the physical timer on boot
and then continues to use the virtual one. We don't really want to support
a full physical timer emulation, so let's just ignore those writes.

Signed-off-by: Alexander Graf 

---

v1 -> v2:

  - Add log message on write
---
 target/arm/hvf/hvf.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 486f90be1d..02db3dc908 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -11,6 +11,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
+#include "qemu/log.h"
 
 #include "sysemu/runstate.h"
 #include "sysemu/hvf.h"
@@ -179,6 +180,7 @@ void hvf_arm_init_debug(void)
 #define SYSREG_OSLSR_EL1  SYSREG(2, 0, 1, 1, 4)
 #define SYSREG_OSDLR_EL1  SYSREG(2, 0, 1, 3, 4)
 #define SYSREG_CNTPCT_EL0 SYSREG(3, 3, 14, 0, 1)
+#define SYSREG_CNTP_CTL_EL0   SYSREG(3, 3, 14, 2, 1)
 #define SYSREG_PMCR_EL0   SYSREG(3, 3, 9, 12, 0)
 #define SYSREG_PMUSERENR_EL0  SYSREG(3, 3, 9, 14, 0)
 #define SYSREG_PMCNTENSET_EL0 SYSREG(3, 3, 9, 12, 1)
@@ -1551,6 +1553,13 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, 
uint64_t val)
 case SYSREG_OSLAR_EL1:
 env->cp15.oslsr_el1 = val & 1;
 break;
+case SYSREG_CNTP_CTL_EL0:
+/*
+ * Guests should not rely on the physical counter, but macOS emits
+ * disable writes to it. Let it do so, but ignore the requests.
+ */
+qemu_log_mask(LOG_UNIMP, "Unsupported write to CNTP_CTL_EL0\n");
+break;
 case SYSREG_OSDLR_EL1:
 /* Dummy register */
 break;
-- 
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






[PATCH v2 02/12] hw/misc/pvpanic: Add MMIO interface

2023-08-30 Thread Alexander Graf
In addition to the ISA and PCI variants of pvpanic, let's add an MMIO
platform device that we can use in embedded arm environments.

Signed-off-by: Alexander Graf 
Reviewed-by: Philippe Mathieu-Daudé 
Tested-by: Philippe Mathieu-Daudé 

---

v1 -> v2:

  - Use SPDX header
  - Remove useless includes
  - Adapt to new meson.build target (system_ss)
---
 include/hw/misc/pvpanic.h |  1 +
 hw/misc/pvpanic-mmio.c| 61 +++
 hw/misc/Kconfig   |  4 +++
 hw/misc/meson.build   |  1 +
 4 files changed, 67 insertions(+)
 create mode 100644 hw/misc/pvpanic-mmio.c

diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index fab94165d0..f9e7c1ea17 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -20,6 +20,7 @@
 
 #define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
 #define TYPE_PVPANIC_PCI_DEVICE "pvpanic-pci"
+#define TYPE_PVPANIC_MMIO_DEVICE "pvpanic-mmio"
 
 #define PVPANIC_IOPORT_PROP "ioport"
 
diff --git a/hw/misc/pvpanic-mmio.c b/hw/misc/pvpanic-mmio.c
new file mode 100644
index 00..99a24f104c
--- /dev/null
+++ b/hw/misc/pvpanic-mmio.c
@@ -0,0 +1,61 @@
+/*
+ * QEMU simulated pvpanic device (MMIO frontend)
+ *
+ * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/qdev-properties.h"
+#include "hw/misc/pvpanic.h"
+#include "hw/sysbus.h"
+#include "standard-headers/linux/pvpanic.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicMMIOState, PVPANIC_MMIO_DEVICE)
+
+#define PVPANIC_MMIO_SIZE 0x2
+
+struct PVPanicMMIOState {
+SysBusDevice parent_obj;
+
+PVPanicState pvpanic;
+};
+
+static void pvpanic_mmio_initfn(Object *obj)
+{
+PVPanicMMIOState *s = PVPANIC_MMIO_DEVICE(obj);
+
+pvpanic_setup_io(>pvpanic, DEVICE(s), PVPANIC_MMIO_SIZE);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), >pvpanic.mr);
+}
+
+static Property pvpanic_mmio_properties[] = {
+DEFINE_PROP_UINT8("events", PVPanicMMIOState, pvpanic.events,
+  PVPANIC_PANICKED | PVPANIC_CRASH_LOADED),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pvpanic_mmio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+device_class_set_props(dc, pvpanic_mmio_properties);
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static const TypeInfo pvpanic_mmio_info = {
+.name  = TYPE_PVPANIC_MMIO_DEVICE,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(PVPanicMMIOState),
+.instance_init = pvpanic_mmio_initfn,
+.class_init= pvpanic_mmio_class_init,
+};
+
+static void pvpanic_register_types(void)
+{
+type_register_static(_mmio_info);
+}
+
+type_init(pvpanic_register_types)
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 6996d265e4..b69746a60a 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -125,6 +125,10 @@ config PVPANIC_ISA
 depends on ISA_BUS
 select PVPANIC_COMMON
 
+config PVPANIC_MMIO
+bool
+select PVPANIC_COMMON
+
 config AUX
 bool
 select I2C
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 892f8b91c5..63821d6040 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -116,6 +116,7 @@ system_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: 
files('armsse-mhu.c'))
 
 system_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
 system_ss.add(when: 'CONFIG_PVPANIC_PCI', if_true: files('pvpanic-pci.c'))
+system_ss.add(when: 'CONFIG_PVPANIC_MMIO', if_true: files('pvpanic-mmio.c'))
 system_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
 system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
   'aspeed_hace.c',
-- 
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




Re: [PATCH 12/12] hw/vmapple/vmapple: Add vmapple machine type

2023-08-30 Thread Alexander Graf


On 20.06.23 19:35, Bernhard Beschow wrote:



Am 14. Juni 2023 22:57:34 UTC schrieb Alexander Graf :

Apple defines a new "vmapple" machine type as part of its proprietary
macOS Virtualization.Framework vmm. This machine type is similar to the
virt one, but with subtle differences in base devices, a few special
vmapple device additions and a vastly different boot chain.

This patch reimplements this machine type in QEMU. To use it, you
have to have a readily installed version of macOS for VMApple,
run on macOS with -accel hvf, pass the Virtualization.Framework
boot rom (AVPBooter) in via -bios, pass the aux and root volume as pflash
and pass aux and root volume as virtio drives. In addition, you also
need to find the machine UUID and pass that as -M vmapple,uuid= parameter:

$ qemu-system-aarch64 -accel hvf -M vmapple,uuid=0x1234 -m 4G \
-bios 
/System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPBooter.vmapple2.bin
-drive file=aux,if=pflash,format=raw \
-drive file=root,if=pflash,format=raw \
-drive file=aux,if=none,id=aux,format=raw \
-device virtio-blk-pci,drive=aux,x-apple-type=2 \
-drive file=root,if=none,id=root,format=raw \
-device virtio-blk-pci,drive=root,x-apple-type=1

With all these in place, you should be able to see macOS booting
successfully.

This documentation seems valuable for the QEMU manual. But AFAICS there is no 
documentation like this added to the QEMU manual in this series. This means that it'll 
get "lost". How about adding it, possibly in this patch?



Thanks, I love the idea :). Let me do that for v2!




Note that I'm not able to test this series. I'm just seeing the 
valuable-information-in-the-commit-message-which-will-get-lost pattern.


Signed-off-by: Alexander Graf 
---
hw/vmapple/Kconfig |  19 ++
hw/vmapple/meson.build |   1 +
hw/vmapple/vmapple.c   | 661 +
3 files changed, 681 insertions(+)
create mode 100644 hw/vmapple/vmapple.c

diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index ba37fc5b81..7a2375dc95 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -9,3 +9,22 @@ config VMAPPLE_CFG

config VMAPPLE_PVG
 bool
+
+config VMAPPLE
+bool
+depends on ARM && HVF
+default y if ARM && HVF
+imply PCI_DEVICES
+select ARM_GIC
+select PLATFORM_BUS
+select PCI_EXPRESS
+select PCI_EXPRESS_GENERIC_BRIDGE
+select PL011 # UART
+select PL031 # RTC
+select PL061 # GPIO
+select GPIO_PWR
+select PVPANIC_MMIO
+select VMAPPLE_AES
+select VMAPPLE_BDIF
+select VMAPPLE_CFG
+select VMAPPLE_PVG
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
index 31fec87156..d732873d35 100644
--- a/hw/vmapple/meson.build
+++ b/hw/vmapple/meson.build
@@ -2,3 +2,4 @@ softmmu_ss.add(when: 'CONFIG_VMAPPLE_AES',  if_true: 
files('aes.c'))
softmmu_ss.add(when: 'CONFIG_VMAPPLE_BDIF', if_true: files('bdif.c'))
softmmu_ss.add(when: 'CONFIG_VMAPPLE_CFG',  if_true: files('cfg.c'))
softmmu_ss.add(when: 'CONFIG_VMAPPLE_PVG',  if_true: [files('apple-gfx.m'), 
pvg, metal])
+specific_ss.add(when: 'CONFIG_VMAPPLE', if_true: files('vmapple.c'))
diff --git a/hw/vmapple/vmapple.c b/hw/vmapple/vmapple.c
new file mode 100644
index 00..5d3fe54b96
--- /dev/null
+++ b/hw/vmapple/vmapple.c
@@ -0,0 +1,661 @@
+/*
+ * VMApple machine emulation
+ *
+ * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Is an "All Rights Reserved" wording compatible with the GPL?



IANAL. You will find the pattern commonly across the code base already. 
My understanding is that all rights are reserved, but additionally I 
grant you the permissions of the GPL.



Alex





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




Re: [PATCH 05/12] hw/virtio: Add support for apple virtio-blk

2023-08-24 Thread Alexander Graf


On 16.06.23 13:48, Kevin Wolf wrote:


Am 15.06.2023 um 00:56 hat Alexander Graf geschrieben:

Apple has its own virtio-blk PCI device ID where it deviates from the
official virtio-pci spec slightly: It puts a new "apple type"
field at a static offset in config space and introduces a new discard
command.

In other words, it's a different device. We shouldn't try to
differentiate only with a property, but actually model it as a separate
device.



I agree and is what I tried at first, but how do I change behavior of a 
virtio-blk-pci subclass all the way down to its virtio-blk 
implementation which lives completely outside of the scope of the 
respective class?


The best thing I could come up with was the QEMU internal qom property 
x-apple-type. Happy to split them: Make the change of virtio-blk 
behavior depend on the property and make all of the PCI device/vendor 
swapping depend on a new class which then sets the x-apple-type.






This patch adds a new qdev property called "apple-type" to virtio-blk-pci.
When that property is set, we assume the virtio-blk device is an Apple one
of the specific type and act accordingly.

Do we have any information on what the number in "apple-type" actually
means or do we have to treat it as a black box?



I have ideas, but no documentation. It's an enum space that defines 
different types of devices (AUX device, root device, etc)






Signed-off-by: Alexander Graf 
---
  hw/block/virtio-blk.c   | 23 +
  hw/virtio/virtio-blk-pci.c  |  7 +++
  include/hw/pci/pci_ids.h|  1 +
  include/hw/virtio/virtio-blk.h  |  1 +
  include/standard-headers/linux/virtio_blk.h |  3 +++
  5 files changed, 35 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 39e7f23fab..76b85bb3cb 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1120,6 +1120,20 @@ static int virtio_blk_handle_request(VirtIOBlockReq 
*req, MultiReqBuffer *mrb)

  break;
  }
+case VIRTIO_BLK_T_APPLE1:

Can we have a more descriptive name?


+{
+if (s->conf.x_apple_type) {
+/* Only valid on Apple Virtio */
+char buf[iov_size(in_iov, in_num)];
+memset(buf, 0, sizeof(buf));
+iov_from_buf(in_iov, in_num, 0, buf, sizeof(buf));
+virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);

So this is a command that simply fills the guest buffer with zeros
without accessing the disk content? Weird, but ok, if that's what they
are doing...

The commit message talks about a discard command. I would have expected
a command that discards/unmaps data from the disk. I think it would be
good to call it something else in the commit message if it has nothing
to do with this.



You're completely right. I looked it up again and turns out this is 
actually a barrier command. Any ideas on how to best implement an actual 
barrier in virtio-blk? Otherwise I'll just ignore it and always return 
S_OK. No need for the memset muckery above.






+} else {
+virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+}
+virtio_blk_free_request(req);
+break;
+}
  default:
  virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
  virtio_blk_free_request(req);
@@ -1351,6 +1365,10 @@ static void virtio_blk_update_config(VirtIODevice *vdev, 
uint8_t *config)
  } else {
  blkcfg.zoned.model = VIRTIO_BLK_Z_NONE;
  }
+if (s->conf.x_apple_type) {
+/* Apple abuses the same location for its type id */
+blkcfg.max_secure_erase_sectors = s->conf.x_apple_type;

Ideally, blkcfg would contain a union there. Since this is a type
imported from the kernel, we can't change it inside of QEMU only. Works
for me with this comment.


+}
  memcpy(config, , s->config_size);
  }

@@ -1625,6 +1643,10 @@ static void virtio_blk_device_realize(DeviceState *dev, 
Error **errp)

  s->config_size = virtio_get_config_size(_blk_cfg_size_params,
  s->host_features);
+if (s->conf.x_apple_type) {
+/* Apple Virtio puts the blk type at 0x3c, make sure we have space. */
+s->config_size = MAX(s->config_size, 0x3d);
+}
  virtio_init(vdev, VIRTIO_ID_BLOCK, s->config_size);

  s->blk = conf->conf.blk;
@@ -1734,6 +1756,7 @@ static Property virtio_blk_properties[] = {
 conf.max_write_zeroes_sectors, 
BDRV_REQUEST_MAX_SECTORS),
  DEFINE_PROP_BOOL("x-enable-wce-if-config-wce", VirtIOBlock,
   conf.x_enable_wce_if_config_wce, true),
+DEFINE_PROP_UINT32("x-apple-type", VirtIOBlock, conf.x_apple_type, 0),

In a separate device, this would probably be called "apple-type"
(without "x-") like promised in the commit message?

If not, what is the reason for 

Re: [PATCH 10/12] hw/vmapple/cfg: Introduce vmapple cfg region

2023-08-22 Thread Alexander Graf


On 16.06.23 12:47, Philippe Mathieu-Daudé wrote:


On 15/6/23 00:57, Alexander Graf wrote:

Instead of device tree or other more standardized means, VMApple passes
platform configuration to the first stage boot loader in a binary 
encoded

format that resides at a dedicated RAM region in physical address space.

This patch models this configuration space as a qdev device which we can
then map at the fixed location in the address space. That way, we can
influence and annotate all configuration fields easily.

Signed-off-by: Alexander Graf 
---
  hw/vmapple/Kconfig   |   3 ++
  hw/vmapple/cfg.c | 105 +++
  hw/vmapple/meson.build   |   1 +
  include/hw/vmapple/cfg.h |  68 +
  4 files changed, 177 insertions(+)
  create mode 100644 hw/vmapple/cfg.c
  create mode 100644 include/hw/vmapple/cfg.h




diff --git a/hw/vmapple/cfg.c b/hw/vmapple/cfg.c
new file mode 100644
index 00..d48e3c3afa
--- /dev/null
+++ b/hw/vmapple/cfg.c
@@ -0,0 +1,105 @@
+/*
+ * VMApple Configuration Region
+ *
+ * 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/cfg.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+
+static void vmapple_cfg_reset(DeviceState *dev)
+{
+    VMAppleCfgState *s = VMAPPLE_CFG(dev);
+    VMAppleCfg *cfg;
+
+    cfg = memory_region_get_ram_ptr(>mem);
+    memset((void *)cfg, 0, VMAPPLE_CFG_SIZE);


I'm a bit confused here: DeviceReset() handler is called _after_
DeviceRealize().



Yes. In Realize we set up s->cfg (the template). In reset, we fetch a 
pointer to the guest exposed memory region (cfg), wipe it and then copy 
the template over it in the next line:






+    *cfg = s->cfg;



[...]





diff --git a/include/hw/vmapple/cfg.h b/include/hw/vmapple/cfg.h
new file mode 100644
index 00..3337064e44
--- /dev/null
+++ b/include/hw/vmapple/cfg.h
@@ -0,0 +1,68 @@
+/*
+ * VMApple Configuration Region
+ *
+ * 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_CFG_H
+#define HW_VMAPPLE_CFG_H
+
+#include "hw/sysbus.h"
+#include "qom/object.h"
+#include "net/net.h"
+
+typedef struct VMAppleCfg {
+    uint32_t version; /* 0x000 */
+    uint32_t nr_cpus; /* 0x004 */
+    uint32_t unk1;    /* 0x008 */
+    uint32_t unk2;    /* 0x00c */
+    uint32_t unk3;    /* 0x010 */
+    uint32_t unk4;    /* 0x014 */
+    uint64_t ecid;    /* 0x018 */
+    uint64_t ram_size;    /* 0x020 */
+    uint32_t run_installer1;  /* 0x028 */
+    uint32_t unk5;    /* 0x02c */
+    uint32_t unk6;    /* 0x030 */
+    uint32_t run_installer2;  /* 0x034 */
+    uint32_t rnd; /* 0x038 */
+    uint32_t unk7;    /* 0x03c */
+    MACAddr mac_en0;  /* 0x040 */
+    uint8_t pad1[2];
+    MACAddr mac_en1;  /* 0x048 */
+    uint8_t pad2[2];
+    MACAddr mac_wifi0;    /* 0x050 */
+    uint8_t pad3[2];
+    MACAddr mac_bt0;  /* 0x058 */
+    uint8_t pad4[2];
+    uint8_t reserved[0xa0];   /* 0x060 */
+    uint32_t cpu_ids[0x80];   /* 0x100 */
+    uint8_t scratch[0x200];   /* 0x180 */
+    char serial[32];  /* 0x380 */
+    char unk8[32];    /* 0x3a0 */
+    char model[32];   /* 0x3c0 */
+    uint8_t unk9[32]; /* 0x3e0 */
+    uint32_t unk10;   /* 0x400 */
+    char soc_name[32];    /* 0x404 */
+} VMAppleCfg;


Since you access this structure via qdev properties (which is
good), then we can restrict its definition to cfg.c (no need to
expose it).



This struct is part of VMAppleCfgState which (unless we go through 
pointers and allocate dynamically - bleks) means it needs to know the 
size of the struct which again means it needs to be part of the header :)



Alex





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




Re: [PATCH 09/12] hw/vmapple/bdif: Introduce vmapple backdoor interface

2023-08-22 Thread Alexander Graf


On 16.06.23 12:39, Philippe Mathieu-Daudé wrote:


On 15/6/23 00:56, 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.

Signed-off-by: Alexander Graf 
---
  hw/vmapple/Kconfig    |   2 +
  hw/vmapple/bdif.c | 245 ++
  hw/vmapple/meson.build    |   1 +
  hw/vmapple/trace-events   |   5 +
  include/hw/vmapple/bdif.h |  31 +


Please enable scripts/git.orderfile if possible.



Sure, happy to :)





+#define REG_DEVID_MASK  0x
+#define DEVID_ROOT  0x
+#define DEVID_AUX   0x0001
+#define DEVID_USB   0x0010
+
+#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




+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 = 0x800;
+    break;
+    case DEVID_AUX:
+    ret = 0x1;
+    break;
+    }
+    break;
+    }
+
+    trace_bdif_read(offset, size, ret);
+    return ret;
+}




+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,


IIUC your implementation is using (min, max) = (4, 4):
i.e. if the guest emits a 64-bit read at offset 0, we want to return
both REG_STATUS/REG_CFG registers.



I don't know if the BDIF device carries those semantics. Today, I'm only 
seeing 32bit accesses which is what I can vouch for. Will 8bit accesses 
go to a different register space or just access a subset of the 32bit 
register? I don't know :)


The same applies to 64bit ones. For all I know, they might as well end 
up as completely different registers.



Alex





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




Re: [PATCH 00/12] Introduce new vmapple machine type

2023-06-21 Thread Alexander Graf

Hi Mads,


On 20.06.23 13:17, Mads Ynddal wrote:




On 15 Jun 2023, at 00.40, Alexander Graf  wrote:

This patch set introduces a new ARM and HVF specific machine type
called "vmapple". It mimicks the device model that Apple's proprietary
Virtualization.Framework exposes, but implements it in QEMU.

With this new machine type, you can run macOS guests on Apple Silicon
systems via HVF. To do so, you need to first install macOS using
Virtualization.Framework onto a virtual disk image using a tool like
macosvm (https://github.com/s-u/macosvm)

  $ macosvm --disk disk.img,size=32g --aux aux.img \
--restore UniversalMac_12.0.1_21A559_Restore.ipsw vm.json

Then, extract the ECID from the installed VM:

  $ cat "$DIR/macosvm.json" | python3 -c \
  'import json,sys;obj=json.load(sys.stdin);print(obj["machineId"]) |\
  base64 -d | plutil -extract ECID raw -

Beware, that the file will be called 'vm.json' and DIR is undefined following
the previous line. Also, it's missing a single-quote at the end of
`["machineId"])`.



Thanks :)





In addition, cut off the first 16kb of the aux.img:

  $ dd if=aux.img of=aux.img.trimmed bs=$(( 0x4000 )) skip=1

Now, you can just launch QEMU with the bits generated above:

  $ qemu-system-aarch64 -serial mon:stdio\
  -m 4G  \
  -M vmapple,uuid=6240349656165161789\
  -bios /Sys*/Lib*/Fra*/Virtualization.f*/R*/AVPBooter.vmapple2.bin  \
  -pflash aux.img.trimmed\
  -pflash disk.img   \
  -drive file=disk.img,if=none,id=root   \
  -device virtio-blk-pci,drive=root,x-apple-type=1   \
  -drive file=aux.img.trimmed,if=none,id=aux \
  -device virtio-blk-pci,drive=aux,x-apple-type=2\
  -accel hvf -no-reboot

Just for clarity, I'd add that the 'vmapple,uuid=...' has to be set to the
ECID the previous step.

You haven't defined a display, but I'm not sure if that is on purpose to
show a minimal setup. I had to add '-display sdl' for it to fully work.



Weird, I do get a normal cocoa output screen by default.





There are a few limitations with this implementation:

  - Only runs on macOS because it relies on
ParavirtualizesGraphics.Framework
  - Something is not fully correct on interrupt delivery or
similar - the keyboard does not work
  - No Rosetta in the guest because we lack the private
entitlement to enable TSO

Would it be possible to mitigate the keyboard issue using an emulated USB
keyboard? I tried poking around with it, but with no success.



Unfortunately I was not able to get USB stable inside the guest. This 
may be an issue with interrupt propagation: With usb-kbd I see macOS not 
pick up key up or down events in time.



Alex





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




Re: [PATCH 03/12] hvf: Increase number of possible memory slots

2023-06-21 Thread Alexander Graf

Hi Philippe,


On 16.06.23 12:28, Philippe Mathieu-Daudé wrote:



On 15/6/23 00:40, Alexander Graf wrote:

For PVG we will need more than the current 32 possible memory slots.
Bump the limit to 512 instead.

Signed-off-by: Alexander Graf 
---
  accel/hvf/hvf-accel-ops.c | 2 +-
  include/sysemu/hvf_int.h  | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index 9c3da03c94..bf0caaa852 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -88,7 +88,7 @@ struct mac_slot {
  uint64_t gva;
  };

-struct mac_slot mac_slots[32];
+struct mac_slot mac_slots[512];

  static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
  {
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
index 6ab119e49f..c7623a2c09 100644
--- a/include/sysemu/hvf_int.h
+++ b/include/sysemu/hvf_int.h
@@ -40,7 +40,7 @@ typedef struct hvf_vcpu_caps {

  struct HVFState {
  AccelState parent;
-    hvf_slot slots[32];
+    hvf_slot slots[512];
  int num_slots;

  hvf_vcpu_caps *hvf_caps;


Please add a definition in this header (using in ops.c).



Happy to :)




In order to save memory and woods, what about keeping
32 on x86 and only raising to 512 on arm?



I am hoping that someone takes the apple-gfx driver and enables it for 
x86 as well, so I'd rather keep them consistent.


Alex




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




[PATCH 12/12] hw/vmapple/vmapple: Add vmapple machine type

2023-06-14 Thread Alexander Graf
Apple defines a new "vmapple" machine type as part of its proprietary
macOS Virtualization.Framework vmm. This machine type is similar to the
virt one, but with subtle differences in base devices, a few special
vmapple device additions and a vastly different boot chain.

This patch reimplements this machine type in QEMU. To use it, you
have to have a readily installed version of macOS for VMApple,
run on macOS with -accel hvf, pass the Virtualization.Framework
boot rom (AVPBooter) in via -bios, pass the aux and root volume as pflash
and pass aux and root volume as virtio drives. In addition, you also
need to find the machine UUID and pass that as -M vmapple,uuid= parameter:

$ qemu-system-aarch64 -accel hvf -M vmapple,uuid=0x1234 -m 4G \
-bios 
/System/Library/Frameworks/Virtualization.framework/Versions/A/Resources/AVPBooter.vmapple2.bin
-drive file=aux,if=pflash,format=raw \
-drive file=root,if=pflash,format=raw \
-drive file=aux,if=none,id=aux,format=raw \
-device virtio-blk-pci,drive=aux,x-apple-type=2 \
-drive file=root,if=none,id=root,format=raw \
-device virtio-blk-pci,drive=root,x-apple-type=1

With all these in place, you should be able to see macOS booting
successfully.

Signed-off-by: Alexander Graf 
---
 hw/vmapple/Kconfig |  19 ++
 hw/vmapple/meson.build |   1 +
 hw/vmapple/vmapple.c   | 661 +
 3 files changed, 681 insertions(+)
 create mode 100644 hw/vmapple/vmapple.c

diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index ba37fc5b81..7a2375dc95 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -9,3 +9,22 @@ config VMAPPLE_CFG
 
 config VMAPPLE_PVG
 bool
+
+config VMAPPLE
+bool
+depends on ARM && HVF
+default y if ARM && HVF
+imply PCI_DEVICES
+select ARM_GIC
+select PLATFORM_BUS
+select PCI_EXPRESS
+select PCI_EXPRESS_GENERIC_BRIDGE
+select PL011 # UART
+select PL031 # RTC
+select PL061 # GPIO
+select GPIO_PWR
+select PVPANIC_MMIO
+select VMAPPLE_AES
+select VMAPPLE_BDIF
+select VMAPPLE_CFG
+select VMAPPLE_PVG
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
index 31fec87156..d732873d35 100644
--- a/hw/vmapple/meson.build
+++ b/hw/vmapple/meson.build
@@ -2,3 +2,4 @@ softmmu_ss.add(when: 'CONFIG_VMAPPLE_AES',  if_true: 
files('aes.c'))
 softmmu_ss.add(when: 'CONFIG_VMAPPLE_BDIF', if_true: files('bdif.c'))
 softmmu_ss.add(when: 'CONFIG_VMAPPLE_CFG',  if_true: files('cfg.c'))
 softmmu_ss.add(when: 'CONFIG_VMAPPLE_PVG',  if_true: [files('apple-gfx.m'), 
pvg, metal])
+specific_ss.add(when: 'CONFIG_VMAPPLE', if_true: files('vmapple.c'))
diff --git a/hw/vmapple/vmapple.c b/hw/vmapple/vmapple.c
new file mode 100644
index 00..5d3fe54b96
--- /dev/null
+++ b/hw/vmapple/vmapple.c
@@ -0,0 +1,661 @@
+/*
+ * VMApple machine emulation
+ *
+ * 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.
+ *
+ * VMApple is the device model that the macOS built-in hypervisor called
+ * "Virtualization.framework" exposes to Apple Silicon macOS guests. The
+ * machine model in this file implements the same device model in QEMU, but
+ * does not use any code from Virtualization.Framework.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/help-texts.h"
+#include "qemu/datadir.h"
+#include "qemu/units.h"
+#include "qemu/option.h"
+#include "monitor/qdev.h"
+#include "qapi/error.h"
+#include "hw/sysbus.h"
+#include "hw/arm/boot.h"
+#include "hw/arm/primecell.h"
+#include "hw/boards.h"
+#include "net/net.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/runstate.h"
+#include "sysemu/kvm.h"
+#include "sysemu/hvf.h"
+#include "hw/loader.h"
+#include "qapi/error.h"
+#include "qemu/bitops.h"
+#include "qemu/error-report.h"
+#include "qemu/module.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/virtio/virtio-pci.h"
+#include "hw/qdev-properties.h"
+#include "hw/intc/arm_gic.h"
+#include "hw/intc/arm_gicv3_common.h"
+#include "hw/irq.h"
+#include "qapi/visitor.h"
+#include "qapi/qapi-visit-common.h"
+#include "standard-headers/linux/input.h"
+#include "target/arm/internals.h"
+#include "target/arm/kvm_arm.h"
+#include "hw/char/pl011.h"
+#include "qemu/guest-random.h"
+#include "sysemu/reset.h"
+#include "qemu/log.h"
+#include "hw/vmapple/cfg.h"
+#include "hw/misc/pvpanic.h"
+#include "hw/vmapple/bdif.h"
+
+struct VMAppleMachineClass {
+MachineClass parent;
+};
+
+struct VM

[PATCH 11/12] hw/vmapple/apple-gfx: Introduce ParavirtualizedGraphics.Framework support

2023-06-14 Thread Alexander Graf
MacOS provides a framework (library) that allows any vmm to implement a
paravirtualized 3d graphics passthrough to the host metal stack called
ParavirtualizedGraphics.Framework (PVG). The library abstracts away
almost every aspect of the paravirtualized device model and only provides
and receives callbacks on MMIO access as well as to share memory address
space between the VM and PVG.

This patch implements a QEMU device that drives PVG for the VMApple
variant of it.

Signed-off-by: Alexander Graf 
---
 hw/vmapple/Kconfig  |   3 +
 hw/vmapple/apple-gfx.m  | 578 
 hw/vmapple/meson.build  |   1 +
 hw/vmapple/trace-events |  22 ++
 meson.build |   4 +
 5 files changed, 608 insertions(+)
 create mode 100644 hw/vmapple/apple-gfx.m

diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index 542426a740..ba37fc5b81 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -6,3 +6,6 @@ config VMAPPLE_BDIF
 
 config VMAPPLE_CFG
 bool
+
+config VMAPPLE_PVG
+bool
diff --git a/hw/vmapple/apple-gfx.m b/hw/vmapple/apple-gfx.m
new file mode 100644
index 00..97dd2cd9ae
--- /dev/null
+++ b/hw/vmapple/apple-gfx.m
@@ -0,0 +1,578 @@
+/*
+ * QEMU Apple ParavirtualizedGraphics.framework device
+ *
+ * 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.
+ *
+ * ParavirtualizedGraphics.framework is a set of libraries that macOS provides
+ * which implements 3d graphics passthrough to the host as well as a
+ * proprietary guest communication channel to drive it. This device model
+ * implements support to drive that library from within QEMU.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+#include "hw/sysbus.h"
+#include "hw/pci/msi.h"
+#include "crypto/hash.h"
+#include "sysemu/cpus.h"
+#include "ui/console.h"
+#include "monitor/monitor.h"
+#import 
+
+#define TYPE_APPLE_GFX  "apple-gfx"
+
+#define MAX_MRS 512
+
+static const PGDisplayCoord_t apple_gfx_modes[] = {
+{ .x = 1440, .y = 1080 },
+{ .x = 1280, .y = 1024 },
+};
+
+/*
+ * We have to map PVG memory into our address space. Use the one below
+ * as base start address. In normal linker setups it points to a free
+ * memory range.
+ */
+#define APPLE_GFX_BASE_VA ((void *)(uintptr_t)0x5000UL)
+
+/*
+ * ParavirtualizedGraphics.Framework only ships header files for the x86
+ * variant which does not include IOSFC descriptors and host devices. We add
+ * their definitions here so that we can also work with the ARM version.
+ */
+typedef bool(^IOSFCRaiseInterrupt)(uint32_t vector);
+typedef bool(^IOSFCUnmapMemory)(void *a, void *b, void *c, void *d, void *e, 
void *f);
+typedef bool(^IOSFCMapMemory)(uint64_t phys, uint64_t len, bool ro, void **va, 
void *e, void *f);
+
+@interface PGDeviceDescriptorExt : PGDeviceDescriptor
+@property (readwrite, nonatomic) bool usingIOSurfaceMapper;
+@end
+
+@interface PGIOSurfaceHostDeviceDescriptor : NSObject
+-(PGIOSurfaceHostDeviceDescriptor *)init;
+@property (readwrite, nonatomic, copy, nullable) IOSFCMapMemory mapMemory;
+@property (readwrite, nonatomic, copy, nullable) IOSFCUnmapMemory unmapMemory;
+@property (readwrite, nonatomic, copy, nullable) IOSFCRaiseInterrupt 
raiseInterrupt;
+@end
+
+@interface PGIOSurfaceHostDevice : NSObject
+-(void)initWithDescriptor:(PGIOSurfaceHostDeviceDescriptor *) desc;
+-(uint32_t)mmioReadAtOffset:(size_t) offset;
+-(void)mmioWriteAtOffset:(size_t) offset value:(uint32_t)value;
+@end
+
+typedef struct AppleGFXMR {
+QTAILQ_ENTRY(AppleGFXMR) node;
+hwaddr pa;
+void *va;
+uint64_t len;
+} AppleGFXMR;
+
+typedef QTAILQ_HEAD(, AppleGFXMR) AppleGFXMRList;
+
+typedef struct AppleGFXTask {
+QTAILQ_ENTRY(AppleGFXTask) node;
+void *mem;
+uint64_t len;
+} AppleGFXTask;
+
+typedef QTAILQ_HEAD(, AppleGFXTask) AppleGFXTaskList;
+
+typedef struct AppleGFXState {
+/* Private */
+SysBusDevice parent_obj;
+
+/* Public */
+qemu_irq irq_gfx;
+qemu_irq irq_iosfc;
+MemoryRegion iomem_gfx;
+MemoryRegion iomem_iosfc;
+id pgdev;
+id pgdisp;
+PGIOSurfaceHostDevice *pgiosfc;
+AppleGFXMRList mrs;
+AppleGFXTaskList tasks;
+QemuConsole *con;
+void *vram;
+id mtl;
+id texture;
+bool handles_frames;
+bool new_frame;
+bool cursor_show;
+DisplaySurface *surface;
+QEMUCursor *cursor;
+} AppleGFXState;
+
+
+OBJECT_DECLARE_SIMPLE_TYPE(AppleGFXState, APPLE_GFX)
+
+static AppleGFXTask *apple_gfx_new_task(AppleGFXState *s, uint64_t len)
+{
+void *base = APPLE_GFX_BASE_VA;
+AppleGFXTask *task;
+
+QTAILQ_FOREACH(task, >tasks, nod

[PATCH 10/12] hw/vmapple/cfg: Introduce vmapple cfg region

2023-06-14 Thread Alexander Graf
Instead of device tree or other more standardized means, VMApple passes
platform configuration to the first stage boot loader in a binary encoded
format that resides at a dedicated RAM region in physical address space.

This patch models this configuration space as a qdev device which we can
then map at the fixed location in the address space. That way, we can
influence and annotate all configuration fields easily.

Signed-off-by: Alexander Graf 
---
 hw/vmapple/Kconfig   |   3 ++
 hw/vmapple/cfg.c | 105 +++
 hw/vmapple/meson.build   |   1 +
 include/hw/vmapple/cfg.h |  68 +
 4 files changed, 177 insertions(+)
 create mode 100644 hw/vmapple/cfg.c
 create mode 100644 include/hw/vmapple/cfg.h

diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index 388a2bc60c..542426a740 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -3,3 +3,6 @@ config VMAPPLE_AES
 
 config VMAPPLE_BDIF
 bool
+
+config VMAPPLE_CFG
+bool
diff --git a/hw/vmapple/cfg.c b/hw/vmapple/cfg.c
new file mode 100644
index 00..d48e3c3afa
--- /dev/null
+++ b/hw/vmapple/cfg.c
@@ -0,0 +1,105 @@
+/*
+ * VMApple Configuration Region
+ *
+ * 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/cfg.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "qapi/error.h"
+
+static void vmapple_cfg_reset(DeviceState *dev)
+{
+VMAppleCfgState *s = VMAPPLE_CFG(dev);
+VMAppleCfg *cfg;
+
+cfg = memory_region_get_ram_ptr(>mem);
+memset((void *)cfg, 0, VMAPPLE_CFG_SIZE);
+*cfg = s->cfg;
+}
+
+static void vmapple_cfg_realize(DeviceState *dev, Error **errp)
+{
+VMAppleCfgState *s = VMAPPLE_CFG(dev);
+uint32_t i;
+
+strncpy(s->cfg.serial, s->serial, sizeof(s->cfg.serial));
+strncpy(s->cfg.model, s->model, sizeof(s->cfg.model));
+strncpy(s->cfg.soc_name, s->soc_name, sizeof(s->cfg.soc_name));
+strncpy(s->cfg.unk8, "D/A", sizeof(s->cfg.soc_name));
+s->cfg.ecid = cpu_to_be64(s->cfg.ecid);
+s->cfg.version = 2;
+s->cfg.unk1 = 1;
+s->cfg.unk2 = 1;
+s->cfg.unk3 = 0x20;
+s->cfg.unk4 = 0;
+s->cfg.unk5 = 1;
+s->cfg.unk6 = 1;
+s->cfg.unk7 = 0;
+s->cfg.unk10 = 1;
+
+g_assert(s->cfg.nr_cpus < ARRAY_SIZE(s->cfg.cpu_ids));
+for (i = 0; i < s->cfg.nr_cpus; i++) {
+s->cfg.cpu_ids[i] = i;
+}
+}
+
+static void vmapple_cfg_init(Object *obj)
+{
+VMAppleCfgState *s = VMAPPLE_CFG(obj);
+
+memory_region_init_ram(>mem, obj, "VMApple Config", VMAPPLE_CFG_SIZE,
+   _fatal);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), >mem);
+
+s->serial = (char *)"1234";
+s->model = (char *)"VM0001";
+s->soc_name = (char *)"Apple M1 (Virtual)";
+}
+
+static Property vmapple_cfg_properties[] = {
+DEFINE_PROP_UINT32("nr-cpus", VMAppleCfgState, cfg.nr_cpus, 1),
+DEFINE_PROP_UINT64("ecid", VMAppleCfgState, cfg.ecid, 0),
+DEFINE_PROP_UINT64("ram-size", VMAppleCfgState, cfg.ram_size, 0),
+DEFINE_PROP_UINT32("run_installer1", VMAppleCfgState, cfg.run_installer1, 
0),
+DEFINE_PROP_UINT32("run_installer2", VMAppleCfgState, cfg.run_installer2, 
0),
+DEFINE_PROP_UINT32("rnd", VMAppleCfgState, cfg.rnd, 0),
+DEFINE_PROP_MACADDR("mac-en0", VMAppleCfgState, cfg.mac_en0),
+DEFINE_PROP_MACADDR("mac-en1", VMAppleCfgState, cfg.mac_en1),
+DEFINE_PROP_MACADDR("mac-wifi0", VMAppleCfgState, cfg.mac_wifi0),
+DEFINE_PROP_MACADDR("mac-bt0", VMAppleCfgState, cfg.mac_bt0),
+DEFINE_PROP_STRING("serial", VMAppleCfgState, serial),
+DEFINE_PROP_STRING("model", VMAppleCfgState, model),
+DEFINE_PROP_STRING("soc_name", VMAppleCfgState, soc_name),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void vmapple_cfg_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+dc->realize = vmapple_cfg_realize;
+dc->desc = "VMApple Configuration Region";
+device_class_set_props(dc, vmapple_cfg_properties);
+dc->reset = vmapple_cfg_reset;
+}
+
+static const TypeInfo vmapple_cfg_info = {
+.name  = TYPE_VMAPPLE_CFG,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(VMAppleCfgState),
+.instance_init = vmapple_cfg_init,
+.class_init= vmapple_cfg_class_init,
+};
+
+static void vmapple_cfg_register_types(void)
+{
+type_register_static(_cfg_info);
+}
+
+type_init(vmapple_cfg_register_types)
diff --git a/hw/v

[PATCH 09/12] hw/vmapple/bdif: Introduce vmapple backdoor interface

2023-06-14 Thread Alexander Graf
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.

Signed-off-by: Alexander Graf 
---
 hw/vmapple/Kconfig|   2 +
 hw/vmapple/bdif.c | 245 ++
 hw/vmapple/meson.build|   1 +
 hw/vmapple/trace-events   |   5 +
 include/hw/vmapple/bdif.h |  31 +
 5 files changed, 284 insertions(+)
 create mode 100644 hw/vmapple/bdif.c
 create mode 100644 include/hw/vmapple/bdif.h

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/bdif.c b/hw/vmapple/bdif.c
new file mode 100644
index 00..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  0x
+#define DEVID_ROOT  0x
+#define DEVID_AUX   0x0001
+#define DEVID_USB   0x0010
+
+#define REG_STATUS  0x0
+#define REG_STATUS_ACTIVE BIT(0)
+#define REG_CFG 0x4
+#define REG_CFG_ACTIVEBIT(1)
+#define REG_UNK10x8
+#define REG_BUSY0x10
+#define REG_BUSY_READYBIT(0)
+#define REG_UNK20x400
+#define REG_CMD 0x408
+#define REG_NEXT_DEVICE 0x420
+#define REG_UNK30x434
+
+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 = 0x800;
+break;
+case DEVID_AUX:
+ret = 0x1;
+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(>sector);
+le2cpu_reqcmd(>data);
+le2cpu_reqcmd(>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, , sizeof(req));
+le2cpu_req();
+
+if (req.sector.len != sizeof(sector)) {
+ret = VBLK_RET_FAILED;
+goto out;
+}
+
+/* Read the vblk command */
+cpu_physical_memory_read(req.sector.addr, , sizeof(sector));
+le2cpu_sector();
+
+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 ? &qu

[PATCH 08/12] hw/vmapple/aes: Introduce aes engine

2023-06-14 Thread Alexander Graf
VMApple contains an "aes" engine device that it uses to encrypt and
decrypt its nvram. It has trivial hard coded keys it uses for that
purpose.

Add device emulation for this device model.

Signed-off-by: Alexander Graf 
---
 hw/vmapple/Kconfig  |   2 +
 hw/vmapple/aes.c| 583 
 hw/vmapple/meson.build  |   1 +
 hw/vmapple/trace-events |  18 ++
 4 files changed, 604 insertions(+)
 create mode 100644 hw/vmapple/aes.c

diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
index 8b13789179..a73504d599 100644
--- a/hw/vmapple/Kconfig
+++ b/hw/vmapple/Kconfig
@@ -1 +1,3 @@
+config VMAPPLE_AES
+bool
 
diff --git a/hw/vmapple/aes.c b/hw/vmapple/aes.c
new file mode 100644
index 00..eaf1e26abe
--- /dev/null
+++ b/hw/vmapple/aes.c
@@ -0,0 +1,583 @@
+/*
+ * QEMU Apple AES device emulation
+ *
+ * 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/irq.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "trace.h"
+#include "hw/sysbus.h"
+#include "crypto/hash.h"
+#include "crypto/aes.h"
+#include "crypto/cipher.h"
+
+#define TYPE_AES  "apple-aes"
+#define MAX_FIFO_SIZE 9
+
+#define CMD_KEY   0x1
+#define CMD_KEY_CONTEXT_SHIFT27
+#define CMD_KEY_CONTEXT_MASK (0x1 << CMD_KEY_CONTEXT_SHIFT)
+#define CMD_KEY_SELECT_SHIFT 24
+#define CMD_KEY_SELECT_MASK  (0x7 << CMD_KEY_SELECT_SHIFT)
+#define CMD_KEY_KEY_LEN_SHIFT22
+#define CMD_KEY_KEY_LEN_MASK (0x3 << CMD_KEY_KEY_LEN_SHIFT)
+#define CMD_KEY_ENCRYPT_SHIFT20
+#define CMD_KEY_ENCRYPT_MASK (0x1 << CMD_KEY_ENCRYPT_SHIFT)
+#define CMD_KEY_BLOCK_MODE_SHIFT 16
+#define CMD_KEY_BLOCK_MODE_MASK  (0x3 << CMD_KEY_BLOCK_MODE_SHIFT)
+#define CMD_IV0x2
+#define CMD_IV_CONTEXT_SHIFT 26
+#define CMD_IV_CONTEXT_MASK  (0x3 << CMD_KEY_CONTEXT_SHIFT)
+#define CMD_DSB   0x3
+#define CMD_SKG   0x4
+#define CMD_DATA  0x5
+#define CMD_DATA_KEY_CTX_SHIFT   27
+#define CMD_DATA_KEY_CTX_MASK(0x1 << CMD_DATA_KEY_CTX_SHIFT)
+#define CMD_DATA_IV_CTX_SHIFT25
+#define CMD_DATA_IV_CTX_MASK (0x3 << CMD_DATA_IV_CTX_SHIFT)
+#define CMD_DATA_LEN_MASK0xff
+#define CMD_STORE_IV  0x6
+#define CMD_STORE_IV_ADDR_MASK   0xff
+#define CMD_WRITE_REG 0x7
+#define CMD_FLAG  0x8
+#define CMD_FLAG_STOP_MASK   BIT(26)
+#define CMD_FLAG_RAISE_IRQ_MASK  BIT(27)
+#define CMD_FLAG_INFO_MASK   0xff
+#define CMD_MAX   0x10
+
+#define CMD_SHIFT 28
+
+#define REG_STATUS0xc
+#define REG_STATUS_DMA_READ_RUNNING BIT(0)
+#define REG_STATUS_DMA_READ_PENDING BIT(1)
+#define REG_STATUS_DMA_WRITE_RUNNINGBIT(2)
+#define REG_STATUS_DMA_WRITE_PENDINGBIT(3)
+#define REG_STATUS_BUSY BIT(4)
+#define REG_STATUS_EXECUTINGBIT(5)
+#define REG_STATUS_READYBIT(6)
+#define REG_STATUS_TEXT_DPA_SEEDED  BIT(7)
+#define REG_STATUS_UNWRAP_DPA_SEEDEDBIT(8)
+
+#define REG_IRQ_STATUS0x18
+#define REG_IRQ_STATUS_INVALID_CMD  BIT(2)
+#define REG_IRQ_STATUS_FLAG BIT(5)
+#define REG_IRQ_ENABLE0x1c
+#define REG_WATERMARK 0x20
+#define REG_Q_STATUS  0x24
+#define REG_FLAG_INFO 0x30
+#define REG_FIFO  0x200
+
+static const uint32_t key_lens[4] = {
+[0] = 16,
+[1] = 24,
+[2] = 32,
+[3] = 64,
+};
+
+struct key {
+uint32_t key_len;
+uint32_t key[8];
+};
+
+struct iv {
+uint32_t iv[4];
+};
+
+struct context {
+struct key key;
+struct iv iv;
+};
+
+static struct key builtin_keys[7] = {
+[1] = {
+.key_len = 32,
+.key = { 0x1 },
+},
+[2] = {
+.key_len = 32,
+.key = { 0x2 },
+},
+[3] = {
+.key_len = 32,
+.key = { 0x3 },
+}
+};
+
+typedef struct AESState {
+/* Private */
+SysBusDevice parent_obj;
+
+/* Public */
+qemu_irq irq;
+MemoryRegion iomem1;
+MemoryRegion iomem2;
+
+uint32_t status;
+uint32_t q_status;
+uint32_t irq_status;
+uint32_t irq_enable;
+uint32_t watermark;
+uint32_t flag_info;
+uint32_t fifo[MAX_FIFO_SIZE];
+uint32_t fifo_idx;
+struct key key[2];
+struct iv iv[4];
+bool is_encrypt;
+QCryptoCipherMode block_mode;
+} AESState;
+
+OBJECT_DECLARE_SIMPLE_TYPE(AESState, AES)
+
+static void aes_update_irq(AESState *s)
+{
+qemu_set_irq(s->irq, !!(s->irq_status & s->irq_enable));
+}
+
+static uint64_t aes1_read(void *opaque, hwaddr offset, unsigned size)
+{
+AESState *s = opaque;
+uint64_

[PATCH 07/12] gpex: Allow more than 4 legacy IRQs

2023-06-14 Thread Alexander Graf
Some boards such as vmapple don't do real legacy PCI IRQ swizzling.
Instead, they just keep allocating more board IRQ lines for each new
legacy IRQ. Let's support that mode by giving instantiators a new
"nr_irqs" property they can use to support more than 4 legacy IRQ lines.
In this mode, GPEX will export more IRQ lines, one for each device.

Signed-off-by: Alexander Graf 
---
 hw/arm/sbsa-ref.c  |  2 +-
 hw/arm/virt.c  |  2 +-
 hw/i386/microvm.c  |  2 +-
 hw/loongarch/virt.c|  2 +-
 hw/mips/loongson3_virt.c   |  2 +-
 hw/openrisc/virt.c | 12 ++--
 hw/pci-host/gpex.c | 36 +++-
 hw/riscv/virt.c| 12 ++--
 hw/xtensa/virt.c   |  2 +-
 include/hw/pci-host/gpex.h |  7 +++
 10 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
index de21200ff9..2715ea7b2f 100644
--- a/hw/arm/sbsa-ref.c
+++ b/hw/arm/sbsa-ref.c
@@ -647,7 +647,7 @@ static void create_pcie(SBSAMachineState *sms)
 /* Map IO port space */
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
qdev_get_gpio_in(sms->gic, irq + i));
 gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 9b9f7d9c68..cabb5d14f2 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1466,7 +1466,7 @@ static void create_pcie(VirtMachineState *vms)
 /* Map IO port space */
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
qdev_get_gpio_in(vms->gic, irq + i));
 gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 7227a2156c..9ca007b870 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -139,7 +139,7 @@ static void create_gpex(MicrovmMachineState *mms)
 mms->gpex.mmio64.base, mmio64_alias);
 }
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
x86ms->gsi[mms->gpex.irq + i]);
 }
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index ceddec1b23..6a0c2f3103 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -512,7 +512,7 @@ static void loongarch_devices_init(DeviceState *pch_pic, 
LoongArchMachineState *
 memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE,
 pio_alias);
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 sysbus_connect_irq(d, i,
qdev_get_gpio_in(pch_pic, 16 + i));
 gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c
index 216812f660..acf9fead85 100644
--- a/hw/mips/loongson3_virt.c
+++ b/hw/mips/loongson3_virt.c
@@ -438,7 +438,7 @@ static inline void loongson3_virt_devices_init(MachineState 
*machine,
 virt_memmap[VIRT_PCIE_PIO].base, s->pio_alias);
 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, virt_memmap[VIRT_PCIE_PIO].base);
 
-for (i = 0; i < GPEX_NUM_IRQS; i++) {
+for (i = 0; i < PCI_NUM_PINS; i++) {
 irq = qdev_get_gpio_in(pic, PCIE_IRQ_BASE + i);
 sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
 gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ_BASE + i);
diff --git a/hw/openrisc/virt.c b/hw/openrisc/virt.c
index f8a68a6a6b..16a5676c4b 100644
--- a/hw/openrisc/virt.c
+++ b/hw/openrisc/virt.c
@@ -318,7 +318,7 @@ static void create_pcie_irq_map(void *fdt, char *nodename, 
int irq_base,
 {
 int pin, dev;
 uint32_t irq_map_stride = 0;
-uint32_t full_irq_map[GPEX_NUM_IRQS * GPEX_NUM_IRQS * 6] = {};
+uint32_t full_irq_map[PCI_NUM_PINS * PCI_NUM_PINS * 6] = {};
 uint32_t *irq_map = full_irq_map;
 
 /*
@@ -330,11 +330,11 @@ static void create_pcie_irq_map(void *fdt, char 
*nodename, int irq_base,
  * possible slot) seeing the interrupt-map-mask will allow the table
  * to wrap to any number of devices.
  */
-for (dev = 0; dev < GPEX_NUM_IRQS; dev++) {
+for (dev = 0; dev < PCI_NUM_PINS; dev++) {
 int devfn = dev << 3;
 
-for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
-int irq_nr = irq_base + ((pin + PCI_SLOT(devfn)) % GPEX_NUM_IRQS);
+for (pin = 0; pin < PCI_NUM_PINS; pin++) {
+int irq_nr = irq_base + ((pin + PCI_SLOT(devfn)) % PCI_NUM_PINS);
 int i = 0;
 
 /* Fill PCI address cells */
@@ -357,7 +357,7 @@ static void create_pcie_irq_map(

[PATCH 05/12] hw/virtio: Add support for apple virtio-blk

2023-06-14 Thread Alexander Graf
Apple has its own virtio-blk PCI device ID where it deviates from the
official virtio-pci spec slightly: It puts a new "apple type"
field at a static offset in config space and introduces a new discard
command.

This patch adds a new qdev property called "apple-type" to virtio-blk-pci.
When that property is set, we assume the virtio-blk device is an Apple one
of the specific type and act accordingly.

Signed-off-by: Alexander Graf 
---
 hw/block/virtio-blk.c   | 23 +
 hw/virtio/virtio-blk-pci.c  |  7 +++
 include/hw/pci/pci_ids.h|  1 +
 include/hw/virtio/virtio-blk.h  |  1 +
 include/standard-headers/linux/virtio_blk.h |  3 +++
 5 files changed, 35 insertions(+)

diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 39e7f23fab..76b85bb3cb 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -1120,6 +1120,20 @@ static int virtio_blk_handle_request(VirtIOBlockReq 
*req, MultiReqBuffer *mrb)
 
 break;
 }
+case VIRTIO_BLK_T_APPLE1:
+{
+if (s->conf.x_apple_type) {
+/* Only valid on Apple Virtio */
+char buf[iov_size(in_iov, in_num)];
+memset(buf, 0, sizeof(buf));
+iov_from_buf(in_iov, in_num, 0, buf, sizeof(buf));
+virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+} else {
+virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+}
+virtio_blk_free_request(req);
+break;
+}
 default:
 virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
 virtio_blk_free_request(req);
@@ -1351,6 +1365,10 @@ static void virtio_blk_update_config(VirtIODevice *vdev, 
uint8_t *config)
 } else {
 blkcfg.zoned.model = VIRTIO_BLK_Z_NONE;
 }
+if (s->conf.x_apple_type) {
+/* Apple abuses the same location for its type id */
+blkcfg.max_secure_erase_sectors = s->conf.x_apple_type;
+}
 memcpy(config, , s->config_size);
 }
 
@@ -1625,6 +1643,10 @@ static void virtio_blk_device_realize(DeviceState *dev, 
Error **errp)
 
 s->config_size = virtio_get_config_size(_blk_cfg_size_params,
 s->host_features);
+if (s->conf.x_apple_type) {
+/* Apple Virtio puts the blk type at 0x3c, make sure we have space. */
+s->config_size = MAX(s->config_size, 0x3d);
+}
 virtio_init(vdev, VIRTIO_ID_BLOCK, s->config_size);
 
 s->blk = conf->conf.blk;
@@ -1734,6 +1756,7 @@ static Property virtio_blk_properties[] = {
conf.max_write_zeroes_sectors, 
BDRV_REQUEST_MAX_SECTORS),
 DEFINE_PROP_BOOL("x-enable-wce-if-config-wce", VirtIOBlock,
  conf.x_enable_wce_if_config_wce, true),
+DEFINE_PROP_UINT32("x-apple-type", VirtIOBlock, conf.x_apple_type, 0),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/virtio/virtio-blk-pci.c b/hw/virtio/virtio-blk-pci.c
index 9743bee965..5fbf98f750 100644
--- a/hw/virtio/virtio-blk-pci.c
+++ b/hw/virtio/virtio-blk-pci.c
@@ -62,6 +62,13 @@ static void virtio_blk_pci_realize(VirtIOPCIProxy *vpci_dev, 
Error **errp)
 }
 
 qdev_realize(vdev, BUS(_dev->bus), errp);
+
+if (conf->x_apple_type) {
+/* Apple virtio-blk uses a different vendor/device id */
+pci_config_set_vendor_id(vpci_dev->pci_dev.config, 
PCI_VENDOR_ID_APPLE);
+pci_config_set_device_id(vpci_dev->pci_dev.config,
+ PCI_DEVICE_ID_APPLE_VIRTIO_BLK);
+}
 }
 
 static void virtio_blk_pci_class_init(ObjectClass *klass, void *data)
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index e4386ebb20..74e589a298 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -188,6 +188,7 @@
 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP0x0020
 #define PCI_DEVICE_ID_APPLE_U3_AGP   0x004b
 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC   0x0021
+#define PCI_DEVICE_ID_APPLE_VIRTIO_BLK   0x1a00
 
 #define PCI_VENDOR_ID_SUN0x108e
 #define PCI_DEVICE_ID_SUN_EBUS   0x1000
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index dafec432ce..7117ce754c 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -46,6 +46,7 @@ struct VirtIOBlkConf
 uint32_t max_discard_sectors;
 uint32_t max_write_zeroes_sectors;
 bool x_enable_wce_if_config_wce;
+uint32_t x_apple_type;
 };
 
 struct VirtIOBlockDataPlane;
diff --git a/include/standard-headers/linux/virtio_blk.h 
b/include/standard-headers/linux/virtio_blk.h
index 7155b1a470..bbea5d50b9 100644
--- a/include/standard-headers/linux/virtio_blk.h
+++ b/include/standard-headers/linux/virtio_blk.h
@@ -204,6 +204,9 @@ struct virtio_blk_config {
 /* Reset All zones command */
 #define VIRTIO_BLK_T_ZONE_RESET_ALL 26
 
+/* Write zeroes command */
+#define V

[PATCH 06/12] hw: Add vmapple subdir

2023-06-14 Thread Alexander Graf
We will introduce a number of devices that are specific to the vmapple
target machine. To keep them all tidily together, let's put them into
a single target directory.

Signed-off-by: Alexander Graf 
---
 MAINTAINERS | 6 ++
 hw/Kconfig  | 1 +
 hw/meson.build  | 1 +
 hw/vmapple/Kconfig  | 1 +
 hw/vmapple/meson.build  | 0
 hw/vmapple/trace-events | 2 ++
 hw/vmapple/trace.h  | 1 +
 meson.build | 1 +
 8 files changed, 13 insertions(+)
 create mode 100644 hw/vmapple/Kconfig
 create mode 100644 hw/vmapple/meson.build
 create mode 100644 hw/vmapple/trace-events
 create mode 100644 hw/vmapple/trace.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 4a80a38511..7d5cb3e3e6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2547,6 +2547,12 @@ F: hw/usb/canokey.c
 F: hw/usb/canokey.h
 F: docs/system/devices/canokey.rst
 
+VMapple
+M: Alexander Graf 
+S: Maintained
+F: hw/vmapple/*
+F: include/hw/vmapple/*
+
 Subsystems
 --
 Overall Audio backends
diff --git a/hw/Kconfig b/hw/Kconfig
index ba62ff6417..d99854afdd 100644
--- a/hw/Kconfig
+++ b/hw/Kconfig
@@ -41,6 +41,7 @@ source tpm/Kconfig
 source usb/Kconfig
 source virtio/Kconfig
 source vfio/Kconfig
+source vmapple/Kconfig
 source xen/Kconfig
 source watchdog/Kconfig
 
diff --git a/hw/meson.build b/hw/meson.build
index c7ac7d3d75..e156a6618f 100644
--- a/hw/meson.build
+++ b/hw/meson.build
@@ -40,6 +40,7 @@ subdir('tpm')
 subdir('usb')
 subdir('vfio')
 subdir('virtio')
+subdir('vmapple')
 subdir('watchdog')
 subdir('xen')
 subdir('xenpv')
diff --git a/hw/vmapple/Kconfig b/hw/vmapple/Kconfig
new file mode 100644
index 00..8b13789179
--- /dev/null
+++ b/hw/vmapple/Kconfig
@@ -0,0 +1 @@
+
diff --git a/hw/vmapple/meson.build b/hw/vmapple/meson.build
new file mode 100644
index 00..e69de29bb2
diff --git a/hw/vmapple/trace-events b/hw/vmapple/trace-events
new file mode 100644
index 00..9ccc579048
--- /dev/null
+++ b/hw/vmapple/trace-events
@@ -0,0 +1,2 @@
+# See docs/devel/tracing.rst for syntax documentation.
+
diff --git a/hw/vmapple/trace.h b/hw/vmapple/trace.h
new file mode 100644
index 00..572adbefe0
--- /dev/null
+++ b/hw/vmapple/trace.h
@@ -0,0 +1 @@
+#include "trace/trace-hw_vmapple.h"
diff --git a/meson.build b/meson.build
index 0bb5ea9d10..e0203518ef 100644
--- a/meson.build
+++ b/meson.build
@@ -3273,6 +3273,7 @@ if have_system
 'hw/usb',
 'hw/vfio',
 'hw/virtio',
+'hw/vmapple',
 'hw/watchdog',
 'hw/xen',
 'hw/gpio',
-- 
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






[PATCH 04/12] hvf: arm: Ignore writes to CNTP_CTL_EL0

2023-06-14 Thread Alexander Graf
MacOS unconditionally disables interrupts of the physical timer on boot
and then continues to use the virtual one. We don't really want to support
a full physical timer emulation, so let's just ignore those writes.

Signed-off-by: Alexander Graf 
---
 target/arm/hvf/hvf.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 8f72624586..0dff63fb5f 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -179,6 +179,7 @@ void hvf_arm_init_debug(void)
 #define SYSREG_OSLSR_EL1  SYSREG(2, 0, 1, 1, 4)
 #define SYSREG_OSDLR_EL1  SYSREG(2, 0, 1, 3, 4)
 #define SYSREG_CNTPCT_EL0 SYSREG(3, 3, 14, 0, 1)
+#define SYSREG_CNTP_CTL_EL0   SYSREG(3, 3, 14, 2, 1)
 #define SYSREG_PMCR_EL0   SYSREG(3, 3, 9, 12, 0)
 #define SYSREG_PMUSERENR_EL0  SYSREG(3, 3, 9, 14, 0)
 #define SYSREG_PMCNTENSET_EL0 SYSREG(3, 3, 9, 12, 1)
@@ -1551,6 +1552,12 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, 
uint64_t val)
 case SYSREG_OSLAR_EL1:
 env->cp15.oslsr_el1 = val & 1;
 break;
+case SYSREG_CNTP_CTL_EL0:
+/*
+ * Guests should not rely on the physical counter, but macOS emits
+ * disable writes to it. Let it do so, but ignore the requests.
+ */
+break;
 case SYSREG_OSDLR_EL1:
 /* Dummy register */
 break;
-- 
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






[PATCH 00/12] Introduce new vmapple machine type

2023-06-14 Thread Alexander Graf
This patch set introduces a new ARM and HVF specific machine type
called "vmapple". It mimicks the device model that Apple's proprietary
Virtualization.Framework exposes, but implements it in QEMU.

With this new machine type, you can run macOS guests on Apple Silicon
systems via HVF. To do so, you need to first install macOS using
Virtualization.Framework onto a virtual disk image using a tool like
macosvm (https://github.com/s-u/macosvm)

  $ macosvm --disk disk.img,size=32g --aux aux.img \
--restore UniversalMac_12.0.1_21A559_Restore.ipsw vm.json

Then, extract the ECID from the installed VM:

  $ cat "$DIR/macosvm.json" | python3 -c \
  'import json,sys;obj=json.load(sys.stdin);print(obj["machineId"]) |\
  base64 -d | plutil -extract ECID raw -

In addition, cut off the first 16kb of the aux.img:

  $ dd if=aux.img of=aux.img.trimmed bs=$(( 0x4000 )) skip=1

Now, you can just launch QEMU with the bits generated above:

  $ qemu-system-aarch64 -serial mon:stdio\
  -m 4G  \
  -M vmapple,uuid=6240349656165161789\
  -bios /Sys*/Lib*/Fra*/Virtualization.f*/R*/AVPBooter.vmapple2.bin  \
  -pflash aux.img.trimmed\
  -pflash disk.img   \
  -drive file=disk.img,if=none,id=root   \
  -device virtio-blk-pci,drive=root,x-apple-type=1   \
  -drive file=aux.img.trimmed,if=none,id=aux \
  -device virtio-blk-pci,drive=aux,x-apple-type=2\
  -accel hvf -no-reboot

There are a few limitations with this implementation:

  - Only runs on macOS because it relies on
ParavirtualizesGraphics.Framework
  - Something is not fully correct on interrupt delivery or
similar - the keyboard does not work
  - No Rosetta in the guest because we lack the private
entitlement to enable TSO

Over time, I hope that some of the limitations above could cease to exist.
This device model would enable very nice use cases with KVM on an Asahi
Linux device.


Alexander Graf (12):
  build: Only define OS_OBJECT_USE_OBJC with gcc
  hw/misc/pvpanic: Add MMIO interface
  hvf: Increase number of possible memory slots
  hvf: arm: Ignore writes to CNTP_CTL_EL0
  hw/virtio: Add support for apple virtio-blk
  hw: Add vmapple subdir
  gpex: Allow more than 4 legacy IRQs
  hw/vmapple/aes: Introduce aes engine
  hw/vmapple/bdif: Introduce vmapple backdoor interface
  hw/vmapple/cfg: Introduce vmapple cfg region
  hw/vmapple/apple-gfx: Introduce ParavirtualizedGraphics.Framework
support
  hw/vmapple/vmapple: Add vmapple machine type

 MAINTAINERS |   6 +
 accel/hvf/hvf-accel-ops.c   |   2 +-
 hw/Kconfig  |   1 +
 hw/arm/sbsa-ref.c   |   2 +-
 hw/arm/virt.c   |   2 +-
 hw/block/virtio-blk.c   |  23 +
 hw/i386/microvm.c   |   2 +-
 hw/loongarch/virt.c |   2 +-
 hw/meson.build  |   1 +
 hw/mips/loongson3_virt.c|   2 +-
 hw/misc/Kconfig |   4 +
 hw/misc/meson.build |   1 +
 hw/misc/pvpanic-mmio.c  |  66 ++
 hw/openrisc/virt.c  |  12 +-
 hw/pci-host/gpex.c  |  36 +-
 hw/riscv/virt.c |  12 +-
 hw/virtio/virtio-blk-pci.c  |   7 +
 hw/vmapple/Kconfig  |  30 +
 hw/vmapple/aes.c| 583 +
 hw/vmapple/apple-gfx.m  | 578 +
 hw/vmapple/bdif.c   | 245 
 hw/vmapple/cfg.c| 105 
 hw/vmapple/meson.build  |   5 +
 hw/vmapple/trace-events |  47 ++
 hw/vmapple/trace.h  |   1 +
 hw/vmapple/vmapple.c| 661 
 hw/xtensa/virt.c|   2 +-
 include/hw/misc/pvpanic.h   |   1 +
 include/hw/pci-host/gpex.h  |   7 +-
 include/hw/pci/pci_ids.h|   1 +
 include/hw/virtio/virtio-blk.h  |   1 +
 include/hw/vmapple/bdif.h   |  31 +
 include/hw/vmapple/cfg.h|  68 ++
 include/standard-headers/linux/virtio_blk.h |   3 +
 include/sysemu/hvf_int.h|   2 +-
 meson.build |   9 +-
 target/arm/hvf/hvf.c|   7 +
 37 files changed, 2538 insertions(+), 30 deletions(-)
 create mode 100644 hw/misc/pvpanic-mmio.c

[PATCH 02/12] hw/misc/pvpanic: Add MMIO interface

2023-06-14 Thread Alexander Graf
In addition to the ISA and PCI variants of pvpanic, let's add an MMIO
platform device that we can use in embedded arm environments.

Signed-off-by: Alexander Graf 
---
 hw/misc/Kconfig   |  4 +++
 hw/misc/meson.build   |  1 +
 hw/misc/pvpanic-mmio.c| 66 +++
 include/hw/misc/pvpanic.h |  1 +
 4 files changed, 72 insertions(+)
 create mode 100644 hw/misc/pvpanic-mmio.c

diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index e4c2149175..21913ef191 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -125,6 +125,10 @@ config PVPANIC_ISA
 depends on ISA_BUS
 select PVPANIC_COMMON
 
+config PVPANIC_MMIO
+bool
+select PVPANIC_COMMON
+
 config AUX
 bool
 select I2C
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 78ca857c9d..b935e74d51 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -115,6 +115,7 @@ softmmu_ss.add(when: 'CONFIG_ARMSSE_MHU', if_true: 
files('armsse-mhu.c'))
 
 softmmu_ss.add(when: 'CONFIG_PVPANIC_ISA', if_true: files('pvpanic-isa.c'))
 softmmu_ss.add(when: 'CONFIG_PVPANIC_PCI', if_true: files('pvpanic-pci.c'))
+softmmu_ss.add(when: 'CONFIG_PVPANIC_MMIO', if_true: files('pvpanic-mmio.c'))
 softmmu_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
 softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
   'aspeed_hace.c',
diff --git a/hw/misc/pvpanic-mmio.c b/hw/misc/pvpanic-mmio.c
new file mode 100644
index 00..aebe7227e6
--- /dev/null
+++ b/hw/misc/pvpanic-mmio.c
@@ -0,0 +1,66 @@
+/*
+ * QEMU simulated pvpanic device (MMIO frontend)
+ *
+ * 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 "qemu/module.h"
+#include "sysemu/runstate.h"
+
+#include "hw/nvram/fw_cfg.h"
+#include "hw/qdev-properties.h"
+#include "hw/misc/pvpanic.h"
+#include "qom/object.h"
+#include "hw/isa/isa.h"
+#include "standard-headers/linux/pvpanic.h"
+
+OBJECT_DECLARE_SIMPLE_TYPE(PVPanicMMIOState, PVPANIC_MMIO_DEVICE)
+
+#define PVPANIC_MMIO_SIZE 0x2
+
+struct PVPanicMMIOState {
+SysBusDevice parent_obj;
+
+PVPanicState pvpanic;
+};
+
+static void pvpanic_mmio_initfn(Object *obj)
+{
+PVPanicMMIOState *s = PVPANIC_MMIO_DEVICE(obj);
+
+pvpanic_setup_io(>pvpanic, DEVICE(s), PVPANIC_MMIO_SIZE);
+sysbus_init_mmio(SYS_BUS_DEVICE(obj), >pvpanic.mr);
+}
+
+static Property pvpanic_mmio_properties[] = {
+DEFINE_PROP_UINT8("events", PVPanicMMIOState, pvpanic.events,
+  PVPANIC_PANICKED | PVPANIC_CRASH_LOADED),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void pvpanic_mmio_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+
+device_class_set_props(dc, pvpanic_mmio_properties);
+set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static const TypeInfo pvpanic_mmio_info = {
+.name  = TYPE_PVPANIC_MMIO_DEVICE,
+.parent= TYPE_SYS_BUS_DEVICE,
+.instance_size = sizeof(PVPanicMMIOState),
+.instance_init = pvpanic_mmio_initfn,
+.class_init= pvpanic_mmio_class_init,
+};
+
+static void pvpanic_register_types(void)
+{
+type_register_static(_mmio_info);
+}
+
+type_init(pvpanic_register_types)
diff --git a/include/hw/misc/pvpanic.h b/include/hw/misc/pvpanic.h
index fab94165d0..f9e7c1ea17 100644
--- a/include/hw/misc/pvpanic.h
+++ b/include/hw/misc/pvpanic.h
@@ -20,6 +20,7 @@
 
 #define TYPE_PVPANIC_ISA_DEVICE "pvpanic"
 #define TYPE_PVPANIC_PCI_DEVICE "pvpanic-pci"
+#define TYPE_PVPANIC_MMIO_DEVICE "pvpanic-mmio"
 
 #define PVPANIC_IOPORT_PROP "ioport"
 
-- 
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




[PATCH 01/12] build: Only define OS_OBJECT_USE_OBJC with gcc

2023-06-14 Thread Alexander Graf
Recent versions of macOS use clang instead of gcc. The OS_OBJECT_USE_OBJC
define is only necessary when building with gcc. Let's not define it when
building with clang.

With this patch, I can successfully include GCD headers in QEMU when
building with clang.

Signed-off-by: Alexander Graf 
---
 meson.build | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index 34306a6205..0bb5ea9d10 100644
--- a/meson.build
+++ b/meson.build
@@ -225,7 +225,9 @@ qemu_ldflags = []
 if targetos == 'darwin'
   # Disable attempts to use ObjectiveC features in os/object.h since they
   # won't work when we're compiling with gcc as a C compiler.
-  qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
+  if compiler.get_id() == 'gcc'
+qemu_common_flags += '-DOS_OBJECT_USE_OBJC=0'
+  endif
 elif targetos == 'solaris'
   # needed for CMSG_ macros in sys/socket.h
   qemu_common_flags += '-D_XOPEN_SOURCE=600'
-- 
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






[PATCH 04/12] hvf: arm: Ignore writes to CNTP_CTL_EL0

2023-06-14 Thread Alexander Graf
MacOS unconditionally disables interrupts of the physical timer on boot
and then continues to use the virtual one. We don't really want to support
a full physical timer emulation, so let's just ignore those writes.

Signed-off-by: Alexander Graf 
---
 target/arm/hvf/hvf.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 8f72624586..0dff63fb5f 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -179,6 +179,7 @@ void hvf_arm_init_debug(void)
 #define SYSREG_OSLSR_EL1  SYSREG(2, 0, 1, 1, 4)
 #define SYSREG_OSDLR_EL1  SYSREG(2, 0, 1, 3, 4)
 #define SYSREG_CNTPCT_EL0 SYSREG(3, 3, 14, 0, 1)
+#define SYSREG_CNTP_CTL_EL0   SYSREG(3, 3, 14, 2, 1)
 #define SYSREG_PMCR_EL0   SYSREG(3, 3, 9, 12, 0)
 #define SYSREG_PMUSERENR_EL0  SYSREG(3, 3, 9, 14, 0)
 #define SYSREG_PMCNTENSET_EL0 SYSREG(3, 3, 9, 12, 1)
@@ -1551,6 +1552,12 @@ static int hvf_sysreg_write(CPUState *cpu, uint32_t reg, 
uint64_t val)
 case SYSREG_OSLAR_EL1:
 env->cp15.oslsr_el1 = val & 1;
 break;
+case SYSREG_CNTP_CTL_EL0:
+/*
+ * Guests should not rely on the physical counter, but macOS emits
+ * disable writes to it. Let it do so, but ignore the requests.
+ */
+break;
 case SYSREG_OSDLR_EL1:
 /* Dummy register */
 break;
-- 
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






[PATCH 03/12] hvf: Increase number of possible memory slots

2023-06-14 Thread Alexander Graf
For PVG we will need more than the current 32 possible memory slots.
Bump the limit to 512 instead.

Signed-off-by: Alexander Graf 
---
 accel/hvf/hvf-accel-ops.c | 2 +-
 include/sysemu/hvf_int.h  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index 9c3da03c94..bf0caaa852 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -88,7 +88,7 @@ struct mac_slot {
 uint64_t gva;
 };
 
-struct mac_slot mac_slots[32];
+struct mac_slot mac_slots[512];
 
 static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
 {
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
index 6ab119e49f..c7623a2c09 100644
--- a/include/sysemu/hvf_int.h
+++ b/include/sysemu/hvf_int.h
@@ -40,7 +40,7 @@ typedef struct hvf_vcpu_caps {
 
 struct HVFState {
 AccelState parent;
-hvf_slot slots[32];
+hvf_slot slots[512];
 int num_slots;
 
 hvf_vcpu_caps *hvf_caps;
-- 
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






Re: [PATCH v2 28/32] contrib/gitdm: add Amazon to the domain map

2023-03-17 Thread Alexander Graf


On 15.03.23 20:18, Durrant, Paul wrote:

-Original Message-
From: Alex Bennée 
Sent: 15 March 2023 17:43
To: qemu-de...@nongnu.org
Cc: Akihiko Odaki ; Marc-André Lureau
; qemu-ri...@nongnu.org; Riku Voipio
; Igor Mammedov ; Xiao Guangrong
; Thomas Huth ; Wainer dos
Santos Moschetta ; Dr. David Alan Gilbert
; Alex Williamson ; Hao
Wu ; Cleber Rosa ; Daniel Henrique
Barboza ; Jan Kiszka ; Aurelien
Jarno ; qemu-...@nongnu.org; Marcelo Tosatti
; Eduardo Habkost ; Alexandre
Iooss ; Gerd Hoffmann ; Palmer
Dabbelt ; Ilya Leoshkevich ; qemu-
p...@nongnu.org; Juan Quintela ; Cédric Le Goater
; Darren Kenny ;
k...@vger.kernel.org; Marcel Apfelbaum ; Peter
Maydell ; Richard Henderson
; Stafford Horne ; Weiwei
Li ; Sunil V L ; Stefan
Hajnoczi ; Thomas Huth ; Vijai
Kumar K ; Liu Zhiwei
; David Gibson
; Song Gao ; Paolo
Bonzini ; Michael S. Tsirkin ; Niek
Linnenbank ; Greg Kurz ; Laurent
Vivier ; Qiuhao Li ; Philippe
Mathieu-Daudé ; Xiaojuan Yang
; Mahmoud Mandour ;
Alexander Bulekov ; Jiaxun Yang ;
qemu-block@nongnu.org; Yanan Wang ; David
Woodhouse ; qemu-s3...@nongnu.org; Strahinja Jankovic
; Bandan Das ; Alistair
Francis ; Aleksandar Rikalo
; Tyrone Ting ; Kevin
Wolf ; David Hildenbrand ; Beraldo
Leal ; Beniamino Galvani ; Paul
Durrant ; Bin Meng ; Sunil
Muthuswamy ; Hanna Reitz ;
Peter Xu ; Alex Bennée ; Graf
(AWS), Alexander ; Durrant, Paul ;
Woodhouse, David 
Subject: [EXTERNAL] [PATCH v2 28/32] contrib/gitdm: add Amazon to the
domain map

CAUTION: This email originated from outside of the organization. Do not
click links or open attachments unless you can confirm the sender and know
the content is safe.



We have multiple contributors from both .co.uk and .com versions of
the address.

Signed-off-by: Alex Bennée 
Cc: Alexander Graf 
Cc: Paul Durrant 
Cc: David Wooodhouse 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20230310180332.2274827-7-alex.ben...@linaro.org>
---
  contrib/gitdm/domain-map | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/contrib/gitdm/domain-map b/contrib/gitdm/domain-map
index 4a988c5b5f..8dce276a1c 100644
--- a/contrib/gitdm/domain-map
+++ b/contrib/gitdm/domain-map
@@ -4,6 +4,8 @@
  # This maps email domains to nice easy to read company names
  #

+amazon.com  Amazon
+amazon.co.ukAmazon

You might want 'amazon.de' too but as far as it goes...



Yes, please add amazon.de here. Once that's added, feel free to take my

Reviewed-by: Alexander Graf 


Alex





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




Re: [PATCH] hw/block/nvme: fix legacy namespace registration

2021-02-11 Thread Alexander Graf



On 11.02.21 11:54, Klaus Jensen wrote:

From: Klaus Jensen 

Moving namespace registration to the nvme-ns realization function had
the unintended side-effect of breaking legacy namespace registration.
Fix this.

Fixes: 15d024d4aa9b ("hw/block/nvme: split setup and register for namespace")
Reported-by: Alexander Graf 
Cc: Minwoo Im 
Signed-off-by: Klaus Jensen 



I can confirm that this fixes the upstream regression. Thanks a lot. 
Please work on a way with Peter to pull this into the tree as quickly as 
possible, so that we maintain a working master branch with NVMe.


Tested-by: Alexander Graf 


Thanks!

Alex



---
  hw/block/nvme.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 5ce21b7100b3..d36e14fe13e2 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -4507,6 +4507,12 @@ static void nvme_realize(PCIDevice *pci_dev, Error 
**errp)
  if (nvme_ns_setup(ns, errp)) {
  return;
  }
+
+if (nvme_register_namespace(n, ns, errp)) {
+error_propagate_prepend(errp, local_err,
+"could not register namespace: ");
+return;
+}
  }
  }
  




Re: [PULL 32/56] hw/block/nvme: split setup and register for namespace

2021-02-11 Thread Alexander Graf

Hi Klaus,

On 09.02.21 08:30, Klaus Jensen wrote:

From: Minwoo Im 

In NVMe, namespace is being attached to process I/O.  We register NVMe
namespace to a controller via nvme_register_namespace() during
nvme_ns_setup().  This is main reason of receiving NvmeCtrl object
instance to this function to map the namespace to a controller.

To make namespace instance more independent, it should be split into two
parts: setup and register.  This patch split them into two differnt
parts, and finally nvme_ns_setup() does not have nothing to do with
NvmeCtrl instance at all.

This patch is a former patch to introduce NVMe subsystem scheme to the
existing design especially for multi-path.  In that case, it should be
split into two to make namespace independent from a controller.

Signed-off-by: Minwoo Im 
Signed-off-by: Klaus Jensen 



In latest master, I can no longer access NVMe devices from edk2. Git 
bisect pointed me to this commit.


To reproduce:

  $ ./build/qemu-system-x86_64 -enable-kvm -pflash 
build/pc-bios/edk2-x86_64-code.fd -drive 
file=image.raw,if=none,id=d,snapshot=on -device nvme,serial=1234,drive=d 
-nographic -net none


You will see that before this commit, edk2 is able to enumerate the 
block device, while after this commit it does not find it.



good:

Mapping table
      FS0: Alias(s):HD1b:;BLK2:
         
PciRoot(0x0)/Pci(0x3,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)/HD(1,GPT,7A866FF6-0A12-4911-A4ED-D0565BEB41A2,0x80,0x64000)

     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
     BLK1: Alias(s):
         
PciRoot(0x0)/Pci(0x3,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)

     BLK3: Alias(s):
         
PciRoot(0x0)/Pci(0x3,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)/HD(2,GPT,F070566B-C58D-4F13-9B92-64F1794385E7,0x64080,0x4)

     BLK4: Alias(s):
         
PciRoot(0x0)/Pci(0x3,0x0)/NVMe(0x1,00-00-00-00-00-00-00-00)/HD(3,GPT,EDE86BE3-C64F-4ACB-B4AA-5E6C0135D335,0xA4080,0x315BF1B)



bad:

Mapping table
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)



Thanks,

Alex





Re: [Qemu-block] [RFC 03/19] sysbus: Set user_creatable=false by default on TYPE_SYS_BUS_DEVICE

2017-04-04 Thread Alexander Graf



On 04.04.17 08:58, Thomas Huth wrote:

On 04.04.2017 08:53, Alexander Graf wrote:



On 03.04.17 23:00, Eduardo Habkost wrote:

On Mon, Apr 03, 2017 at 10:15:44PM +0200, Alexander Graf wrote:



On 03.04.17 22:10, Eduardo Habkost wrote:

On Mon, Apr 03, 2017 at 08:49:16PM +0100, Peter Maydell wrote:

On 1 April 2017 at 01:46, Eduardo Habkost <ehabk...@redhat.com> wrote:

commit 33cd52b5d7b9adfd009e95f07e6c64dd88ae2a31 unset
cannot_instantiate_with_device_add_yet in TYPE_SYSBUS, making
all kinds of untested devices available to -device and
device_add.

The problem with that is: setting has_dynamic_sysbus on a
machine-type lets it accept all the 288 sysbus device types we
have in QEMU, and most of them were never meant to be used with
-device. That's a lot of untested code.

Fortunately today we have just a few has_dynamic_sysbus=1
machines: virt, pc-q35-*, ppce500, and spapr.

virt, ppce500, and spapr have extra checks to ensure just a few
device types can be instantiated:

* virt supports only TYPE_VFIO_CALXEDA_XGMAC, TYPE_VFIO_AMD_XGBE.
* ppce500 supports only TYPE_ETSEC_COMMON.
* spapr supports only TYPE_SPAPR_PCI_HOST_BRIDGE.

q35 has no code to block unsupported sysbus devices, however, and
accepts all device types. Fortunately, only the following 20
device types are compiled into the qemu-system-x86_64 and
qemu-system-i386 binaries:

* allwinner-ahci
* amd-iommu
* cfi.pflash01
* esp
* fw_cfg_io
* fw_cfg_mem
* generic-sdhci
* hpet
* intel-iommu
* ioapic
* isabus-bridge
* kvmclock
* kvm-ioapic
* kvmvapic
* SUNW,fdtwo
* sysbus-ahci
* sysbus-fdc
* sysbus-ohci
* unimplemented-device
* virtio-mmio

Instead of requiring each machine-type with has_dynamic_sysbus=1
to implement its own mechanism to block unsupported devices, we
can use the user_creatable flag to ensure we won't let the user
plug anything that will never work.


How does this work? Which devices can be dynamically
plugged is machine dependent. You can't dynamically-plug
an intel-iommu on the ARM virt board, and you can't
dynamically-plug the vfio-calxeda-xgmac on the spapr
board, and so on. So I don't see how we can just have
a flag on the device itself that controls whether
it can be dynamically plugged.

So I'm definitely coming around to the opinion that
it's just a bug in the q35 board that it doesn't have
any device whitelisting, and we should fix that.


OK, let's assume q35 must implement a whitelist:

To build that whitelist, we need to be able to know what should
be in the whitelist, or not. And nobody knew for sure what was
user-creatable in q35 by accident, and what was really supposed
to be user-creatable in q35. See the "q35 and sysbus devices"
thread I started ~2 weeks ago.

Building a q35 whitelist will be much easier if make
sys-bus-devices non-user-creatable by default.


So why are they user creatable in the first place?

We used to have boards that were dynamic sysbus aware (ppce500, virt)
that
allowed dynamic creation and every other board did not. I don't
remember the
exact mechanism behind it though.

When did that behavior change? It sounds like a regression somewhere.


See patch description:


commit 33cd52b5d7b9adfd009e95f07e6c64dd88ae2a31 unset
cannot_instantiate_with_device_add_yet in TYPE_SYSBUS,


Note that the commit above is not a regression[1] (because q35
didn't have has_dynamic_sysbus=1 yet), but having sysbus devices
have cannot_instantiate_with_device_add_yet=false/user_creatable=true
by default makes it harder to build the whitelist for q35 (or
other machines that will have has_dynamic_sysbus=1 in the
future).


I seem to miss the bigger picture.

Why would anyone set has_dynamic_sysbus=1 in a board file without an
explicit whitelist? The whitelist is *not* device specific. It's board
specific, because your board needs to know how to wire up a device and
how to expose the fact that it exists to the OS.

So the real bug is that someone set has_dynamic_sysbus=1 in q35 without
implementing all of the dynamic sysbus logic, no?


According to commit bf8d492405feaee2c1685b3b9d5e03228ed3e47f this was
just introduced for allowing the "intel-iommu" device, so I guess this
is the device that we want to have in a whitelist there?


If you want a dynamic intel-iommu, you also need to have dynamic ACPI 
generation to create DMAR tables the OS can use to drive the IOMMU, no? 
At last at that point, someone should have realized that a "whitelist" 
is mandatory.


But yes, please just only add a whitelist for intel-iommu to the q35 
board. That is the real bug.


The basic idea behind dynamic sysbus is that you move the responsibility 
of sysbus spawnability checks from the sysbus layer to the board file. 
If the board file ignores to do those checks, it's at fault.



Alex



Re: [Qemu-block] [RFC 03/19] sysbus: Set user_creatable=false by default on TYPE_SYS_BUS_DEVICE

2017-04-04 Thread Alexander Graf



On 03.04.17 23:00, Eduardo Habkost wrote:

On Mon, Apr 03, 2017 at 10:15:44PM +0200, Alexander Graf wrote:



On 03.04.17 22:10, Eduardo Habkost wrote:

On Mon, Apr 03, 2017 at 08:49:16PM +0100, Peter Maydell wrote:

On 1 April 2017 at 01:46, Eduardo Habkost <ehabk...@redhat.com> wrote:

commit 33cd52b5d7b9adfd009e95f07e6c64dd88ae2a31 unset
cannot_instantiate_with_device_add_yet in TYPE_SYSBUS, making
all kinds of untested devices available to -device and
device_add.

The problem with that is: setting has_dynamic_sysbus on a
machine-type lets it accept all the 288 sysbus device types we
have in QEMU, and most of them were never meant to be used with
-device. That's a lot of untested code.

Fortunately today we have just a few has_dynamic_sysbus=1
machines: virt, pc-q35-*, ppce500, and spapr.

virt, ppce500, and spapr have extra checks to ensure just a few
device types can be instantiated:

* virt supports only TYPE_VFIO_CALXEDA_XGMAC, TYPE_VFIO_AMD_XGBE.
* ppce500 supports only TYPE_ETSEC_COMMON.
* spapr supports only TYPE_SPAPR_PCI_HOST_BRIDGE.

q35 has no code to block unsupported sysbus devices, however, and
accepts all device types. Fortunately, only the following 20
device types are compiled into the qemu-system-x86_64 and
qemu-system-i386 binaries:

* allwinner-ahci
* amd-iommu
* cfi.pflash01
* esp
* fw_cfg_io
* fw_cfg_mem
* generic-sdhci
* hpet
* intel-iommu
* ioapic
* isabus-bridge
* kvmclock
* kvm-ioapic
* kvmvapic
* SUNW,fdtwo
* sysbus-ahci
* sysbus-fdc
* sysbus-ohci
* unimplemented-device
* virtio-mmio

Instead of requiring each machine-type with has_dynamic_sysbus=1
to implement its own mechanism to block unsupported devices, we
can use the user_creatable flag to ensure we won't let the user
plug anything that will never work.


How does this work? Which devices can be dynamically
plugged is machine dependent. You can't dynamically-plug
an intel-iommu on the ARM virt board, and you can't
dynamically-plug the vfio-calxeda-xgmac on the spapr
board, and so on. So I don't see how we can just have
a flag on the device itself that controls whether
it can be dynamically plugged.

So I'm definitely coming around to the opinion that
it's just a bug in the q35 board that it doesn't have
any device whitelisting, and we should fix that.


OK, let's assume q35 must implement a whitelist:

To build that whitelist, we need to be able to know what should
be in the whitelist, or not. And nobody knew for sure what was
user-creatable in q35 by accident, and what was really supposed
to be user-creatable in q35. See the "q35 and sysbus devices"
thread I started ~2 weeks ago.

Building a q35 whitelist will be much easier if make
sys-bus-devices non-user-creatable by default.


So why are they user creatable in the first place?

We used to have boards that were dynamic sysbus aware (ppce500, virt) that
allowed dynamic creation and every other board did not. I don't remember the
exact mechanism behind it though.

When did that behavior change? It sounds like a regression somewhere.


See patch description:


commit 33cd52b5d7b9adfd009e95f07e6c64dd88ae2a31 unset
cannot_instantiate_with_device_add_yet in TYPE_SYSBUS,


Note that the commit above is not a regression[1] (because q35
didn't have has_dynamic_sysbus=1 yet), but having sysbus devices
have cannot_instantiate_with_device_add_yet=false/user_creatable=true
by default makes it harder to build the whitelist for q35 (or
other machines that will have has_dynamic_sysbus=1 in the
future).


I seem to miss the bigger picture.

Why would anyone set has_dynamic_sysbus=1 in a board file without an 
explicit whitelist? The whitelist is *not* device specific. It's board 
specific, because your board needs to know how to wire up a device and 
how to expose the fact that it exists to the OS.


So the real bug is that someone set has_dynamic_sysbus=1 in q35 without 
implementing all of the dynamic sysbus logic, no?



Alex



Re: [Qemu-block] [RFC 03/19] sysbus: Set user_creatable=false by default on TYPE_SYS_BUS_DEVICE

2017-04-03 Thread Alexander Graf



On 03.04.17 22:10, Eduardo Habkost wrote:

On Mon, Apr 03, 2017 at 08:49:16PM +0100, Peter Maydell wrote:

On 1 April 2017 at 01:46, Eduardo Habkost  wrote:

commit 33cd52b5d7b9adfd009e95f07e6c64dd88ae2a31 unset
cannot_instantiate_with_device_add_yet in TYPE_SYSBUS, making
all kinds of untested devices available to -device and
device_add.

The problem with that is: setting has_dynamic_sysbus on a
machine-type lets it accept all the 288 sysbus device types we
have in QEMU, and most of them were never meant to be used with
-device. That's a lot of untested code.

Fortunately today we have just a few has_dynamic_sysbus=1
machines: virt, pc-q35-*, ppce500, and spapr.

virt, ppce500, and spapr have extra checks to ensure just a few
device types can be instantiated:

* virt supports only TYPE_VFIO_CALXEDA_XGMAC, TYPE_VFIO_AMD_XGBE.
* ppce500 supports only TYPE_ETSEC_COMMON.
* spapr supports only TYPE_SPAPR_PCI_HOST_BRIDGE.

q35 has no code to block unsupported sysbus devices, however, and
accepts all device types. Fortunately, only the following 20
device types are compiled into the qemu-system-x86_64 and
qemu-system-i386 binaries:

* allwinner-ahci
* amd-iommu
* cfi.pflash01
* esp
* fw_cfg_io
* fw_cfg_mem
* generic-sdhci
* hpet
* intel-iommu
* ioapic
* isabus-bridge
* kvmclock
* kvm-ioapic
* kvmvapic
* SUNW,fdtwo
* sysbus-ahci
* sysbus-fdc
* sysbus-ohci
* unimplemented-device
* virtio-mmio

Instead of requiring each machine-type with has_dynamic_sysbus=1
to implement its own mechanism to block unsupported devices, we
can use the user_creatable flag to ensure we won't let the user
plug anything that will never work.


How does this work? Which devices can be dynamically
plugged is machine dependent. You can't dynamically-plug
an intel-iommu on the ARM virt board, and you can't
dynamically-plug the vfio-calxeda-xgmac on the spapr
board, and so on. So I don't see how we can just have
a flag on the device itself that controls whether
it can be dynamically plugged.

So I'm definitely coming around to the opinion that
it's just a bug in the q35 board that it doesn't have
any device whitelisting, and we should fix that.


OK, let's assume q35 must implement a whitelist:

To build that whitelist, we need to be able to know what should
be in the whitelist, or not. And nobody knew for sure what was
user-creatable in q35 by accident, and what was really supposed
to be user-creatable in q35. See the "q35 and sysbus devices"
thread I started ~2 weeks ago.

Building a q35 whitelist will be much easier if make
sys-bus-devices non-user-creatable by default.


So why are they user creatable in the first place?

We used to have boards that were dynamic sysbus aware (ppce500, virt) 
that allowed dynamic creation and every other board did not. I don't 
remember the exact mechanism behind it though.


When did that behavior change? It sounds like a regression somewhere.


Alex



Re: [Qemu-block] [PATCH 1/3] qcow2: Set MIN_L2_CACHE_SIZE to 2

2015-06-01 Thread Alexander Graf


On 01.06.15 18:09, Max Reitz wrote:
 The L2 cache must cover at least two L2 tables, because during COW two
 L2 tables are accessed simultaneously.
 
 Reported-by: Alexander Graf ag...@suse.de
 Cc: qemu-stable qemu-sta...@nongnu.org
 Signed-off-by: Max Reitz mre...@redhat.com

Tested-by: Alexander Graf ag...@suse.de


Alex

 ---
  block/qcow2.h | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/block/qcow2.h b/block/qcow2.h
 index 0076512..aa20022 100644
 --- a/block/qcow2.h
 +++ b/block/qcow2.h
 @@ -62,7 +62,8 @@
  #define MIN_CLUSTER_BITS 9
  #define MAX_CLUSTER_BITS 21
  
 -#define MIN_L2_CACHE_SIZE 1 /* cluster */
 +/* Must be at least 2 to cover COW */
 +#define MIN_L2_CACHE_SIZE 2 /* clusters */
  
  /* Must be at least 4 to cover all cases of refcount table growth */
  #define MIN_REFCOUNT_CACHE_SIZE 4 /* clusters */