All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mohamed Mediouni <mohamed@unpredictable.fr>
To: qemu-devel@nongnu.org
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
	"Roman Bolshakov" <rbolshakov@ddn.com>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Peter Xu" <peterx@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@linaro.org>,
	qemu-arm@nongnu.org, "Phil Dennis-Jordan" <phil@philjordan.eu>,
	"Akihiko Odaki" <odaki@rsg.ci.i.u-tokyo.ac.jp>,
	"Mohamed Mediouni" <mohamed@unpredictable.fr>,
	"Alexander Graf" <agraf@csgraf.de>,
	"Paolo Bonzini" <pbonzini@redhat.com>
Subject: [RFC PATCH v8 05/10] vmapple: apple-gfx: make it work on the latest macOS release
Date: Wed, 16 Sep 2026 12:00:13 +0200	[thread overview]
Message-ID: <20260916100021.73825-6-mohamed@unpredictable.fr> (raw)
In-Reply-To: <20260916100021.73825-1-mohamed@unpredictable.fr>

Follow changes in memory management introduced on macOS 15.4.

The legacy memory management API has been removed for the IOSurface mapper on that macOS version.

Also enable process isolation for a sandboxed GPU process when on a new OS.

Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
---
 hw/display/apple-gfx-mmio.m | 58 ++++++++++++++++++------
 hw/display/apple-gfx.h      | 16 +++++++
 hw/display/apple-gfx.m      | 90 ++++++++++++++++++++++++++++++++-----
 3 files changed, 138 insertions(+), 26 deletions(-)

diff --git a/hw/display/apple-gfx-mmio.m b/hw/display/apple-gfx-mmio.m
index 58beaadd1f..19e2d38a1e 100644
--- a/hw/display/apple-gfx-mmio.m
+++ b/hw/display/apple-gfx-mmio.m
@@ -19,6 +19,7 @@
 #include "hw/core/irq.h"
 #include "apple-gfx.h"
 #include "trace.h"
+#include "system/address-spaces.h"
 
 #import <ParavirtualizedGraphics/ParavirtualizedGraphics.h>
 
@@ -36,12 +37,19 @@ typedef bool(^IOSFCMapMemory)(uint64_t phys, uint64_t len, bool ro, void **va,
 
 @interface PGDeviceDescriptor (IOSurfaceMapper)
 @property (readwrite, nonatomic) bool usingIOSurfaceMapper;
+@property (readwrite, nonatomic) bool enableArgumentBuffers;
+@property (readwrite, nonatomic) bool enableProcessIsolation;
+@property (readwrite, nonatomic) bool enableProtectedContent;
+
+@property (readwrite, nonatomic, copy, nullable) PGMemoryMapDescriptor* memoryMapDescriptor;
 @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) PGMemoryMapDescriptor* memoryMapDescriptor;
+@property (readwrite, nonatomic) unsigned long long mmioLength;
 @property (readwrite, nonatomic, copy, nullable) IOSFCRaiseInterrupt raiseInterrupt;
 @end
 
@@ -183,19 +191,32 @@ static bool apple_gfx_mmio_unmap_surface_memory(void *ptr)
         [PGIOSurfaceHostDeviceDescriptor new];
     PGIOSurfaceHostDevice *iosfc_host_dev;
 
