VirtualBox

Changeset 105689 in vbox


Ignore:
Timestamp:
Aug 15, 2024 12:47:47 PM (6 months ago)
Author:
vboxsync
Message:

VMMArm/NEMR3Native-darwin-armv8: Some preliminary code to support the new nested virtualization (EL2) support with the upcoming Sequioa (15.0) on M3 hardware, not yet working, bugref:10747

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-darwin-armv8.cpp

    r103298 r105689  
    4646#include <VBox/vmm/vmcc.h>
    4747#include <VBox/vmm/vmm.h>
     48#include <VBox/gic.h>
    4849#include "dtrace/VBoxVMM.h"
    4950
     
    7677*********************************************************************************************************************************/
    7778
     79#if MAC_OS_X_VERSION_MIN_REQUIRED < 150000
     80
     81/* Since 15.0+ */
     82typedef enum hv_gic_distributor_reg_t : uint16_t
     83{
     84    HV_GIC_DISTRIBUTOR_REG_GICD_CTLR,
     85    HV_GIC_DISTRIBUTOR_REG_GICD_ICACTIVER0
     86    /** @todo */
     87} hv_gic_distributor_reg_t;
     88
     89
     90typedef enum hv_gic_icc_reg_t : uint16_t
     91{
     92    HV_GIC_ICC_REG_AP0R0_EL1
     93    /** @todo */
     94} hv_gic_icc_reg_t;
     95
     96
     97typedef enum hv_gic_ich_reg_t : uint16_t
     98{
     99    HV_GIC_ICH_REG_AP0R0_EL2
     100    /** @todo */
     101} hv_gic_ich_reg_t;
     102
     103
     104typedef enum hv_gic_icv_reg_t : uint16_t
     105{
     106    HV_GIC_ICV_REG_AP0R0_EL1
     107    /** @todo */
     108} hv_gic_icv_reg_t;
     109
     110
     111typedef enum hv_gic_msi_reg_t : uint16_t
     112{
     113    HV_GIC_REG_GICM_SET_SPI_NSR
     114    /** @todo */
     115} hv_gic_msi_reg_t;
     116
     117
     118typedef enum hv_gic_redistributor_reg_t : uint16_t
     119{
     120    HV_GIC_REDISTRIBUTOR_REG_GICR_ICACTIVER0
     121    /** @todo */
     122} hv_gic_redistributor_reg_t;
     123
     124
     125typedef enum hv_gic_intid_t : uint16_t
     126{
     127    HV_GIC_INT_EL1_PHYSICAL_TIMER  = 23,
     128    HV_GIC_INT_EL1_VIRTUAL_TIMER   = 25,
     129    HV_GIC_INT_EL2_PHYSICAL_TIMER  = 26,
     130    HV_GIC_INT_MAINTENANCE         = 27,
     131    HV_GIC_INT_PERFORMANCE_MONITOR = 30
     132} hv_gic_intid_t;
     133
     134#endif
     135
     136typedef hv_return_t FN_HV_VM_CONFIG_GET_EL2_SUPPORTED(bool *el2_supported);
     137typedef hv_return_t FN_HV_VM_CONFIG_GET_EL2_ENABLED(hv_vm_config_t config, bool *el2_enabled);
     138typedef hv_return_t FN_HV_VM_CONFIG_SET_EL2_ENABLED(hv_vm_config_t config, bool el2_enabled);
     139
     140typedef struct hv_gic_config_s *hv_gic_config_t;
     141typedef hv_return_t     FN_HV_GIC_CREATE(hv_gic_config_t gic_config);
     142typedef hv_return_t     FN_HV_GIC_RESET(void);
     143typedef hv_gic_config_t FN_HV_GIC_CONFIG_CREATE(void);
     144typedef hv_return_t     FN_HV_GIC_CONFIG_SET_DISTRIBUTOR_BASE(hv_gic_config_t config, hv_ipa_t distributor_base_address);
     145typedef hv_return_t     FN_HV_GIC_CONFIG_SET_REDISTRIBUTOR_BASE(hv_gic_config_t config, hv_ipa_t redistributor_base_address);
     146typedef hv_return_t     FN_HV_GIC_CONFIG_SET_MSI_REGION_BASE(hv_gic_config_t config, hv_ipa_t msi_region_base_address);
     147typedef hv_return_t     FN_HV_GIC_CONFIG_SET_MSI_INTERRUPT_RANGE(hv_gic_config_t config, uint32_t msi_intid_base, uint32_t msi_intid_count);
     148
     149typedef hv_return_t     FN_HV_GIC_GET_REDISTRIBUTOR_BASE(hv_vcpu_t vcpu, hv_ipa_t *redistributor_base_address);
     150typedef hv_return_t     FN_HV_GIC_GET_REDISTRIBUTOR_REGION_SIZE(size_t *redistributor_region_size);
     151typedef hv_return_t     FN_HV_GIC_GET_REDISTRIBUTOR_SIZE(size_t *redistributor_size);
     152typedef hv_return_t     FN_HV_GIC_GET_DISTRIBUTOR_SIZE(size_t *distributor_size);
     153typedef hv_return_t     FN_HV_GIC_GET_DISTRIBUTOR_BASE_ALIGNMENT(size_t *distributor_base_alignment);
     154typedef hv_return_t     FN_HV_GIC_GET_REDISTRIBUTOR_BASE_ALIGNMENT(size_t *redistributor_base_alignment);
     155typedef hv_return_t     FN_HV_GIC_GET_MSI_REGION_BASE_ALIGNMENT(size_t *msi_region_base_alignment);
     156typedef hv_return_t     FN_HV_GIC_GET_MSI_REGION_SIZE(size_t *msi_region_size);
     157typedef hv_return_t     FN_HV_GIC_GET_SPI_INTERRUPT_RANGE(uint32_t *spi_intid_base, uint32_t *spi_intid_count);
     158
     159typedef struct hv_gic_state_s *hv_gic_state_t;
     160typedef hv_gic_state_t  FN_HV_GIC_STATE_CREATE(void);
     161typedef hv_return_t     FN_HV_GIC_SET_STATE(const void *gic_state_data, size_t gic_state_size);
     162typedef hv_return_t     FN_HV_GIC_STATE_GET_SIZE(hv_gic_state_t state, size_t *gic_state_size);
     163typedef hv_return_t     FN_HV_GIC_STATE_GET_DATA(hv_gic_state_t state, void *gic_state_data);
     164
     165typedef hv_return_t     FN_HV_GIC_SEND_MSI(hv_ipa_t address, uint32_t intid);
     166typedef hv_return_t     FN_HV_GIC_SET_SPI(uint32_t intid, bool level);
     167
     168typedef hv_return_t     FN_HV_GIC_GET_DISTRIBUTOR_REG(hv_gic_distributor_reg_t reg, uint64_t *value);
     169typedef hv_return_t     FN_HV_GIC_GET_MSI_REG(hv_gic_msi_reg_t reg, uint64_t *value);
     170typedef hv_return_t     FN_HV_GIC_GET_ICC_REG(hv_vcpu_t vcpu, hv_gic_icc_reg_t reg, uint64_t *value);
     171typedef hv_return_t     FN_HV_GIC_GET_ICH_REG(hv_vcpu_t vcpu, hv_gic_ich_reg_t reg, uint64_t *value);
     172typedef hv_return_t     FN_HV_GIC_GET_ICV_REG(hv_vcpu_t vcpu, hv_gic_icv_reg_t reg, uint64_t *value);
     173typedef hv_return_t     FN_HV_GIC_GET_REDISTRIBUTOR_REG(hv_vcpu_t vcpu, hv_gic_redistributor_reg_t reg, uint64_t *value);
     174
     175typedef hv_return_t     FN_HV_GIC_SET_DISTRIBUTOR_REG(hv_gic_distributor_reg_t reg, uint64_t value);
     176typedef hv_return_t     FN_HV_GIC_SET_MSI_REG(hv_gic_msi_reg_t reg, uint64_t value);
     177typedef hv_return_t     FN_HV_GIC_SET_ICC_REG(hv_vcpu_t vcpu, hv_gic_icc_reg_t reg, uint64_t value);
     178typedef hv_return_t     FN_HV_GIC_SET_ICH_REG(hv_vcpu_t vcpu, hv_gic_ich_reg_t reg, uint64_t value);
     179typedef hv_return_t     FN_HV_GIC_SET_ICV_REG(hv_vcpu_t vcpu, hv_gic_icv_reg_t reg, uint64_t value);
     180typedef hv_return_t     FN_HV_GIC_SET_REDISTRIBUTOR_REG(hv_vcpu_t vcpu, hv_gic_redistributor_reg_t reg, uint64_t value);
     181
     182typedef hv_return_t     FN_HV_GIC_GET_INTID(hv_gic_intid_t interrupt, uint32_t *intid);
    78183
    79184/*********************************************************************************************************************************
    80185*   Global Variables                                                                                                             *
    81186*********************************************************************************************************************************/
     187/** @name Optional APIs imported from Hypervisor.framework.
     188 * @{ */
     189static FN_HV_VM_CONFIG_GET_EL2_SUPPORTED *g_pfnHvVmConfigGetEl2Supported                        = NULL; /* Since 15.0 */
     190static FN_HV_VM_CONFIG_GET_EL2_ENABLED   *g_pfnHvVmConfigGetEl2Enabled                          = NULL; /* Since 15.0 */
     191static FN_HV_VM_CONFIG_SET_EL2_ENABLED   *g_pfnHvVmConfigSetEl2Enabled                          = NULL; /* Since 15.0 */
     192
     193static FN_HV_GIC_CREATE                             *g_pfnHvGicCreate                           = NULL; /* Since 15.0 */
     194static FN_HV_GIC_RESET                              *g_pfnHvGicReset                            = NULL; /* Since 15.0 */
     195static FN_HV_GIC_CONFIG_CREATE                      *g_pfnHvGicConfigCreate                     = NULL; /* Since 15.0 */
     196static FN_HV_GIC_CONFIG_SET_DISTRIBUTOR_BASE        *g_pfnHvGicConfigSetDistributorBase         = NULL; /* Since 15.0 */
     197static FN_HV_GIC_CONFIG_SET_REDISTRIBUTOR_BASE      *g_pfnHvGicConfigSetRedistributorBase       = NULL; /* Since 15.0 */
     198static FN_HV_GIC_CONFIG_SET_MSI_REGION_BASE         *g_pfnHvGicConfigSetMsiRegionBase           = NULL; /* Since 15.0 */
     199static FN_HV_GIC_CONFIG_SET_MSI_INTERRUPT_RANGE     *g_pfnHvGicConfigSetMsiInterruptRange       = NULL; /* Since 15.0 */
     200static FN_HV_GIC_GET_REDISTRIBUTOR_BASE             *g_pfnHvGicGetRedistributorBase             = NULL; /* Since 15.0 */
     201static FN_HV_GIC_GET_REDISTRIBUTOR_REGION_SIZE      *g_pfnHvGicGetRedistributorRegionSize       = NULL; /* Since 15.0 */
     202static FN_HV_GIC_GET_REDISTRIBUTOR_SIZE             *g_pfnHvGicGetRedistributorSize             = NULL; /* Since 15.0 */
     203static FN_HV_GIC_GET_DISTRIBUTOR_SIZE               *g_pfnHvGicGetDistributorSize               = NULL; /* Since 15.0 */
     204static FN_HV_GIC_GET_DISTRIBUTOR_BASE_ALIGNMENT     *g_pfnHvGicGetDistributorBaseAlignment      = NULL; /* Since 15.0 */
     205static FN_HV_GIC_GET_REDISTRIBUTOR_BASE_ALIGNMENT   *g_pfnHvGicGetRedistributorBaseAlignment    = NULL; /* Since 15.0 */
     206static FN_HV_GIC_GET_MSI_REGION_BASE_ALIGNMENT      *g_pfnHvGicGetMsiRegionBaseAlignment        = NULL; /* Since 15.0 */
     207static FN_HV_GIC_GET_MSI_REGION_SIZE                *g_pfnHvGicGetMsiRegionSize                 = NULL; /* Since 15.0 */
     208static FN_HV_GIC_GET_SPI_INTERRUPT_RANGE            *g_pfnHvGicGetSpiInterruptRange             = NULL; /* Since 15.0 */
     209static FN_HV_GIC_STATE_CREATE                       *g_pfnHvGicStateCreate                      = NULL; /* Since 15.0 */
     210static FN_HV_GIC_SET_STATE                          *g_pfnHvGicSetState                         = NULL; /* Since 15.0 */
     211static FN_HV_GIC_STATE_GET_SIZE                     *g_pfnHvGicStateGetSize                     = NULL; /* Since 15.0 */
     212static FN_HV_GIC_STATE_GET_DATA                     *g_pfnHvGicStateGetData                     = NULL; /* Since 15.0 */
     213static FN_HV_GIC_SEND_MSI                           *g_pfnHvGicSendMsi                          = NULL; /* Since 15.0 */
     214static FN_HV_GIC_SET_SPI                            *g_pfnHvGicSetSpi                           = NULL; /* Since 15.0 */
     215static FN_HV_GIC_GET_DISTRIBUTOR_REG                *g_pfnHvGicGetDistributorReg                = NULL; /* Since 15.0 */
     216static FN_HV_GIC_GET_MSI_REG                        *g_pfnHvGicGetMsiReg                        = NULL; /* Since 15.0 */
     217static FN_HV_GIC_GET_ICC_REG                        *g_pfnHvGicGetIccReg                        = NULL; /* Since 15.0 */
     218static FN_HV_GIC_GET_ICH_REG                        *g_pfnHvGicGetIchReg                        = NULL; /* Since 15.0 */
     219static FN_HV_GIC_GET_ICV_REG                        *g_pfnHvGicGetIcvReg                        = NULL; /* Since 15.0 */
     220static FN_HV_GIC_GET_REDISTRIBUTOR_REG              *g_pfnHvGicGetRedistributorReg              = NULL; /* Since 15.0 */
     221static FN_HV_GIC_SET_DISTRIBUTOR_REG                *g_pfnHvGicSetDistributorReg                = NULL; /* Since 15.0 */
     222static FN_HV_GIC_SET_MSI_REG                        *g_pfnHvGicSetMsiReg                        = NULL; /* Since 15.0 */
     223static FN_HV_GIC_SET_ICC_REG                        *g_pfnHvGicSetIccReg                        = NULL; /* Since 15.0 */
     224static FN_HV_GIC_SET_ICH_REG                        *g_pfnHvGicSetIchReg                        = NULL; /* Since 15.0 */
     225static FN_HV_GIC_SET_ICV_REG                        *g_pfnHvGicSetIcvReg                        = NULL; /* Since 15.0 */
     226static FN_HV_GIC_SET_REDISTRIBUTOR_REG              *g_pfnHvGicSetRedistributorReg              = NULL; /* Since 15.0 */
     227static FN_HV_GIC_GET_INTID                          *g_pfnHvGicGetIntid                         = NULL; /* Since 15.0 */
     228/** @} */
     229
     230
     231/**
     232 * Import instructions.
     233 */
     234static const struct
     235{
     236    void        **ppfn;     /**< The function pointer variable. */
     237    const char  *pszName;   /**< The function name. */
     238} g_aImports[] =
     239{
     240#define NEM_DARWIN_IMPORT(a_Pfn, a_Name) { (void **)&(a_Pfn), #a_Name }
     241    NEM_DARWIN_IMPORT(g_pfnHvVmConfigGetEl2Supported,           hv_vm_config_get_el2_supported),
     242    NEM_DARWIN_IMPORT(g_pfnHvVmConfigGetEl2Enabled,             hv_vm_config_get_el2_enabled),
     243    NEM_DARWIN_IMPORT(g_pfnHvVmConfigSetEl2Enabled,             hv_vm_config_set_el2_enabled),
     244
     245    NEM_DARWIN_IMPORT(g_pfnHvGicCreate,                         hv_gic_create),
     246    NEM_DARWIN_IMPORT(g_pfnHvGicReset,                          hv_gic_reset),
     247    NEM_DARWIN_IMPORT(g_pfnHvGicConfigCreate,                   hv_gic_config_create),
     248    NEM_DARWIN_IMPORT(g_pfnHvGicConfigSetDistributorBase,       hv_gic_config_set_distributor_base),
     249    NEM_DARWIN_IMPORT(g_pfnHvGicConfigSetRedistributorBase,     hv_gic_config_set_redistributor_base),
     250    NEM_DARWIN_IMPORT(g_pfnHvGicConfigSetMsiRegionBase,         hv_gic_config_set_msi_region_base),
     251    NEM_DARWIN_IMPORT(g_pfnHvGicConfigSetMsiInterruptRange,     hv_gic_config_set_msi_interrupt_range),
     252    NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorBase,           hv_gic_get_redistributor_base),
     253    NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorRegionSize,     hv_gic_get_redistributor_region_size),
     254    NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorSize,           hv_gic_get_redistributor_size),
     255    NEM_DARWIN_IMPORT(g_pfnHvGicGetDistributorSize,             hv_gic_get_distributor_size),
     256    NEM_DARWIN_IMPORT(g_pfnHvGicGetDistributorBaseAlignment,    hv_gic_get_distributor_base_alignment),
     257    NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorBaseAlignment,  hv_gic_get_redistributor_base_alignment),
     258    NEM_DARWIN_IMPORT(g_pfnHvGicGetMsiRegionBaseAlignment,      hv_gic_get_msi_region_base_alignment),
     259    NEM_DARWIN_IMPORT(g_pfnHvGicGetMsiRegionSize,               hv_gic_get_msi_region_size),
     260    NEM_DARWIN_IMPORT(g_pfnHvGicGetSpiInterruptRange,           hv_gic_get_spi_interrupt_range),
     261    NEM_DARWIN_IMPORT(g_pfnHvGicStateCreate,                    hv_gic_state_create),
     262    NEM_DARWIN_IMPORT(g_pfnHvGicSetState,                       hv_gic_set_state),
     263    NEM_DARWIN_IMPORT(g_pfnHvGicStateGetSize,                   hv_gic_state_get_size),
     264    NEM_DARWIN_IMPORT(g_pfnHvGicStateGetData,                   hv_gic_state_get_data),
     265    NEM_DARWIN_IMPORT(g_pfnHvGicSendMsi,                        hv_gic_send_msi),
     266    NEM_DARWIN_IMPORT(g_pfnHvGicSetSpi,                         hv_gic_set_spi),
     267    NEM_DARWIN_IMPORT(g_pfnHvGicGetDistributorReg,              hv_gic_get_distributor_reg),
     268    NEM_DARWIN_IMPORT(g_pfnHvGicGetMsiReg,                      hv_gic_get_msi_reg),
     269    NEM_DARWIN_IMPORT(g_pfnHvGicGetIccReg,                      hv_gic_get_icc_reg),
     270    NEM_DARWIN_IMPORT(g_pfnHvGicGetIchReg,                      hv_gic_get_ich_reg),
     271    NEM_DARWIN_IMPORT(g_pfnHvGicGetIcvReg,                      hv_gic_get_icv_reg),
     272    NEM_DARWIN_IMPORT(g_pfnHvGicGetRedistributorReg,            hv_gic_get_redistributor_reg),
     273    NEM_DARWIN_IMPORT(g_pfnHvGicSetDistributorReg,              hv_gic_set_distributor_reg),
     274    NEM_DARWIN_IMPORT(g_pfnHvGicSetMsiReg,                      hv_gic_set_msi_reg),
     275    NEM_DARWIN_IMPORT(g_pfnHvGicSetIccReg,                      hv_gic_set_icc_reg),
     276    NEM_DARWIN_IMPORT(g_pfnHvGicSetIchReg,                      hv_gic_set_ich_reg),
     277    NEM_DARWIN_IMPORT(g_pfnHvGicSetIcvReg,                      hv_gic_set_icv_reg),
     278    NEM_DARWIN_IMPORT(g_pfnHvGicSetRedistributorReg,            hv_gic_set_redistributor_reg),
     279    NEM_DARWIN_IMPORT(g_pfnHvGicGetIntid,                       hv_gic_get_intid)
     280#undef NEM_DARWIN_IMPORT
     281};
     282
     283
     284/*
     285 * Let the preprocessor alias the APIs to import variables for better autocompletion.
     286 */
     287#ifndef IN_SLICKEDIT
     288# define hv_vm_config_get_el2_supported             g_pfnHvVmConfigGetEl2Supported
     289# define hv_vm_config_get_el2_enabled               g_pfnHvVmConfigGetEl2Enabled
     290# define hv_vm_config_set_el2_enabled               g_pfnHvVmConfigSetEl2Enabled
     291
     292# define hv_gic_create                              g_pfnHvGicCreate
     293# define hv_gic_reset                               g_pfnHvGicReset
     294# define hv_gic_config_create                       g_pfnHvGicConfigCreate
     295# define hv_gic_config_set_distributor_base         g_pfnHvGicConfigSetDistributorBase
     296# define hv_gic_config_set_redistributor_base       g_pfnHvGicConfigSetRedistributorBase
     297# define hv_gic_config_set_msi_region_base          g_pfnHvGicConfigSetMsiRegionBase
     298# define hv_gic_config_set_msi_interrupt_range      g_pfnHvGicConfigSetMsiInterruptRange
     299# define hv_gic_get_redistributor_base              g_pfnHvGicGetRedistributorBase
     300# define hv_gic_get_redistributor_region_size       g_pfnHvGicGetRedistributorRegionSize
     301# define hv_gic_get_redistributor_size              g_pfnHvGicGetRedistributorSize
     302# define hv_gic_get_distributor_size                g_pfnHvGicGetDistributorSize
     303# define hv_gic_get_distributor_base_alignment      g_pfnHvGicGetDistributorBaseAlignment
     304# define hv_gic_get_redistributor_base_alignment    g_pfnHvGicGetRedistributorBaseAlignment
     305# define hv_gic_get_msi_region_base_alignment       g_pfnHvGicGetMsiRegionBaseAlignment
     306# define hv_gic_get_msi_region_size                 g_pfnHvGicGetMsiRegionSize
     307# define hv_gic_get_spi_interrupt_range             g_pfnHvGicGetSpiInterruptRange
     308# define hv_gic_state_create                        g_pfnHvGicStateCreate
     309# define hv_gic_set_state                           g_pfnHvGicSetState
     310# define hv_gic_state_get_size                      g_pfnHvGicStateGetSize
     311# define hv_gic_state_get_data                      g_pfnHvGicStateGetData
     312# define hv_gic_send_msi                            g_pfnHvGicSendMsi
     313# define hv_gic_set_spi                             g_pfnHvGicSetSpi
     314# define hv_gic_get_distributor_reg                 g_pfnHvGicGetDistributorReg
     315# define hv_gic_get_msi_reg                         g_pfnHvGicGetMsiReg
     316# define hv_gic_get_icc_reg                         g_pfnHvGicGetIccReg
     317# define hv_gic_get_ich_reg                         g_pfnHvGicGetIchReg
     318# define hv_gic_get_icv_reg                         g_pfnHvGicGetIcvReg
     319# define hv_gic_get_redistributor_reg               g_pfnHvGicGetRedistributorReg
     320# define hv_gic_set_distributor_reg                 g_pfnHvGicSetDistributorReg
     321# define hv_gic_set_msi_reg                         g_pfnHvGicSetMsiReg
     322# define hv_gic_set_icc_reg                         g_pfnHvGicSetIccReg
     323# define hv_gic_set_ich_reg                         g_pfnHvGicSetIchReg
     324# define hv_gic_set_icv_reg                         g_pfnHvGicSetIcvReg
     325# define hv_gic_set_redistributor_reg               g_pfnHvGicSetRedistributorReg
     326# define hv_gic_get_intid                           g_pfnHvGicGetIntid
     327#endif
     328
     329
    82330/** The general registers. */
    83331static const struct
     
    267515    { HV_SYS_REG_MDCCINT_EL1,       CPUMCTX_EXTRN_SYSREG_MISC,      RT_UOFFSETOF(CPUMCTX, MDccInt.u64)      }
    268516
     517};
     518/** EL2 support system registers. */
     519static const struct
     520{
     521    uint16_t            idSysReg;
     522    uint32_t            offCpumCtx;
     523} s_aCpumEl2SysRegs[] =
     524{
     525    { ARMV8_AARCH64_SYSREG_CNTHCTL_EL2,    RT_UOFFSETOF(CPUMCTX, CntHCtlEl2.u64)    },
     526    { ARMV8_AARCH64_SYSREG_CNTHP_CTL_EL2,  RT_UOFFSETOF(CPUMCTX, CntHpCtlEl2.u64)   },
     527    { ARMV8_AARCH64_SYSREG_CNTHP_CVAL_EL2, RT_UOFFSETOF(CPUMCTX, CntHpCValEl2.u64)  },
     528    { ARMV8_AARCH64_SYSREG_CNTHP_TVAL_EL2, RT_UOFFSETOF(CPUMCTX, CntHpTValEl2.u64)  },
     529    { ARMV8_AARCH64_SYSREG_CNTVOFF_EL2,    RT_UOFFSETOF(CPUMCTX, CntVOffEl2.u64)    },
     530    { ARMV8_AARCH64_SYSREG_CPTR_EL2,       RT_UOFFSETOF(CPUMCTX, CptrEl2.u64)       },
     531    { ARMV8_AARCH64_SYSREG_ELR_EL2,        RT_UOFFSETOF(CPUMCTX, ElrEl2.u64)        },
     532    { ARMV8_AARCH64_SYSREG_ESR_EL2,        RT_UOFFSETOF(CPUMCTX, EsrEl2.u64)        },
     533    { ARMV8_AARCH64_SYSREG_FAR_EL2,        RT_UOFFSETOF(CPUMCTX, FarEl2.u64)        },
     534    { ARMV8_AARCH64_SYSREG_HCR_EL2,        RT_UOFFSETOF(CPUMCTX, HcrEl2.u64)        },
     535    { ARMV8_AARCH64_SYSREG_HPFAR_EL2,      RT_UOFFSETOF(CPUMCTX, HpFarEl2.u64)      },
     536    { ARMV8_AARCH64_SYSREG_MAIR_EL2,       RT_UOFFSETOF(CPUMCTX, MairEl2.u64)       },
     537    //{ ARMV8_AARCH64_SYSREG_MDCR_EL2,       RT_UOFFSETOF(CPUMCTX, MdcrEl2.u64)       },
     538    { ARMV8_AARCH64_SYSREG_SCTLR_EL2,      RT_UOFFSETOF(CPUMCTX, SctlrEl2.u64)      },
     539    { ARMV8_AARCH64_SYSREG_SPSR_EL2,       RT_UOFFSETOF(CPUMCTX, SpsrEl2.u64)       },
     540    { ARMV8_AARCH64_SYSREG_SP_EL2,         RT_UOFFSETOF(CPUMCTX, SpEl2.u64)         },
     541    { ARMV8_AARCH64_SYSREG_TCR_EL2,        RT_UOFFSETOF(CPUMCTX, TcrEl2.u64)        },
     542    { ARMV8_AARCH64_SYSREG_TPIDR_EL2,      RT_UOFFSETOF(CPUMCTX, TpidrEl2.u64)      },
     543    { ARMV8_AARCH64_SYSREG_TTBR0_EL2,      RT_UOFFSETOF(CPUMCTX, Ttbr0El2.u64)      },
     544    { ARMV8_AARCH64_SYSREG_TTBR1_EL2,      RT_UOFFSETOF(CPUMCTX, Ttbr1El2.u64)      },
     545    { ARMV8_AARCH64_SYSREG_VBAR_EL2,       RT_UOFFSETOF(CPUMCTX, VBarEl2.u64)       },
     546    { ARMV8_AARCH64_SYSREG_VMPIDR_EL2,     RT_UOFFSETOF(CPUMCTX, VMpidrEl2.u64)     },
     547    { ARMV8_AARCH64_SYSREG_VPIDR_EL2,      RT_UOFFSETOF(CPUMCTX, VPidrEl2.u64)      },
     548    { ARMV8_AARCH64_SYSREG_VTCR_EL2,       RT_UOFFSETOF(CPUMCTX, VTcrEl2.u64)       },
     549    { ARMV8_AARCH64_SYSREG_VTTBR_EL2,      RT_UOFFSETOF(CPUMCTX, VTtbrEl2.u64)      }
    269550};
    270551/** ID registers. */
     
    551832#endif
    552833        Log3(("%s%s\n", szRegs, szInstr));
     834
     835        if (pVM->nem.s.fEl2Enabled)
     836        {
     837            DBGFR3RegPrintf(pVM->pUVM, pVCpu->idCpu, &szRegs[0], sizeof(szRegs),
     838                            "sp_el2=%016VR{sp_el2} elr_el2=%016VR{elr_el2}\n"
     839                            "spsr_el2=%016VR{spsr_el2} tpidr_el2=%016VR{tpidr_el2}\n"
     840                            "sctlr_el2=%016VR{sctlr_el2} tcr_el2=%016VR{tcr_el2}\n"
     841                            "ttbr0_el2=%016VR{ttbr0_el2} ttbr1_el2=%016VR{ttbr1_el2}\n"
     842                            "esr_el2=%016VR{esr_el2} far_el2=%016VR{far_el2}\n"
     843                            "hcr_el2=%016VR{hcr_el2} tcr_el2=%016VR{tcr_el2}\n"
     844                            "vbar_el2=%016VR{vbar_el2} cptr_el2=%016VR{cptr_el2}\n"
     845                            );
     846        }
     847        Log3(("%s%s\n", szRegs));
    553848    }
    554849}
     
    625920
    626921    if (   hrc == HV_SUCCESS
     922        && (fWhat & CPUMCTX_EXTRN_SYSREG_EL2)
     923        && pVM->nem.s.fEl2Enabled)
     924    {
     925        for (uint32_t i = 0; i < RT_ELEMENTS(s_aCpumEl2SysRegs); i++)
     926        {
     927            uint64_t *pu64 = (uint64_t *)((uint8_t *)&pVCpu->cpum.GstCtx + s_aCpumEl2SysRegs[i].offCpumCtx);
     928            hrc |= hv_vcpu_get_sys_reg(pVCpu->nem.s.hVCpu, (hv_sys_reg_t)s_aCpumEl2SysRegs[i].idSysReg, pu64);
     929        }
     930    }
     931
     932    if (   hrc == HV_SUCCESS
    627933        && (fWhat & CPUMCTX_EXTRN_PSTATE))
    628934    {
     
    7171023
    7181024    if (   hrc == HV_SUCCESS
     1025        && !(pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_SYSREG_EL2)
     1026        && pVM->nem.s.fEl2Enabled)
     1027    {
     1028        for (uint32_t i = 0; i < RT_ELEMENTS(s_aCpumEl2SysRegs); i++)
     1029        {
     1030            uint64_t *pu64 = (uint64_t *)((uint8_t *)&pVCpu->cpum.GstCtx + s_aCpumEl2SysRegs[i].offCpumCtx);
     1031            hrc |= hv_vcpu_set_sys_reg(pVCpu->nem.s.hVCpu, (hv_sys_reg_t)s_aCpumEl2SysRegs[i].idSysReg, *pu64);
     1032            Assert(hrc == HV_SUCCESS);
     1033        }
     1034    }
     1035
     1036    if (   hrc == HV_SUCCESS
    7191037        && !(pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_PSTATE))
    7201038        hrc = hv_vcpu_set_reg(pVCpu->nem.s.hVCpu, HV_REG_CPSR, pVCpu->cpum.GstCtx.fPState);
     
    7221040    pVCpu->cpum.GstCtx.fExtrn |= CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_KEEPER_NEM;
    7231041    return nemR3DarwinHvSts2Rc(hrc);
     1042}
     1043
     1044
     1045/**
     1046 * Worker for nemR3NativeInit that loads the Hypervisor.framework shared library.
     1047 *
     1048 * @returns VBox status code.
     1049 * @param   pErrInfo            Where to always return error info.
     1050 */
     1051static int nemR3DarwinLoadHv(PRTERRINFO pErrInfo)
     1052{
     1053    RTLDRMOD hMod = NIL_RTLDRMOD;
     1054    static const char *s_pszHvPath = "/System/Library/Frameworks/Hypervisor.framework/Hypervisor";
     1055
     1056    int rc = RTLdrLoadEx(s_pszHvPath, &hMod, RTLDRLOAD_FLAGS_NO_UNLOAD | RTLDRLOAD_FLAGS_NO_SUFFIX, pErrInfo);
     1057    if (RT_SUCCESS(rc))
     1058    {
     1059        for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++)
     1060        {
     1061            int rc2 = RTLdrGetSymbol(hMod, g_aImports[i].pszName, (void **)g_aImports[i].ppfn);
     1062            if (RT_SUCCESS(rc2))
     1063            {
     1064                LogRel(("NEM:  info: Found optional import Hypervisor!%s.\n",
     1065                        g_aImports[i].pszName));
     1066            }
     1067            else
     1068            {
     1069                *g_aImports[i].ppfn = NULL;
     1070
     1071                LogRel(("NEM:  info: Failed to import Hypervisor!%s: %Rrc\n",
     1072                        g_aImports[i].pszName, rc2));
     1073            }
     1074        }
     1075        if (RT_SUCCESS(rc))
     1076        {
     1077            Assert(!RTErrInfoIsSet(pErrInfo));
     1078        }
     1079
     1080        RTLdrClose(hMod);
     1081    }
     1082    else
     1083    {
     1084        RTErrInfoAddF(pErrInfo, rc, "Failed to load Hypervisor.framwork: %s: %Rrc", s_pszHvPath, rc);
     1085        rc = VERR_NEM_INIT_FAILED;
     1086    }
     1087
     1088    return rc;
     1089}
     1090
     1091
     1092/**
     1093 * Dumps some GIC information to the release log.
     1094 */
     1095static void nemR3DarwinDumpGicInfo(void)
     1096{
     1097    size_t val = 0;
     1098    hv_return_t hrc = hv_gic_get_redistributor_size(&val);
     1099    LogRel(("GICNem: hv_gic_get_redistributor_size()                    -> hrc=%#x / size=%zu\n", hrc, val));
     1100    hrc = hv_gic_get_distributor_size(&val);
     1101    LogRel(("GICNem: hv_gic_get_distributor_size()                      -> hrc=%#x / size=%zu\n", hrc, val));
     1102    hrc = hv_gic_get_distributor_base_alignment(&val);
     1103    LogRel(("GICNem: hv_gic_get_distributor_base_alignment()            -> hrc=%#x / size=%zu\n", hrc, val));
     1104    hrc = hv_gic_get_redistributor_base_alignment(&val);
     1105    LogRel(("GICNem: hv_gic_get_redistributor_base_alignment()          -> hrc=%#x / size=%zu\n", hrc, val));
     1106    hrc = hv_gic_get_msi_region_base_alignment(&val);
     1107    LogRel(("GICNem: hv_gic_get_msi_region_base_alignment()             -> hrc=%#x / size=%zu\n", hrc, val));
     1108    hrc = hv_gic_get_msi_region_size(&val);
     1109    LogRel(("GICNem: hv_gic_get_msi_region_size()                       -> hrc=%#x / size=%zu\n", hrc, val));
     1110    uint32_t u32SpiIntIdBase = 0;
     1111    uint32_t cSpiIntIds = 0;
     1112    hrc = hv_gic_get_spi_interrupt_range(&u32SpiIntIdBase, &cSpiIntIds);
     1113    LogRel(("GICNem: hv_gic_get_spi_interrupt_range()                   -> hrc=%#x / SpiIntIdBase=%u, cSpiIntIds=%u\n", hrc, u32SpiIntIdBase, cSpiIntIds));
     1114
     1115    uint32_t u32IntId = 0;
     1116    hrc = hv_gic_get_intid(HV_GIC_INT_EL1_PHYSICAL_TIMER, &u32IntId);
     1117    LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_EL1_PHYSICAL_TIMER)    -> hrc=%#x / IntId=%u\n", hrc, u32IntId));
     1118    hrc = hv_gic_get_intid(HV_GIC_INT_EL1_VIRTUAL_TIMER, &u32IntId);
     1119    LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_EL1_VIRTUAL_TIMER)     -> hrc=%#x / IntId=%u\n", hrc, u32IntId));
     1120    hrc = hv_gic_get_intid(HV_GIC_INT_EL2_PHYSICAL_TIMER, &u32IntId);
     1121    LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_EL2_PHYSICAL_TIMER)    -> hrc=%#x / IntId=%u\n", hrc, u32IntId));
     1122    hrc = hv_gic_get_intid(HV_GIC_INT_MAINTENANCE, &u32IntId);
     1123    LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_MAINTENANCE)           -> hrc=%#x / IntId=%u\n", hrc, u32IntId));
     1124    hrc = hv_gic_get_intid(HV_GIC_INT_PERFORMANCE_MONITOR, &u32IntId);
     1125    LogRel(("GICNem: hv_gic_get_intid(HV_GIC_INT_PERFORMANCE_MONITOR)   -> hrc=%#x / IntId=%u\n", hrc, u32IntId));
     1126}
     1127
     1128
     1129/**
     1130 * Sets the given SPI inside the in-kernel KVM GIC.
     1131 *
     1132 * @returns VBox status code.
     1133 * @param   pVM         The VM instance.
     1134 * @param   uIntId      The SPI ID to update.
     1135 * @param   fAsserted   Flag whether the interrupt is asserted (true) or not (false).
     1136 */
     1137VMMR3_INT_DECL(int) GICR3NemSpiSet(PVMCC pVM, uint32_t uIntId, bool fAsserted)
     1138{
     1139    RT_NOREF(pVM);
     1140    Assert(hv_gic_set_spi);
     1141
     1142    hv_return_t hrc = hv_gic_set_spi(uIntId + GIC_INTID_RANGE_SPI_START, fAsserted);
     1143    return nemR3DarwinHvSts2Rc(hrc);
     1144}
     1145
     1146
     1147/**
     1148 * Sets the given PPI inside the in-kernel KVM GIC.
     1149 *
     1150 * @returns VBox status code.
     1151 * @param   pVCpu       The vCPU for whih the PPI state is updated.
     1152 * @param   uIntId      The PPI ID to update.
     1153 * @param   fAsserted   Flag whether the interrupt is asserted (true) or not (false).
     1154 */
     1155VMMR3_INT_DECL(int) GICR3NemPpiSet(PVMCPUCC pVCpu, uint32_t uIntId, bool fAsserted)
     1156{
     1157    RT_NOREF(pVCpu, uIntId, fAsserted);
     1158
     1159    /* Should never be called as the PPIs are handled entirely in Hypervisor.framework/AppleHV. */
     1160    AssertFailed();
     1161    return VERR_NEM_IPE_9;
     1162}
     1163
     1164
     1165static int nemR3DarwinGicCreate(PVM pVM)
     1166{
     1167    nemR3DarwinDumpGicInfo();
     1168
     1169    //PCFGMNODE pGicDev = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices/gic/0");
     1170    PCFGMNODE pGicCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "Devices/gic-nem/0/Config");
     1171
     1172    hv_gic_config_t hGicCfg = hv_gic_config_create();
     1173
     1174    /*
     1175     * Query the MMIO ranges.
     1176     */
     1177    RTGCPHYS GCPhysMmioBaseDist = 0;
     1178    int rc = CFGMR3QueryU64(pGicCfg, "DistributorMmioBase", &GCPhysMmioBaseDist);
     1179    if (RT_FAILURE(rc))
     1180        return VMSetError(pVM, rc, RT_SRC_POS,
     1181                          "Configuration error: Failed to get the \"DistributorMmioBase\" value\n");
     1182
     1183    RTGCPHYS GCPhysMmioBaseReDist = 0;
     1184    rc = CFGMR3QueryU64(pGicCfg, "RedistributorMmioBase", &GCPhysMmioBaseReDist);
     1185    if (RT_FAILURE(rc))
     1186        return VMSetError(pVM, rc, RT_SRC_POS,
     1187                          "Configuration error: Failed to get the \"RedistributorMmioBase\" value\n");
     1188
     1189    hv_return_t hrc = hv_gic_config_set_distributor_base(hGicCfg, GCPhysMmioBaseDist);
     1190    if (hrc != HV_SUCCESS)
     1191        return nemR3DarwinHvSts2Rc(hrc);
     1192
     1193    hrc = hv_gic_config_set_redistributor_base(hGicCfg, GCPhysMmioBaseReDist);
     1194    if (hrc != HV_SUCCESS)
     1195        return nemR3DarwinHvSts2Rc(hrc);
     1196
     1197    hrc = hv_gic_create(hGicCfg);
     1198    os_release(hGicCfg);
     1199    if (hrc != HV_SUCCESS)
     1200        return nemR3DarwinHvSts2Rc(hrc);
     1201
     1202    /* Make sure the device is not instantiated as Hypervisor.framework provides it. */
     1203    //CFGMR3RemoveNode(pGicDev);
     1204    return rc;
    7241205}
    7251206
     
    7551236    PRTERRINFO pErrInfo = RTErrInfoInitStatic(&ErrInfo);
    7561237
    757     int rc = VINF_SUCCESS;
    758     hv_return_t hrc = hv_vm_create(NULL);
     1238    /* Resolve optional imports */
     1239    int rc = nemR3DarwinLoadHv(pErrInfo);
     1240    if (RT_FAILURE(rc))
     1241        return rc;
     1242
     1243    /*
     1244     * Need to enable nested virt here if supported and reset the CFGM value to false
     1245     * if not supported. This ASSUMES that NEM is initialized before CPUM.
     1246     */
     1247    PCFGMNODE pCfgCpum = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM/");
     1248    hv_vm_config_t hVmCfg = hv_vm_config_create();
     1249
     1250    if (hv_vm_config_get_el2_supported)
     1251    {
     1252        bool fHvEl2Supported = false;
     1253        hv_return_t hrc = hv_vm_config_get_el2_supported(&fHvEl2Supported);
     1254        if (   hrc == HV_SUCCESS
     1255            && fHvEl2Supported)
     1256        {
     1257            /** @cfgm{/CPUM/NestedHWVirt, bool, false}
     1258             * Whether to expose the hardware virtualization (EL2/VHE) feature to the guest.
     1259             * The default is false. Only supported on M3 and later and macOS 15.0+ (Sonoma).
     1260             */
     1261            bool fNestedHWVirt = false;
     1262            rc = CFGMR3QueryBoolDef(pCfgCpum, "NestedHWVirt", &fNestedHWVirt, false);
     1263            AssertLogRelRCReturn(rc, rc);
     1264            if (fNestedHWVirt)
     1265            {
     1266                hrc = hv_vm_config_set_el2_enabled(hVmCfg, fNestedHWVirt);
     1267                if (hrc != HV_SUCCESS)
     1268                    return VMSetError(pVM, VERR_CPUM_INVALID_HWVIRT_CONFIG, RT_SRC_POS,
     1269                                      "Cannot enable nested virtualization (hrc=%#x)!\n", hrc);
     1270                else
     1271                {
     1272                    pVM->nem.s.fEl2Enabled = true;
     1273                    LogRel(("NEM: Enabled nested virtualization (EL2) support\n"));
     1274                }
     1275            }
     1276        }
     1277        else
     1278        {
     1279            /* Ensure nested virt is not set. */
     1280            rc = CFGMR3RemoveValue(pCfgCpum, "NestedHWVirt");
     1281
     1282            LogRel(("NEM: The host doesn't supported nested virtualization! (hrc=%#x fHvEl2Supported=%RTbool)\n",
     1283                    hrc, fHvEl2Supported));
     1284        }
     1285    }
     1286    else
     1287    {
     1288        /* Ensure nested virt is not set. */
     1289        rc = CFGMR3RemoveValue(pCfgCpum, "NestedHWVirt");
     1290        LogRel(("NEM: Hypervisor.framework doesn't supported nested virtualization!\n"));
     1291    }
     1292
     1293    hv_return_t hrc = hv_vm_create(hVmCfg);
     1294    os_release(hVmCfg);
    7591295    if (hrc == HV_SUCCESS)
    7601296    {
     
    7811317        return VMSetError(pVM, RT_SUCCESS_NP(rc) ? VERR_NEM_NOT_AVAILABLE : rc, RT_SRC_POS, "%s", pErrInfo->pszMsg);
    7821318
    783 if (RTErrInfoIsSet(pErrInfo))
     1319    if (RTErrInfoIsSet(pErrInfo))
    7841320        LogRel(("NEM: Not available: %s\n", pErrInfo->pszMsg));
    7851321    return VINF_SUCCESS;
     
    8711407    AssertReturn(!pVM->nem.s.fCreatedEmts, VERR_WRONG_ORDER);
    8721408    AssertReturn(pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API, VERR_WRONG_ORDER);
     1409
     1410    /* Need to create the GIC here before any vCPU is created according to the Apple docs. */
     1411    if (hv_gic_create)
     1412    {
     1413        int rc = nemR3DarwinGicCreate(pVM);
     1414        if (RT_FAILURE(rc))
     1415            return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, "Creating the GIC failed: %Rrc", rc);
     1416    }
    8731417
    8741418    /*
     
    12091753 * @param   uIss            The instruction specific syndrome value.
    12101754 */
    1211 static VBOXSTRICTRC nemR3DarwinHandleExitExceptionTrappedHvcInsn(PVM pVM, PVMCPU pVCpu, uint32_t uIss)
     1755static VBOXSTRICTRC nemR3DarwinHandleExitExceptionTrappedHvcInsn(PVM pVM, PVMCPU pVCpu, uint32_t uIss, bool fAdvancePc = false)
    12121756{
    12131757    uint16_t u16Imm = ARMV8_EC_ISS_AARCH64_TRAPPED_HVC_INSN_IMM_GET(uIss);
     
    12781822                        case ARM_PSCI_FUNC_ID_SYSTEM_RESET2:
    12791823                        case ARM_PSCI_FUNC_ID_CPU_ON:
     1824                        case ARM_PSCI_FUNC_ID_MIGRATE_INFO_TYPE:
    12801825                            nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0,
    12811826                                               false /*f64BitReg*/, false /*fSignExtend*/,
     
    12891834                    break;
    12901835                }
     1836                case ARM_PSCI_FUNC_ID_MIGRATE_INFO_TYPE:
     1837                    nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, false /*f64BitReg*/, false /*fSignExtend*/, ARM_PSCI_MIGRATE_INFO_TYPE_TOS_NOT_PRESENT);
     1838                    break;
    12911839                default:
    12921840                    nemR3DarwinSetGReg(pVCpu, ARMV8_AARCH64_REG_X0, false /*f64BitReg*/, false /*fSignExtend*/, (uint64_t)ARM_PSCI_STS_NOT_SUPPORTED);
     
    12971845    }
    12981846    /** @todo What to do if immediate is != 0? */
     1847
     1848    if (   rcStrict == VINF_SUCCESS
     1849        && fAdvancePc)
     1850        pVCpu->cpum.GstCtx.Pc.u64 += sizeof(uint32_t);
    12991851
    13001852    return rcStrict;
     
    13291881        case ARMV8_ESR_EL2_EC_AARCH64_HVC_INSN:
    13301882            return nemR3DarwinHandleExitExceptionTrappedHvcInsn(pVM, pVCpu, uIss);
     1883        case ARMV8_ESR_EL2_EC_AARCH64_SMC_INSN:
     1884            return nemR3DarwinHandleExitExceptionTrappedHvcInsn(pVM, pVCpu, uIss, true);
    13311885        case ARMV8_ESR_EL2_EC_TRAPPED_WFX:
    13321886        {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette