VirtualBox

Changeset 79202 in vbox


Ignore:
Timestamp:
Jun 18, 2019 9:13:29 AM (5 years ago)
Author:
vboxsync
Message:

VMM: Nested VMX: bugref:9180 VMCS shadowing, work in progress.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/hm_vmx.h

    r79195 r79202  
    466466/**
    467467 * EPT Page Directory Pointer Entry. Bit view.
     468 * In accordance with the VT-x spec.
     469 *
    468470 * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC,
    469471 *       this did cause trouble with one compiler/version).
     
    497499/**
    498500 * EPT PML4E.
     501 * In accordance with the VT-x spec.
    499502 */
    500503typedef union EPTPML4E
     
    517520/**
    518521 * EPT PML4 Table.
     522 * In accordance with the VT-x spec.
    519523 */
    520524typedef struct EPTPML4
     
    530534/**
    531535 * EPT Page Directory Pointer Entry. Bit view.
     536 * In accordance with the VT-x spec.
    532537 */
    533538typedef struct EPTPDPTEBITS
     
    559564/**
    560565 * EPT Page Directory Pointer.
     566 * In accordance with the VT-x spec.
    561567 */
    562568typedef union EPTPDPTE
     
    579585/**
    580586 * EPT Page Directory Pointer Table.
     587 * In accordance with the VT-x spec.
    581588 */
    582589typedef struct EPTPDPT
     
    592599/**
    593600 * EPT Page Directory Table Entry. Bit view.
     601 * In accordance with the VT-x spec.
    594602 */
    595603typedef struct EPTPDEBITS
     
    623631/**
    624632 * EPT 2MB Page Directory Table Entry. Bit view.
     633 * In accordance with the VT-x spec.
    625634 */
    626635typedef struct EPTPDE2MBITS
     
    654663/**
    655664 * EPT Page Directory Table Entry.
     665 * In accordance with the VT-x spec.
    656666 */
    657667typedef union EPTPDE
     
    676686/**
    677687 * EPT Page Directory Table.
     688 * In accordance with the VT-x spec.
    678689 */
    679690typedef struct EPTPD
     
    689700/**
    690701 * EPT Page Table Entry. Bit view.
     702 * In accordance with the VT-x spec.
    691703 */
    692704typedef struct EPTPTEBITS
     
    725737/**
    726738 * EPT Page Table Entry.
     739 * In accordance with the VT-x spec.
    727740 */
    728741typedef union EPTPTE
     
    745758/**
    746759 * EPT Page Table.
     760 * In accordance with the VT-x spec.
    747761 */
    748762typedef struct EPTPT
     
    816830/**
    817831 * VMX VMCS revision identifier.
     832 * In accordance with the VT-x spec.
    818833 */
    819834typedef union
     
    837852/**
    838853 * VMX VM-exit instruction information.
     854 * In accordance with the VT-x spec.
    839855 */
    840856typedef union
     
    11261142/**
    11271143 * VMX controls MSR.
     1144 * In accordance with the VT-x spec.
    11281145 */
    11291146typedef union
     
    13511368
    13521369/** @name VM Instruction Errors.
     1370 * In accordance with the VT-x spec.
    13531371 * See Intel spec. "30.4 VM Instruction Error Numbers"
    13541372 * @{
     
    14131431
    14141432/** @name VMX abort reasons.
     1433 * In accordance with the VT-x spec.
    14151434 * See Intel spec. "27.7 VMX Aborts".
    14161435 * Update HMGetVmxAbortDesc() if new reasons are added. @{
     
    16931712
    16941713
    1695 /** @name VMCS field encoding: 16-bit control fields.
    1696  * @{
    1697  */
     1714/** @name VMCS fields and encoding.
     1715 *
     1716 *  When adding a new field:
     1717 *    - Always add it to g_aVmcsFields.
     1718 *    - Consider if it needs to be added to VMXVVMCS.
     1719 * @{
     1720 */
     1721/** 16-bit control fields.  */
    16981722#define VMX_VMCS16_VPID                                         0x0000
    16991723#define VMX_VMCS16_POSTED_INT_NOTIFY_VECTOR                     0x0002
    17001724#define VMX_VMCS16_EPTP_INDEX                                   0x0004
    1701 /** @} */
    1702 
    1703 
    1704 /** @name VMCS field encoding: 16-bit guest-state fields.
    1705  * @{
    1706  */
     1725
     1726/** 16-bit guest-state fields.  */
    17071727#define VMX_VMCS16_GUEST_ES_SEL                                 0x0800
    17081728#define VMX_VMCS16_GUEST_CS_SEL                                 0x0802
     
    17151735#define VMX_VMCS16_GUEST_INTR_STATUS                            0x0810
    17161736#define VMX_VMCS16_GUEST_PML_INDEX                              0x0812
    1717 /** @} */
    1718 
    1719 
    1720 /** @name VMCS field encoding: 16-bits host-state fields.
    1721  * @{
    1722  */
     1737
     1738/** 16-bits host-state fields.  */
    17231739#define VMX_VMCS16_HOST_ES_SEL                                  0x0c00
    17241740#define VMX_VMCS16_HOST_CS_SEL                                  0x0c02
     
    17281744#define VMX_VMCS16_HOST_GS_SEL                                  0x0c0a
    17291745#define VMX_VMCS16_HOST_TR_SEL                                  0x0c0c
    1730 /** @} */
    1731 
    1732 
    1733 /** @name VMCS field encoding: 64-bit control fields.
    1734  * @{
    1735  */
     1746
     1747/** 64-bit control fields. */
    17361748#define VMX_VMCS64_CTRL_IO_BITMAP_A_FULL                        0x2000
    17371749#define VMX_VMCS64_CTRL_IO_BITMAP_A_HIGH                        0x2001
     
    17841796#define VMX_VMCS64_CTRL_TSC_MULTIPLIER_FULL                     0x2032
    17851797#define VMX_VMCS64_CTRL_TSC_MULTIPLIER_HIGH                     0x2033
    1786 /** @} */
    1787 
    1788 
    1789 /** @name VMCS field encoding: 64-bit read-only data fields.
    1790  * @{
    1791  */
     1798
     1799/** 64-bit read-only data fields.  */
    17921800#define VMX_VMCS64_RO_GUEST_PHYS_ADDR_FULL                      0x2400
    17931801#define VMX_VMCS64_RO_GUEST_PHYS_ADDR_HIGH                      0x2401
    1794 /** @} */
    1795 
    1796 
    1797 /** @name VMCS field encoding: 64-bit guest-state fields.
    1798  * @{
    1799  */
     1802
     1803/** 64-bit guest-state fields.  */
    18001804#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_FULL                     0x2800
    18011805#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_HIGH                     0x2801
     
    18181822#define VMX_VMCS64_GUEST_BNDCFGS_FULL                           0x2812
    18191823#define VMX_VMCS64_GUEST_BNDCFGS_HIGH                           0x2813
    1820 /** @} */
    1821 
    1822 
    1823 /** @name VMCS field encoding: 64-bit host-state fields.
    1824  * @{
    1825  */
     1824
     1825/** 64-bit host-state fields.  */
    18261826#define VMX_VMCS64_HOST_PAT_FULL                                0x2c00
    18271827#define VMX_VMCS64_HOST_PAT_HIGH                                0x2c01
     
    18301830#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_FULL                   0x2c04
    18311831#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_HIGH                   0x2c05
    1832 /** @} */
    1833 
    1834 
    1835 /** @name VMCS field encoding: 32-bit control fields.
    1836  * @{
    1837  */
     1832
     1833/** 32-bit control fields.  */
    18381834#define VMX_VMCS32_CTRL_PIN_EXEC                                0x4000
    18391835#define VMX_VMCS32_CTRL_PROC_EXEC                               0x4002
     
    18541850#define VMX_VMCS32_CTRL_PLE_GAP                                 0x4020
    18551851#define VMX_VMCS32_CTRL_PLE_WINDOW                              0x4022
    1856 /** @} */
    1857 
    1858 
    1859 /** @name VMCS field encoding: 32-bits read-only fields.
    1860  * @{
    1861  */
     1852
     1853/** 32-bits read-only fields. */
    18621854#define VMX_VMCS32_RO_VM_INSTR_ERROR                            0x4400
    18631855#define VMX_VMCS32_RO_EXIT_REASON                               0x4402
     
    18681860#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH                         0x440c
    18691861#define VMX_VMCS32_RO_EXIT_INSTR_INFO                           0x440e
    1870 /** @} */
    1871 
    1872 
    1873 /** @name VMCS field encoding: 32-bit guest-state fields.
    1874  * @{
    1875  */
     1862
     1863/** 32-bit guest-state fields. */
    18761864#define VMX_VMCS32_GUEST_ES_LIMIT                               0x4800
    18771865#define VMX_VMCS32_GUEST_CS_LIMIT                               0x4802
     
    18971885#define VMX_VMCS32_GUEST_SYSENTER_CS                            0x482a
    18981886#define VMX_VMCS32_PREEMPT_TIMER_VALUE                          0x482e
    1899 /** @} */
    1900 
    1901 
    1902 /** @name VMCS field encoding: 32-bit host-state fields.
    1903  * @{
    1904  */
     1887
     1888/** 32-bit host-state fields. */
    19051889#define VMX_VMCS32_HOST_SYSENTER_CS                             0x4C00
    1906 /** @} */
    1907 
    1908 
    1909 /** @name VMCS field encoding: Natural-width control fields.
    1910  * @{
    1911  */
     1890
     1891/** Natural-width control fields.  */
    19121892#define VMX_VMCS_CTRL_CR0_MASK                                  0x6000
    19131893#define VMX_VMCS_CTRL_CR4_MASK                                  0x6002
     
    19181898#define VMX_VMCS_CTRL_CR3_TARGET_VAL2                           0x600c
    19191899#define VMX_VMCS_CTRL_CR3_TARGET_VAL3                           0x600e
    1920 /** @} */
    1921 
    1922 
    1923 /** @name Natural-width read-only data fields.
    1924  * @{
    1925  */
     1900
     1901/** Natural-width read-only data fields. */
    19261902#define VMX_VMCS_RO_EXIT_QUALIFICATION                          0x6400
    19271903#define VMX_VMCS_RO_IO_RCX                                      0x6402
     
    19301906#define VMX_VMCS_RO_IO_RIP                                      0x6408
    19311907#define VMX_VMCS_RO_GUEST_LINEAR_ADDR                           0x640a
    1932 /** @} */
    1933 
    1934 
    1935 /** @name VMCS field encoding: Natural-width guest-state fields.
    1936  * @{
    1937  */
     1908
     1909/** Natural-width guest-state fields. */
    19381910#define VMX_VMCS_GUEST_CR0                                      0x6800
    19391911#define VMX_VMCS_GUEST_CR3                                      0x6802
     
    19561928#define VMX_VMCS_GUEST_SYSENTER_ESP                             0x6824
    19571929#define VMX_VMCS_GUEST_SYSENTER_EIP                             0x6826
    1958 /** @} */
    1959 
    1960 
    1961 /** @name VMCS field encoding: Natural-width host-state fields.
    1962  * @{
    1963  */
     1930
     1931/** Natural-width host-state fields. */
    19641932#define VMX_VMCS_HOST_CR0                                       0x6c00
    19651933#define VMX_VMCS_HOST_CR3                                       0x6c02
     
    19741942#define VMX_VMCS_HOST_RSP                                       0x6c14
    19751943#define VMX_VMCS_HOST_RIP                                       0x6c16
    1976 /** @} */
    1977 
    1978 
    1979 /** @name VMCS field encoding: Access.
    1980  * @{ */
    1981 typedef enum
    1982 {
    1983     VMXVMCSFIELDACCESS_FULL = 0,
    1984     VMXVMCSFIELDACCESS_HIGH
    1985 } VMXVMCSFIELDACCESS;
    1986 AssertCompileSize(VMXVMCSFIELDACCESS, 4);
    1987 
    1988 /** VMCS field encoding type: Full. */
    1989 #define VMX_VMCS_ENC_ACCESS_TYPE_FULL                           0
    1990 /** VMCS field encoding type: High. */
    1991 #define VMX_VMCS_ENC_ACCESS_TYPE_HIGH                           1
    1992 /** @} */
    1993 
    1994 
    1995 /** @name VMCS field encoding: Type.
    1996  * @{ */
    1997 typedef enum
    1998 {
    1999     VMXVMCSFIELDTYPE_CONTROL = 0,
    2000     VMXVMCSFIELDTYPE_VMEXIT_INFO,
    2001     VMXVMCSFIELDTYPE_GUEST_STATE,
    2002     VMXVMCSFIELDTYPE_HOST_STATE
    2003 } VMXVMCSFIELDTYPE;
    2004 AssertCompileSize(VMXVMCSFIELDTYPE, 4);
    2005 
    2006 /** VMCS field encoding type: Control. */
    2007 #define VMX_VMCS_ENC_TYPE_CONTROL                               0
    2008 /** VMCS field encoding type: VM-exit information / read-only fields. */
    2009 #define VMX_VMCS_ENC_TYPE_VMEXIT_INFO                           1
    2010 /** VMCS field encoding type: Guest-state. */
    2011 #define VMX_VMCS_ENC_TYPE_GUEST_STATE                           2
    2012 /** VMCS field encoding type: Host-state. */
    2013 #define VMX_VMCS_ENC_TYPE_HOST_STATE                            3
    2014 /** @} */
    2015 
    2016 
    2017 /** @name VMCS field encoding: Width.
    2018  * @{ */
    2019 typedef enum
    2020 {
    2021     VMXVMCSFIELDWIDTH_16BIT = 0,
    2022     VMXVMCSFIELDWIDTH_64BIT,
    2023     VMXVMCSFIELDWIDTH_32BIT,
    2024     VMXVMCSFIELDWIDTH_NATURAL
    2025 } VMXVMCSFIELDWIDTH;
    2026 AssertCompileSize(VMXVMCSFIELDWIDTH, 4);
    2027 
    2028 /** VMCS field encoding width: 16-bit. */
    2029 #define VMX_VMCS_ENC_WIDTH_16BIT                                0
    2030 /** VMCS field encoding width: 64-bit. */
    2031 #define VMX_VMCS_ENC_WIDTH_64BIT                                1
    2032 /** VMCS field encoding width: 32-bit. */
    2033 #define VMX_VMCS_ENC_WIDTH_32BIT                                2
    2034 /** VMCS field encoding width: Natural width. */
    2035 #define VMX_VMCS_ENC_WIDTH_NATURAL                              3
    2036 /** @} */
    2037 
    2038 
    2039 /** @name VMCS field.
    2040  * @{ */
     1944
     1945/**
     1946 * VMCS field.
     1947 * In accordance with the VT-x spec.
     1948 */
    20411949typedef union
    20421950{
     
    20611969} VMXVMCSFIELD;
    20621970AssertCompileSize(VMXVMCSFIELD, 4);
    2063 /** Pointer to a VMCS field encoding. */
     1971/** Pointer to a VMCS field. */
    20641972typedef VMXVMCSFIELD *PVMXVMCSFIELD;
    2065 /** Pointer to a const VMCS field encoding. */
     1973/** Pointer to a const VMCS field. */
    20661974typedef const VMXVMCSFIELD *PCVMXVMCSFIELD;
    20671975
    2068 /** VMCS field encoding: Mask of reserved bits (bits 63:15 MBZ), bit 12 is
    2069  *  not included! */
    2070 #define VMX_VMCS_ENC_RSVD_MASK                                  UINT64_C(0xffffffffffff8000)
    2071 
    2072 /** Bits fields for VMCS field encoding. */
    2073 #define VMX_BF_VMCS_ENC_ACCESS_TYPE_SHIFT                       0
    2074 #define VMX_BF_VMCS_ENC_ACCESS_TYPE_MASK                        UINT32_C(0x00000001)
    2075 #define VMX_BF_VMCS_ENC_INDEX_SHIFT                             1
    2076 #define VMX_BF_VMCS_ENC_INDEX_MASK                              UINT32_C(0x000003fe)
    2077 #define VMX_BF_VMCS_ENC_TYPE_SHIFT                              10
    2078 #define VMX_BF_VMCS_ENC_TYPE_MASK                               UINT32_C(0x00000c00)
    2079 #define VMX_BF_VMCS_ENC_RSVD_12_SHIFT                           12
    2080 #define VMX_BF_VMCS_ENC_RSVD_12_MASK                            UINT32_C(0x00001000)
    2081 #define VMX_BF_VMCS_ENC_WIDTH_SHIFT                             13
    2082 #define VMX_BF_VMCS_ENC_WIDTH_MASK                              UINT32_C(0x00006000)
    2083 #define VMX_BF_VMCS_ENC_RSVD_15_31_SHIFT                        15
    2084 #define VMX_BF_VMCS_ENC_RSVD_15_31_MASK                         UINT32_C(0xffff8000)
    2085 RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_VMCS_ENC_, UINT32_C(0), UINT32_MAX,
     1976/** VMCS field: Mask of reserved bits (bits 63:15 MBZ), bit 12 is not included! */
     1977#define VMX_VMCSFIELD_RSVD_MASK                                 UINT64_C(0xffffffffffff8000)
     1978
     1979/** Bits fields for a VMCS field. */
     1980#define VMX_BF_VMCSFIELD_ACCESS_TYPE_SHIFT                      0
     1981#define VMX_BF_VMCSFIELD_ACCESS_TYPE_MASK                       UINT32_C(0x00000001)
     1982#define VMX_BF_VMCSFIELD_INDEX_SHIFT                            1
     1983#define VMX_BF_VMCSFIELD_INDEX_MASK                             UINT32_C(0x000003fe)
     1984#define VMX_BF_VMCSFIELD_TYPE_SHIFT                             10
     1985#define VMX_BF_VMCSFIELD_TYPE_MASK                              UINT32_C(0x00000c00)
     1986#define VMX_BF_VMCSFIELD_RSVD_12_SHIFT                          12
     1987#define VMX_BF_VMCSFIELD_RSVD_12_MASK                           UINT32_C(0x00001000)
     1988#define VMX_BF_VMCSFIELD_WIDTH_SHIFT                            13
     1989#define VMX_BF_VMCSFIELD_WIDTH_MASK                             UINT32_C(0x00006000)
     1990#define VMX_BF_VMCSFIELD_RSVD_15_31_SHIFT                       15
     1991#define VMX_BF_VMCSFIELD_RSVD_15_31_MASK                        UINT32_C(0xffff8000)
     1992RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_VMCSFIELD_, UINT32_C(0), UINT32_MAX,
    20861993                            (ACCESS_TYPE, INDEX, TYPE, RSVD_12, WIDTH, RSVD_15_31));
     1994
     1995/**
     1996 * VMCS field encoding: Access type.
     1997 * In accordance with the VT-x spec.
     1998 */
     1999typedef enum
     2000{
     2001    VMXVMCSFIELDACCESS_FULL = 0,
     2002    VMXVMCSFIELDACCESS_HIGH
     2003} VMXVMCSFIELDACCESS;
     2004AssertCompileSize(VMXVMCSFIELDACCESS, 4);
     2005/** VMCS field encoding type: Full. */
     2006#define VMX_VMCSFIELD_ACCESS_FULL                               0
     2007/** VMCS field encoding type: High. */
     2008#define VMX_VMCSFIELD_ACCESS_HIGH                               1
     2009
     2010/**
     2011 * VMCS field encoding: Type.
     2012 * In accordance with the VT-x spec.
     2013 */
     2014typedef enum
     2015{
     2016    VMXVMCSFIELDTYPE_CONTROL = 0,
     2017    VMXVMCSFIELDTYPE_VMEXIT_INFO,
     2018    VMXVMCSFIELDTYPE_GUEST_STATE,
     2019    VMXVMCSFIELDTYPE_HOST_STATE
     2020} VMXVMCSFIELDTYPE;
     2021AssertCompileSize(VMXVMCSFIELDTYPE, 4);
     2022/** VMCS field encoding type: Control. */
     2023#define VMX_VMCSFIELD_TYPE_CONTROL                              0
     2024/** VMCS field encoding type: VM-exit information / read-only fields. */
     2025#define VMX_VMCSFIELD_TYPE_VMEXIT_INFO                          1
     2026/** VMCS field encoding type: Guest-state. */
     2027#define VMX_VMCSFIELD_TYPE_GUEST_STATE                          2
     2028/** VMCS field encoding type: Host-state. */
     2029#define VMX_VMCSFIELD_TYPE_HOST_STATE                           3
     2030
     2031/**
     2032 * VMCS field encoding: Width.
     2033 * In accordance with the VT-x spec.
     2034 */
     2035typedef enum
     2036{
     2037    VMXVMCSFIELDWIDTH_16BIT = 0,
     2038    VMXVMCSFIELDWIDTH_64BIT,
     2039    VMXVMCSFIELDWIDTH_32BIT,
     2040    VMXVMCSFIELDWIDTH_NATURAL
     2041} VMXVMCSFIELDWIDTH;
     2042AssertCompileSize(VMXVMCSFIELDWIDTH, 4);
     2043/** VMCS field encoding width: 16-bit. */
     2044#define VMX_VMCSFIELD_WIDTH_16BIT                               0
     2045/** VMCS field encoding width: 64-bit. */
     2046#define VMX_VMCSFIELD_WIDTH_64BIT                               1
     2047/** VMCS field encoding width: 32-bit. */
     2048#define VMX_VMCSFIELD_WIDTH_32BIT                               2
     2049/** VMCS field encoding width: Natural width. */
     2050#define VMX_VMCSFIELD_WIDTH_NATURAL                             3
    20872051/** @} */
    20882052
     
    31113075/**
    31123076 * APIC-access type.
     3077 * In accordance with the VT-x spec.
    31133078 */
    31143079typedef enum
     
    33853350
    33863351/** The highest index value used for supported virtual VMCS field encoding. */
    3387 #define VMX_V_VMCS_MAX_INDEX                                    RT_BF_GET(VMX_VMCS64_CTRL_TSC_MULTIPLIER_HIGH, VMX_BF_VMCS_ENC_INDEX)
     3352#define VMX_V_VMCS_MAX_INDEX                                    RT_BF_GET(VMX_VMCS64_CTRL_TSC_MULTIPLIER_HIGH, VMX_BF_VMCSFIELD_INDEX)
    33883353
    33893354/**
     
    34723437 *
    34733438 * Note! Any fields that are added or modified here, make sure to update the
    3474  *       corresponding fields in g_aoffVmcsMap in IEM.
     3439 *       corresponding fields in IEM (g_aoffVmcsMap), the corresponding saved
     3440 *       state structure in CPUM (g_aVmxHwvirtVmcs) and bump the SSM version.
    34753441 */
    34763442#pragma pack(1)
  • trunk/include/VBox/vmm/hmvmxinline.h

    r78220 r79202  
    8484 * @param   uFieldEnc   The VMCS field encoding.
    8585 *
    86  * @remarks Warning! This function does not verify the encoding is for a valid and
    87  *          supported VMCS field.
     86 * @remarks Warning! This function does not verify that the encoding is for a valid
     87 *          and/or supported VMCS field.
    8888 */
    8989DECLINLINE(bool) HMVmxIsVmcsFieldReadOnly(uint32_t uFieldEnc)
    9090{
    9191    /* See Intel spec. B.4.2 "Natural-Width Read-Only Data Fields". */
    92     return (RT_BF_GET(uFieldEnc, VMX_BF_VMCS_ENC_TYPE) == VMXVMCSFIELDTYPE_VMEXIT_INFO);
     92    return (RT_BF_GET(uFieldEnc, VMX_BF_VMCSFIELD_TYPE) == VMXVMCSFIELDTYPE_VMEXIT_INFO);
    9393}
    9494
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r79194 r79202  
    36073607     * encoding (i.e. bit 12).
    36083608     */
    3609     if (u64FieldEnc & VMX_VMCS_ENC_RSVD_MASK)
     3609    if (u64FieldEnc & VMX_VMCSFIELD_RSVD_MASK)
    36103610        return true;
    36113611
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r79167 r79202  
    2525#include <iprt/asm-amd64-x86.h>
    2626#include <iprt/thread.h>
     27#include <iprt/mem.h>
    2728
    2829#include <VBox/vmm/pdmapi.h>
     
    489490*   Global Variables                                                                                                             *
    490491*********************************************************************************************************************************/
     492#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     493/**
     494 * Array of all VMCS fields.
     495 * Any fields added to the VT-x spec. should be added here.
     496 *
     497 * Currently only used to derive shadow VMCS fields for hardware-assisted execution
     498 * of nested-guests.
     499 */
     500static const uint32_t g_aVmcsFields[] =
     501{
     502    /* 16-bit control fields. */
     503    VMX_VMCS16_VPID,
     504    VMX_VMCS16_POSTED_INT_NOTIFY_VECTOR,
     505    VMX_VMCS16_EPTP_INDEX,
     506
     507    /* 16-bit guest-state fields. */
     508    VMX_VMCS16_GUEST_ES_SEL,
     509    VMX_VMCS16_GUEST_CS_SEL,
     510    VMX_VMCS16_GUEST_SS_SEL,
     511    VMX_VMCS16_GUEST_DS_SEL,
     512    VMX_VMCS16_GUEST_FS_SEL,
     513    VMX_VMCS16_GUEST_GS_SEL,
     514    VMX_VMCS16_GUEST_LDTR_SEL,
     515    VMX_VMCS16_GUEST_TR_SEL,
     516    VMX_VMCS16_GUEST_INTR_STATUS,
     517    VMX_VMCS16_GUEST_PML_INDEX,
     518
     519    /* 16-bits host-state fields. */
     520    VMX_VMCS16_HOST_ES_SEL,
     521    VMX_VMCS16_HOST_CS_SEL,
     522    VMX_VMCS16_HOST_SS_SEL,
     523    VMX_VMCS16_HOST_DS_SEL,
     524    VMX_VMCS16_HOST_FS_SEL,
     525    VMX_VMCS16_HOST_GS_SEL,
     526    VMX_VMCS16_HOST_TR_SEL,
     527
     528    /* 64-bit control fields. */
     529    VMX_VMCS64_CTRL_IO_BITMAP_A_FULL,
     530    VMX_VMCS64_CTRL_IO_BITMAP_A_HIGH,
     531    VMX_VMCS64_CTRL_IO_BITMAP_B_FULL,
     532    VMX_VMCS64_CTRL_IO_BITMAP_B_HIGH,
     533    VMX_VMCS64_CTRL_MSR_BITMAP_FULL,
     534    VMX_VMCS64_CTRL_MSR_BITMAP_HIGH,
     535    VMX_VMCS64_CTRL_EXIT_MSR_STORE_FULL,
     536    VMX_VMCS64_CTRL_EXIT_MSR_STORE_HIGH,
     537    VMX_VMCS64_CTRL_EXIT_MSR_LOAD_FULL,
     538    VMX_VMCS64_CTRL_EXIT_MSR_LOAD_HIGH,
     539    VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_FULL,
     540    VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_HIGH,
     541    VMX_VMCS64_CTRL_EXEC_VMCS_PTR_FULL,
     542    VMX_VMCS64_CTRL_EXEC_VMCS_PTR_HIGH,
     543    VMX_VMCS64_CTRL_EXEC_PML_ADDR_FULL,
     544    VMX_VMCS64_CTRL_EXEC_PML_ADDR_HIGH,
     545    VMX_VMCS64_CTRL_TSC_OFFSET_FULL,
     546    VMX_VMCS64_CTRL_TSC_OFFSET_HIGH,
     547    VMX_VMCS64_CTRL_VIRT_APIC_PAGEADDR_FULL,
     548    VMX_VMCS64_CTRL_VIRT_APIC_PAGEADDR_HIGH,
     549    VMX_VMCS64_CTRL_APIC_ACCESSADDR_FULL,
     550    VMX_VMCS64_CTRL_APIC_ACCESSADDR_HIGH,
     551    VMX_VMCS64_CTRL_POSTED_INTR_DESC_FULL,
     552    VMX_VMCS64_CTRL_POSTED_INTR_DESC_HIGH,
     553    VMX_VMCS64_CTRL_VMFUNC_CTRLS_FULL,
     554    VMX_VMCS64_CTRL_VMFUNC_CTRLS_HIGH,
     555    VMX_VMCS64_CTRL_EPTP_FULL,
     556    VMX_VMCS64_CTRL_EPTP_HIGH,
     557    VMX_VMCS64_CTRL_EOI_BITMAP_0_FULL,
     558    VMX_VMCS64_CTRL_EOI_BITMAP_0_HIGH,
     559    VMX_VMCS64_CTRL_EOI_BITMAP_1_FULL,
     560    VMX_VMCS64_CTRL_EOI_BITMAP_1_HIGH,
     561    VMX_VMCS64_CTRL_EOI_BITMAP_2_FULL,
     562    VMX_VMCS64_CTRL_EOI_BITMAP_2_HIGH,
     563    VMX_VMCS64_CTRL_EOI_BITMAP_3_FULL,
     564    VMX_VMCS64_CTRL_EOI_BITMAP_3_HIGH,
     565    VMX_VMCS64_CTRL_EPTP_LIST_FULL,
     566    VMX_VMCS64_CTRL_EPTP_LIST_HIGH,
     567    VMX_VMCS64_CTRL_VMREAD_BITMAP_FULL,
     568    VMX_VMCS64_CTRL_VMREAD_BITMAP_HIGH,
     569    VMX_VMCS64_CTRL_VMWRITE_BITMAP_FULL,
     570    VMX_VMCS64_CTRL_VMWRITE_BITMAP_HIGH,
     571    VMX_VMCS64_CTRL_VIRTXCPT_INFO_ADDR_FULL,
     572    VMX_VMCS64_CTRL_VIRTXCPT_INFO_ADDR_HIGH,
     573    VMX_VMCS64_CTRL_XSS_EXITING_BITMAP_FULL,
     574    VMX_VMCS64_CTRL_XSS_EXITING_BITMAP_HIGH,
     575    VMX_VMCS64_CTRL_ENCLS_EXITING_BITMAP_FULL,
     576    VMX_VMCS64_CTRL_ENCLS_EXITING_BITMAP_HIGH,
     577    VMX_VMCS64_CTRL_TSC_MULTIPLIER_FULL,
     578    VMX_VMCS64_CTRL_TSC_MULTIPLIER_HIGH,
     579
     580    /* 64-bit read-only data fields. */
     581    VMX_VMCS64_RO_GUEST_PHYS_ADDR_FULL,
     582    VMX_VMCS64_RO_GUEST_PHYS_ADDR_HIGH,
     583
     584    /* 64-bit guest-state fields. */
     585    VMX_VMCS64_GUEST_VMCS_LINK_PTR_FULL,
     586    VMX_VMCS64_GUEST_VMCS_LINK_PTR_HIGH,
     587    VMX_VMCS64_GUEST_DEBUGCTL_FULL,
     588    VMX_VMCS64_GUEST_DEBUGCTL_HIGH,
     589    VMX_VMCS64_GUEST_PAT_FULL,
     590    VMX_VMCS64_GUEST_PAT_HIGH,
     591    VMX_VMCS64_GUEST_EFER_FULL,
     592    VMX_VMCS64_GUEST_EFER_HIGH,
     593    VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_FULL,
     594    VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_HIGH,
     595    VMX_VMCS64_GUEST_PDPTE0_FULL,
     596    VMX_VMCS64_GUEST_PDPTE0_HIGH,
     597    VMX_VMCS64_GUEST_PDPTE1_FULL,
     598    VMX_VMCS64_GUEST_PDPTE1_HIGH,
     599    VMX_VMCS64_GUEST_PDPTE2_FULL,
     600    VMX_VMCS64_GUEST_PDPTE2_HIGH,
     601    VMX_VMCS64_GUEST_PDPTE3_FULL,
     602    VMX_VMCS64_GUEST_PDPTE3_HIGH,
     603    VMX_VMCS64_GUEST_BNDCFGS_FULL,
     604    VMX_VMCS64_GUEST_BNDCFGS_HIGH,
     605
     606    /* 64-bit host-state fields. */
     607    VMX_VMCS64_HOST_PAT_FULL,
     608    VMX_VMCS64_HOST_PAT_HIGH,
     609    VMX_VMCS64_HOST_EFER_FULL,
     610    VMX_VMCS64_HOST_EFER_HIGH,
     611    VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_FULL,
     612    VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_HIGH,
     613
     614    /* 32-bit control fields. */
     615    VMX_VMCS32_CTRL_PIN_EXEC,
     616    VMX_VMCS32_CTRL_PROC_EXEC,
     617    VMX_VMCS32_CTRL_EXCEPTION_BITMAP,
     618    VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MASK,
     619    VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MATCH,
     620    VMX_VMCS32_CTRL_CR3_TARGET_COUNT,
     621    VMX_VMCS32_CTRL_EXIT,
     622    VMX_VMCS32_CTRL_EXIT_MSR_STORE_COUNT,
     623    VMX_VMCS32_CTRL_EXIT_MSR_LOAD_COUNT,
     624    VMX_VMCS32_CTRL_ENTRY,
     625    VMX_VMCS32_CTRL_ENTRY_MSR_LOAD_COUNT,
     626    VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO,
     627    VMX_VMCS32_CTRL_ENTRY_EXCEPTION_ERRCODE,
     628    VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH,
     629    VMX_VMCS32_CTRL_TPR_THRESHOLD,
     630    VMX_VMCS32_CTRL_PROC_EXEC2,
     631    VMX_VMCS32_CTRL_PLE_GAP,
     632    VMX_VMCS32_CTRL_PLE_WINDOW,
     633
     634    /* 32-bits read-only fields. */
     635    VMX_VMCS32_RO_VM_INSTR_ERROR,
     636    VMX_VMCS32_RO_EXIT_REASON,
     637    VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO,
     638    VMX_VMCS32_RO_EXIT_INTERRUPTION_ERROR_CODE,
     639    VMX_VMCS32_RO_IDT_VECTORING_INFO,
     640    VMX_VMCS32_RO_IDT_VECTORING_ERROR_CODE,
     641    VMX_VMCS32_RO_EXIT_INSTR_LENGTH,
     642    VMX_VMCS32_RO_EXIT_INSTR_INFO,
     643
     644    /* 32-bit guest-state fields. */
     645    VMX_VMCS32_GUEST_ES_LIMIT,
     646    VMX_VMCS32_GUEST_CS_LIMIT,
     647    VMX_VMCS32_GUEST_SS_LIMIT,
     648    VMX_VMCS32_GUEST_DS_LIMIT,
     649    VMX_VMCS32_GUEST_FS_LIMIT,
     650    VMX_VMCS32_GUEST_GS_LIMIT,
     651    VMX_VMCS32_GUEST_LDTR_LIMIT,
     652    VMX_VMCS32_GUEST_TR_LIMIT,
     653    VMX_VMCS32_GUEST_GDTR_LIMIT,
     654    VMX_VMCS32_GUEST_IDTR_LIMIT,
     655    VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS,
     656    VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS,
     657    VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS,
     658    VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS,
     659    VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS,
     660    VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS,
     661    VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS,
     662    VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS,
     663    VMX_VMCS32_GUEST_INT_STATE,
     664    VMX_VMCS32_GUEST_ACTIVITY_STATE,
     665    VMX_VMCS32_GUEST_SMBASE,
     666    VMX_VMCS32_GUEST_SYSENTER_CS,
     667    VMX_VMCS32_PREEMPT_TIMER_VALUE,
     668
     669    /* 32-bit host-state fields. */
     670    VMX_VMCS32_HOST_SYSENTER_CS,
     671
     672    /* Natural-width control fields. */
     673    VMX_VMCS_CTRL_CR0_MASK,
     674    VMX_VMCS_CTRL_CR4_MASK,
     675    VMX_VMCS_CTRL_CR0_READ_SHADOW,
     676    VMX_VMCS_CTRL_CR4_READ_SHADOW,
     677    VMX_VMCS_CTRL_CR3_TARGET_VAL0,
     678    VMX_VMCS_CTRL_CR3_TARGET_VAL1,
     679    VMX_VMCS_CTRL_CR3_TARGET_VAL2,
     680    VMX_VMCS_CTRL_CR3_TARGET_VAL3,
     681
     682    /* Natural-width read-only data fields. */
     683    VMX_VMCS_RO_EXIT_QUALIFICATION,
     684    VMX_VMCS_RO_IO_RCX,
     685    VMX_VMCS_RO_IO_RSI,
     686    VMX_VMCS_RO_IO_RDI,
     687    VMX_VMCS_RO_IO_RIP,
     688    VMX_VMCS_RO_GUEST_LINEAR_ADDR,
     689
     690    /* Natural-width guest-state field */
     691    VMX_VMCS_GUEST_CR0,
     692    VMX_VMCS_GUEST_CR3,
     693    VMX_VMCS_GUEST_CR4,
     694    VMX_VMCS_GUEST_ES_BASE,
     695    VMX_VMCS_GUEST_CS_BASE,
     696    VMX_VMCS_GUEST_SS_BASE,
     697    VMX_VMCS_GUEST_DS_BASE,
     698    VMX_VMCS_GUEST_FS_BASE,
     699    VMX_VMCS_GUEST_GS_BASE,
     700    VMX_VMCS_GUEST_LDTR_BASE,
     701    VMX_VMCS_GUEST_TR_BASE,
     702    VMX_VMCS_GUEST_GDTR_BASE,
     703    VMX_VMCS_GUEST_IDTR_BASE,
     704    VMX_VMCS_GUEST_DR7,
     705    VMX_VMCS_GUEST_RSP,
     706    VMX_VMCS_GUEST_RIP,
     707    VMX_VMCS_GUEST_RFLAGS,
     708    VMX_VMCS_GUEST_PENDING_DEBUG_XCPTS,
     709    VMX_VMCS_GUEST_SYSENTER_ESP,
     710    VMX_VMCS_GUEST_SYSENTER_EIP,
     711
     712    /* Natural-width host-state fields */
     713    VMX_VMCS_HOST_CR0,
     714    VMX_VMCS_HOST_CR3,
     715    VMX_VMCS_HOST_CR4,
     716    VMX_VMCS_HOST_FS_BASE,
     717    VMX_VMCS_HOST_GS_BASE,
     718    VMX_VMCS_HOST_TR_BASE,
     719    VMX_VMCS_HOST_GDTR_BASE,
     720    VMX_VMCS_HOST_IDTR_BASE,
     721    VMX_VMCS_HOST_SYSENTER_ESP,
     722    VMX_VMCS_HOST_SYSENTER_EIP,
     723    VMX_VMCS_HOST_RSP,
     724    VMX_VMCS_HOST_RIP
     725};
     726#endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
     727
    491728#ifdef VMX_USE_CACHED_VMCS_ACCESSES
    492729static const uint32_t g_aVmcsCacheSegBase[] =
     
    13751612
    13761613
     1614#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     1615/**
     1616 * Initializes the shadow VMCS.
     1617 *
     1618 * This builds an array (for use later while executing a nested-guest) of VMCS
     1619 * fields to copy into the shadow VMCS.
     1620 *
     1621 * @param   pVM     The cross context VM structure.
     1622 */
     1623static void hmR0VmxInitShadowVmcsFieldsArray(PVM pVM)
     1624{
     1625    uint32_t const cVmcsFields = RT_ELEMENTS(g_aVmcsFields);
     1626    for (uint32_t i = 0; i < cVmcsFields; i++)
     1627    {
     1628        /*
     1629         * If the VMCS field depends on a CPU feature that is not exposed to the guest,
     1630         * we must not include it in the shadow VMCS fields array. Guests attempting to
     1631         * VMREAD/VMWRITE such VMCS fields would cause a VM-exit and we shall emulate
     1632         * the required behavior.
     1633         */
     1634        uint32_t const uVmcsField      = g_aVmcsFields[i];
     1635        bool const     fVmcsFieldValid = CPUMIsGuestVmxVmcsFieldValid(pVM, uVmcsField);
     1636        if (fVmcsFieldValid)
     1637        {
     1638            pVM->hm.s.vmx.paShadowVmcsFields[i] = uVmcsField;
     1639            ++pVM->hm.s.vmx.cShadowVmcsFields;
     1640        }
     1641    }
     1642}
     1643
     1644
     1645/**
     1646 * Initializes the VMREAD/VMWRITE bitmaps.
     1647 *
     1648 * @param   pVM                 The cross context VM structure.
     1649 */
     1650static void hmR0VmxInitVmreadVmwriteBitmaps(PVM pVM)
     1651{
     1652    /*
     1653     * By default, ensure guest attempts to acceses to any VMCS fields cause VM-exits.
     1654     */
     1655    uint32_t const  cbBitmap        = X86_PAGE_4K_SIZE;
     1656    uint8_t        *pbVmreadBitmap  = (uint8_t *)pVM->hm.s.vmx.pvVmreadBitmap;
     1657    uint8_t        *pbVmwriteBitmap = (uint8_t *)pVM->hm.s.vmx.pvVmwriteBitmap;
     1658    ASMMemFill32(pbVmreadBitmap,  cbBitmap, UINT32_C(0xffffffff));
     1659    ASMMemFill32(pbVmwriteBitmap, cbBitmap, UINT32_C(0xffffffff));
     1660
     1661    uint32_t const *paShadowVmcsFields = pVM->hm.s.vmx.paShadowVmcsFields;
     1662    uint32_t const  cShadowVmcsFields  = pVM->hm.s.vmx.cShadowVmcsFields;
     1663
     1664    /*
     1665     * Initialize the VMREAD bitmap.
     1666     * All valid guest VMCS fields (read-only and read-write) can be accessed
     1667     * using VMREAD without causing a VM-exit.
     1668     */
     1669    for (uint32_t i = 0; i < cShadowVmcsFields; i++)
     1670    {
     1671        uint32_t const uVmcsField = paShadowVmcsFields[i];
     1672        Assert(!(uVmcsField & VMX_VMCSFIELD_RSVD_MASK));
     1673        uint8_t *pbField = pbVmreadBitmap + (uVmcsField >> 3);
     1674        ASMBitClear(pbField, uVmcsField & 7);
     1675    }
     1676
     1677    /*
     1678     * Initialize the VMWRITE bitmap.
     1679     * Allow the guest to write to read-only guest VMCS fields only if the
     1680     * host CPU supports it, otherwise it would cause a VMWRITE instruction error.
     1681     */
     1682    bool const fHasVmwriteAll = RT_BOOL(pVM->hm.s.vmx.Msrs.u64Misc & VMX_MISC_VMWRITE_ALL);
     1683    for (uint32_t i = 0; i < cShadowVmcsFields; i++)
     1684    {
     1685        uint32_t const uVmcsField = paShadowVmcsFields[i];
     1686        if (   fHasVmwriteAll
     1687            || !HMVmxIsVmcsFieldReadOnly(uVmcsField))
     1688        {
     1689            Assert(!(uVmcsField & VMX_VMCSFIELD_RSVD_MASK));
     1690            uint8_t *pbField = pbVmwriteBitmap + (uVmcsField >> 3);
     1691            ASMBitClear(pbField, uVmcsField & 7);
     1692        }
     1693    }
     1694}
     1695#endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
     1696
     1697
    13771698/**
    13781699 * Allocates and maps a physically contiguous page. The allocated page is
     
    14331754
    14341755    Assert(pVmcsInfo->hMemObjVmcs          == NIL_RTR0MEMOBJ);
     1756    Assert(pVmcsInfo->hMemObjShadowVmcs    == NIL_RTR0MEMOBJ);
    14351757    Assert(pVmcsInfo->hMemObjMsrBitmap     == NIL_RTR0MEMOBJ);
    14361758    Assert(pVmcsInfo->hMemObjGuestMsrLoad  == NIL_RTR0MEMOBJ);
     
    14381760    Assert(pVmcsInfo->hMemObjHostMsrLoad   == NIL_RTR0MEMOBJ);
    14391761    pVmcsInfo->HCPhysVmcs          = NIL_RTHCPHYS;
     1762    pVmcsInfo->HCPhysShadowVmcs    = NIL_RTHCPHYS;
    14401763    pVmcsInfo->HCPhysMsrBitmap     = NIL_RTHCPHYS;
    14411764    pVmcsInfo->HCPhysGuestMsrLoad  = NIL_RTHCPHYS;
     
    14581781    hmR0VmxPageFree(&pVmcsInfo->hMemObjVmcs, &pVmcsInfo->pvVmcs, &pVmcsInfo->HCPhysVmcs);
    14591782
     1783    if (   pVM->cpum.ro.GuestFeatures.fVmx
     1784        && (pVM->hm.s.vmx.Msrs.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_VMCS_SHADOWING))
     1785        hmR0VmxPageFree(&pVmcsInfo->hMemObjShadowVmcs, &pVmcsInfo->pvShadowVmcs, &pVmcsInfo->HCPhysShadowVmcs);
     1786
    14601787    if (pVM->hm.s.vmx.Msrs.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_MSR_BITMAPS)
    14611788        hmR0VmxPageFree(&pVmcsInfo->hMemObjMsrBitmap, &pVmcsInfo->pvMsrBitmap, &pVmcsInfo->HCPhysMsrBitmap);
     
    14871814        if (!fIsNstGstVmcs)
    14881815        {
    1489             /* Get the allocated virtual-APIC page from the virtual APIC device. */
    1490             if (   PDMHasApic(pVCpu->CTX_SUFF(pVM))
    1491                 && (pVM->hm.s.vmx.Msrs.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_TPR_SHADOW))
     1816            /* Allocate the shadow VMCS if supported by the CPU. */
     1817            if (   pVM->cpum.ro.GuestFeatures.fVmx
     1818                && (pVM->hm.s.vmx.Msrs.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_VMCS_SHADOWING))
     1819                rc = hmR0VmxPageAllocZ(&pVmcsInfo->hMemObjShadowVmcs, &pVmcsInfo->pvShadowVmcs, &pVmcsInfo->HCPhysShadowVmcs);
     1820
     1821            if (RT_SUCCESS(rc))
    14921822            {
    1493                 rc = APICGetApicPageForCpu(pVCpu, &pVmcsInfo->HCPhysVirtApic, (PRTR0PTR)&pVmcsInfo->pbVirtApic,
    1494                                            NULL /* pR3Ptr */, NULL /* pRCPtr */);
     1823                /* Get the allocated virtual-APIC page from the virtual APIC device. */
     1824                if (   PDMHasApic(pVCpu->CTX_SUFF(pVM))
     1825                    && (pVM->hm.s.vmx.Msrs.ProcCtls.n.allowed1 & VMX_PROC_CTLS_USE_TPR_SHADOW))
     1826                {
     1827                    rc = APICGetApicPageForCpu(pVCpu, &pVmcsInfo->HCPhysVirtApic, (PRTR0PTR)&pVmcsInfo->pbVirtApic,
     1828                                               NULL /* pR3Ptr */, NULL /* pRCPtr */);
     1829                }
    14951830            }
    14961831        }
    14971832        else
    14981833        {
     1834            /* We don't yet support exposing VMCS shadowing to the guest. */
     1835            Assert(pVmcsInfo->HCPhysShadowVmcs == NIL_RTHCPHYS);
     1836            Assert(!pVmcsInfo->pvShadowVmcs);
     1837
     1838            /* The host-physical address of the virtual-APIC page in guest memory is taken directly. */
    14991839            Assert(pVmcsInfo->HCPhysVirtApic == NIL_RTHCPHYS);
    15001840            Assert(!pVmcsInfo->pbVirtApic);
     
    15701910    hmR0VmxPageFree(&pVM->hm.s.vmx.hMemObjApicAccess, (PRTR0PTR)&pVM->hm.s.vmx.pbApicAccess, &pVM->hm.s.vmx.HCPhysApicAccess);
    15711911
     1912#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     1913    if (   pVM->cpum.ro.GuestFeatures.fVmx
     1914        && (pVM->hm.s.vmx.Msrs.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_VMCS_SHADOWING))
     1915    {
     1916        RTMemFree(pVM->hm.s.vmx.paShadowVmcsFields);
     1917        hmR0VmxPageFree(&pVM->hm.s.vmx.hMemObjVmreadBitmap,  &pVM->hm.s.vmx.pvVmreadBitmap,  &pVM->hm.s.vmx.HCPhysVmreadBitmap);
     1918        hmR0VmxPageFree(&pVM->hm.s.vmx.hMemObjVmwriteBitmap, &pVM->hm.s.vmx.pvVmwriteBitmap, &pVM->hm.s.vmx.HCPhysVmwriteBitmap);
     1919    }
     1920#endif
     1921
    15721922    for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    15731923    {
     
    16562006        }
    16572007    }
     2008
     2009#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     2010    /* Allocate the shadow VMCS fields array, VMREAD, VMWRITE bitmaps if VMCS shadowing supported by the CPU. */
     2011    if (   pVM->cpum.ro.GuestFeatures.fVmx
     2012        && (pVM->hm.s.vmx.Msrs.ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_VMCS_SHADOWING))
     2013    {
     2014        pVM->hm.s.vmx.paShadowVmcsFields = (uint32_t *)RTMemAllocZ(sizeof(g_aVmcsFields));
     2015        if (RT_LIKELY(pVM->hm.s.vmx.paShadowVmcsFields))
     2016        {
     2017            rc = hmR0VmxPageAllocZ(&pVM->hm.s.vmx.hMemObjVmreadBitmap, &pVM->hm.s.vmx.pvVmreadBitmap,
     2018                                   &pVM->hm.s.vmx.HCPhysVmreadBitmap);
     2019            if (RT_SUCCESS(rc))
     2020            {
     2021                rc = hmR0VmxPageAllocZ(&pVM->hm.s.vmx.hMemObjVmwriteBitmap, &pVM->hm.s.vmx.pvVmwriteBitmap,
     2022                                       &pVM->hm.s.vmx.HCPhysVmwriteBitmap);
     2023                if (RT_SUCCESS(rc))
     2024                {
     2025                    hmR0VmxInitShadowVmcsFieldsArray(pVM);
     2026                    hmR0VmxInitVmreadVmwriteBitmaps(pVM);
     2027                }
     2028            }
     2029        }
     2030        else
     2031            rc = VERR_NO_MEMORY;
     2032
     2033        if (RT_FAILURE(rc))
     2034        {
     2035            hmR0VmxStructsFree(pVM);
     2036            return rc;
     2037        }
     2038    }
     2039#endif
    16582040
    16592041    /*
     
    16922074}
    16932075
    1694 
    16952076#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    16962077/**
     
    17102091}
    17112092#endif
    1712 
    17132093
    17142094/**
     
    38444224
    38454225# ifdef VBOX_STRICT
    3846 static bool hmR0VmxIsValidWriteField(uint32_t idxField)
     4226static bool hmR0VmxIsValidWriteFieldInCache(uint32_t idxField)
    38474227{
    38484228    switch (idxField)
     
    38684248}
    38694249
    3870 static bool hmR0VmxIsValidReadField(uint32_t idxField)
     4250static bool hmR0VmxIsValidReadFieldInCache(uint32_t idxField)
    38714251{
    38724252    switch (idxField)
     
    38774257    }
    38784258    /* Remaining readable fields should also be writable. */
    3879     return hmR0VmxIsValidWriteField(idxField);
     4259    return hmR0VmxIsValidWriteFieldInCache(idxField);
    38804260}
    38814261# endif /* VBOX_STRICT */
     
    39024282#ifdef VBOX_STRICT
    39034283    for (uint32_t i = 0; i < pVCpu->hm.s.vmx.VmcsCache.Write.cValidEntries; i++)
    3904         Assert(hmR0VmxIsValidWriteField(pVCpu->hm.s.vmx.VmcsCache.Write.aField[i]));
     4284        Assert(hmR0VmxIsValidWriteFieldInCache(pVCpu->hm.s.vmx.VmcsCache.Write.aField[i]));
    39054285
    39064286    for (uint32_t i = 0; i <pVCpu->hm.s.vmx.VmcsCache.Read.cValidEntries; i++)
    3907         Assert(hmR0VmxIsValidReadField(pVCpu->hm.s.vmx.VmcsCache.Read.aField[i]));
     4287        Assert(hmR0VmxIsValidReadFieldInCache(pVCpu->hm.s.vmx.VmcsCache.Read.aField[i]));
    39084288#endif
    39094289
  • trunk/src/VBox/VMM/include/HMInternal.h

    r79123 r79202  
    528528        /** Set if VT-x VPID is allowed. */
    529529        bool                        fAllowVpid;
    530         /** Set if unrestricted guest execution is in use (real and protected mode without paging). */
     530        /** Set if unrestricted guest execution is in use (real and protected mode
     531         *  without paging). */
    531532        bool                        fUnrestrictedGuest;
    532533        /** Set if unrestricted guest execution is allowed to be used. */
     
    539540        /** Virtual address of the TSS page used for real mode emulation. */
    540541        R3PTRTYPE(PVBOXTSS)         pRealModeTSS;
    541         /** Virtual address of the identity page table used for real mode and protected mode without paging emulation in EPT mode. */
     542        /** Virtual address of the identity page table used for real mode and protected
     543         *  mode without paging emulation in EPT mode. */
    542544        R3PTRTYPE(PX86PD)           pNonPagingModeEPTPageTable;
    543545
     
    549551        R0PTRTYPE(uint8_t *)        pbApicAccess;
    550552
     553        /** Physical address of the VMREAD bitmap. */
     554        RTHCPHYS                    HCPhysVmreadBitmap;
     555        /** Ring-0 memory object for the VMREAD bitmap. */
     556        RTR0MEMOBJ                  hMemObjVmreadBitmap;
     557        /** Pointer to the VMREAD bitmap. */
     558        R0PTRTYPE(void *)           pvVmreadBitmap;
     559
     560        /** Physical address of the VMWRITE bitmap. */
     561        RTHCPHYS                    HCPhysVmwriteBitmap;
     562        /** Ring-0 memory object for the VMWRITE bitmap. */
     563        RTR0MEMOBJ                  hMemObjVmwriteBitmap;
     564        /** Pointer to the VMWRITE bitmap. */
     565        R0PTRTYPE(void *)           pvVmwriteBitmap;
     566
    551567#ifdef VBOX_WITH_CRASHDUMP_MAGIC
     568        /** Physical address of the crash-dump scratch area. */
    552569        RTHCPHYS                    HCPhysScratch;
     570        /** Ring-0 memory object for the crash-dump scratch area. */
    553571        RTR0MEMOBJ                  hMemObjScratch;
     572        /** Pointer to the crash-dump scratch bitmap. */
    554573        R0PTRTYPE(uint8_t *)        pbScratch;
    555574#endif
     
    583602        /** Host-physical address for a failing VMXON instruction. */
    584603        RTHCPHYS                    HCPhysVmxEnableError;
     604
     605        /** Pointer to the shadow VMCS fields array. */
     606        R0PTRTYPE(uint32_t *)       paShadowVmcsFields;
     607        RTR0PTR                     pvR0Alignment1;
     608        /** Number of elements in the shadow VMCS fields array. */
     609        uint32_t                    cShadowVmcsFields;
     610        uint32_t                    u32Alignemnt0;
    585611    } vmx;
    586612
     
    759785    /** Host-virtual address of the VMCS. */
    760786    R0PTRTYPE(void *)           pvVmcs;
     787
     788    /** Host-physical address of the shadow VMCS. */
     789    RTHCPHYS                    HCPhysShadowVmcs;
     790    /** R0 memory object for the shadow VMCS. */
     791    RTR0MEMOBJ                  hMemObjShadowVmcs;
     792    /** Host-virtual address of the shadow VMCS. */
     793    R0PTRTYPE(void *)           pvShadowVmcs;
    761794
    762795    /** Host-physical address of the virtual APIC page. */
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