-    iosfc_desc.mapMemory =
-        ^bool(uint64_t phys, uint64_t len, bool ro, void **va, void *e, void *f) {
-            *va = apple_gfx_mmio_map_surface_memory(phys, len, ro);
-
-            trace_apple_gfx_iosfc_map_memory(phys, len, ro, va, e, f, *va);
-
-            return *va != NULL;
-        };
-
-    iosfc_desc.unmapMemory =
-        ^bool(void *va, void *b, void *c, void *d, void *e, void *f) {
-            return apple_gfx_mmio_unmap_surface_memory(va);
-        };
+    /*
+     * The legacy memory management API is no longer present
+     * for the IOSurface mapper as of macOS 15.4.
+     */
+    if (@available(macOS 15.4, *)) {
+        PGMemoryMapDescriptor *memory_map_descriptor = [PGMemoryMapDescriptor new];
+        FlatView* fv = address_space_to_flatview(&address_space_memory);
+        flatview_for_each_range(fv, apple_gfx_register_memory_cb, memory_map_descriptor);
+        /* the device model defines this as a single-page MMIO region, hence 16KB */
+        iosfc_desc.mmioLength = 0x10000;
+        iosfc_desc.memoryMapDescriptor = memory_map_descriptor;
+    } else {
+        iosfc_desc.mapMemory =
+            ^bool(uint64_t phys, uint64_t len, bool ro, void **va, void *e, void *f) {
+                *va = apple_gfx_mmio_map_surface_memory(phys, len, ro);
+
+                trace_apple_gfx_iosfc_map_memory(phys, len, ro, va, e, f, *va);
+
+                return *va != NULL;
+            };
+
+        iosfc_desc.unmapMemory =
+            ^bool(void *va, void *b, void *c, void *d, void *e, void *f) {
+                return apple_gfx_mmio_unmap_surface_memory(va);
+            };
+    }
 
     iosfc_desc.raiseInterrupt = ^bool(uint32_t vector) {
         trace_apple_gfx_iosfc_raise_irq(vector);
@@ -223,13 +244,22 @@ static void apple_gfx_mmio_realize(DeviceState *dev, Error **errp)
         };
 
         desc.usingIOSurfaceMapper = true;
-        s->pgiosfc = apple_gfx_prepare_iosurface_host_device(s);
+        /* 
+         * Process isolation needs PGMemoryMapDescriptor instead of
+         * the legacy memory management interface present in releases
+         * older than macOS 15.4.
+         */
+        if (@available(macOS 15.4, *)) {
+            desc.enableProcessIsolation = true;
+        }
 
         if (!apple_gfx_common_realize(&s->common, dev, desc, errp)) {
             [s->pgiosfc release];
             s->pgiosfc = nil;
         }
 
+        s->pgiosfc = apple_gfx_prepare_iosurface_host_device(s);
+
         [desc release];
         desc = nil;
     }
diff --git a/hw/display/apple-gfx.h b/hw/display/apple-gfx.h
index 3197bd853d..384aee0c5f 100644
--- a/hw/display/apple-gfx.h
+++ b/hw/display/apple-gfx.h
@@ -12,6 +12,7 @@
 #include "system/memory.h"
 #include "hw/core/qdev-properties.h"
 #include "ui/surface.h"
+#include "objc/NSObject.h"
 
 #define TYPE_APPLE_GFX_MMIO         "apple-gfx-mmio"
 #define TYPE_APPLE_GFX_PCI          "apple-gfx-pci"
@@ -23,6 +24,17 @@
 @protocol MTLTexture;
 @protocol MTLCommandQueue;
 
+typedef struct PGGuestPhysicalRange_s
+{
+    uint64_t physicalAddress;
+    uint64_t physicalLength;
+    void *hostAddress;
+} PGGuestPhysicalRange_t;
+
+@interface PGMemoryMapDescriptor : NSObject
+-(void)addRange:(PGGuestPhysicalRange_t) range;
+@end
+
 typedef QTAILQ_HEAD(, PGTask_s) PGTaskList;
 
 typedef struct AppleGFXDisplayMode {
@@ -68,6 +80,10 @@ void *apple_gfx_host_ptr_for_gpa_range(uint64_t guest_physical,
                                        uint64_t length, bool read_only,
                                        MemoryRegion **mapping_in_region);
 
+bool apple_gfx_register_memory_cb(Int128 start, Int128 len,
+                                  const MemoryRegion *mr,
+                                  hwaddr offset_in_region, void *opaque);
+
 extern const PropertyInfo qdev_prop_apple_gfx_display_mode;
 
 #endif
diff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m
index be0061b9db..4ef8f6dbf3 100644
--- a/hw/display/apple-gfx.m
+++ b/hw/display/apple-gfx.m
@@ -21,6 +21,7 @@
 #include "system/address-spaces.h"
 #include "system/dma.h"
 #include "migration/blocker.h"
+#include "system/memory.h"
 #include "ui/console.h"
 #include "apple-gfx.h"
 #include "trace.h"
@@ -79,6 +80,7 @@ static dispatch_queue_t get_background_queue(void)
     GPtrArray *mapped_regions;
 };
 
+API_OBSOLETED("Legacy ParavirtualizedGraphics", macos(11.0, 27.0, 27.0)) 
 static PGTask_t *apple_gfx_new_task(AppleGFXState *s, uint64_t len)
 {
     mach_vm_address_t task_mem;
@@ -102,6 +104,7 @@ static dispatch_queue_t get_background_queue(void)
     return task;
 }
 
