xref: /illumos-gate/usr/src/uts/intel/io/vmm/amd/vmcb.c (revision 32640292)
14c87aefeSPatrick Mooney /*-
2*32640292SAndy Fiddaman  * SPDX-License-Identifier: BSD-2-Clause
34c87aefeSPatrick Mooney  *
44c87aefeSPatrick Mooney  * Copyright (c) 2013 Anish Gupta (akgupt3@gmail.com)
54c87aefeSPatrick Mooney  * All rights reserved.
64c87aefeSPatrick Mooney  *
74c87aefeSPatrick Mooney  * Redistribution and use in source and binary forms, with or without
84c87aefeSPatrick Mooney  * modification, are permitted provided that the following conditions
94c87aefeSPatrick Mooney  * are met:
104c87aefeSPatrick Mooney  * 1. Redistributions of source code must retain the above copyright
114c87aefeSPatrick Mooney  *    notice unmodified, this list of conditions, and the following
124c87aefeSPatrick Mooney  *    disclaimer.
134c87aefeSPatrick Mooney  * 2. Redistributions in binary form must reproduce the above copyright
144c87aefeSPatrick Mooney  *    notice, this list of conditions and the following disclaimer in the
154c87aefeSPatrick Mooney  *    documentation and/or other materials provided with the distribution.
164c87aefeSPatrick Mooney  *
174c87aefeSPatrick Mooney  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
184c87aefeSPatrick Mooney  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
194c87aefeSPatrick Mooney  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
204c87aefeSPatrick Mooney  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
214c87aefeSPatrick Mooney  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
224c87aefeSPatrick Mooney  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
234c87aefeSPatrick Mooney  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
244c87aefeSPatrick Mooney  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
254c87aefeSPatrick Mooney  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
264c87aefeSPatrick Mooney  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274c87aefeSPatrick Mooney  */
284c87aefeSPatrick Mooney 
29096bb5cbSPatrick Mooney /*
30096bb5cbSPatrick Mooney  * This file and its contents are supplied under the terms of the
31096bb5cbSPatrick Mooney  * Common Development and Distribution License ("CDDL"), version 1.0.
32096bb5cbSPatrick Mooney  * You may only use this file in accordance with the terms of version
33096bb5cbSPatrick Mooney  * 1.0 of the CDDL.
34096bb5cbSPatrick Mooney  *
35096bb5cbSPatrick Mooney  * A full copy of the text of the CDDL should have accompanied this
36096bb5cbSPatrick Mooney  * source.  A copy of the CDDL is also available via the Internet at
37096bb5cbSPatrick Mooney  * http://www.illumos.org/license/CDDL.
38096bb5cbSPatrick Mooney  *
39096bb5cbSPatrick Mooney  * Copyright 2020 Oxide Computer Company
40096bb5cbSPatrick Mooney  */
41096bb5cbSPatrick Mooney 
424c87aefeSPatrick Mooney #include <sys/cdefs.h>
434c87aefeSPatrick Mooney 
444c87aefeSPatrick Mooney #include <sys/param.h>
454c87aefeSPatrick Mooney #include <sys/systm.h>
46ae8179d3SPatrick Mooney #include <sys/x86_archext.h>
474c87aefeSPatrick Mooney 
4854cf5b63SPatrick Mooney #include <machine/specialreg.h>
494c87aefeSPatrick Mooney #include <machine/vmm.h>
504c87aefeSPatrick Mooney 
514c87aefeSPatrick Mooney #include "vmcb.h"
524c87aefeSPatrick Mooney #include "svm.h"
534c87aefeSPatrick Mooney 
54096bb5cbSPatrick Mooney struct vmcb_segment *
vmcb_segptr(struct vmcb * vmcb,int type)554c87aefeSPatrick Mooney vmcb_segptr(struct vmcb *vmcb, int type)
564c87aefeSPatrick Mooney {
57096bb5cbSPatrick Mooney 	struct vmcb_state *state = &vmcb->state;
584c87aefeSPatrick Mooney 
594c87aefeSPatrick Mooney 	switch (type) {
604c87aefeSPatrick Mooney 	case VM_REG_GUEST_CS:
61096bb5cbSPatrick Mooney 		return (&state->cs);
624c87aefeSPatrick Mooney 	case VM_REG_GUEST_DS:
63096bb5cbSPatrick Mooney 		return (&state->ds);
644c87aefeSPatrick Mooney 	case VM_REG_GUEST_ES:
65096bb5cbSPatrick Mooney 		return (&state->es);
664c87aefeSPatrick Mooney 	case VM_REG_GUEST_FS:
67096bb5cbSPatrick Mooney 		return (&state->fs);
684c87aefeSPatrick Mooney 	case VM_REG_GUEST_GS:
69096bb5cbSPatrick Mooney 		return (&state->gs);
704c87aefeSPatrick Mooney 	case VM_REG_GUEST_SS:
71096bb5cbSPatrick Mooney 		return (&state->ss);
724c87aefeSPatrick Mooney 	case VM_REG_GUEST_GDTR:
73096bb5cbSPatrick Mooney 		return (&state->gdt);
744c87aefeSPatrick Mooney 	case VM_REG_GUEST_IDTR:
75096bb5cbSPatrick Mooney 		return (&state->idt);
764c87aefeSPatrick Mooney 	case VM_REG_GUEST_LDTR:
77096bb5cbSPatrick Mooney 		return (&state->ldt);
784c87aefeSPatrick Mooney 	case VM_REG_GUEST_TR:
79096bb5cbSPatrick Mooney 		return (&state->tr);
804c87aefeSPatrick Mooney 	default:
81096bb5cbSPatrick Mooney 		panic("unexpected seg %d", type);
824c87aefeSPatrick Mooney 	}
834c87aefeSPatrick Mooney }
844c87aefeSPatrick Mooney 
85096bb5cbSPatrick Mooney uint64_t *
vmcb_regptr(struct vmcb * vmcb,int ident,uint32_t * dirtyp)86096bb5cbSPatrick Mooney vmcb_regptr(struct vmcb *vmcb, int ident, uint32_t *dirtyp)
874c87aefeSPatrick Mooney {
884c87aefeSPatrick Mooney 	struct vmcb_state *state;
89096bb5cbSPatrick Mooney 	uint64_t *res = NULL;
90096bb5cbSPatrick Mooney 	uint32_t dirty = VMCB_CACHE_NONE;
914c87aefeSPatrick Mooney 
924c87aefeSPatrick Mooney 	state = &vmcb->state;
934c87aefeSPatrick Mooney 
944c87aefeSPatrick Mooney 	switch (ident) {
954c87aefeSPatrick Mooney 	case VM_REG_GUEST_CR2:
96096bb5cbSPatrick Mooney 		res = &state->cr2;
97096bb5cbSPatrick Mooney 		dirty = VMCB_CACHE_CR2;
984c87aefeSPatrick Mooney 		break;
994c87aefeSPatrick Mooney 
1004c87aefeSPatrick Mooney 	case VM_REG_GUEST_CR3:
101096bb5cbSPatrick Mooney 		res = &state->cr3;
102096bb5cbSPatrick Mooney 		dirty = VMCB_CACHE_CR;
1034c87aefeSPatrick Mooney 		break;
1044c87aefeSPatrick Mooney 
1054c87aefeSPatrick Mooney 	case VM_REG_GUEST_CR4:
106096bb5cbSPatrick Mooney 		res = &state->cr4;
107096bb5cbSPatrick Mooney 		dirty = VMCB_CACHE_CR;
1084c87aefeSPatrick Mooney 		break;
1094c87aefeSPatrick Mooney 
1104c87aefeSPatrick Mooney 	case VM_REG_GUEST_DR6:
111096bb5cbSPatrick Mooney 		res = &state->dr6;
112096bb5cbSPatrick Mooney 		dirty = VMCB_CACHE_DR;
1134c87aefeSPatrick Mooney 		break;
1144c87aefeSPatrick Mooney 
1154c87aefeSPatrick Mooney 	case VM_REG_GUEST_DR7:
116096bb5cbSPatrick Mooney 		res = &state->dr7;
117096bb5cbSPatrick Mooney 		dirty = VMCB_CACHE_DR;
1184c87aefeSPatrick Mooney 		break;
1194c87aefeSPatrick Mooney 
1204c87aefeSPatrick Mooney 	case VM_REG_GUEST_EFER:
121096bb5cbSPatrick Mooney 		res = &state->efer;
122096bb5cbSPatrick Mooney 		dirty = VMCB_CACHE_CR;
1234c87aefeSPatrick Mooney 		break;
1244c87aefeSPatrick Mooney 
1254c87aefeSPatrick Mooney 	case VM_REG_GUEST_RAX:
126096bb5cbSPatrick Mooney 		res = &state->rax;
1274c87aefeSPatrick Mooney 		break;
1284c87aefeSPatrick Mooney 
1294c87aefeSPatrick Mooney 	case VM_REG_GUEST_RFLAGS:
130096bb5cbSPatrick Mooney 		res = &state->rflags;
1314c87aefeSPatrick Mooney 		break;
1324c87aefeSPatrick Mooney 
1334c87aefeSPatrick Mooney 	case VM_REG_GUEST_RIP:
134096bb5cbSPatrick Mooney 		res = &state->rip;
1354c87aefeSPatrick Mooney 		break;
1364c87aefeSPatrick Mooney 
1374c87aefeSPatrick Mooney 	case VM_REG_GUEST_RSP:
138096bb5cbSPatrick Mooney 		res = &state->rsp;
1394c87aefeSPatrick Mooney 		break;
1404c87aefeSPatrick Mooney 
1414c87aefeSPatrick Mooney 	default:
142096bb5cbSPatrick Mooney 		panic("unexpected register %d", ident);
1434c87aefeSPatrick Mooney 		break;
1444c87aefeSPatrick Mooney 	}
1454c87aefeSPatrick Mooney 
146096bb5cbSPatrick Mooney 	ASSERT(res != NULL);
147096bb5cbSPatrick Mooney 	if (dirtyp != NULL) {
148096bb5cbSPatrick Mooney 		*dirtyp |= dirty;
1494c87aefeSPatrick Mooney 	}
150096bb5cbSPatrick Mooney 	return (res);
1514c87aefeSPatrick Mooney }
15254cf5b63SPatrick Mooney 
15354cf5b63SPatrick Mooney uint64_t *
vmcb_msr_ptr(struct vmcb * vmcb,uint32_t msr,uint32_t * dirtyp)15454cf5b63SPatrick Mooney vmcb_msr_ptr(struct vmcb *vmcb, uint32_t msr, uint32_t *dirtyp)
15554cf5b63SPatrick Mooney {
15654cf5b63SPatrick Mooney 	uint64_t *res = NULL;
15754cf5b63SPatrick Mooney 	uint32_t dirty = 0;
15854cf5b63SPatrick Mooney 	struct vmcb_state *state = &vmcb->state;
15954cf5b63SPatrick Mooney 
16054cf5b63SPatrick Mooney 	switch (msr) {
16154cf5b63SPatrick Mooney 	case MSR_EFER:
16254cf5b63SPatrick Mooney 		res = &state->efer;
16354cf5b63SPatrick Mooney 		dirty = VMCB_CACHE_CR;
16454cf5b63SPatrick Mooney 		break;
16554cf5b63SPatrick Mooney 
16654cf5b63SPatrick Mooney 	case MSR_GSBASE:
16754cf5b63SPatrick Mooney 		res = &state->gs.base;
16854cf5b63SPatrick Mooney 		dirty = VMCB_CACHE_SEG;
16954cf5b63SPatrick Mooney 		break;
17054cf5b63SPatrick Mooney 	case MSR_FSBASE:
17154cf5b63SPatrick Mooney 		res = &state->fs.base;
17254cf5b63SPatrick Mooney 		dirty = VMCB_CACHE_SEG;
17354cf5b63SPatrick Mooney 		break;
17454cf5b63SPatrick Mooney 	case MSR_KGSBASE:
17554cf5b63SPatrick Mooney 		res = &state->kernelgsbase;
17654cf5b63SPatrick Mooney 		break;
17754cf5b63SPatrick Mooney 
17854cf5b63SPatrick Mooney 	case MSR_STAR:
17954cf5b63SPatrick Mooney 		res = &state->star;
18054cf5b63SPatrick Mooney 		break;
18154cf5b63SPatrick Mooney 	case MSR_LSTAR:
18254cf5b63SPatrick Mooney 		res = &state->lstar;
18354cf5b63SPatrick Mooney 		break;
18454cf5b63SPatrick Mooney 	case MSR_CSTAR:
18554cf5b63SPatrick Mooney 		res = &state->cstar;
18654cf5b63SPatrick Mooney 		break;
18754cf5b63SPatrick Mooney 	case MSR_SF_MASK:
18854cf5b63SPatrick Mooney 		res = &state->sfmask;
18954cf5b63SPatrick Mooney 		break;
19054cf5b63SPatrick Mooney 
19154cf5b63SPatrick Mooney 	case MSR_SYSENTER_CS_MSR:
19254cf5b63SPatrick Mooney 		res = &state->sysenter_cs;
19354cf5b63SPatrick Mooney 		break;
19454cf5b63SPatrick Mooney 	case MSR_SYSENTER_ESP_MSR:
19554cf5b63SPatrick Mooney 		res = &state->sysenter_esp;
19654cf5b63SPatrick Mooney 		break;
19754cf5b63SPatrick Mooney 	case MSR_SYSENTER_EIP_MSR:
19854cf5b63SPatrick Mooney 		res = &state->sysenter_eip;
19954cf5b63SPatrick Mooney 		break;
20054cf5b63SPatrick Mooney 
20154cf5b63SPatrick Mooney 	case MSR_PAT:
20254cf5b63SPatrick Mooney 		res = &state->g_pat;
20354cf5b63SPatrick Mooney 		dirty = VMCB_CACHE_NP;
20454cf5b63SPatrick Mooney 		break;
205ae8179d3SPatrick Mooney 
206ae8179d3SPatrick Mooney 	case MSR_DEBUGCTL:
207ae8179d3SPatrick Mooney 		res = &state->dbgctl;
208ae8179d3SPatrick Mooney 		dirty = VMCB_CACHE_LBR;
209ae8179d3SPatrick Mooney 		break;
210ae8179d3SPatrick Mooney 	case MSR_LBR_FROM:
211ae8179d3SPatrick Mooney 		res = &state->br_from;
212ae8179d3SPatrick Mooney 		dirty = VMCB_CACHE_LBR;
213ae8179d3SPatrick Mooney 		break;
214ae8179d3SPatrick Mooney 	case MSR_LBR_TO:
215ae8179d3SPatrick Mooney 		res = &state->br_to;
216ae8179d3SPatrick Mooney 		dirty = VMCB_CACHE_LBR;
217ae8179d3SPatrick Mooney 		break;
218ae8179d3SPatrick Mooney 	case MSR_LEX_FROM:
219ae8179d3SPatrick Mooney 		res = &state->int_from;
220ae8179d3SPatrick Mooney 		dirty = VMCB_CACHE_LBR;
221ae8179d3SPatrick Mooney 		break;
222ae8179d3SPatrick Mooney 	case MSR_LEX_TO:
223ae8179d3SPatrick Mooney 		res = &state->int_to;
224ae8179d3SPatrick Mooney 		dirty = VMCB_CACHE_LBR;
225ae8179d3SPatrick Mooney 		break;
22654cf5b63SPatrick Mooney 	}
22754cf5b63SPatrick Mooney 
22854cf5b63SPatrick Mooney 	if (res != NULL && dirtyp != NULL) {
22954cf5b63SPatrick Mooney 		*dirtyp = dirty;
23054cf5b63SPatrick Mooney 	}
23154cf5b63SPatrick Mooney 	return (res);
23254cf5b63SPatrick Mooney }
233