Browse Source

hv: added XNU 20 offsets

osy 2 years ago
parent
commit
cc2900ba4f
6 changed files with 1415 additions and 561 deletions
  1. 198 162
      hv.c
  2. 43 399
      hv_kernel_structs.h
  3. 372 0
      hv_kernel_structs_xnu_20.h
  4. 402 0
      hv_kernel_structs_xnu_21.h
  5. 400 0
      sysreg_offsets_xnu_20.h
  6. 0 0
      sysreg_offsets_xnu_21.h

+ 198 - 162
hv.c

@@ -1,5 +1,6 @@
 // Decompiled by hand (based-ish on a Ghidra decompile) from Hypervisor.framework on macOS 12.0b1
-// 06/09/22: updated for 12.5.1
+// 06/09/22: updated for macOS 12.5.1
+// 15/09/22: added offsets for macOS 11.6.5
 #include <assert.h>
 #include <pthread.h>
 #include <stdio.h>
@@ -92,22 +93,24 @@ static hv_return_t _hv_vcpu_config_get_feature_regs(
   if (err) {
     return err;
   }
-  feature_regs->aa64dfr0_el1 = MODIFY_FLAGS_AA64DFR0_EL1(caps->id_aa64dfr0_el1);
-  feature_regs->aa64dfr1_el1 = MODIFY_FLAGS_AA64DFR1_EL1(caps->id_aa64dfr1_el1);
-  feature_regs->aa64isar0_el1 = MODIFY_FLAGS_AA64ISAR0_EL1(caps->id_aa64isar0_el1);
-  feature_regs->aa64isar1_el1 = MODIFY_FLAGS_AA64ISAR1_EL1(caps->id_aa64isar1_el1);
-  feature_regs->aa64mmfr0_el1 = MODIFY_FLAGS_AA64MMFR0_EL1(caps->id_aa64mmfr0_el1);
-  feature_regs->aa64mmfr1_el1 = MODIFY_FLAGS_AA64MMFR1_EL1(caps->id_aa64mmfr1_el1);
-  feature_regs->aa64mmfr2_el1 = MODIFY_FLAGS_AA64MMFR2_EL1(caps->id_aa64mmfr2_el1);
-  feature_regs->aa64pfr0_el1 = MODIFY_FLAGS_AA64PFR0_EL1(caps->id_aa64pfr0_el1);
-  feature_regs->aa64pfr1_el1 = MODIFY_FLAGS_AA64PFR1_EL1(caps->id_aa64pfr1_el1);
-  feature_regs->ctr_el0 = MODIFY_FLAGS_CTR_EL0(caps->ctr_el0);
-  feature_regs->dczid_el0 = MODIFY_FLAGS_DCZID_EL0(caps->dczid_el0);
-  feature_regs->clidr_el1 = MODIFY_FLAGS_CLIDR_EL1(caps->clidr_el1);
-  static_assert(sizeof(feature_regs->ccsidr_el1_inst) == sizeof(caps->ccsidr_el1_inst), "ccsidr_el1_inst size");
-  memcpy(feature_regs->ccsidr_el1_inst, caps->ccsidr_el1_inst, sizeof(feature_regs->ccsidr_el1_inst));
-  static_assert(sizeof(feature_regs->ccsidr_el1_data_or_unified) == sizeof(caps->ccsidr_el1_data_or_unified), "ccsidr_el1_data_or_unified size");
-  memcpy(feature_regs->ccsidr_el1_data_or_unified, caps->ccsidr_el1_data_or_unified, sizeof(feature_regs->ccsidr_el1_data_or_unified));
+  feature_regs->aa64dfr0_el1 = MODIFY_FLAGS_AA64DFR0_EL1(ACCESS(caps, id_aa64dfr0_el1));
+  feature_regs->aa64dfr1_el1 = MODIFY_FLAGS_AA64DFR1_EL1(ACCESS(caps, id_aa64dfr1_el1));
+  feature_regs->aa64isar0_el1 = MODIFY_FLAGS_AA64ISAR0_EL1(ACCESS(caps, id_aa64isar0_el1));
+  feature_regs->aa64isar1_el1 = MODIFY_FLAGS_AA64ISAR1_EL1(ACCESS(caps, id_aa64isar1_el1));
+  feature_regs->aa64mmfr0_el1 = MODIFY_FLAGS_AA64MMFR0_EL1(ACCESS(caps, id_aa64mmfr0_el1));
+  feature_regs->aa64mmfr1_el1 = MODIFY_FLAGS_AA64MMFR1_EL1(ACCESS(caps, id_aa64mmfr1_el1));
+  feature_regs->aa64mmfr2_el1 = MODIFY_FLAGS_AA64MMFR2_EL1(ACCESS(caps, id_aa64mmfr2_el1));
+  feature_regs->aa64pfr0_el1 = MODIFY_FLAGS_AA64PFR0_EL1(ACCESS(caps, id_aa64pfr0_el1));
+  feature_regs->aa64pfr1_el1 = MODIFY_FLAGS_AA64PFR1_EL1(ACCESS(caps, id_aa64pfr1_el1));
+  feature_regs->ctr_el0 = MODIFY_FLAGS_CTR_EL0(ACCESS(caps, ctr_el0));
+  feature_regs->dczid_el0 = MODIFY_FLAGS_DCZID_EL0(ACCESS(caps, dczid_el0));
+  feature_regs->clidr_el1 = MODIFY_FLAGS_CLIDR_EL1(ACCESS(caps, clidr_el1));
+  if (get_xnu_version() >= HV_VERSION_XNU_21) {
+    static_assert(sizeof(feature_regs->ccsidr_el1_inst) == sizeof(caps->v21.ccsidr_el1_inst), "ccsidr_el1_inst size");
+    memcpy(feature_regs->ccsidr_el1_inst, ACCESS(caps, ccsidr_el1_inst), sizeof(feature_regs->ccsidr_el1_inst));
+    static_assert(sizeof(feature_regs->ccsidr_el1_data_or_unified) == sizeof(caps->v21.ccsidr_el1_data_or_unified), "ccsidr_el1_data_or_unified size");
+    memcpy(feature_regs->ccsidr_el1_data_or_unified, ACCESS(caps, ccsidr_el1_data_or_unified), sizeof(feature_regs->ccsidr_el1_data_or_unified));
+  }
   return 0;
 }
 
@@ -204,9 +207,6 @@ struct hv_vcpu_create_kernel_args {
   struct hv_vcpu_zone* output_vcpu_zone;  // 0x8
 };
 
