17c8c0b82SPatrick Mooney /*- 2*32640292SAndy Fiddaman * SPDX-License-Identifier: BSD-2-Clause 37c8c0b82SPatrick Mooney * 47c8c0b82SPatrick Mooney * Copyright (c) 2013 Anish Gupta (akgupt3@gmail.com) 57c8c0b82SPatrick Mooney * All rights reserved. 67c8c0b82SPatrick Mooney * 77c8c0b82SPatrick Mooney * Redistribution and use in source and binary forms, with or without 87c8c0b82SPatrick Mooney * modification, are permitted provided that the following conditions 97c8c0b82SPatrick Mooney * are met: 107c8c0b82SPatrick Mooney * 1. Redistributions of source code must retain the above copyright 117c8c0b82SPatrick Mooney * notice unmodified, this list of conditions, and the following 127c8c0b82SPatrick Mooney * disclaimer. 137c8c0b82SPatrick Mooney * 2. Redistributions in binary form must reproduce the above copyright 147c8c0b82SPatrick Mooney * notice, this list of conditions and the following disclaimer in the 157c8c0b82SPatrick Mooney * documentation and/or other materials provided with the distribution. 167c8c0b82SPatrick Mooney * 177c8c0b82SPatrick Mooney * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 187c8c0b82SPatrick Mooney * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 197c8c0b82SPatrick Mooney * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 207c8c0b82SPatrick Mooney * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 217c8c0b82SPatrick Mooney * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 227c8c0b82SPatrick Mooney * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237c8c0b82SPatrick Mooney * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247c8c0b82SPatrick Mooney * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257c8c0b82SPatrick Mooney * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 267c8c0b82SPatrick Mooney * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277c8c0b82SPatrick Mooney */ 287c8c0b82SPatrick Mooney 297c8c0b82SPatrick Mooney /* 307c8c0b82SPatrick Mooney * This file and its contents are supplied under the terms of the 317c8c0b82SPatrick Mooney * Common Development and Distribution License ("CDDL"), version 1.0. 327c8c0b82SPatrick Mooney * You may only use this file in accordance with the terms of version 337c8c0b82SPatrick Mooney * 1.0 of the CDDL. 347c8c0b82SPatrick Mooney * 357c8c0b82SPatrick Mooney * A full copy of the text of the CDDL should have accompanied this 367c8c0b82SPatrick Mooney * source. A copy of the CDDL is also available via the Internet at 377c8c0b82SPatrick Mooney * http://www.illumos.org/license/CDDL. 387c8c0b82SPatrick Mooney * 393d097f7dSPatrick Mooney * Copyright 2022 Oxide Computer Company 407c8c0b82SPatrick Mooney */ 417c8c0b82SPatrick Mooney 427c8c0b82SPatrick Mooney #ifndef _VMCB_H_ 437c8c0b82SPatrick Mooney #define _VMCB_H_ 447c8c0b82SPatrick Mooney 457c8c0b82SPatrick Mooney struct svm_softc; 467c8c0b82SPatrick Mooney 477c8c0b82SPatrick Mooney #define BIT(n) (1ULL << n) 487c8c0b82SPatrick Mooney 497c8c0b82SPatrick Mooney /* 507c8c0b82SPatrick Mooney * Secure Virtual Machine: AMD64 Programmer's Manual Vol2, Chapter 15 517c8c0b82SPatrick Mooney * Layout of VMCB: AMD64 Programmer's Manual Vol2, Appendix B 527c8c0b82SPatrick Mooney */ 537c8c0b82SPatrick Mooney 547c8c0b82SPatrick Mooney /* vmcb_ctrl->intercept[] array indices */ 557c8c0b82SPatrick Mooney #define VMCB_CR_INTCPT 0 567c8c0b82SPatrick Mooney #define VMCB_DR_INTCPT 1 577c8c0b82SPatrick Mooney #define VMCB_EXC_INTCPT 2 587c8c0b82SPatrick Mooney #define VMCB_CTRL1_INTCPT 3 597c8c0b82SPatrick Mooney #define VMCB_CTRL2_INTCPT 4 607c8c0b82SPatrick Mooney 617c8c0b82SPatrick Mooney /* intercept[VMCB_CTRL1_INTCPT] fields */ 627c8c0b82SPatrick Mooney #define VMCB_INTCPT_INTR BIT(0) 637c8c0b82SPatrick Mooney #define VMCB_INTCPT_NMI BIT(1) 647c8c0b82SPatrick Mooney #define VMCB_INTCPT_SMI BIT(2) 657c8c0b82SPatrick Mooney #define VMCB_INTCPT_INIT BIT(3) 667c8c0b82SPatrick Mooney #define VMCB_INTCPT_VINTR BIT(4) 677c8c0b82SPatrick Mooney #define VMCB_INTCPT_CR0_WRITE BIT(5) 687c8c0b82SPatrick Mooney #define VMCB_INTCPT_IDTR_READ BIT(6) 697c8c0b82SPatrick Mooney #define VMCB_INTCPT_GDTR_READ BIT(7) 707c8c0b82SPatrick Mooney #define VMCB_INTCPT_LDTR_READ BIT(8) 717c8c0b82SPatrick Mooney #define VMCB_INTCPT_TR_READ BIT(9) 727c8c0b82SPatrick Mooney #define VMCB_INTCPT_IDTR_WRITE BIT(10) 737c8c0b82SPatrick Mooney #define VMCB_INTCPT_GDTR_WRITE BIT(11) 747c8c0b82SPatrick Mooney #define VMCB_INTCPT_LDTR_WRITE BIT(12) 757c8c0b82SPatrick Mooney #define VMCB_INTCPT_TR_WRITE BIT(13) 767c8c0b82SPatrick Mooney #define VMCB_INTCPT_RDTSC BIT(14) 777c8c0b82SPatrick Mooney #define VMCB_INTCPT_RDPMC BIT(15) 787c8c0b82SPatrick Mooney #define VMCB_INTCPT_PUSHF BIT(16) 797c8c0b82SPatrick Mooney #define VMCB_INTCPT_POPF BIT(17) 807c8c0b82SPatrick Mooney #define VMCB_INTCPT_CPUID BIT(18) 817c8c0b82SPatrick Mooney #define VMCB_INTCPT_RSM BIT(19) 827c8c0b82SPatrick Mooney #define VMCB_INTCPT_IRET BIT(20) 837c8c0b82SPatrick Mooney #define VMCB_INTCPT_INTn BIT(21) 847c8c0b82SPatrick Mooney #define VMCB_INTCPT_INVD BIT(22) 857c8c0b82SPatrick Mooney #define VMCB_INTCPT_PAUSE BIT(23) 867c8c0b82SPatrick Mooney #define VMCB_INTCPT_HLT BIT(24) 877c8c0b82SPatrick Mooney #define VMCB_INTCPT_INVLPG BIT(25) 887c8c0b82SPatrick Mooney #define VMCB_INTCPT_INVLPGA BIT(26) 897c8c0b82SPatrick Mooney #define VMCB_INTCPT_IO BIT(27) 907c8c0b82SPatrick Mooney #define VMCB_INTCPT_MSR BIT(28) 917c8c0b82SPatrick Mooney #define VMCB_INTCPT_TASK_SWITCH BIT(29) 927c8c0b82SPatrick Mooney #define VMCB_INTCPT_FERR_FREEZE BIT(30) 937c8c0b82SPatrick Mooney #define VMCB_INTCPT_SHUTDOWN BIT(31) 947c8c0b82SPatrick Mooney 957c8c0b82SPatrick Mooney /* intercept[VMCB_CTRL2_INTCPT] fields */ 967c8c0b82SPatrick Mooney #define VMCB_INTCPT_VMRUN BIT(0) 977c8c0b82SPatrick Mooney #define VMCB_INTCPT_VMMCALL BIT(1) 987c8c0b82SPatrick Mooney #define VMCB_INTCPT_VMLOAD BIT(2) 997c8c0b82SPatrick Mooney #define VMCB_INTCPT_VMSAVE BIT(3) 1007c8c0b82SPatrick Mooney #define VMCB_INTCPT_STGI BIT(4) 1017c8c0b82SPatrick Mooney #define VMCB_INTCPT_CLGI BIT(5) 1027c8c0b82SPatrick Mooney #define VMCB_INTCPT_SKINIT BIT(6) 1037c8c0b82SPatrick Mooney #define VMCB_INTCPT_RDTSCP BIT(7) 1047c8c0b82SPatrick Mooney #define VMCB_INTCPT_ICEBP BIT(8) 1057c8c0b82SPatrick Mooney #define VMCB_INTCPT_WBINVD BIT(9) 1067c8c0b82SPatrick Mooney #define VMCB_INTCPT_MONITOR BIT(10) 1077c8c0b82SPatrick Mooney #define VMCB_INTCPT_MWAIT BIT(11) 1087c8c0b82SPatrick Mooney #define VMCB_INTCPT_MWAIT_ARMED BIT(12) 1097c8c0b82SPatrick Mooney #define VMCB_INTCPT_XSETBV BIT(13) 1107c8c0b82SPatrick Mooney 1117c8c0b82SPatrick Mooney /* VMCB TLB control */ 1127c8c0b82SPatrick Mooney #define VMCB_TLB_FLUSH_NOTHING 0 /* Flush nothing */ 1137c8c0b82SPatrick Mooney #define VMCB_TLB_FLUSH_ALL 1 /* Flush entire TLB */ 1147c8c0b82SPatrick Mooney #define VMCB_TLB_FLUSH_GUEST 3 /* Flush all guest entries */ 1157c8c0b82SPatrick Mooney #define VMCB_TLB_FLUSH_GUEST_NONGLOBAL 7 /* Flush guest non-PG entries */ 1167c8c0b82SPatrick Mooney 1177c8c0b82SPatrick Mooney /* VMCB state caching */ 1187c8c0b82SPatrick Mooney #define VMCB_CACHE_NONE 0 /* No caching */ 1197c8c0b82SPatrick Mooney #define VMCB_CACHE_I BIT(0) /* Intercept, TSC off, Pause filter */ 1207c8c0b82SPatrick Mooney #define VMCB_CACHE_IOPM BIT(1) /* I/O and MSR permission */ 1217c8c0b82SPatrick Mooney #define VMCB_CACHE_ASID BIT(2) /* ASID */ 1227c8c0b82SPatrick Mooney #define VMCB_CACHE_TPR BIT(3) /* V_TPR to V_INTR_VECTOR */ 1237c8c0b82SPatrick Mooney #define VMCB_CACHE_NP BIT(4) /* Nested Paging */ 1247c8c0b82SPatrick Mooney #define VMCB_CACHE_CR BIT(5) /* CR0, CR3, CR4 & EFER */ 1257c8c0b82SPatrick Mooney #define VMCB_CACHE_DR BIT(6) /* Debug registers */ 1267c8c0b82SPatrick Mooney #define VMCB_CACHE_DT BIT(7) /* GDT/IDT */ 1277c8c0b82SPatrick Mooney #define VMCB_CACHE_SEG BIT(8) /* User segments, CPL */ 1287c8c0b82SPatrick Mooney #define VMCB_CACHE_CR2 BIT(9) /* page fault address */ 1297c8c0b82SPatrick Mooney #define VMCB_CACHE_LBR BIT(10) /* Last branch */ 1307c8c0b82SPatrick Mooney 1317c8c0b82SPatrick Mooney /* VMCB control event injection */ 1327c8c0b82SPatrick Mooney #define VMCB_EVENTINJ_EC_VALID BIT(11) /* Error Code valid */ 1337c8c0b82SPatrick Mooney #define VMCB_EVENTINJ_VALID BIT(31) /* Event valid */ 1347c8c0b82SPatrick Mooney 1357c8c0b82SPatrick Mooney /* Event types that can be injected */ 1367c8c0b82SPatrick Mooney #define VMCB_EVENTINJ_TYPE_INTR 0 1377c8c0b82SPatrick Mooney #define VMCB_EVENTINJ_TYPE_NMI (2 << 8) 1387c8c0b82SPatrick Mooney #define VMCB_EVENTINJ_TYPE_EXCEPTION (3 << 8) 1397c8c0b82SPatrick Mooney #define VMCB_EVENTINJ_TYPE_INTn (4 << 8) 1407c8c0b82SPatrick Mooney 1417c8c0b82SPatrick Mooney /* VMCB exit code, APM vol2 Appendix C */ 1427c8c0b82SPatrick Mooney #define VMCB_EXIT_CR0_READ 0x00 1437c8c0b82SPatrick Mooney #define VMCB_EXIT_CR15_READ 0x0f 1447c8c0b82SPatrick Mooney #define VMCB_EXIT_CR0_WRITE 0x10 1457c8c0b82SPatrick Mooney #define VMCB_EXIT_CR15_WRITE 0x1f 1463d097f7dSPatrick Mooney #define VMCB_EXIT_EXCP0 0x40 1473d097f7dSPatrick Mooney #define VMCB_EXIT_EXCP31 0x5f 1487c8c0b82SPatrick Mooney #define VMCB_EXIT_INTR 0x60 1497c8c0b82SPatrick Mooney #define VMCB_EXIT_NMI 0x61 1507c8c0b82SPatrick Mooney #define VMCB_EXIT_SMI 0x62 1517c8c0b82SPatrick Mooney #define VMCB_EXIT_INIT 0x63 1527c8c0b82SPatrick Mooney #define VMCB_EXIT_VINTR 0x64 1537c8c0b82SPatrick Mooney #define VMCB_EXIT_CR0_SEL_WRITE 0x65 1547c8c0b82SPatrick Mooney #define VMCB_EXIT_PUSHF 0x70 1557c8c0b82SPatrick Mooney #define VMCB_EXIT_POPF 0x71 1567c8c0b82SPatrick Mooney #define VMCB_EXIT_CPUID 0x72 1577c8c0b82SPatrick Mooney #define VMCB_EXIT_IRET 0x74 1587c8c0b82SPatrick Mooney #define VMCB_EXIT_INVD 0x76 1597c8c0b82SPatrick Mooney #define VMCB_EXIT_PAUSE 0x77 1607c8c0b82SPatrick Mooney #define VMCB_EXIT_HLT 0x78 1617c8c0b82SPatrick Mooney #define VMCB_EXIT_INVLPG 0x79 1627c8c0b82SPatrick Mooney #define VMCB_EXIT_INVLPGA 0x7A 1637c8c0b82SPatrick Mooney #define VMCB_EXIT_IO 0x7B 1647c8c0b82SPatrick Mooney #define VMCB_EXIT_MSR 0x7C 1657c8c0b82SPatrick Mooney #define VMCB_EXIT_SHUTDOWN 0x7F 1667c8c0b82SPatrick Mooney #define VMCB_EXIT_VMRUN 0x80 1677c8c0b82SPatrick Mooney #define VMCB_EXIT_VMMCALL 0x81 1687c8c0b82SPatrick Mooney #define VMCB_EXIT_VMLOAD 0x82 1697c8c0b82SPatrick Mooney #define VMCB_EXIT_VMSAVE 0x83 1707c8c0b82SPatrick Mooney #define VMCB_EXIT_STGI 0x84 1717c8c0b82SPatrick Mooney #define VMCB_EXIT_CLGI 0x85 1727c8c0b82SPatrick Mooney #define VMCB_EXIT_SKINIT 0x86 1734f3f3e9aSAndy Fiddaman #define VMCB_EXIT_WBINVD 0x89 1747c8c0b82SPatrick Mooney #define VMCB_EXIT_MONITOR 0x8A 1757c8c0b82SPatrick Mooney #define VMCB_EXIT_MWAIT 0x8B 1767c8c0b82SPatrick Mooney #define VMCB_EXIT_NPF 0x400 1777c8c0b82SPatrick Mooney #define VMCB_EXIT_INVALID -1 1787c8c0b82SPatrick Mooney 1797c8c0b82SPatrick Mooney /* 1807c8c0b82SPatrick Mooney * Move to/from CRx 1817c8c0b82SPatrick Mooney * Bit definitions to decode EXITINFO1 1827c8c0b82SPatrick Mooney */ 1837c8c0b82SPatrick Mooney #define VMCB_CRx_INFO1_GPR(x) ((x) & 0xf) 1847c8c0b82SPatrick Mooney #define VMCB_CRx_INFO1_VALID(x) ((x) & (1UL << 63)) 1857c8c0b82SPatrick Mooney 1867c8c0b82SPatrick Mooney /* 1877c8c0b82SPatrick Mooney * Nested page fault. 1887c8c0b82SPatrick Mooney * Bit definitions to decode EXITINFO1. 1897c8c0b82SPatrick Mooney */ 1907c8c0b82SPatrick Mooney #define VMCB_NPF_INFO1_P BIT(0) /* Nested page present. */ 1917c8c0b82SPatrick Mooney #define VMCB_NPF_INFO1_W BIT(1) /* Access was write. */ 1927c8c0b82SPatrick Mooney #define VMCB_NPF_INFO1_U BIT(2) /* Access was user access. */ 1937c8c0b82SPatrick Mooney #define VMCB_NPF_INFO1_RSV BIT(3) /* Reserved bits present. */ 1947c8c0b82SPatrick Mooney #define VMCB_NPF_INFO1_ID BIT(4) /* Code read. */ 1957c8c0b82SPatrick Mooney 1967c8c0b82SPatrick Mooney #define VMCB_NPF_INFO1_GPA BIT(32) /* Guest physical address. */ 1977c8c0b82SPatrick Mooney #define VMCB_NPF_INFO1_GPT BIT(33) /* Guest page table. */ 1987c8c0b82SPatrick Mooney 1997c8c0b82SPatrick Mooney /* 2007c8c0b82SPatrick Mooney * EXITINTINFO, Interrupt exit info for all intrecepts. 2017c8c0b82SPatrick Mooney * Section 15.7.2, Intercepts during IDT Interrupt Delivery. 2027c8c0b82SPatrick Mooney */ 2037c8c0b82SPatrick Mooney #define VMCB_EXITINTINFO_VECTOR(x) ((x) & 0xFF) 2047c8c0b82SPatrick Mooney #define VMCB_EXITINTINFO_TYPE(x) ((x) & (0x7 << 8)) 2057c8c0b82SPatrick Mooney #define VMCB_EXITINTINFO_EC_VALID(x) (((x) & BIT(11)) != 0) 2067c8c0b82SPatrick Mooney #define VMCB_EXITINTINFO_VALID(x) (((x) & BIT(31)) != 0) 2077c8c0b82SPatrick Mooney #define VMCB_EXITINTINFO_EC(x) (((x) >> 32) & 0xFFFFFFFF) 2087c8c0b82SPatrick Mooney 2097c8c0b82SPatrick Mooney /* Offset of various VMCB fields. */ 2107c8c0b82SPatrick Mooney #define VMCB_OFF_CTRL(x) (x) 2117c8c0b82SPatrick Mooney #define VMCB_OFF_STATE(x) ((x) + 0x400) 2127c8c0b82SPatrick Mooney 2137c8c0b82SPatrick Mooney #define VMCB_OFF_CR_INTERCEPT VMCB_OFF_CTRL(0x0) 2147c8c0b82SPatrick Mooney #define VMCB_OFF_DR_INTERCEPT VMCB_OFF_CTRL(0x4) 2157c8c0b82SPatrick Mooney #define VMCB_OFF_EXC_INTERCEPT VMCB_OFF_CTRL(0x8) 2167c8c0b82SPatrick Mooney #define VMCB_OFF_INST1_INTERCEPT VMCB_OFF_CTRL(0xC) 2177c8c0b82SPatrick Mooney #define VMCB_OFF_INST2_INTERCEPT VMCB_OFF_CTRL(0x10) 2187c8c0b82SPatrick Mooney #define VMCB_OFF_IO_PERM VMCB_OFF_CTRL(0x40) 2197c8c0b82SPatrick Mooney #define VMCB_OFF_MSR_PERM VMCB_OFF_CTRL(0x48) 2207c8c0b82SPatrick Mooney #define VMCB_OFF_TSC_OFFSET VMCB_OFF_CTRL(0x50) 2217c8c0b82SPatrick Mooney #define VMCB_OFF_ASID VMCB_OFF_CTRL(0x58) 2227c8c0b82SPatrick Mooney #define VMCB_OFF_TLB_CTRL VMCB_OFF_CTRL(0x5C) 2237c8c0b82SPatrick Mooney #define VMCB_OFF_VIRQ VMCB_OFF_CTRL(0x60) 2247c8c0b82SPatrick Mooney #define VMCB_OFF_EXIT_REASON VMCB_OFF_CTRL(0x70) 2257c8c0b82SPatrick Mooney #define VMCB_OFF_EXITINFO1 VMCB_OFF_CTRL(0x78) 2267c8c0b82SPatrick Mooney #define VMCB_OFF_EXITINFO2 VMCB_OFF_CTRL(0x80) 2277c8c0b82SPatrick Mooney #define VMCB_OFF_EXITINTINFO VMCB_OFF_CTRL(0x88) 2287c8c0b82SPatrick Mooney #define VMCB_OFF_AVIC_BAR VMCB_OFF_CTRL(0x98) 2297c8c0b82SPatrick Mooney #define VMCB_OFF_NPT_BASE VMCB_OFF_CTRL(0xB0) 2307c8c0b82SPatrick Mooney #define VMCB_OFF_AVIC_PAGE VMCB_OFF_CTRL(0xE0) 2317c8c0b82SPatrick Mooney #define VMCB_OFF_AVIC_LT VMCB_OFF_CTRL(0xF0) 2327c8c0b82SPatrick Mooney #define VMCB_OFF_AVIC_PT VMCB_OFF_CTRL(0xF8) 2337c8c0b82SPatrick Mooney #define VMCB_OFF_SYSENTER_CS VMCB_OFF_STATE(0x228) 2347c8c0b82SPatrick Mooney #define VMCB_OFF_SYSENTER_ESP VMCB_OFF_STATE(0x230) 2357c8c0b82SPatrick Mooney #define VMCB_OFF_SYSENTER_EIP VMCB_OFF_STATE(0x238) 2367c8c0b82SPatrick Mooney #define VMCB_OFF_GUEST_PAT VMCB_OFF_STATE(0x268) 2377c8c0b82SPatrick Mooney 2387c8c0b82SPatrick Mooney #ifdef _KERNEL 2397c8c0b82SPatrick Mooney /* VMCB save state area segment format */ 2407c8c0b82SPatrick Mooney struct vmcb_segment { 2417c8c0b82SPatrick Mooney uint16_t selector; 2427c8c0b82SPatrick Mooney uint16_t attrib; 2437c8c0b82SPatrick Mooney uint32_t limit; 2447c8c0b82SPatrick Mooney uint64_t base; 2457c8c0b82SPatrick Mooney }; 2467c8c0b82SPatrick Mooney CTASSERT(sizeof (struct vmcb_segment) == 16); 2477c8c0b82SPatrick Mooney 2487c8c0b82SPatrick Mooney /* Convert to/from vmcb segment access to generic (VMX) access */ 2497c8c0b82SPatrick Mooney #define VMCB_ATTR2ACCESS(attr) ((((attr) & 0xf00) << 4) | ((attr) & 0xff)) 2507c8c0b82SPatrick Mooney #define VMCB_ACCESS2ATTR(acc) ((((acc) & 0xf000) >> 4) | ((acc) & 0xff)) 2517c8c0b82SPatrick Mooney 2527c8c0b82SPatrick Mooney /* Code segment descriptor attribute in 12 bit format as saved by VMCB. */ 2537c8c0b82SPatrick Mooney #define VMCB_CS_ATTRIB_L BIT(9) /* Long mode. */ 2547c8c0b82SPatrick Mooney #define VMCB_CS_ATTRIB_D BIT(10) /* OPerand size bit. */ 2557c8c0b82SPatrick Mooney 2567c8c0b82SPatrick Mooney /* Fields for Virtual Interrupt Control (v_irq) */ 2577c8c0b82SPatrick Mooney #define V_IRQ BIT(0) /* Offset 0x60 bit 8 (0x61 bit 0) */ 2587c8c0b82SPatrick Mooney #define V_VGIF_VALUE BIT(1) /* Offset 0x60 bit 9 (0x61 bit 1) */ 2597c8c0b82SPatrick Mooney 2607c8c0b82SPatrick Mooney /* Fields for Virtual Interrupt Control (v_intr_prio) */ 2617c8c0b82SPatrick Mooney #define V_INTR_PRIO 0xf /* Offset 0x60 bits 16-19 (0x62 bits 0-3) */ 2627c8c0b82SPatrick Mooney #define V_IGN_TPR BIT(4) /* Offset 0x60 bit 20 (0x62 bit 4) */ 2637c8c0b82SPatrick Mooney 2647c8c0b82SPatrick Mooney /* Fields for Virtual Interrupt Control (v_intr_ctrl) */ 2657c8c0b82SPatrick Mooney #define V_INTR_MASKING BIT(0) /* Offset 0x60 bit 24 (0x63 bit 0) */ 2667c8c0b82SPatrick Mooney #define V_VGIF_ENABLE BIT(1) /* Offset 0x60 bit 25 (0x63 bit 1) */ 2677c8c0b82SPatrick Mooney #define V_AVIC_ENABLE BIT(7) /* Offset 0x60 bit 31 (0x63 bit 7) */ 2687c8c0b82SPatrick Mooney 2697c8c0b82SPatrick Mooney /* Fields in Interrupt Shadow, offset 0x68 */ 2707c8c0b82SPatrick Mooney #define VIRTUAL_INTR_SHADOW BIT(0) 2717c8c0b82SPatrick Mooney #define GUEST_INTERRUPT_MASK BIT(1) 2727c8c0b82SPatrick Mooney 2737c8c0b82SPatrick Mooney /* Fields in Nested Paging, offset 0x90 */ 2747c8c0b82SPatrick Mooney #define NP_ENABLE BIT(0) /* Enable nested paging */ 2757c8c0b82SPatrick Mooney #define SEV_ENABLE BIT(1) /* Enable SEV */ 2767c8c0b82SPatrick Mooney #define SEV_ES_ENABLE BIT(2) /* Enable SEV-ES */ 2777c8c0b82SPatrick Mooney #define GUEST_MODE_EXEC_TRAP BIT(3) /* Guest mode execute trap */ 2787c8c0b82SPatrick Mooney #define VIRT_TRANSPAR_ENCRYPT BIT(5) /* Virtual transparent encryption */ 2797c8c0b82SPatrick Mooney 2807c8c0b82SPatrick Mooney /* Fields in Misc virt controls, offset 0xB8 */ 2817c8c0b82SPatrick Mooney #define LBR_VIRT_ENABLE BIT(0) /* Enable LBR virtualization accel */ 2827c8c0b82SPatrick Mooney #define VIRT_VMSAVE_VMLOAD BIT(1) /* Virtualized VMSAVE/VMLOAD */ 2837c8c0b82SPatrick Mooney 2847c8c0b82SPatrick Mooney /* 2857c8c0b82SPatrick Mooney * The VMCB is divided into two areas - the first one contains various 2867c8c0b82SPatrick Mooney * control bits including the intercept vector and the second one contains 2877c8c0b82SPatrick Mooney * the guest state. 2887c8c0b82SPatrick Mooney */ 2897c8c0b82SPatrick Mooney 2907c8c0b82SPatrick Mooney /* VMCB control area - padded up to 1024 bytes */ 2917c8c0b82SPatrick Mooney struct vmcb_ctrl { 2927c8c0b82SPatrick Mooney uint32_t intercept[5]; /* 0x00-0x13: all intercepts */ 2937c8c0b82SPatrick Mooney uint32_t _pad1[10]; /* 0x14-0x3B: Reserved. */ 2947c8c0b82SPatrick Mooney uint32_t pause_ctrl; /* 0x3C, PAUSE filter thresh/count */ 2957c8c0b82SPatrick Mooney uint64_t iopm_base_pa; /* 0x40: IOPM_BASE_PA */ 2967c8c0b82SPatrick Mooney uint64_t msrpm_base_pa; /* 0x48: MSRPM_BASE_PA */ 2977c8c0b82SPatrick Mooney uint64_t tsc_offset; /* 0x50: TSC_OFFSET */ 2987c8c0b82SPatrick Mooney uint32_t asid; /* 0x58: Guest ASID */ 2997c8c0b82SPatrick Mooney uint8_t tlb_ctrl; /* 0x5C: TLB_CONTROL */ 3007c8c0b82SPatrick Mooney uint8_t _pad2[3]; /* 0x5D-0x5F: Reserved. */ 3017c8c0b82SPatrick Mooney uint8_t v_tpr; /* 0x60: Virtual TPR */ 3027c8c0b82SPatrick Mooney uint8_t v_irq; /* 0x61: V_IRQ, V_GIF_VALUE + Reserved */ 3037c8c0b82SPatrick Mooney uint8_t v_intr_prio; /* 0x62: V_INTR_PRIO, V_IGN_TPR */ 3047c8c0b82SPatrick Mooney uint8_t v_intr_ctrl; /* 0x63: V_INTR_MASKING, vGIF and AVIC enable */ 3057c8c0b82SPatrick Mooney uint8_t v_intr_vector; /* 0x64: Virtual interrupt vector */ 3067c8c0b82SPatrick Mooney uint8_t _pad3[3]; /* 0x65-0x67: Reserved */ 3077c8c0b82SPatrick Mooney uint64_t intr_shadow; /* 0x68: Interrupt shadow (and more) */ 3087c8c0b82SPatrick Mooney uint64_t exitcode; /* 0x70, Exitcode */ 3097c8c0b82SPatrick Mooney uint64_t exitinfo1; /* 0x78, EXITINFO1 */ 3107c8c0b82SPatrick Mooney uint64_t exitinfo2; /* 0x80, EXITINFO2 */ 3117c8c0b82SPatrick Mooney uint64_t exitintinfo; /* 0x88, Interrupt exit value. */ 3127c8c0b82SPatrick Mooney uint64_t np_ctrl; /* 0x90, Nested paging control. */ 3137c8c0b82SPatrick Mooney uint64_t _pad4[2]; /* 0x98-0xA7 reserved. */ 3147c8c0b82SPatrick Mooney uint64_t eventinj; /* 0xA8, Event injection. */ 3157c8c0b82SPatrick Mooney uint64_t n_cr3; /* 0xB0, Nested page table. */ 3167c8c0b82SPatrick Mooney uint64_t misc_ctrl; /* 0xB8, Misc virt controls */ 3177c8c0b82SPatrick Mooney uint32_t vmcb_clean; /* 0xC0: VMCB clean bits for caching */ 3187c8c0b82SPatrick Mooney uint32_t _pad5; /* 0xC4: Reserved */ 3197c8c0b82SPatrick Mooney uint64_t nrip; /* 0xC8: Guest next nRIP. */ 3207c8c0b82SPatrick Mooney uint8_t inst_len; /* 0xD0: #NPF decode assist */ 3217c8c0b82SPatrick Mooney uint8_t inst_bytes[15]; /* 0xD1-0xDF: guest instr bytes */ 3227c8c0b82SPatrick Mooney uint64_t avic_page_pa; /* 0xEO: AVIC backing page */ 3237c8c0b82SPatrick Mooney uint64_t _pad6; /* 0xE8-0xEF: Reserved */ 3247c8c0b82SPatrick Mooney uint64_t avic_log_tbl; /* 0xFO: AVIC logical table */ 3257c8c0b82SPatrick Mooney uint64_t avic_phys_tbl; /* 0xF8: AVIC physical page */ 3267c8c0b82SPatrick Mooney uint64_t _pad7; /* 0x100-0x107: Reserved */ 3277c8c0b82SPatrick Mooney uint64_t vmsa_pa; /* 0x108: VMSA pointer */ 3287c8c0b82SPatrick Mooney uint64_t _pad8[94]; /* 0x110-0x3FF: Reserved */ 3297c8c0b82SPatrick Mooney }; 3307c8c0b82SPatrick Mooney CTASSERT(sizeof (struct vmcb_ctrl) == 1024); 3317c8c0b82SPatrick Mooney CTASSERT(offsetof(struct vmcb_ctrl, vmsa_pa) == 0x108); 3327c8c0b82SPatrick Mooney 3337c8c0b82SPatrick Mooney struct vmcb_state { 3347c8c0b82SPatrick Mooney struct vmcb_segment es; /* 0x00: 32bit base */ 3357c8c0b82SPatrick Mooney struct vmcb_segment cs; /* 0x10: 32bit base */ 3367c8c0b82SPatrick Mooney struct vmcb_segment ss; /* 0x20: 32bit base */ 3377c8c0b82SPatrick Mooney struct vmcb_segment ds; /* 0x30: 32bit base */ 3387c8c0b82SPatrick Mooney struct vmcb_segment fs; /* 0x40 */ 3397c8c0b82SPatrick Mooney struct vmcb_segment gs; /* 0x50 */ 3407c8c0b82SPatrick Mooney struct vmcb_segment gdt; /* 0x60: base + 16bit limit */ 3417c8c0b82SPatrick Mooney struct vmcb_segment ldt; /* 0x70 */ 3427c8c0b82SPatrick Mooney struct vmcb_segment idt; /* 0x80: base + 16bit limit */ 3437c8c0b82SPatrick Mooney struct vmcb_segment tr; /* 0x90 */ 3447c8c0b82SPatrick Mooney uint8_t _pad1[43]; /* 0xA0-0xCA: Reserved */ 3457c8c0b82SPatrick Mooney uint8_t cpl; /* 0xCB: CPL (real mode: 0, virt: 3) */ 3467c8c0b82SPatrick Mooney uint32_t _pad2; /* 0xCC-0xCF: Reserved */ 3477c8c0b82SPatrick Mooney uint64_t efer; /* 0xD0 */ 3487c8c0b82SPatrick Mooney uint64_t _pad3[14]; /* 0xD8-0x147: Reserved */ 3497c8c0b82SPatrick Mooney uint64_t cr4; /* 0x148 */ 3507c8c0b82SPatrick Mooney uint64_t cr3; /* 0x150 */ 3517c8c0b82SPatrick Mooney uint64_t cr0; /* 0x158 */ 3527c8c0b82SPatrick Mooney uint64_t dr7; /* 0x160 */ 3537c8c0b82SPatrick Mooney uint64_t dr6; /* 0x168 */ 3547c8c0b82SPatrick Mooney uint64_t rflags; /* 0x170 */ 3557c8c0b82SPatrick Mooney uint64_t rip; /* 0x178 */ 3567c8c0b82SPatrick Mooney uint64_t _pad4[11]; /* 0x180-0x1D7: Reserved */ 3577c8c0b82SPatrick Mooney uint64_t rsp; /* 0x1D8 */ 3587c8c0b82SPatrick Mooney uint64_t _pad5[3]; /* 0x1E0-0x1F7: Reserved */ 3597c8c0b82SPatrick Mooney uint64_t rax; /* 0x1F8 */ 3607c8c0b82SPatrick Mooney uint64_t star; /* 0x200 */ 3617c8c0b82SPatrick Mooney uint64_t lstar; /* 0x208 */ 3627c8c0b82SPatrick Mooney uint64_t cstar; /* 0x210 */ 3637c8c0b82SPatrick Mooney uint64_t sfmask; /* 0x218 */ 3647c8c0b82SPatrick Mooney uint64_t kernelgsbase; /* 0x220 */ 3657c8c0b82SPatrick Mooney uint64_t sysenter_cs; /* 0x228 */ 3667c8c0b82SPatrick Mooney uint64_t sysenter_esp; /* 0x230 */ 3677c8c0b82SPatrick Mooney uint64_t sysenter_eip; /* 0x238 */ 3687c8c0b82SPatrick Mooney uint64_t cr2; /* 0x240 */ 3697c8c0b82SPatrick Mooney uint64_t _pad6[4]; /* 0x248-0x267: Reserved */ 3707c8c0b82SPatrick Mooney uint64_t g_pat; /* 0x268 */ 3717c8c0b82SPatrick Mooney uint64_t dbgctl; /* 0x270 */ 3727c8c0b82SPatrick Mooney uint64_t br_from; /* 0x278 */ 3737c8c0b82SPatrick Mooney uint64_t br_to; /* 0x280 */ 3747c8c0b82SPatrick Mooney uint64_t int_from; /* 0x288 */ 3757c8c0b82SPatrick Mooney uint64_t int_to; /* 0x290 */ 3767c8c0b82SPatrick Mooney uint64_t _pad7[301]; /* Reserved up to end of VMCB */ 3777c8c0b82SPatrick Mooney }; 3787c8c0b82SPatrick Mooney CTASSERT(sizeof (struct vmcb_state) == 0xC00); 3797c8c0b82SPatrick Mooney CTASSERT(offsetof(struct vmcb_state, int_to) == 0x290); 3807c8c0b82SPatrick Mooney 3817c8c0b82SPatrick Mooney /* 3827c8c0b82SPatrick Mooney * The VMCB aka Virtual Machine Control Block is a 4KB aligned page 3837c8c0b82SPatrick Mooney * in memory that describes the virtual machine. 3847c8c0b82SPatrick Mooney * 3857c8c0b82SPatrick Mooney * The VMCB contains: 3867c8c0b82SPatrick Mooney * - instructions or events in the guest to intercept 3877c8c0b82SPatrick Mooney * - control bits that modify execution environment of the guest 3887c8c0b82SPatrick Mooney * - guest processor state (e.g. general purpose registers) 3897c8c0b82SPatrick Mooney */ 3907c8c0b82SPatrick Mooney struct vmcb { 3917c8c0b82SPatrick Mooney struct vmcb_ctrl ctrl; 3927c8c0b82SPatrick Mooney struct vmcb_state state; 3937c8c0b82SPatrick Mooney }; 3947c8c0b82SPatrick Mooney CTASSERT(sizeof (struct vmcb) == PAGE_SIZE); 3957c8c0b82SPatrick Mooney CTASSERT(offsetof(struct vmcb, state) == 0x400); 3967c8c0b82SPatrick Mooney 3977c8c0b82SPatrick Mooney struct vmcb_segment *vmcb_segptr(struct vmcb *vmcb, int type); 3987c8c0b82SPatrick Mooney uint64_t *vmcb_regptr(struct vmcb *vmcb, int ident, uint32_t *dirtyp); 39954cf5b63SPatrick Mooney uint64_t *vmcb_msr_ptr(struct vmcb *vmcb, uint32_t ident, uint32_t *dirtyp); 4007c8c0b82SPatrick Mooney 4017c8c0b82SPatrick Mooney #endif /* _KERNEL */ 4027c8c0b82SPatrick Mooney #endif /* _VMCB_H_ */ 403