+API_OBSOLETED("Legacy ParavirtualizedGraphics", macos(11.0, 27.0, 27.0))
 static void apple_gfx_destroy_task(AppleGFXState *s, PGTask_t *task)
 {
     GPtrArray *regions = task->mapped_regions;
@@ -151,6 +154,7 @@ static void apple_gfx_destroy_task(AppleGFXState *s, PGTask_t *task)
     return host_ptr;
 }
 
+API_OBSOLETED("Legacy ParavirtualizedGraphics", macos(11.0, 27.0, 27.0))
 static bool apple_gfx_task_map_memory(AppleGFXState *s, PGTask_t *task,
                                       uint64_t virtual_offset,
                                       PGPhysicalMemoryRange_t *ranges,
@@ -207,6 +211,7 @@ static bool apple_gfx_task_map_memory(AppleGFXState *s, PGTask_t *task,
     return success;
 }
 
+API_OBSOLETED("Legacy ParavirtualizedGraphics", macos(11.0, 27.0, 27.0))
 static void apple_gfx_task_unmap_memory(AppleGFXState *s, PGTask_t *task,
                                         uint64_t virtual_offset, uint64_t length)
 {
@@ -596,6 +601,36 @@ void apple_gfx_common_init(Object *obj, AppleGFXState *s, const char* obj_name)
     /* TODO: PVG framework supports serialising device state: integrate it! */
 }
 
+@interface PGDeviceDescriptor (IOSurfaceMapper)
+@property (readwrite, nonatomic, copy, nullable) PGMemoryMapDescriptor* memoryMapDescriptor;
+@end
+
+bool apple_gfx_register_memory_cb(Int128 start, Int128 len,
+                                  const MemoryRegion *mr,
+                                  hwaddr offset_in_region, void *opaque) {
+    PGGuestPhysicalRange_t range;
+    PGMemoryMapDescriptor *memory_map_descriptor = opaque;
+    if (memory_access_is_direct(mr, true, MEMTXATTRS_UNSPECIFIED)) {
+        range.physicalAddress = start;
+        range.physicalLength = len;
+        range.hostAddress = memory_region_get_ram_ptr(mr);
+        [memory_map_descriptor addRange:range];
+    }
+    return false;
+}
+
+static void apple_gfx_register_memory(AppleGFXState *s,
+                                                     PGDeviceDescriptor *desc)
+{
+    PGMemoryMapDescriptor* memoryMapDescriptor = [PGMemoryMapDescriptor new];
+
+    FlatView* fv = address_space_to_flatview(&address_space_memory);
+    flatview_for_each_range(fv, apple_gfx_register_memory_cb, memoryMapDescriptor);
+
+    desc.memoryMapDescriptor = memoryMapDescriptor;
+}
+
+API_OBSOLETED("Legacy ParavirtualizedGraphics", macos(11.0, 27.0, 27.0))
 static void apple_gfx_register_task_mapping_handlers(AppleGFXState *s,
                                                      PGDeviceDescriptor *desc)
 {
@@ -667,16 +702,25 @@ static void new_frame_handler_bh(void *opaque)
         BQL_LOCK_GUARD();
         set_mode(s, sizeInPixels.x, sizeInPixels.y);
     };
-    disp_desc.cursorGlyphHandler = ^(NSBitmapImageRep *glyph,
-                                     PGDisplayCoord_t hotspot) {
-        AppleGFXSetCursorGlyphJob *job = g_malloc0(sizeof(*job));
-        job->s = s;
-        job->glyph = glyph;
-        job->hotspot = hotspot;
-        [glyph retain];
-        aio_bh_schedule_oneshot(qemu_get_aio_context(),
-                                set_cursor_glyph, job);
-    };
+
+    if (@available(macOS 27.0, *)) {
+
+    } else {
+#ifndef __MAC_27_0
+        disp_desc.cursorGlyphHandler = ^(NSBitmapImageRep *glyph,
+                                         PGDisplayCoord_t hotspot) {
+            AppleGFXSetCursorGlyphJob *job = g_malloc0(sizeof(*job));
+            job->s = s;
+            job->glyph = glyph;
+            job->hotspot = hotspot;
+            [glyph retain];
+            aio_bh_schedule_oneshot(qemu_get_aio_context(),
+                                    set_cursor_glyph, job);
+        };
+#else
+        abort();
+#endif
+    }
     disp_desc.cursorShowHandler = ^(BOOL show) {
         trace_apple_gfx_cursor_show(show);
         qatomic_set(&s->cursor_show, show);
@@ -763,11 +807,33 @@ bool apple_gfx_common_realize(AppleGFXState *s, DeviceState *dev,
 
     desc.device = s->mtl;
 
-    apple_gfx_register_task_mapping_handlers(s, desc);
+    /* 
+     * The legacy memory management interface doesn't allow for
+     * vGPU sandboxing. As such, always use the new interface
+     * on macOS 15.4 onwards. 
+     */
+    if (@available(macOS 15.4, *)) {
+        apple_gfx_register_memory(s, desc);
+    } else {
+#ifndef __MAC_27_0
+        apple_gfx_register_task_mapping_handlers(s, desc);
+#else
+        abort();
+#endif
+    }
 
     s->cursor_show = true;
 
-    s->pgdev = PGNewDeviceWithDescriptor(desc);
+    if (@available(macOS 15.2, *)) {
+        s->pgdev = PGCreateDeviceWithDescriptor(desc);
+    }
+    else {
+#ifndef __MAC_27_0
+        s->pgdev = PGNewDeviceWithDescriptor(desc);
+#else
+        abort();
+#endif
+    }
 
     disp_desc = apple_gfx_prepare_display_descriptor(s);
     /*
-- 
2.54.0 (Apple Git-157)



  parent reply	other threads:[~2026-09-16 10:02 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-16 10:00 [RFC PATCH v8 00/10] vmapple: making it work on the latest macOS host releases Mohamed Mediouni
2026-09-16 10:00 ` [RFC PATCH v8 01/10] target/arm/emulate: add ISV=0 emulation library with load/store immediate Mohamed Mediouni
2026-09-17 20:32   ` Akihiko Odaki
2026-09-16 10:00 ` [RFC PATCH v8 02/10] target/arm/emulate: add load/store register offset Mohamed Mediouni
2026-09-16 10:00 ` [RFC PATCH v8 03/10] target/arm/emulate: add load/store pair Mohamed Mediouni
2026-09-17 20:33   ` Akihiko Odaki
2026-09-16 10:00 ` [RFC PATCH v8 04/10] target/arm/hvf, whpx: wire ISV=0 emulation for data aborts Mohamed Mediouni
2026-09-17 20:37   ` Akihiko Odaki
2026-09-16 10:00 ` Mohamed Mediouni [this message]
2026-09-17 20:37   ` [RFC PATCH v8 05/10] vmapple: apple-gfx: make it work on the latest macOS release Akihiko Odaki
2026-09-17 21:49     ` Mohamed Mediouni
2026-10-04  6:24       ` Akihiko Odaki
2026-09-16 10:00 ` [RFC PATCH v8 06/10] hw/vmapple: aes: convert MAX_LEN to a #define Mohamed Mediouni
2026-09-16 11:20   ` Peter Maydell
2026-09-16 11:34     ` Daniel P. Berrangé
2026-09-16 10:00 ` [RFC PATCH v8 07/10] Revert "hw/arm: Do not build VMapple machine by default" Mohamed Mediouni
2026-09-16 10:00 ` [RFC PATCH v8 08/10] vmapple: add gicv2m Mohamed Mediouni
2026-09-16 10:00 ` [RFC PATCH v8 09/10] vmapple, gicv2m: add macOS compat quirk Mohamed Mediouni
2026-09-16 10:51   ` Peter Maydell
2026-09-16 10:56     ` Mohamed Mediouni
2026-09-16 10:00 ` [RFC PATCH v8 10/10] hw/vmapple: virtio-blk: allow FileVault off Mohamed Mediouni
2026-09-17 20:37   ` Akihiko Odaki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260916100021.73825-6-mohamed@unpredictable.fr \
    --to=mohamed@unpredictable.fr \
    --cc=agraf@csgraf.de \
    --cc=mst@redhat.com \
    --cc=odaki@rsg.ci.i.u-tokyo.ac.jp \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=peterx@redhat.com \
    --cc=phil@philjordan.eu \
    --cc=philmd@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rbolshakov@ddn.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.