-// ' hyp', 0xe
-static const uint64_t kHvVcpuMagic = 0x206879700000000eull;
-
 struct hv_vcpu_config_private {
   char field_0[16];
   uint64_t vmkeylo_el2;
@@ -237,8 +237,9 @@ hv_return_t hv_vcpu_create(hv_vcpu_t* vcpu, hv_vcpu_exit_t** exit, hv_vcpu_confi
     return err;
   }
   printf("vcpu_zone = %p\n", args.output_vcpu_zone);
-  if (args.output_vcpu_zone->ro.ver != kHvVcpuMagic) {
-    printf("Invalid magic! expected %llx, got %llx\n", kHvVcpuMagic, args.output_vcpu_zone->ro.ver);
+  uint64_t expected_magic = get_expected_magic();
+  if (args.output_vcpu_zone->ro.ver != expected_magic) {
+    printf("Invalid magic! expected %llx, got %llx\n", expected_magic, args.output_vcpu_zone->ro.ver);
 #ifndef USE_KERNEL_BYPASS_CHECKS
     hv_trap(HV_CALL_VCPU_DESTROY, NULL);
     pthread_mutex_unlock(&vcpus_mutex);
@@ -248,6 +249,8 @@ hv_return_t hv_vcpu_create(hv_vcpu_t* vcpu, hv_vcpu_exit_t** exit, hv_vcpu_confi
 #endif
   }
   vcpu_data->vcpu_zone = args.output_vcpu_zone;
+  arm_guest_ro_context_t *ro = &vcpu_data->vcpu_zone->ro;
+  arm_guest_rw_context_t *rw = &vcpu_data->vcpu_zone->rw;
   *vcpu = cpuid;
   *exit = &vcpu_data->exit;
   pthread_mutex_unlock(&vcpus_mutex);
@@ -259,21 +262,21 @@ hv_return_t hv_vcpu_create(hv_vcpu_t* vcpu, hv_vcpu_exit_t** exit, hv_vcpu_confi
   }
 
   if (config) {
-    vcpu_data->vcpu_zone->rw.controls.vmkeylo_el2 = _config->vmkeylo_el2;
-    vcpu_data->vcpu_zone->rw.controls.vmkeyhi_el2 = _config->vmkeyhi_el2;
+    ACCESS(rw, controls.vmkeylo_el2) = _config->vmkeylo_el2;
+    ACCESS(rw, controls.vmkeyhi_el2) = _config->vmkeyhi_el2;
   }
 
   // Apple traps PMCCNTR_EL0 using this proprietary register, then translates the syndrome.
   // No, I don't know why Apple doesn't just use HDFGRTR_EL2 or MDCR_EL2
-  vcpu_data->vcpu_zone->rw.controls.hacr_el2 |= 1ull << 56;
+  ACCESS(rw, controls.hacr_el2) |= 1ull << 56;
   // TID3: trap the feature regs so we can handle these ourselves
-  vcpu_data->vcpu_zone->rw.controls.hcr_el2 |= 0x40000ull;
+  ACCESS(rw, controls.hcr_el2) |= 0x40000ull;
   // if ro hacr has a bit set, clear rw hcr_el2 TIDCP?!
-  if ((vcpu_data->vcpu_zone->ro.controls.hacr_el2 >> 4 & 1) != 0) {
-    vcpu_data->vcpu_zone->rw.controls.hcr_el2 &= ~0x100000;
+  if ((ACCESS(ro, controls.hacr_el2) >> 4 & 1) != 0) {
+    ACCESS(rw, controls.hcr_el2) &= ~0x100000;
   }
-  vcpu_data->vcpu_zone->rw.controls.hcr_el2 |= 0x80000;
-  vcpu_data->vcpu_zone->rw.state_dirty |= 0x4;
+  ACCESS(rw, controls.hcr_el2) |= 0x80000;
+  ACCESS(rw, state_dirty) |= 0x4;
   return 0;
 }
 
@@ -296,13 +299,15 @@ static void deliver_uncategorized_exception(struct hv_vcpu_data* vcpu_data);
 hv_return_t hv_vcpu_run(hv_vcpu_t vcpu) {
   // update registers
   struct hv_vcpu_data* vcpu_data = &vcpus[vcpu];
+  arm_guest_ro_context_t *ro = &vcpu_data->vcpu_zone->ro;
+  arm_guest_rw_context_t *rw = &vcpu_data->vcpu_zone->rw;
   bool injected_interrupt = false;
   if (vcpu_data->pending_interrupts) {
     injected_interrupt = true;
-    vcpu_data->vcpu_zone->rw.controls.hcr_el2 |= vcpu_data->pending_interrupts;
-    vcpu_data->vcpu_zone->rw.state_dirty |= 0x4;
+    ACCESS(rw, controls.hcr_el2) |= vcpu_data->pending_interrupts;
+    ACCESS(rw, state_dirty) |= 0x4;
   }
-  vcpu_data->timer_enabled = vcpu_data->vcpu_zone->rw.controls.timer & 1;
+  vcpu_data->timer_enabled = ACCESS(rw, controls.timer) & 1;
   while (true) {
     hv_return_t err = hv_trap(HV_CALL_VCPU_RUN, NULL);
     if (err) {
@@ -311,11 +316,11 @@ hv_return_t hv_vcpu_run(hv_vcpu_t vcpu) {
     bool print_vmexit = false;
     if (print_vmexit) {
       printf("exit = %d (esr = %x far = %llx hpfar = %llx)\n",
-             vcpu_data->vcpu_zone->ro.exit.vmexit_reason, vcpu_data->vcpu_zone->ro.exit.vmexit_esr,
-             vcpu_data->vcpu_zone->ro.exit.vmexit_far, vcpu_data->vcpu_zone->ro.exit.vmexit_hpfar);
+             ACCESS(ro, exit.vmexit_reason), ACCESS(ro, exit.vmexit_esr),
+             ACCESS(ro, exit.vmexit_far), ACCESS(ro, exit.vmexit_hpfar));
     }
     hv_vcpu_exit_t* exit = &vcpu_data->exit;
-    switch (vcpu_data->vcpu_zone->ro.exit.vmexit_reason) {
+    switch (ACCESS(ro, exit.vmexit_reason)) {
       case 0: {
         exit->reason = HV_EXIT_REASON_CANCELED;
         break;
@@ -330,10 +335,10 @@ hv_return_t hv_vcpu_run(hv_vcpu_t vcpu) {
       }
       case 3:
       case 4: {
-        if (!vcpu_data->timer_enabled && vcpu_data->vcpu_zone->rw.banked_sysregs.cntv_ctl_el0 == 5) {
+        if (!vcpu_data->timer_enabled && ACCESS(rw, banked_sysregs.cntv_ctl_el0) == 5) {
           exit->reason = HV_EXIT_REASON_VTIMER_ACTIVATED;
           // mask vtimer
-          vcpu_data->vcpu_zone->rw.controls.timer |= 1ull;
+          ACCESS(rw, controls.timer) |= 1ull;
         } else {
           exit->reason = HV_EXIT_REASON_UNKNOWN;
         }
@@ -354,8 +359,8 @@ hv_return_t hv_vcpu_run(hv_vcpu_t vcpu) {
     }
     if (injected_interrupt) {
       vcpu_data->pending_interrupts = 0;
-      vcpu_data->vcpu_zone->rw.controls.hcr_el2 &= ~0xc0ull;
-      vcpu_data->vcpu_zone->rw.state_dirty |= 0x4;
+      ACCESS(rw, controls.hcr_el2) &= ~0xc0ull;
+      ACCESS(rw, state_dirty) |= 0x4;
     }
     return 0;
   }
@@ -366,20 +371,21 @@ hv_return_t hv_vcpu_get_reg(hv_vcpu_t vcpu, hv_reg_t reg, uint64_t* value) {
     return HV_BAD_ARGUMENT;
   }
   struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
   if (reg < HV_REG_FP) {
-    *value = vcpu_zone->rw.regs.x[reg];
+    *value = ACCESS(rw, regs.x[reg]);
   } else if (reg == HV_REG_FP) {
-    *value = vcpu_zone->rw.regs.fp;
+    *value = ACCESS(rw, regs.fp);
   } else if (reg == HV_REG_LR) {
-    *value = vcpu_zone->rw.regs.lr;
+    *value = ACCESS(rw, regs.lr);
   } else if (reg == HV_REG_PC) {
-    *value = vcpu_zone->rw.regs.pc;
+    *value = ACCESS(rw, regs.pc);
   } else if (reg == HV_REG_FPCR) {
-    *value = vcpu_zone->rw.neon.fpcr;
+    *value = ACCESS(rw, neon.fpcr);
   } else if (reg == HV_REG_FPSR) {
-    *value = vcpu_zone->rw.neon.fpsr;
+    *value = ACCESS(rw, neon.fpsr);
   } else if (reg == HV_REG_CPSR) {
-    *value = vcpu_zone->rw.regs.cpsr;
+    *value = ACCESS(rw, regs.cpsr);
   }
   return 0;
 }
@@ -389,20 +395,21 @@ hv_return_t hv_vcpu_set_reg(hv_vcpu_t vcpu, hv_reg_t reg, uint64_t value) {
     return HV_BAD_ARGUMENT;
   }
   struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
   if (reg < HV_REG_FP) {
-    vcpu_zone->rw.regs.x[reg] = value;
+    ACCESS(rw, regs.x[reg]) = value;
   } else if (reg == HV_REG_FP) {
-    vcpu_zone->rw.regs.lr = value;
+    ACCESS(rw, regs.lr) = value;
   } else if (reg == HV_REG_LR) {
-    vcpu_zone->rw.regs.lr = value;
+    ACCESS(rw, regs.lr) = value;
   } else if (reg == HV_REG_PC) {
-    vcpu_zone->rw.regs.pc = value;
+    ACCESS(rw, regs.pc) = value;
   } else if (reg == HV_REG_FPCR) {
-    vcpu_zone->rw.neon.fpcr = value;
+    ACCESS(rw, neon.fpcr) = value;
   } else if (reg == HV_REG_FPSR) {
-    vcpu_zone->rw.neon.fpsr = value;
+    ACCESS(rw, neon.fpsr) = value;
   } else if (reg == HV_REG_CPSR) {
-    vcpu_zone->rw.regs.cpsr = value;
+    ACCESS(rw, regs.cpsr) = value;
   }
   return 0;
 }
@@ -413,7 +420,8 @@ hv_return_t hv_vcpu_get_simd_fp_reg(hv_vcpu_t vcpu, hv_simd_fp_reg_t reg,
     return HV_BAD_ARGUMENT;
   }
   struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
-  *((__uint128_t*)value) = vcpu_zone->rw.neon.q[reg];
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  *((__uint128_t*)value) = ACCESS(rw, neon.q[reg]);
   return 0;
 }
 
@@ -423,17 +431,28 @@ hv_return_t hv_vcpu_set_simd_fp_reg(hv_vcpu_t vcpu, hv_simd_fp_reg_t reg,
     return HV_BAD_ARGUMENT;
   }
   struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
-  vcpu_zone->rw.neon.q[reg] = *((__uint128_t*)&value);
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  ACCESS(rw, neon.q[reg]) = *((__uint128_t*)&value);
   return 0;
 }
 
 static bool find_sys_reg(hv_sys_reg_t sys_reg, uint64_t* offset, uint64_t* sync_mask) {
   uint64_t o = 0;
   uint64_t f = 0;
-  switch (sys_reg) {
-#include "sysreg_offsets.h"
-    default:
-      return false;
+  if (get_xnu_version() == HV_VERSION_XNU_20) {
+    switch (sys_reg) {
+#include "sysreg_offsets_xnu_20.h"
+      default:
+        return false;
+    }
+  } else if (get_xnu_version() == HV_VERSION_XNU_21) {
+    switch (sys_reg) {
+#include "sysreg_offsets_xnu_21.h"
+      default:
+        return false;
+    }
+  } else {
+    return false;
   }
   *offset = o;
   *sync_mask = f;
@@ -447,12 +466,14 @@ hv_return_t hv_vcpu_get_sys_reg(hv_vcpu_t vcpu, hv_sys_reg_t sys_reg, uint64_t*
   hv_return_t err;
   struct hv_vcpu_data* vcpu_data = &vcpus[vcpu];
   struct hv_vcpu_zone* vcpu_zone = vcpu_data->vcpu_zone;
+  arm_guest_ro_context_t *ro = &vcpu_zone->ro;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
   switch (sys_reg) {
     case HV_SYS_REG_MIDR_EL1:
-      *value = vcpu_zone->rw.controls.vpidr_el2;
+      *value = ACCESS(rw, controls.vpidr_el2);
       return 0;
     case HV_SYS_REG_MPIDR_EL1:
-      *value = vcpu_zone->rw.controls.vmpidr_el2;
+      *value = ACCESS(rw, controls.vmpidr_el2);
       return 0;
     case HV_SYS_REG_ID_AA64PFR0_EL1:
       *value = vcpu_data->feature_regs.aa64pfr0_el1;
@@ -493,12 +514,12 @@ hv_return_t hv_vcpu_get_sys_reg(hv_vcpu_t vcpu, hv_sys_reg_t sys_reg, uint64_t*
     return HV_BAD_ARGUMENT;
   }
   if ((sync_mask != 0) &&
-     ((vcpu_zone->rw.state_dirty & sync_mask) == 0 && (vcpu_zone->ro.state_valid & sync_mask) == 0)) {
+     ((ACCESS(rw, state_dirty) & sync_mask) == 0 && (ACCESS(ro, state_valid) & sync_mask) == 0)) {
     if ((err = hv_trap(HV_CALL_VCPU_SYSREGS_SYNC, 0)) != 0) {
       return err;
     }
   }
-  *value = *(uint64_t*)((char*)(&vcpu_zone->rw) + offset);
+  *value = *(uint64_t*)((char*)rw + offset);
   return 0;
 }
 
@@ -506,15 +527,17 @@ hv_return_t hv_vcpu_set_sys_reg(hv_vcpu_t vcpu, hv_sys_reg_t sys_reg, uint64_t v
   hv_return_t err;
   struct hv_vcpu_data* vcpu_data = &vcpus[vcpu];
   struct hv_vcpu_zone* vcpu_zone = vcpu_data->vcpu_zone;
+  arm_guest_ro_context_t *ro = &vcpu_zone->ro;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
   switch (sys_reg) {
     case HV_SYS_REG_MIDR_EL1: {
-      vcpu_zone->rw.controls.vpidr_el2 = value;
-      vcpu_zone->rw.state_dirty |= 0x4;
+      ACCESS(rw, controls.vpidr_el2) = value;
+      ACCESS(rw, state_dirty) |= 0x4;
       return 0;
     }
     case HV_SYS_REG_MPIDR_EL1: {
-      vcpu_zone->rw.controls.vmpidr_el2 = value;
-      vcpu_zone->rw.state_dirty |= 0x4;
+      ACCESS(rw, controls.vmpidr_el2) = value;
+      ACCESS(rw, state_dirty) |= 0x4;
       return 0;
     }
       // the kernel doesn't set these - userspace traps and handles these
@@ -556,14 +579,14 @@ hv_return_t hv_vcpu_set_sys_reg(hv_vcpu_t vcpu, hv_sys_reg_t sys_reg, uint64_t v
     printf("invalid set sys reg: %x\n", sys_reg);
     return HV_BAD_ARGUMENT;
   }
-  if ((sync_mask != 0) && (((vcpu_zone->ro.state_valid & sync_mask) == 0))) {
+  if ((sync_mask != 0) && (((ACCESS(ro, state_valid) & sync_mask) == 0))) {
     if ((err = hv_trap(HV_CALL_VCPU_SYSREGS_SYNC, 0)) != 0) {
       return err;
     }
   }
-  *(uint64_t*)((char*)(&vcpu_zone->rw) + offset) = value;
+  *(uint64_t*)((char*)rw + offset) = value;
   if (sync_mask != 0) {
-    vcpu_zone->rw.state_dirty |= sync_mask;
+    ACCESS(rw, state_dirty) |= sync_mask;
   }
   return 0;
 }
@@ -573,26 +596,30 @@ hv_return_t hv_vcpu_get_vtimer_mask(hv_vcpu_t vcpu, bool* vtimer_is_masked) {
     return HV_BAD_ARGUMENT;
   }
   struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
-  *vtimer_is_masked = vcpu_zone->rw.controls.timer & 1;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  *vtimer_is_masked = ACCESS(rw, controls.timer) & 1;
   return 0;
 }
 
 hv_return_t hv_vcpu_set_vtimer_mask(hv_vcpu_t vcpu, bool vtimer_is_masked) {
   struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
-  vcpu_zone->rw.controls.timer = (vcpu_zone->rw.controls.timer & ~1ull) | vtimer_is_masked;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  ACCESS(rw, controls.timer) = (ACCESS(rw, controls.timer) & ~1ull) | vtimer_is_masked;
   return 0;
 }
 
 hv_return_t hv_vcpu_get_vtimer_offset(hv_vcpu_t vcpu, uint64_t* vtimer_offset) {
   struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
-  *vtimer_offset = vcpu_zone->rw.controls.virtual_timer_offset;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  *vtimer_offset = ACCESS(rw, controls.virtual_timer_offset);
   return 0;
 }
 
 hv_return_t hv_vcpu_set_vtimer_offset(hv_vcpu_t vcpu, uint64_t vtimer_offset) {
   struct hv_vcpu_zone* vcpu_zone = vcpus[vcpu].vcpu_zone;
-  vcpu_zone->rw.controls.virtual_timer_offset = vtimer_offset;
-  vcpu_zone->rw.state_dirty |= 0x4;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  ACCESS(rw, controls.virtual_timer_offset) = vtimer_offset;
+  ACCESS(rw, state_dirty) |= 0x4;
   return 0;
 }
 
@@ -633,33 +660,37 @@ hv_return_t hv_vcpus_exit(hv_vcpu_t* vcpus, uint32_t vcpu_count) {
 
 void sync_and_dirty_banked_state(struct hv_vcpu_zone *vcpu_zone, uint64_t state)
 {
-  if (((vcpu_zone->ro.state_valid & state) == 0) && hv_trap(HV_CALL_VCPU_SYSREGS_SYNC, 0) != 0) {
+  arm_guest_ro_context_t *ro = &vcpu_zone->ro;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  if (((ACCESS(ro, state_valid) & state) == 0) && hv_trap(HV_CALL_VCPU_SYSREGS_SYNC, 0) != 0) {
     assert(false);
   }
-  vcpu_zone->rw.state_dirty = vcpu_zone->rw.state_dirty | state;
+  ACCESS(rw, state_dirty) = ACCESS(rw, state_dirty) | state;
   return;
 }
 
 static bool deliver_msr_trap(struct hv_vcpu_data* vcpu_data, hv_vcpu_exit_t* exit) {
-  uint64_t esr = vcpu_data->vcpu_zone->ro.exit.vmexit_esr;
+  struct hv_vcpu_zone* vcpu_zone = vcpu_data->vcpu_zone;
+  arm_guest_ro_context_t *ro = &vcpu_zone->ro;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  uint64_t esr = ACCESS(ro, exit.vmexit_esr);
   uint32_t reg = (esr >> 5) & 0x1f;
   uint32_t sysreg = esr & 0x3ffc1e;
-  struct hv_vcpu_zone* vcpu_zone = vcpu_data->vcpu_zone;
   if ((esr & 0x300000) == 0x200000) {
-    if ((vcpu_zone->rw.controls.mdcr_el2 >> 9 & 1) != 0) {
+    if ((ACCESS(rw, controls.mdcr_el2) >> 9 & 1) != 0) {
       return false;
     }
     if ((esr & 1) == 0) {
       switch (sysreg) {
         case 0x200004:
-          vcpu_zone->rw.dbgregs.mdccint_el1 = vcpu_zone->rw.regs.x[reg];
+          ACCESS(rw, dbgregs.mdccint_el1) = ACCESS(rw, regs.x[reg]);
           break;
         case 0x240000:
-          vcpu_zone->rw.dbgregs.osdtrrx_el1 = vcpu_zone->rw.regs.x[reg];
+          ACCESS(rw, dbgregs.osdtrrx_el1) = ACCESS(rw, regs.x[reg]);
           break;
         case 0x20c008:
         case 0x240006:
-          vcpu_zone->rw.dbgregs.osdtrtx_el1 = vcpu_zone->rw.regs.x[reg];
+          ACCESS(rw, dbgregs.osdtrtx_el1) = ACCESS(rw, regs.x[reg]);
           break;
         default:
           return false;
@@ -667,18 +698,18 @@ static bool deliver_msr_trap(struct hv_vcpu_data* vcpu_data, hv_vcpu_exit_t* exi
     } else {
       switch (sysreg) {
         case 0x200004:
-          vcpu_zone->rw.regs.x[reg] = vcpu_zone->rw.dbgregs.mdccint_el1;
+          ACCESS(rw, regs.x[reg]) = ACCESS(rw, dbgregs.mdccint_el1);
           break;
         case 0x20c008:
         case 0x20c00a:
         case 0x240000:
-          vcpu_zone->rw.regs.x[reg] = vcpu_zone->rw.dbgregs.osdtrrx_el1;
+          ACCESS(rw, regs.x[reg]) = ACCESS(rw, dbgregs.osdtrrx_el1);
           break;
         case 0x240006:
-          vcpu_zone->rw.regs.x[reg] = vcpu_zone->rw.dbgregs.osdtrtx_el1;
+          ACCESS(rw, regs.x[reg]) = ACCESS(rw, dbgregs.osdtrtx_el1);
           break;
         case 0x20c002:
-          vcpu_zone->rw.regs.x[reg] = 0;
+          ACCESS(rw, regs.x[reg]) = 0;
           break;
         default:
           return false;
@@ -707,151 +738,155 @@ static bool deliver_msr_trap(struct hv_vcpu_data* vcpu_data, hv_vcpu_exit_t* exi
       case 0x3c0002:
       case 0x3c0004:
       case 0x3e0002:
-        vcpu_zone->rw.regs.x[reg] = 0;
+        ACCESS(rw, regs.x[reg]) = 0;
         break;
       case 0x34000e:
-        vcpu_zone->rw.regs.x[reg] = vcpu_data->feature_regs.aa64mmfr2_el1;
+        ACCESS(rw, regs.x[reg]) = vcpu_data->feature_regs.aa64mmfr2_el1;
         break;
       case 0x300008:
-        vcpu_zone->rw.regs.x[reg] = vcpu_data->feature_regs.aa64pfr0_el1;
+        ACCESS(rw, regs.x[reg]) = vcpu_data->feature_regs.aa64pfr0_el1;
         break;
       case 0x30000a:
-        vcpu_zone->rw.regs.x[reg] = vcpu_data->feature_regs.aa64dfr0_el1;
+        ACCESS(rw, regs.x[reg]) = vcpu_data->feature_regs.aa64dfr0_el1;
         break;
       case 0x30000c:
-        vcpu_zone->rw.regs.x[reg] = vcpu_data->feature_regs.aa64isar0_el1;
+        ACCESS(rw, regs.x[reg]) = vcpu_data->feature_regs.aa64isar0_el1;
         break;
       case 0x30000e:
-        vcpu_zone->rw.regs.x[reg] = vcpu_data->feature_regs.aa64mmfr0_el1;
+        ACCESS(rw, regs.x[reg]) = vcpu_data->feature_regs.aa64mmfr0_el1;
         break;
       case 0x320008:
-        vcpu_zone->rw.regs.x[reg] = vcpu_data->feature_regs.aa64pfr1_el1;
+        ACCESS(rw, regs.x[reg]) = vcpu_data->feature_regs.aa64pfr1_el1;
         break;
       case 0x32000a:
-        vcpu_zone->rw.regs.x[reg] = vcpu_data->feature_regs.aa64dfr1_el1;
+        ACCESS(rw, regs.x[reg]) = vcpu_data->feature_regs.aa64dfr1_el1;
         break;
       case 0x32000c:
-        vcpu_zone->rw.regs.x[reg] = vcpu_data->feature_regs.aa64isar1_el1;
+        ACCESS(rw, regs.x[reg]) = vcpu_data->feature_regs.aa64isar1_el1;
         break;
       case 0x32000e:
-        vcpu_zone->rw.regs.x[reg] = vcpu_data->feature_regs.aa64mmfr1_el1;
+        ACCESS(rw, regs.x[reg]) = vcpu_data->feature_regs.aa64mmfr1_el1;
         break;
       default:
         return false;
     }
   }
-  vcpu_zone->rw.regs.pc += 4;
+  ACCESS(rw, regs.pc) += 4;
   return true;
 }
 
 static bool deliver_pac_trap(struct hv_vcpu_data* vcpu_data) {
-  uint64_t esr = vcpu_data->vcpu_zone->ro.exit.vmexit_esr;
   struct hv_vcpu_zone* vcpu_zone = vcpu_data->vcpu_zone;
+  arm_guest_ro_context_t *ro = &vcpu_zone->ro;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  uint64_t esr = ACCESS(ro, exit.vmexit_esr);
   uint32_t uVar6;
   uint64_t uVar9;
 
   if (((esr & 0xffff) != 0) ||
-     ((vcpu_zone->rw.regs.x[0] & 0xff000000) != 0xc1000000)) {
+     ((ACCESS(rw, regs.x[0]) & 0xff000000) != 0xc1000000)) {
     return false;
   }
-  uVar6 = vcpu_zone->rw.regs.x[0] & 0xffffff;
-  if (((vcpu_zone->ro.controls.hacr_el2 >> 4 & 1) == 0) ||
+  uVar6 = ACCESS(rw, regs.x[0]) & 0xffffff;
+  if (((ACCESS(ro, controls.hacr_el2) >> 4 & 1) == 0) ||
      (6 < uVar6)) {
-    vcpu_zone->rw.regs.x[0] = 0xffffffff;
+    ACCESS(rw, regs.x[0]) = 0xffffffff;
     return true;
   }
   switch(uVar6) {
   default:
-    vcpu_zone->rw.extregs.apctl_el1 = 0x11;
+    ACCESS(rw, extregs.apctl_el1) = 0x11;
     sync_and_dirty_banked_state(vcpu_zone, 0x2000000000000000);
-    vcpu_zone->rw.extregs.apiakeylo_el1 = 0xfeedfacefeedfacf;
-    vcpu_zone->rw.extregs.apiakeyhi_el1 = 0xfeedfacefeedfad0;
-    vcpu_zone->rw.extregs.apdakeylo_el1 = 0xfeedfacefeedfad1;
-    vcpu_zone->rw.extregs.apdakeyhi_el1 = 0xfeedfacefeedfad2;
+    ACCESS(rw, extregs.apiakeylo_el1) = 0xfeedfacefeedfacf;
+    ACCESS(rw, extregs.apiakeyhi_el1) = 0xfeedfacefeedfad0;
+    ACCESS(rw, extregs.apdakeylo_el1) = 0xfeedfacefeedfad1;
+    ACCESS(rw, extregs.apdakeyhi_el1) = 0xfeedfacefeedfad2;
     sync_and_dirty_banked_state(vcpu_zone, 0x2000000000000000);
-    vcpu_zone->rw.extregs.apibkeylo_el1 = 0xfeedfacefeedfad5;
-    vcpu_zone->rw.extregs.apibkeyhi_el1 = 0xfeedfacefeedfad6;
-    vcpu_zone->rw.extregs.apdbkeylo_el1 = 0xfeedfacefeedfad7;
-    vcpu_zone->rw.extregs.apdbkeyhi_el1 = 0xfeedfacefeedfad8;
+    ACCESS(rw, extregs.apibkeylo_el1) = 0xfeedfacefeedfad5;
+    ACCESS(rw, extregs.apibkeyhi_el1) = 0xfeedfacefeedfad6;
+    ACCESS(rw, extregs.apdbkeylo_el1) = 0xfeedfacefeedfad7;
+    ACCESS(rw, extregs.apdbkeyhi_el1) = 0xfeedfacefeedfad8;
     sync_and_dirty_banked_state(vcpu_zone, 0x2000000000000000);
-    vcpu_zone->rw.extregs.apgakeylo_el1 = 0xfeedfacefeedfad9;
-    vcpu_zone->rw.extregs.apgakeyhi_el1 = 0xfeedfacefeedfada;
+    ACCESS(rw, extregs.apgakeylo_el1) = 0xfeedfacefeedfad9;
+    ACCESS(rw, extregs.apgakeyhi_el1) = 0xfeedfacefeedfada;
     sync_and_dirty_banked_state(vcpu_zone, 0x1000000000000000);
-    vcpu_zone->rw.extregs.kernkeylo_el1 = 0xfeedfacefeedfad3;
-    vcpu_zone->rw.extregs.kernkeyhi_el1 = 0xfeedfacefeedfad4;
+    ACCESS(rw, extregs.kernkeylo_el1) = 0xfeedfacefeedfad3;
+    ACCESS(rw, extregs.kernkeyhi_el1) = 0xfeedfacefeedfad4;
     break;
   case 1:
-    vcpu_zone->rw.regs.x[1] = 0xfeedfacefeedfacf;
-    vcpu_zone->rw.regs.x[0] = 0;
-    vcpu_zone->rw.regs.x[3] = 0xfeedfacefeedfad3;
-    vcpu_zone->rw.regs.x[2] = 0xfeedfacefeedfad5;
-    vcpu_zone->rw.regs.x[4] = 0xfeedfacefeedfad9;
+    ACCESS(rw, regs.x[1]) = 0xfeedfacefeedfacf;
+    ACCESS(rw, regs.x[0]) = 0;
+    ACCESS(rw, regs.x[3]) = 0xfeedfacefeedfad3;
+    ACCESS(rw, regs.x[2]) = 0xfeedfacefeedfad5;
+    ACCESS(rw, regs.x[4]) = 0xfeedfacefeedfad9;
     return true;
   case 2:
-    uVar9 = vcpu_zone->rw.regs.x[1];
+    uVar9 = ACCESS(rw, regs.x[1]);
     sync_and_dirty_banked_state(vcpu_zone, 0x2000000000000000);
-    vcpu_zone->rw.extregs.apiakeylo_el1 = uVar9;
-    vcpu_zone->rw.extregs.apiakeyhi_el1 = uVar9 + 1;
-    vcpu_zone->rw.extregs.apdakeylo_el1 = uVar9 + 2;
-    vcpu_zone->rw.extregs.apdakeyhi_el1 = uVar9 + 3;
+    ACCESS(rw, extregs.apiakeylo_el1) = uVar9;
+    ACCESS(rw, extregs.apiakeyhi_el1) = uVar9 + 1;
+    ACCESS(rw, extregs.apdakeylo_el1) = uVar9 + 2;
+    ACCESS(rw, extregs.apdakeyhi_el1) = uVar9 + 3;
     break;
   case 3:
-    uVar9 = vcpu_zone->rw.regs.x[1];
+    uVar9 = ACCESS(rw, regs.x[1]);
     sync_and_dirty_banked_state(vcpu_zone, 0x2000000000000000);
-    vcpu_zone->rw.extregs.apibkeylo_el1 = uVar9;
-    vcpu_zone->rw.extregs.apibkeyhi_el1 = uVar9 + 1;
-    vcpu_zone->rw.extregs.apdbkeylo_el1 = uVar9 + 2;
-    vcpu_zone->rw.extregs.apdbkeyhi_el1 = uVar9 + 3;
+    ACCESS(rw, extregs.apibkeylo_el1) = uVar9;
+    ACCESS(rw, extregs.apibkeyhi_el1) = uVar9 + 1;
+    ACCESS(rw, extregs.apdbkeylo_el1) = uVar9 + 2;
+    ACCESS(rw, extregs.apdbkeyhi_el1) = uVar9 + 3;
     break;
   case 4:
-    uVar9 = vcpu_zone->rw.regs.x[1];
+    uVar9 = ACCESS(rw, regs.x[1]);
     sync_and_dirty_banked_state(vcpu_zone, 0x1000000000000000);
-    vcpu_zone->rw.extregs.kernkeylo_el1 = uVar9;
-    vcpu_zone->rw.extregs.kernkeyhi_el1 = uVar9 + 1;
+    ACCESS(rw, extregs.kernkeylo_el1) = uVar9;
+    ACCESS(rw, extregs.kernkeyhi_el1) = uVar9 + 1;
     break;
   case 5:
-    uVar9 = vcpu_zone->rw.regs.x[2];
+    uVar9 = ACCESS(rw, regs.x[2]);
     sync_and_dirty_banked_state(vcpu_zone, 0x1000000000000000);
-    vcpu_zone->rw.extregs.kernkeylo_el1 = uVar9;
-    vcpu_zone->rw.extregs.kernkeyhi_el1 = uVar9 + 1;
-    uVar9 = vcpu_zone->rw.regs.x[1];
+    ACCESS(rw, extregs.kernkeylo_el1) = uVar9;
+    ACCESS(rw, extregs.kernkeyhi_el1) = uVar9 + 1;
+    uVar9 = ACCESS(rw, regs.x[1]);
     if (uVar9 == 0) {
-      vcpu_zone->rw.extregs.apctl_el1 = vcpu_zone->rw.extregs.apctl_el1 & 0xfffffffffffffffd;
+      ACCESS(rw, extregs.apctl_el1) = ACCESS(rw, extregs.apctl_el1) & 0xfffffffffffffffd;
     }
     else if (uVar9 == 1) {
-      vcpu_zone->rw.extregs.apctl_el1 = vcpu_zone->rw.extregs.apctl_el1 | 2;
+      ACCESS(rw, extregs.apctl_el1) = ACCESS(rw, extregs.apctl_el1) | 2;
     }
     break;
   case 6:
-    uVar9 = vcpu_zone->rw.regs.x[1];
+    uVar9 = ACCESS(rw, regs.x[1]);
     sync_and_dirty_banked_state(vcpu_zone, 0x2000000000000000);
-    vcpu_zone->rw.extregs.apgakeylo_el1 = uVar9;
-    vcpu_zone->rw.extregs.apgakeyhi_el1 = uVar9 + 1;
+    ACCESS(rw, extregs.apgakeylo_el1) = uVar9;
+    ACCESS(rw, extregs.apgakeyhi_el1) = uVar9 + 1;
     break;
   }
-  vcpu_zone->rw.regs.x[0] = 0;
+  ACCESS(rw, regs.x[0]) = 0;
   return true;
 }
 
 static bool deliver_ordinary_exception(struct hv_vcpu_data* vcpu_data, hv_vcpu_exit_t* exit) {
-  uint64_t esr = vcpu_data->vcpu_zone->ro.exit.vmexit_esr;
   struct hv_vcpu_zone* vcpu_zone = vcpu_data->vcpu_zone;
+  arm_guest_ro_context_t *ro = &vcpu_zone->ro;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
+  uint64_t esr = ACCESS(ro, exit.vmexit_esr);
 
   exit->reason = HV_EXIT_REASON_EXCEPTION;
   exit->exception.syndrome = esr;
-  exit->exception.virtual_address = vcpu_data->vcpu_zone->ro.exit.vmexit_far;
-  exit->exception.physical_address = vcpu_data->vcpu_zone->ro.exit.vmexit_hpfar;
+  exit->exception.virtual_address = ACCESS(ro, exit.vmexit_far);
+  exit->exception.physical_address = ACCESS(ro, exit.vmexit_hpfar);
   
   if ((esr >> 26) == 0x16) {
     return deliver_pac_trap(vcpu_data);
   } else if ((esr >> 26) == 0x3f) {
-    if (vcpu_zone->ro.exit.vmexit_reason != 8) {
+    if (ACCESS(ro, exit.vmexit_reason) != 8) {
       deliver_uncategorized_exception(vcpu_data);
       return true;
     }
-    uint64_t exit_instr = vcpu_zone->ro.exit.vmexit_instr;
+    uint64_t exit_instr = ACCESS(ro, exit.vmexit_instr);
     if (((exit_instr ^ 0xffffffff) & 0x302c00) == 0) {
-      if ((vcpu_zone->ro.controls.hacr_el2 >> 4 & 1) != 0) {
+      if ((ACCESS(ro, controls.hacr_el2) >> 4 & 1) != 0) {
         deliver_uncategorized_exception(vcpu_data);
         return true;
       }
@@ -859,9 +894,9 @@ static bool deliver_ordinary_exception(struct hv_vcpu_data* vcpu_data, hv_vcpu_e
       exit->exception.syndrome = exit_instr & 0xffff | 0x5e000000;
     } else {
       if (((exit_instr & 0x3ffc1e) == 0x3e4000) &&
-         ((vcpu_zone->ro.controls.hacr_el2 >> 4 & 1) != 0)) {
-        vcpu_zone->rw.regs.x[((exit_instr >> 5) & 0x1f)] = 0x980200;
-        vcpu_zone->rw.regs.pc += 4;
+         ((ACCESS(ro, controls.hacr_el2) >> 4 & 1) != 0)) {
+        ACCESS(rw, regs.x[((exit_instr >> 5) & 0x1f)]) = 0x980200;
+        ACCESS(rw, regs.pc) += 4;
         return true;
       }
       exit->exception.syndrome = exit_instr & 0x1ffffff | 0x62000000;
@@ -875,15 +910,16 @@ static bool deliver_ordinary_exception(struct hv_vcpu_data* vcpu_data, hv_vcpu_e
 
 static void deliver_uncategorized_exception(struct hv_vcpu_data* vcpu_data) {
   struct hv_vcpu_zone* vcpu_zone = vcpu_data->vcpu_zone;
+  arm_guest_rw_context_t *rw = &vcpu_zone->rw;
   uint64_t cpsr, vbar_el1, pc;
 
   sync_and_dirty_banked_state(vcpu_zone, 1);
-  vcpu_zone->rw.banked_sysregs.elr_el1 = vcpu_zone->rw.regs.pc;
-  vcpu_zone->rw.banked_sysregs.esr_el1 = 0x2000000;
-  vcpu_zone->rw.banked_sysregs.spsr_el1 = vcpu_zone->rw.regs.cpsr;
-  cpsr = vcpu_zone->rw.regs.cpsr;
+  ACCESS(rw, banked_sysregs.elr_el1) = ACCESS(rw, regs.pc);
+  ACCESS(rw, banked_sysregs.esr_el1) = 0x2000000;
+  ACCESS(rw, banked_sysregs.spsr_el1) = ACCESS(rw, regs.cpsr);
+  cpsr = ACCESS(rw, regs.cpsr);
   assert((cpsr >> 4 & 1) == 0); // (m & SPSR_MODE_RW_32) == 0
-  vbar_el1 = vcpu_zone->rw.banked_sysregs.vbar_el1;
+  vbar_el1 = ACCESS(rw, banked_sysregs.vbar_el1);
   pc = vbar_el1;
   if ((cpsr & 1) != 0) {
     pc = vbar_el1 + 0x200;
@@ -891,7 +927,7 @@ static void deliver_uncategorized_exception(struct hv_vcpu_data* vcpu_data) {
   if ((cpsr & 0x1f) < 4) {
     pc = vbar_el1 + 0x400;
   }
-  vcpu_zone->rw.regs.pc = pc;
-  vcpu_zone->rw.regs.cpsr = vcpu_zone->rw.regs.cpsr & 0xffffffe0;
-  vcpu_zone->rw.regs.cpsr = vcpu_zone->rw.regs.cpsr | 0x3c5;
+  ACCESS(rw, regs.pc) = pc;
+  ACCESS(rw, regs.cpsr) = ACCESS(rw, regs.cpsr) & 0xffffffe0;
+  ACCESS(rw, regs.cpsr) = ACCESS(rw, regs.cpsr) | 0x3c5;
 }

+ 43 - 399
hv_kernel_structs.h

@@ -1,411 +1,55 @@
 #pragma once
-#include <Hypervisor/Hypervisor.h>
 
-// Headers extracted from
-// Kernel_Debug_Kit_12.5_build_21G5027d.dmg/kernel.release.t8101
-
-// type lookup hv_vcpu_t
-// type lookup arm_guest_context_t
-
-typedef struct {
-  uint64_t mdscr_el1;
-  uint64_t tpidr_el1;
-  uint64_t tpidr_el0;
-  uint64_t tpidrro_el0;
-  uint64_t sp_el0;
-  uint64_t sp_el1;
-  uint64_t par_el1;
-  uint64_t csselr_el1;
-  uint64_t apstate;
-  uint64_t afpcr_el0;
-} arm_guest_shared_sysregs_t;
-
-typedef struct {
-  uint64_t ttbr0_el1;
-  uint64_t ttbr1_el1;
-  uint64_t tcr_el1;
-  uint64_t elr_el1;
-  uint64_t far_el1;
-  uint64_t esr_el1;
-  uint64_t mair_el1;
-  uint64_t amair_el1;
-  uint64_t vbar_el1;
-  uint64_t cntv_cval_el0;
-  uint64_t cntp_cval_el0;
-  uint64_t actlr_el1;
-  uint64_t sctlr_el1;
-  uint64_t cpacr_el1;
-  uint64_t spsr_el1;
-  uint64_t afsr0_el1;
-  uint64_t afsr1_el1;
-  uint64_t contextidr_el1;
-  uint64_t cntv_ctl_el0;
-  uint64_t cntp_ctl_el0;
-  uint64_t cntkctl_el1;
-#ifndef OLDSTRUCT_IOS141
-  uint64_t ich_vmcr_el2;
-#endif
-} arm_guest_banked_sysregs_t;
-
-typedef struct {
-  uint64_t hcr_el2;
-  uint64_t hacr_el2;
-  uint64_t cptr_el2;
-  uint64_t mdcr_el2;
-  uint64_t vmpidr_el2;
-  uint64_t vpidr_el2;
-  uint64_t virtual_timer_offset;
-#ifdef OLDSTRUCT_IOS141
-  uint64_t ich_hcr_el2;
-#endif
-  uint64_t hfgrtr_el2;
-  uint64_t hfgwtr_el2;
-  uint64_t hfgitr_el2;
-  uint64_t hdfgrtr_el2;
-  uint64_t hdfgwtr_el2;
-#ifndef OLDSTRUCT_IOS141
-  uint64_t cnthctl_el2;
-#endif
-  uint64_t timer;
-  uint64_t vmkeyhi_el2;
-  uint64_t vmkeylo_el2;
-  uint64_t apsts_el1;
-#ifndef OLDSTRUCT_IOS141
-  uint64_t ich_hcr_el2;
-  uint64_t ich_lr_el2[8];
-#endif
-  uint64_t host_debug;
-#ifdef OLDSTRUCT_IOS141
-  uint64_t state_used;
-#endif
-} arm_guest_controls_t;
-
-typedef struct {
-  struct {
-    uint64_t bvr;
-    uint64_t bcr;
-  } bp[16];
-  struct {
-    uint64_t wvr;
-    uint64_t wcr;
-  } wp[16];
-  uint64_t mdccint_el1;
-  uint64_t osdtrrx_el1;
-  uint64_t osdtrtx_el1;
-  uint8_t dbgclaim_el1;
-} arm_guest_dbgregs_t;
-
-typedef struct {
-  uint64_t amx_state_t_el1;
-  uint64_t amx_config_el1;
-  uint64_t aspsr_el1;
-  uint64_t ctrr_ctl_el1;
-  uint64_t ctrr_a_lwr_el1;
-  uint64_t ctrr_a_upr_el1;
-  uint64_t ctrr_b_lwr_el1;
-  uint64_t ctrr_b_upr_el1;
-  uint64_t ctrr_lock_el1;
-  uint64_t vmsa_lock_el1;
-  uint64_t pmcr1_el1;
-  uint64_t apctl_el1;
-  uint64_t apgakeyhi_el1;
-  uint64_t apgakeylo_el1;
-  uint64_t apiakeyhi_el1;
-  uint64_t apiakeylo_el1;
-  uint64_t apibkeyhi_el1;
-  uint64_t apibkeylo_el1;
-  uint64_t apdakeyhi_el1;
-  uint64_t apdakeylo_el1;
-  uint64_t apdbkeyhi_el1;
-  uint64_t apdbkeylo_el1;
-  uint64_t kernkeyhi_el1;
-  uint64_t kernkeylo_el1;
-  uint64_t gxf_config_el1;
-  uint64_t gxf_entry_el1;
-  uint64_t gxf_pabentry_el1;
-  uint64_t sp_gl1;
-  uint64_t tpidr_gl1;
-  uint64_t aspsr_gl1;
-  uint64_t vbar_gl1;
-  uint64_t far_gl1;
-  uint64_t esr_gl1;
-  uint64_t elr_gl1;
-  uint64_t spsr_gl1;
-  uint64_t pmcr1_gl1;
-  uint64_t afsr1_gl1;
-  uint64_t sprr_config_el1;
-  uint64_t sprr_amrange_el1;
-  uint64_t sprr_pperm_el1;
-  uint64_t sprr_uperm_el0;
-  uint64_t sprr_pmprr_el1;
-  uint64_t sprr_umprr_el1;
-  uint64_t sprr_pperm_sh1_el1;
-  uint64_t sprr_pperm_sh2_el1;
-  uint64_t sprr_pperm_sh3_el1;
-  uint64_t sprr_pperm_sh4_el1;
-  uint64_t sprr_pperm_sh5_el1;
-  uint64_t sprr_pperm_sh6_el1;
-  uint64_t sprr_pperm_sh7_el1;
-  uint64_t sprr_uperm_sh1_el1;
-  uint64_t sprr_uperm_sh2_el1;
-  uint64_t sprr_uperm_sh3_el1;
-  uint64_t sprr_uperm_sh4_el1;
-  uint64_t sprr_uperm_sh5_el1;
-  uint64_t sprr_uperm_sh6_el1;
-  uint64_t sprr_uperm_sh7_el1;
-  uint64_t acfg_el1;
-  uint64_t jrange_el1;
-  uint64_t jctl_el1;
-  uint64_t japiakeyhi_el1;
-  uint64_t japiakeylo_el1;
-  uint64_t japibkeyhi_el1;
-  uint64_t japibkeylo_el1;
-} arm_guest_extregs_t;
-
-typedef struct {
-  uint8_t __res_00_20[32];
-  uint64_t vttbr_el2;
-  uint64_t __res_28;
-  uint64_t vsttbr_el2;
-  uint64_t __res_38;
-  uint64_t vtcr_el2;
-  uint64_t vstcr_el2;
-  uint64_t vmpidr_el2;
-  uint64_t __res_58;
-  uint64_t cntvoff_el2;
-  uint8_t __res_68_78[16];
-  uint64_t hcr_el2;
-  uint64_t hstr_el2;
-  uint64_t vpidr_el2;
-  uint64_t tpidr_el2;
-  uint8_t __res_98_b0[24];
-  uint64_t vncr_el2;
-  uint8_t __res_b8_100[72];
-  uint64_t cpacr_el1;
-  uint64_t contextidr_el1;
-  uint64_t sctlr_el1;
-  uint64_t actlr_el1;
-  uint64_t tcr_el1;
-  uint64_t afsr0_el1;
-  uint64_t afsr1_el1;
-  uint64_t esr_el1;
-  uint64_t mair_el1;
-  uint64_t amair_el1;
-  uint8_t __res_158_150[8];
-  uint64_t mdscr_el1;
-  uint64_t spsr_el1;
-  uint64_t cntv_cval_el0;
-  uint64_t cntv_ctl_el0;
-  uint64_t cntp_cval_el0;
-  uint64_t cntp_ctl_el0;
-  uint64_t scxtnum_el1;
-  uint64_t tfsr_el1;
-  uint8_t __res_198_1a8[16];
-  uint64_t cntpoff_el2;
-  uint8_t __res_1b0_1b8[8];
-  uint64_t hfgrtr_el2;
-  uint64_t hfgwtr_el2;
-  uint64_t hfgitr_el2;
-  uint64_t hdfgrtr_el2;
-  uint64_t hdfgwtr_el2;
-  uint64_t zcr_el1;
-  uint8_t __res_1e8_200[24];
-  uint64_t ttbr0_el1;
-  uint8_t __res_208_210[8];
-  uint64_t ttbr1_el1;
-  uint8_t __res_218_220[8];
-  uint64_t far_el1;
-  uint8_t __res_228_230[8];
-  uint64_t elr_el1;
-  uint8_t __res_238_240[8];
-  uint64_t sp_el1;
-  uint8_t __res_248_250[8];
-  uint64_t vbar_el1;
-  uint8_t __res_400_258[424];
-  uint64_t ich_lr_el2[16];
-  uint64_t ich_ap0r_el2[4];
-  uint64_t ich_ap1r_el2[4];
-  uint64_t ich_hcr_el2;
-  uint64_t ich_vmcr_el2;
-  uint8_t __res_4d0_500[48];
-  uint64_t vdisr_el2;
-  uint64_t vsesr_el2;
-  uint8_t __res_510_800[752];
-  uint64_t pmblimitr_el1;
-  uint8_t __res_808_810[8];
-  uint64_t pmbptr_el1;
-  uint8_t __res_818_820[8];
-  uint64_t pmbsr_el1;
-  uint64_t pmscr_el1;
-  uint64_t pmsevfr_el1;
-  uint64_t pmsicr_el1;
-  uint64_t pmsirr_el1;
-  uint64_t pmslatfr_el1;
-  uint8_t __res_850_880[48];
-  uint64_t trfcr_el1;
-  uint8_t __res_888_1000[1912];
-} arm_vncr_context_t;
-
-typedef struct {
-  uint8_t __res_000_008[8];
-  uint64_t avncr_el2;
-  uint64_t aspsr_el1;
-  uint8_t __res_018_100[232];
-  uint64_t apctl_el1;
-  uint64_t apsts_el1;
-  uint64_t vmkey_lo_el2;
-  uint64_t vmkey_hi_el2;
-  uint64_t apgakeylo_el1;
-  uint64_t apgakeyhi_el1;
-  uint64_t apiakeylo_el1;
-  uint64_t apiakeyhi_el1;
-  uint64_t apibkeylo_el1;
-  uint64_t apibkeyhi_el1;
-  uint64_t apdakeylo_el1;
-  uint64_t apdakeyhi_el1;
-  uint64_t apdbkeylo_el1;
-  uint64_t apdbkeyhi_el1;
-  uint64_t kernkeylo_el1;
-  uint64_t kernkeyhi_el1;
-  uint8_t __res_180_2d0[336];
-  uint64_t jctl_el1;
-  uint64_t jrange_el1;
-  uint64_t japiakeylo_el1;
-  uint64_t japiakeyhi_el1;
-  uint64_t japibkeylo_el1;
-  uint64_t japibkeyhi_el1;
-  uint64_t amx_config_el1;
-  uint8_t __res_308_360[88];
-  uint64_t vmsa_lock_el1;
-  uint8_t __res_368_3c0[88];
-  uint64_t pmcr1_el1;
-  uint8_t __res_3c8_400[56];
-  uint64_t apl_lrtmr_el2;
-  uint64_t apl_intenable_el2;
-  uint8_t __res_410_1000[3056];
-} apple_vncr_context_t;
+#include "hv_kernel_structs_xnu_20.h"
+#include "hv_kernel_structs_xnu_21.h"
 
 typedef union {
-  struct {
-    union {
-      // arm_context_t guest_context;
-      struct {
-        uint64_t res1[1];
-        struct {
-          uint64_t x[29];
-          uint64_t fp;
-          uint64_t lr;
-          uint64_t sp;
-          uint64_t pc;
-          uint32_t cpsr;
-          uint32_t pad;
-        } regs;
-        uint64_t res2[4];
-        struct {
-          __uint128_t q[32];
-          uint32_t fpsr;
-          uint32_t fpcr;
-        } neon;
-      };
-    };
-    arm_guest_shared_sysregs_t shared_sysregs;
-    arm_guest_banked_sysregs_t banked_sysregs;
-    arm_guest_dbgregs_t dbgregs;
-    volatile arm_guest_controls_t controls;
-    volatile uint64_t state_dirty;
-    uint64_t guest_tick_count;
-    arm_guest_extregs_t extregs;
-    arm_vncr_context_t vncr;
-    apple_vncr_context_t avncr;
-  };
-  uint8_t page[16384];
+  arm_guest_rw_context_20_t v20;
+  arm_guest_rw_context_21_t v21;
 } arm_guest_rw_context_t;
 
-typedef struct {
-  uint32_t vmexit_reason;
-  uint32_t vmexit_esr;
-  uint32_t vmexit_instr;
-  uint64_t vmexit_far;
-  uint64_t vmexit_hpfar;
-} arm_guest_vmexit_t;
-
 typedef union {
-  struct {
-    uint64_t ver;
-    arm_guest_vmexit_t exit;
-    arm_guest_controls_t controls;
-    uint64_t state_valid;
-    uint64_t state_dirty;
-    uint64_t state_used;
-    uint32_t ich_vtr_el2;
-    uint32_t ich_misr_el2;
-    uint32_t ich_elrsr_el2;
-  };
-  uint8_t page[16384];
+  arm_guest_ro_context_20_t v20;
+  arm_guest_ro_context_21_t v21;
+  uint64_t ver;
 } arm_guest_ro_context_t;
 
-typedef struct {
-  uint64_t cptr_el2;
-  uint64_t mdscr_el1;
-  uint64_t tpidr_el1;
-  uint64_t tpidr_el0;
-  uint64_t tpidrro_el0;
-  uint64_t sp_el0;
-  uint64_t jop_hash;
-  uint64_t vmenter_ticks;
-  uint64_t vmexit_ticks;
-  uint64_t vncr_el2;
-  uint64_t avncr_el2;
-  uint64_t ich_ap0r0_el2;
-  uint64_t ich_ap1r0_el2;
-  vm_map_t guest_map;
-  bool flush_local_tlb;
-  uint64_t actlr_en_mdsb;
-} arm_host_context_t;
-
-typedef struct {
-  arm_guest_rw_context_t rw;
-  arm_guest_ro_context_t ro;
-  arm_host_context_t priv;
+typedef union {
+  arm_guest_context_20_t v20;
+  arm_guest_context_21_t v21;
 } arm_guest_context_t;
 
-typedef struct {
-    uint64_t api;
-    uint64_t vcpumax;
-    uint64_t control_hcr;
-    uint64_t control_hacr;
-    uint64_t control_cptr;
-    uint64_t control_mdcr;
-    uint64_t control_ich_hcr;
-    uint64_t control_vmpidr;
-    uint64_t control_vpidr;
-    uint64_t control_virtual_timer_offset;
-    uint64_t control_timer;
-    uint64_t control_vmkeyhi;
-    uint64_t control_vmkeylo;
-    uint64_t control_apsts;
-    uint64_t control_state_used;
-    uint64_t control_hfgrtr;
-    uint64_t control_hfgwtr;
-    uint64_t control_hfgitr;
-    uint64_t control_hdfgrtr;
-    uint64_t control_hdfgwtr;
-    uint64_t control_cnthctl;
-    uint64_t ctr_el0;
-    uint64_t dczid_el0;
-    uint64_t clidr_el1;
-    uint64_t ccsidr_el1_inst[8];
-    uint64_t ccsidr_el1_data_or_unified[8];
-    uint64_t id_aa64dfr0_el1;
-    uint64_t id_aa64dfr1_el1;
-    uint64_t id_aa64isar0_el1;
-    uint64_t id_aa64isar1_el1;
-    uint64_t id_aa64mmfr0_el1;
-    uint64_t id_aa64mmfr1_el1;
-    uint64_t id_aa64mmfr2_el1;
-    uint64_t id_aa64pfr0_el1;
-    uint64_t id_aa64pfr1_el1;
-    uint8_t gic_npie_active_pending_bug;
-    uint64_t ipa_bits_4k;
-    uint64_t ipa_bits_16k;
+typedef union {
+  hv_capabilities_20_t v20;
+  hv_capabilities_21_t v21;
 } hv_capabilities_t;
+
+static int _get_xnu_version(void) {
+  if (__builtin_available(iOS 16, macOS 13, watchOS 9, tvOS 16, bridgeOS 7, *)) {
+    return 0; // not yet supported
+  } else if (__builtin_available(iOS 15, macOS 12, watchOS 8, tvOS 15, bridgeOS 6, *)) {
+    return HV_VERSION_XNU_21;
+  } else if (__builtin_available(iOS 14, macOS 11, watchOS 7, tvOS 14, bridgeOS 5, *)) {
+    return HV_VERSION_XNU_20;
+  } else {
+    return 0; // not yet supported
+  }
+}
+
+static inline int get_xnu_version(void) {
+  static int version = -1;
+  if (__builtin_expect(version < 0, 0)) {
+    version = _get_xnu_version();
+  }
+  return version;
+}
+
+static inline uint64_t get_expected_magic(void) {
+  switch (get_xnu_version()) {
+    case HV_VERSION_XNU_20: return HV_XNU_20_MAGIC;
+    case HV_VERSION_XNU_21: return HV_XNU_21_MAGIC;
+    default: return 0;
+  }
+}
+
+#define ACCESS(s, f) (*(get_xnu_version() == HV_VERSION_XNU_21 ? &(s)->v21.f : (get_xnu_version() == HV_VERSION_XNU_20 ? &(s)->v20.f : NULL))) 

+ 372 - 0
hv_kernel_structs_xnu_20.h

@@ -0,0 +1,372 @@
+#pragma once
+#include <Hypervisor/Hypervisor.h>
+
+// Headers extracted from
+// Kernel_Debug_Kit_11.6.5_build_20G527.dmg
+
+// type lookup hv_vcpu_t
+// type lookup arm_guest_context_t
+
+typedef struct {
+  uint64_t mdscr_el1;
+  uint64_t tpidr_el1;
+  uint64_t tpidr_el0;
+  uint64_t tpidrro_el0;
+  uint64_t sp_el0;
+  uint64_t sp_el1;
+  uint64_t par_el1;
+  uint64_t csselr_el1;
+  uint64_t apstate;
+  uint64_t afpcr_el0;
+} arm_guest_shared_sysregs_20_t;
+
+typedef struct {
+  uint64_t ttbr0_el1;
+  uint64_t ttbr1_el1;
+  uint64_t tcr_el1;
+  uint64_t elr_el1;
+  uint64_t far_el1;
+  uint64_t esr_el1;
+  uint64_t mair_el1;
+  uint64_t amair_el1;
+  uint64_t vbar_el1;
+  uint64_t cntv_cval_el0;
+  uint64_t cntp_cval_el0;
+  uint64_t actlr_el1;
+  uint64_t sctlr_el1;
+  uint64_t cpacr_el1;
+  uint64_t spsr_el1;
+  uint64_t afsr0_el1;
+  uint64_t afsr1_el1;
+  uint64_t contextidr_el1;
+  uint64_t cntv_ctl_el0;
+  uint64_t cntp_ctl_el0;
+  uint64_t cntkctl_el1;
+} arm_guest_banked_sysregs_20_t;
+
+typedef struct {
+  uint64_t hcr_el2;
+  uint64_t hacr_el2;
+  uint64_t cptr_el2;
+  uint64_t mdcr_el2;
+  uint64_t vmpidr_el2;
+  uint64_t vpidr_el2;
+  uint64_t virtual_timer_offset;
+  uint64_t ich_hcr_el2;
+  uint64_t hfgrtr_el2;
+  uint64_t hfgwtr_el2;
+  uint64_t hfgitr_el2;
+  uint64_t hdfgrtr_el2;
+  uint64_t hdfgwtr_el2;
+  uint64_t timer;
+  uint64_t vmkeyhi_el2;
+  uint64_t vmkeylo_el2;
+  uint64_t apsts_el1;
+  uint64_t host_debug;
+} arm_guest_controls_20_t;
+
+typedef struct {
+  struct {
+    uint64_t bvr;
+    uint64_t bcr;
+  } bp[16];
+  struct {
+    uint64_t wvr;
+    uint64_t wcr;
+  } wp[16];
+  uint64_t mdccint_el1;
+  uint64_t osdtrrx_el1;
+  uint64_t osdtrtx_el1;
+  uint8_t dbgclaim_el1;
+} arm_guest_dbgregs_20_t;
+
+typedef struct {
+  uint64_t amx_state_t_el1;
+  uint64_t amx_config_el1;
+  uint64_t aspsr_el1;
+  uint64_t ctrr_ctl_el1;
+  uint64_t ctrr_a_lwr_el1;
+  uint64_t ctrr_a_upr_el1;
+  uint64_t ctrr_b_lwr_el1;
+  uint64_t ctrr_b_upr_el1;
+  uint64_t ctrr_lock_el1;
+  uint64_t vmsa_lock_el1;
+  uint64_t pmcr1_el1;
+  uint64_t apctl_el1;
+  uint64_t apgakeyhi_el1;
+  uint64_t apgakeylo_el1;
+  uint64_t apiakeyhi_el1;
+  uint64_t apiakeylo_el1;
+  uint64_t apibkeyhi_el1;
+  uint64_t apibkeylo_el1;
+  uint64_t apdakeyhi_el1;
+  uint64_t apdakeylo_el1;
+  uint64_t apdbkeyhi_el1;
+  uint64_t apdbkeylo_el1;
+  uint64_t kernkeyhi_el1;
+  uint64_t kernkeylo_el1;
+  uint64_t gxf_config_el1;
+  uint64_t gxf_entry_el1;
+  uint64_t gxf_pabentry_el1;
+  uint64_t sp_gl1;
+  uint64_t tpidr_gl1;
+  uint64_t aspsr_gl1;
+  uint64_t vbar_gl1;
+  uint64_t far_gl1;
+  uint64_t esr_gl1;
+  uint64_t elr_gl1;
+  uint64_t spsr_gl1;
+  uint64_t pmcr1_gl1;
+  uint64_t afsr1_gl1;
+  uint64_t sprr_config_el1;
+  uint64_t sprr_amrange_el1;
+  uint64_t sprr_pperm_el1;
+  uint64_t sprr_uperm_el0;
+  uint64_t sprr_pmprr_el1;
+  uint64_t sprr_umprr_el1;
+  uint64_t sprr_pperm_sh1_el1;
+  uint64_t sprr_pperm_sh2_el1;
+  uint64_t sprr_pperm_sh3_el1;
+  uint64_t sprr_pperm_sh4_el1;
+  uint64_t sprr_pperm_sh5_el1;
+  uint64_t sprr_pperm_sh6_el1;
+  uint64_t sprr_pperm_sh7_el1;
+  uint64_t sprr_uperm_sh1_el1;
+  uint64_t sprr_uperm_sh2_el1;
+  uint64_t sprr_uperm_sh3_el1;
+  uint64_t sprr_uperm_sh4_el1;
+  uint64_t sprr_uperm_sh5_el1;
+  uint64_t sprr_uperm_sh6_el1;
+  uint64_t sprr_uperm_sh7_el1;
+} arm_guest_extregs_20_t;
+
+typedef struct {
+  uint8_t __res_00_20[32];
+  uint64_t vttbr_el2;
+  uint64_t __res_28;
+  uint64_t vsttbr_el2;
+  uint64_t __res_38;
+  uint64_t vtcr_el2;
+  uint64_t vstcr_el2;
+  uint64_t vmpidr_el2;
+  uint64_t __res_58;
+  uint64_t cntvoff_el2;
+  uint8_t __res_68_78[16];
+  uint64_t hcr_el2;
+  uint64_t hstr_el2;
+  uint64_t vpidr_el2;
+  uint64_t tpidr_el2;
+  uint8_t __res_98_b0[24];
+  uint64_t vncr_el2;
+  uint8_t __res_b8_100[72];
+  uint64_t cpacr_el1;
+  uint64_t contextidr_el1;
+  uint64_t sctlr_el1;
+  uint64_t actlr_el1;
+  uint64_t tcr_el1;
+  uint64_t afsr0_el1;
+  uint64_t afsr1_el1;
+  uint64_t esr_el1;
+  uint64_t mair_el1;
+  uint64_t amair_el1;
+  uint8_t __res_158_150[8];
+  uint64_t mdscr_el1;
+  uint64_t spsr_el1;
+  uint64_t cntv_cval_el0;
+  uint64_t cntv_ctl_el0;
+  uint64_t cntp_cval_el0;
+  uint64_t cntp_ctl_el0;
+  uint8_t __res_188_1e0[88];
+  uint64_t zcr_el1;
+  uint8_t __res_1e8_200[24];
+  uint64_t ttbr0_el1;
+  uint8_t __res_208_210[8];
+  uint64_t ttbr1_el1;
+  uint8_t __res_218_220[8];
+  uint64_t far_el1;
+  uint8_t __res_228_230[8];
+  uint64_t elr_el1;
+  uint8_t __res_238_240[8];
+  uint64_t sp_el1;
+  uint8_t __res_248_250[8];
+  uint64_t vbar_el1;
+  uint8_t __res_400_258[424];
+  uint64_t ich_lr_el2[16];
+  uint64_t ich_ap0r_el2[4];
+  uint64_t ich_ap1r_el2[4];
+  uint64_t ich_hcr_el2;
+  uint64_t ich_vmcr_el2;
+  uint8_t __res_4d0_500[48];
+  uint64_t vdisr_el2;
+  uint64_t vsesr_el2;
+  uint8_t __res_510_800[752];
+  uint64_t pmblimitr_el1;
+  uint8_t __res_808_810[8];
+  uint64_t pmbptr_el1;
+  uint8_t __res_818_820[8];
+  uint64_t pmbsr_el1;
+  uint64_t pmscr_el1;
+  uint64_t pmsevfr_el1;
+  uint64_t pmsicr_el1;
+  uint64_t pmsirr_el1;
+  uint64_t pmslatfr_el1;
+  uint8_t __res_850_880[48];
+  uint64_t trfcr_el1;
+  uint8_t __res_888_1000[1912];
+} arm_vncr_context_20_t;
+
+typedef struct {
+  uint8_t __res_000_008[8];
+  uint64_t avncr_el2;
+  uint64_t aspsr_el1;
+  uint8_t __res_018_100[232];
+  uint64_t apctl_el1;
+  uint64_t apsts_el1;
+  uint64_t vmkey_lo_el2;
+  uint64_t vmkey_hi_el2;
+  uint64_t apgakeylo_el1;
+  uint64_t apgakeyhi_el1;
+  uint64_t apiakeylo_el1;
+  uint64_t apiakeyhi_el1;
+  uint64_t apibkeylo_el1;
+  uint64_t apibkeyhi_el1;
+  uint64_t apdakeylo_el1;
+  uint64_t apdakeyhi_el1;
+  uint64_t apdbkeylo_el1;
+  uint64_t apdbkeyhi_el1;
+  uint64_t kernkeylo_el1;
+  uint64_t kernkeyhi_el1;
+  uint8_t __res_180_2d0[336];
+  uint64_t jctl_el1;
+  uint64_t jrange_el1;
+  uint64_t japiakeylo_el1;
+  uint64_t japiakeyhi_el1;
+  uint64_t japibkeylo_el1;
+  uint64_t japibkeyhi_el1;
+  uint64_t amx_config_el1;
+  uint8_t __res_308_360[88];
+  uint64_t vmsa_lock_el1;
+  uint8_t __res_368_3c0[88];
+  uint64_t pmcr1_el1;
+  uint8_t __res_3c8_400[56];
+  uint64_t apl_lrtmr_el2;
+  uint64_t apl_intenable_el2;
+  uint8_t __res_410_1000[3056];
+} apple_vncr_context_20_t;
+
+typedef union {
+  struct {
+    union {
+      // arm_context_t guest_context;
+      struct {
+        uint64_t res1[1];
+        struct {
+          uint64_t x[29];
+          uint64_t fp;
+          uint64_t lr;
+          uint64_t sp;
+          uint64_t pc;
+          uint32_t cpsr;
+          uint32_t pad;
+        } regs;
+        uint64_t res2[4];
+        struct {
+          __uint128_t q[32];
+          uint32_t fpsr;
+          uint32_t fpcr;
+        } neon;
+      };
+    };
+    arm_guest_shared_sysregs_20_t shared_sysregs;
+    arm_guest_banked_sysregs_20_t banked_sysregs;
+    arm_guest_dbgregs_20_t dbgregs;
+    volatile arm_guest_controls_20_t controls;
+    volatile uint64_t state_dirty;
+    uint64_t guest_tick_count;
+    arm_guest_extregs_20_t extregs;
+    arm_vncr_context_20_t vncr;
+    apple_vncr_context_20_t avncr;
+  };
+  uint8_t page[16384];
+} arm_guest_rw_context_20_t;
+
+typedef struct {
+  uint32_t vmexit_reason;
+  uint32_t vmexit_esr;
+  uint32_t vmexit_instr;
+  uint64_t vmexit_far;
+  uint64_t vmexit_hpfar;
+} arm_guest_vmexit_20_t;
+
+typedef union {
+  struct {
+    uint64_t ver;
+    arm_guest_vmexit_20_t exit;
+    arm_guest_controls_20_t controls;
+    uint64_t state_valid;
+    uint64_t state_dirty;
+  };
+  uint8_t page[16384];
+} arm_guest_ro_context_20_t;
+
+typedef struct {
+  uint64_t cptr_el2;
+  uint64_t mdscr_el1;
+  uint64_t tpidr_el1;
+  uint64_t tpidr_el0;
+  uint64_t tpidrro_el0;
+  uint64_t sp_el0;
+  uint64_t jop_hash;
+  uint64_t vmenter_ticks;
+  uint64_t vmexit_ticks;
+  uint64_t vncr_el2;
+  uint64_t avncr_el2;
+  vm_map_t guest_map;
+  bool flush_local_tlb;
+  uint64_t actlr_en_mdsb;
+} arm_host_context_20_t;
+
+typedef struct {
+  arm_guest_rw_context_20_t rw;
+  arm_guest_ro_context_20_t ro;
+  arm_host_context_20_t priv;
+} arm_guest_context_20_t;
+
+typedef struct {
+  uint64_t api;
+  uint64_t vcpumax;
+  uint64_t control_hcr;
+  uint64_t control_hacr;
+  uint64_t control_cptr;
+  uint64_t control_mdcr;
+  uint64_t control_vmpidr;
+  uint64_t control_vpidr;
+  uint64_t control_virtual_timer_offset;
+  uint64_t control_timer;
+  uint64_t control_vmkeyhi;
+  uint64_t control_vmkeylo;
+  uint64_t control_apsts;
+  uint64_t control_state_used;
+  uint64_t control_hfgrtr;
+  uint64_t control_hfgwtr;
+  uint64_t control_hfgitr;
+  uint64_t control_hdfgrtr;
+  uint64_t control_hdfgwtr;
+  uint64_t ctr_el0;
+  uint64_t dczid_el0;
+  uint64_t clidr_el1;
+  uint64_t ccsidr_el1_inst[8];
+  uint64_t ccsidr_el1_data_or_unified[8];
+  uint64_t id_aa64dfr0_el1;
+  uint64_t id_aa64dfr1_el1;
+  uint64_t id_aa64isar0_el1;
+  uint64_t id_aa64isar1_el1;
+  uint64_t id_aa64mmfr0_el1;
+  uint64_t id_aa64mmfr1_el1;
+  uint64_t id_aa64mmfr2_el1;
+  uint64_t id_aa64pfr0_el1;
+  uint64_t id_aa64pfr1_el1;
+} hv_capabilities_20_t;
+
+#define HV_XNU_20_MAGIC (0x2068797000000009)
+#define HV_VERSION_XNU_20 (20)

+ 402 - 0
hv_kernel_structs_xnu_21.h

@@ -0,0 +1,402 @@
+#pragma once
+#include <Hypervisor/Hypervisor.h>
+
+// Headers extracted from
+// Kernel_Debug_Kit_12.5_build_21G5027d.dmg/kernel.release.t8101
+
+// type lookup hv_vcpu_t
+// type lookup arm_guest_context_t
+
+typedef struct {
+  uint64_t mdscr_el1;
+  uint64_t tpidr_el1;
+  uint64_t tpidr_el0;
+  uint64_t tpidrro_el0;
+  uint64_t sp_el0;
+  uint64_t sp_el1;
+  uint64_t par_el1;
+  uint64_t csselr_el1;
+  uint64_t apstate;
+  uint64_t afpcr_el0;
+} arm_guest_shared_sysregs_21_t;
+
+typedef struct {
+  uint64_t ttbr0_el1;
+  uint64_t ttbr1_el1;
+  uint64_t tcr_el1;
+  uint64_t elr_el1;
+  uint64_t far_el1;
+  uint64_t esr_el1;
+  uint64_t mair_el1;
+  uint64_t amair_el1;
+  uint64_t vbar_el1;
+  uint64_t cntv_cval_el0;
+  uint64_t cntp_cval_el0;
+  uint64_t actlr_el1;
+  uint64_t sctlr_el1;
+  uint64_t cpacr_el1;
+  uint64_t spsr_el1;
+  uint64_t afsr0_el1;
+  uint64_t afsr1_el1;
+  uint64_t contextidr_el1;
+  uint64_t cntv_ctl_el0;
+  uint64_t cntp_ctl_el0;
+  uint64_t cntkctl_el1;
+  uint64_t ich_vmcr_el2;
+} arm_guest_banked_sysregs_21_t;
+
+typedef struct {
+  uint64_t hcr_el2;
+  uint64_t hacr_el2;
+  uint64_t cptr_el2;
+  uint64_t mdcr_el2;
+  uint64_t vmpidr_el2;
+  uint64_t vpidr_el2;
+  uint64_t virtual_timer_offset;
+  uint64_t hfgrtr_el2;
+  uint64_t hfgwtr_el2;
+  uint64_t hfgitr_el2;
+  uint64_t hdfgrtr_el2;
+  uint64_t hdfgwtr_el2;
+  uint64_t cnthctl_el2;
+  uint64_t timer;
+  uint64_t vmkeyhi_el2;
+  uint64_t vmkeylo_el2;
+  uint64_t apsts_el1;
+  uint64_t ich_hcr_el2;
+  uint64_t ich_lr_el2[8];
+  uint64_t host_debug;
+} arm_guest_controls_21_t;
+
+typedef struct {
+  struct {
+    uint64_t bvr;
+    uint64_t bcr;
+  } bp[16];
+  struct {
+    uint64_t wvr;
+    uint64_t wcr;
+  } wp[16];
+  uint64_t mdccint_el1;
+  uint64_t osdtrrx_el1;
+  uint64_t osdtrtx_el1;
+  uint8_t dbgclaim_el1;
+} arm_guest_dbgregs_21_t;
+
+typedef struct {
+  uint64_t amx_state_t_el1;
+  uint64_t amx_config_el1;
+  uint64_t aspsr_el1;
+  uint64_t ctrr_ctl_el1;
+  uint64_t ctrr_a_lwr_el1;
+  uint64_t ctrr_a_upr_el1;
+  uint64_t ctrr_b_lwr_el1;
+  uint64_t ctrr_b_upr_el1;
+  uint64_t ctrr_lock_el1;
+  uint64_t vmsa_lock_el1;
+  uint64_t pmcr1_el1;
+  uint64_t apctl_el1;
+  uint64_t apgakeyhi_el1;
+  uint64_t apgakeylo_el1;
+  uint64_t apiakeyhi_el1;
+  uint64_t apiakeylo_el1;
+  uint64_t apibkeyhi_el1;
+  uint64_t apibkeylo_el1;
+  uint64_t apdakeyhi_el1;
+  uint64_t apdakeylo_el1;
+  uint64_t apdbkeyhi_el1;
+  uint64_t apdbkeylo_el1;
+  uint64_t kernkeyhi_el1;
+  uint64_t kernkeylo_el1;
+  uint64_t gxf_config_el1;
+  uint64_t gxf_entry_el1;
+  uint64_t gxf_pabentry_el1;
+  uint64_t sp_gl1;
+  uint64_t tpidr_gl1;
+  uint64_t aspsr_gl1;
+  uint64_t vbar_gl1;
+  uint64_t far_gl1;
+  uint64_t esr_gl1;
+  uint64_t elr_gl1;
+  uint64_t spsr_gl1;
+  uint64_t pmcr1_gl1;
+  uint64_t afsr1_gl1;
+  uint64_t sprr_config_el1;
+  uint64_t sprr_amrange_el1;
+  uint64_t sprr_pperm_el1;
+  uint64_t sprr_uperm_el0;
+  uint64_t sprr_pmprr_el1;
+  uint64_t sprr_umprr_el1;
+  uint64_t sprr_pperm_sh1_el1;
+  uint64_t sprr_pperm_sh2_el1;
+  uint64_t sprr_pperm_sh3_el1;
+  uint64_t sprr_pperm_sh4_el1;
+  uint64_t sprr_pperm_sh5_el1;
+  uint64_t sprr_pperm_sh6_el1;
+  uint64_t sprr_pperm_sh7_el1;
+  uint64_t sprr_uperm_sh1_el1;
+  uint64_t sprr_uperm_sh2_el1;
+  uint64_t sprr_uperm_sh3_el1;
+  uint64_t sprr_uperm_sh4_el1;
+  uint64_t sprr_uperm_sh5_el1;
+  uint64_t sprr_uperm_sh6_el1;
+  uint64_t sprr_uperm_sh7_el1;
+  uint64_t acfg_el1;
+  uint64_t jrange_el1;
+  uint64_t jctl_el1;
+  uint64_t japiakeyhi_el1;
+  uint64_t japiakeylo_el1;
+  uint64_t japibkeyhi_el1;
+  uint64_t japibkeylo_el1;
+} arm_guest_extregs_21_t;
+
+typedef struct {
+  uint8_t __res_00_20[32];
+  uint64_t vttbr_el2;
+  uint64_t __res_28;
+  uint64_t vsttbr_el2;
+  uint64_t __res_38;
+  uint64_t vtcr_el2;
+  uint64_t vstcr_el2;
+  uint64_t vmpidr_el2;
+  uint64_t __res_58;
+  uint64_t cntvoff_el2;
+  uint8_t __res_68_78[16];
+  uint64_t hcr_el2;
+  uint64_t hstr_el2;
+  uint64_t vpidr_el2;
+  uint64_t tpidr_el2;
+  uint8_t __res_98_b0[24];
+  uint64_t vncr_el2;
+  uint8_t __res_b8_100[72];
+  uint64_t cpacr_el1;
+  uint64_t contextidr_el1;
+  uint64_t sctlr_el1;
+  uint64_t actlr_el1;
+  uint64_t tcr_el1;
+  uint64_t afsr0_el1;
+  uint64_t afsr1_el1;
+  uint64_t esr_el1;
+  uint64_t mair_el1;
+  uint64_t amair_el1;
+  uint8_t __res_158_150[8];
+  uint64_t mdscr_el1;
+  uint64_t spsr_el1;
+  uint64_t cntv_cval_el0;
+  uint64_t cntv_ctl_el0;
+  uint64_t cntp_cval_el0;
+  uint64_t cntp_ctl_el0;
+  uint64_t scxtnum_el1;
+  uint64_t tfsr_el1;
+  uint8_t __res_198_1a8[16];
+  uint64_t cntpoff_el2;
+  uint8_t __res_1b0_1b8[8];
+  uint64_t hfgrtr_el2;
+  uint64_t hfgwtr_el2;
+  uint64_t hfgitr_el2;
+  uint64_t hdfgrtr_el2;
+  uint64_t hdfgwtr_el2;
+  uint64_t zcr_el1;
+  uint8_t __res_1e8_200[24];
+  uint64_t ttbr0_el1;
+  uint8_t __res_208_210[8];
+  uint64_t ttbr1_el1;
+  uint8_t __res_218_220[8];
+  uint64_t far_el1;
+  uint8_t __res_228_230[8];
+  uint64_t elr_el1;
+  uint8_t __res_238_240[8];
+  uint64_t sp_el1;
+  uint8_t __res_248_250[8];
+  uint64_t vbar_el1;
+  uint8_t __res_400_258[424];
+  uint64_t ich_lr_el2[16];
+  uint64_t ich_ap0r_el2[4];
+  uint64_t ich_ap1r_el2[4];
+  uint64_t ich_hcr_el2;
+  uint64_t ich_vmcr_el2;
+  uint8_t __res_4d0_500[48];
+  uint64_t vdisr_el2;
+  uint64_t vsesr_el2;
+  uint8_t __res_510_800[752];
+  uint64_t pmblimitr_el1;
+  uint8_t __res_808_810[8];
+  uint64_t pmbptr_el1;
+  uint8_t __res_818_820[8];
+  uint64_t pmbsr_el1;
+  uint64_t pmscr_el1;
+  uint64_t pmsevfr_el1;
+  uint64_t pmsicr_el1;
+  uint64_t pmsirr_el1;
+  uint64_t pmslatfr_el1;
+  uint8_t __res_850_880[48];
+  uint64_t trfcr_el1;
+  uint8_t __res_888_1000[1912];
+} arm_vncr_context_21_t;
+
+typedef struct {
+  uint8_t __res_000_008[8];
+  uint64_t avncr_el2;
+  uint64_t aspsr_el1;
+  uint8_t __res_018_100[232];
+  uint64_t apctl_el1;
+  uint64_t apsts_el1;
+  uint64_t vmkey_lo_el2;
+  uint64_t vmkey_hi_el2;
+  uint64_t apgakeylo_el1;
+  uint64_t apgakeyhi_el1;
+  uint64_t apiakeylo_el1;
+  uint64_t apiakeyhi_el1;
+  uint64_t apibkeylo_el1;
+  uint64_t apibkeyhi_el1;
+  uint64_t apdakeylo_el1;
+  uint64_t apdakeyhi_el1;
+  uint64_t apdbkeylo_el1;
+  uint64_t apdbkeyhi_el1;
+  uint64_t kernkeylo_el1;
+  uint64_t kernkeyhi_el1;
+  uint8_t __res_180_2d0[336];
+  uint64_t jctl_el1;
+  uint64_t jrange_el1;
+  uint64_t japiakeylo_el1;
+  uint64_t japiakeyhi_el1;
+  uint64_t japibkeylo_el1;
+  uint64_t japibkeyhi_el1;
+  uint64_t amx_config_el1;
+  uint8_t __res_308_360[88];
+  uint64_t vmsa_lock_el1;
+  uint8_t __res_368_3c0[88];
+  uint64_t pmcr1_el1;
+  uint8_t __res_3c8_400[56];
+  uint64_t apl_lrtmr_el2;
+  uint64_t apl_intenable_el2;
+  uint8_t __res_410_1000[3056];
+} apple_vncr_context_21_t;
+
+typedef union {
+  struct {
+    union {
+      // arm_context_t guest_context;
+      struct {
+        uint64_t res1[1];
+        struct {
+          uint64_t x[29];
+          uint64_t fp;
+          uint64_t lr;
+          uint64_t sp;
+          uint64_t pc;
+          uint32_t cpsr;
+          uint32_t pad;
+        } regs;
+        uint64_t res2[4];
+        struct {
+          __uint128_t q[32];
+          uint32_t fpsr;
+          uint32_t fpcr;
+        } neon;
+      };
+    };
+    arm_guest_shared_sysregs_21_t shared_sysregs;
+    arm_guest_banked_sysregs_21_t banked_sysregs;
+    arm_guest_dbgregs_21_t dbgregs;
+    volatile arm_guest_controls_21_t controls;
+    volatile uint64_t state_dirty;
+    uint64_t guest_tick_count;
+    arm_guest_extregs_21_t extregs;
+    arm_vncr_context_21_t vncr;
+    apple_vncr_context_21_t avncr;
+  };
+  uint8_t page[16384];
+} arm_guest_rw_context_21_t;
+
+typedef struct {
+  uint32_t vmexit_reason;
+  uint32_t vmexit_esr;
+  uint32_t vmexit_instr;
+  uint64_t vmexit_far;
+  uint64_t vmexit_hpfar;
+} arm_guest_vmexit_21_t;
+
+typedef union {
+  struct {
+    uint64_t ver;
+    arm_guest_vmexit_21_t exit;
+    arm_guest_controls_21_t controls;
+    uint64_t state_valid;
+    uint64_t state_dirty;
+    uint64_t state_used;
+    uint32_t ich_vtr_el2;
+    uint32_t ich_misr_el2;
+    uint32_t ich_elrsr_el2;
+  };
+  uint8_t page[16384];
+} arm_guest_ro_context_21_t;
+
+typedef struct {
+  uint64_t cptr_el2;
+  uint64_t mdscr_el1;
+  uint64_t tpidr_el1;
+  uint64_t tpidr_el0;
+  uint64_t tpidrro_el0;
+  uint64_t sp_el0;
+  uint64_t jop_hash;
+  uint64_t vmenter_ticks;
+  uint64_t vmexit_ticks;
+  uint64_t vncr_el2;
+  uint64_t avncr_el2;
+  uint64_t ich_ap0r0_el2;
+  uint64_t ich_ap1r0_el2;
+  vm_map_t guest_map;
+  bool flush_local_tlb;
+  uint64_t actlr_en_mdsb;
+} arm_host_context_21_t;
+
+typedef struct {
+  arm_guest_rw_context_21_t rw;
+  arm_guest_ro_context_21_t ro;
+  arm_host_context_21_t priv;
+} arm_guest_context_21_t;
+
+typedef struct {
+    uint64_t api;
+    uint64_t vcpumax;
+    uint64_t control_hcr;
+    uint64_t control_hacr;
+    uint64_t control_cptr;
+    uint64_t control_mdcr;
+    uint64_t control_ich_hcr;
+    uint64_t control_vmpidr;
+    uint64_t control_vpidr;
+    uint64_t control_virtual_timer_offset;
+    uint64_t control_timer;
+    uint64_t control_vmkeyhi;
+    uint64_t control_vmkeylo;
+    uint64_t control_apsts;
+    uint64_t control_state_used;
+    uint64_t control_hfgrtr;
+    uint64_t control_hfgwtr;
+    uint64_t control_hfgitr;
+    uint64_t control_hdfgrtr;
+    uint64_t control_hdfgwtr;
+    uint64_t control_cnthctl;
+    uint64_t ctr_el0;
+    uint64_t dczid_el0;
+    uint64_t clidr_el1;
+    uint64_t ccsidr_el1_inst[8];
+    uint64_t ccsidr_el1_data_or_unified[8];
+    uint64_t id_aa64dfr0_el1;
+    uint64_t id_aa64dfr1_el1;
+    uint64_t id_aa64isar0_el1;
+    uint64_t id_aa64isar1_el1;
+    uint64_t id_aa64mmfr0_el1;
+    uint64_t id_aa64mmfr1_el1;
+    uint64_t id_aa64mmfr2_el1;
+    uint64_t id_aa64pfr0_el1;
+    uint64_t id_aa64pfr1_el1;
+    uint8_t gic_npie_active_pending_bug;
+    uint64_t ipa_bits_4k;
+    uint64_t ipa_bits_16k;
+} hv_capabilities_21_t;
+
+#define HV_XNU_21_MAGIC (0x206879700000000e)
+#define HV_VERSION_XNU_21 (21)

+ 400 - 0
sysreg_offsets_xnu_20.h

@@ -0,0 +1,400 @@
+case HV_SYS_REG_DBGBCR0_EL1:
+  o = 0x450;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR0_EL1:
+  o = 0x548;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR0_EL1:
+  o = 0x550;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR1_EL1:
+  o = 0x458;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR1_EL1:
+  o = 0x460;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR1_EL1:
+  o = 0x558;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR1_EL1:
+  o = 0x560;
+  f = 2;
+  break;
+case HV_SYS_REG_MDCCINT_EL1:
+  o = 0x648;
+  f = 2;
+  break;
+case HV_SYS_REG_MDSCR_EL1:
+  o = 0x350;
+  f = 0;
+  break;
+case HV_SYS_REG_DBGBVR2_EL1:
+  o = 0x468;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR2_EL1:
+  o = 0x470;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR2_EL1:
+  o = 0x568;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR2_EL1:
+  o = 0x570;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR3_EL1:
+  o = 0x478;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR3_EL1:
+  o = 0x480;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR3_EL1:
+  o = 0x578;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR3_EL1:
+  o = 0x580;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR4_EL1:
+  o = 0x488;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR4_EL1:
+  o = 0x490;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR4_EL1:
+  o = 0x588;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR4_EL1:
+  o = 0x590;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR5_EL1:
+  o = 0x498;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR5_EL1:
+  o = 0x4a0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR5_EL1:
+  o = 0x598;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR5_EL1:
+  o = 0x5a0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR6_EL1:
+  o = 0x4a8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR6_EL1:
+  o = 0x4b0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR6_EL1:
+  o = 0x5a8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR6_EL1:
+  o = 0x5b0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR7_EL1:
+  o = 0x4b8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR7_EL1:
+  o = 0x4c0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR7_EL1:
+  o = 0x5b8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR7_EL1:
+  o = 0x5c0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR8_EL1:
+  o = 0x4c8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR8_EL1:
+  o = 0x4d0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR8_EL1:
+  o = 0x5c8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR8_EL1:
+  o = 0x5d0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR9_EL1:
+  o = 0x4d8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR9_EL1:
+  o = 0x4e0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR9_EL1:
+  o = 0x5d8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR9_EL1:
+  o = 0x5e0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR10_EL1:
+  o = 0x4e8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR10_EL1:
+  o = 0x4f0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR10_EL1:
+  o = 0x5e8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR10_EL1:
+  o = 0x5f0;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR11_EL1:
+  o = 0x4f8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR11_EL1:
+  o = 0x500;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR11_EL1:
+  o = 0x5f8;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR11_EL1:
+  o = 0x600;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR12_EL1:
+  o = 0x508;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR12_EL1:
+  o = 0x510;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR12_EL1:
+  o = 0x608;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR12_EL1:
+  o = 0x610;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR13_EL1:
+  o = 0x518;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR13_EL1:
+  o = 0x520;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR13_EL1:
+  o = 0x618;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR13_EL1:
+  o = 0x620;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR14_EL1:
+  o = 0x528;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR14_EL1:
+  o = 0x530;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR14_EL1:
+  o = 0x628;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR14_EL1:
+  o = 0x630;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBVR15_EL1:
+  o = 0x538;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGBCR15_EL1:
+  o = 0x540;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWVR15_EL1:
+  o = 0x638;
+  f = 2;
+  break;
+case HV_SYS_REG_DBGWCR15_EL1:
+  o = 0x640;
+  f = 2;
+  break;
+case HV_SYS_REG_SCTLR_EL1:
+  o = 0x400;
+  f = 1;
+  break;
+case HV_SYS_REG_AFSR0_EL1:
+  o = 0x418;
+  f = 1;
+  break;
+case HV_SYS_REG_AFSR1_EL1:
+  o = 0x420;
+  f = 0x1;
+  break;
+case HV_SYS_REG_ESR_EL1:
+  o = 0x3c8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_FAR_EL1:
+  o = 0x3c0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_PAR_EL1:
+  o = 0x380;
+  f = 0x0;
+  break;
+case HV_SYS_REG_MAIR_EL1:
+  o = 0x3d0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_AMAIR_EL1:
+  o = 0x3d8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_VBAR_EL1:
+  o = 0x3e0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_CONTEXTIDR_EL1:
+  o = 0x428;
+  f = 0x1;
+  break;
+case HV_SYS_REG_TPIDR_EL1:
+  o = 0x358;
+  f = 0x0;
+  break;
+case HV_SYS_REG_CNTKCTL_EL1:
+  o = 0x440;
+  f = 0x1;
+  break;
+case HV_SYS_REG_CSSELR_EL1:
+  o = 0x388;
+  f = 0x0;
+  break;
+case HV_SYS_REG_TPIDR_EL0:
+  o = 0x360;
+  f = 0x0;
+  break;
+case HV_SYS_REG_TPIDRRO_EL0:
+  o = 0x368;
+  f = 0x0;
+  break;
+case HV_SYS_REG_CNTV_CTL_EL0:
+  o = 0x430;
+  f = 0x1;
+  break;
+case HV_SYS_REG_CNTV_CVAL_EL0:
+  o = 0x3e8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_SP_EL1:
+  o = 0x378;
+  f = 0x0;
+  break;
+case HV_SYS_REG_SPSR_EL1:
+  o = 0x410;
+  f = 0x1;
+  break;
+case HV_SYS_REG_ELR_EL1:
+  o = 0x3b8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_SP_EL0:
+  o = 0x370;
+  f = 0x0;
+  break;
+case HV_SYS_REG_CPACR_EL1:
+  o = 0x408;
+  f = 0x1;
+  break;
+case HV_SYS_REG_TTBR0_EL1:
+  o = 0x3a0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_TTBR1_EL1:
+  o = 0x3a8;
+  f = 0x1;
+  break;
+case HV_SYS_REG_TCR_EL1:
+  o = 0x3b0;
+  f = 0x1;
+  break;
+case HV_SYS_REG_APIAKEYLO_EL1:
+  f = 0x2000000000000000;
+  o = 0x788;
+  break;
+case HV_SYS_REG_APIAKEYHI_EL1:
+  f = 0x2000000000000000;
+  o = 0x780;
+  break;
+case HV_SYS_REG_APIBKEYLO_EL1:
+  f = 0x2000000000000000;
+  o = 0x798;
+  break;
+case HV_SYS_REG_APIBKEYHI_EL1:
+  f = 0x2000000000000000;
+  o = 0x790;
+  break;
+case HV_SYS_REG_APDAKEYLO_EL1:
+  f = 0x2000000000000000;
+  o = 0x7a8;
+  break;
+case HV_SYS_REG_APDAKEYHI_EL1:
+  f = 0x2000000000000000;
+  o = 0x7a0;
+  break;
+case HV_SYS_REG_APDBKEYLO_EL1:
+  f = 0x2000000000000000;
+  o = 0x7b8;
+  break;
+case HV_SYS_REG_APDBKEYHI_EL1:
+  f = 0x2000000000000000;
+  o = 0x7b0;
+  break;
+case HV_SYS_REG_APGAKEYLO_EL1:
+  f = 0x2000000000000000;
+  o = 0x778;
+  break;
+case HV_SYS_REG_APGAKEYHI_EL1:
+  f = 0x2000000000000000;
+  o = 0x770;
+  break;

+ 0 - 0
sysreg_offsets.h → sysreg_offsets_xnu_21.h