xref: /illumos-gate/usr/src/uts/intel/io/vmm/amd/vmcb.c (revision 5b0d53307d70a828ad7aef4dc6d8a3ad7d5c231b)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2013 Anish Gupta (akgupt3@gmail.com)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * This file and its contents are supplied under the terms of the
31  * Common Development and Distribution License ("CDDL"), version 1.0.
32  * You may only use this file in accordance with the terms of version
33  * 1.0 of the CDDL.
34  *
35  * A full copy of the text of the CDDL should have accompanied this
36  * source.  A copy of the CDDL is also available via the Internet at
37  * http://www.illumos.org/license/CDDL.
38  *
39  * Copyright 2020 Oxide Computer Company
40  */
41 
42 #include <sys/cdefs.h>
43 __FBSDID("$FreeBSD$");
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 
48 #include <machine/vmm.h>
49 
50 #include "vmcb.h"
51 #include "svm.h"
52 
53 struct vmcb_segment *
54 vmcb_segptr(struct vmcb *vmcb, int type)
55 {
56 	struct vmcb_state *state = &vmcb->state;
57 
58 	switch (type) {
59 	case VM_REG_GUEST_CS:
60 		return (&state->cs);
61 	case VM_REG_GUEST_DS:
62 		return (&state->ds);
63 	case VM_REG_GUEST_ES:
64 		return (&state->es);
65 	case VM_REG_GUEST_FS:
66 		return (&state->fs);
67 	case VM_REG_GUEST_GS:
68 		return (&state->gs);
69 	case VM_REG_GUEST_SS:
70 		return (&state->ss);
71 	case VM_REG_GUEST_GDTR:
72 		return (&state->gdt);
73 	case VM_REG_GUEST_IDTR:
74 		return (&state->idt);
75 	case VM_REG_GUEST_LDTR:
76 		return (&state->ldt);
77 	case VM_REG_GUEST_TR:
78 		return (&state->tr);
79 	default:
80 		panic("unexpected seg %d", type);
81 	}
82 }
83 
84 uint64_t *
85 vmcb_regptr(struct vmcb *vmcb, int ident, uint32_t *dirtyp)
86 {
87 	struct vmcb_state *state;
88 	uint64_t *res = NULL;
89 	uint32_t dirty = VMCB_CACHE_NONE;
90 
91 	state = &vmcb->state;
92 
93 	switch (ident) {
94 	case VM_REG_GUEST_CR2:
95 		res = &state->cr2;
96 		dirty = VMCB_CACHE_CR2;
97 		break;
98 
99 	case VM_REG_GUEST_CR3:
100 		res = &state->cr3;
101 		dirty = VMCB_CACHE_CR;
102 		break;
103 
104 	case VM_REG_GUEST_CR4:
105 		res = &state->cr4;
106 		dirty = VMCB_CACHE_CR;
107 		break;
108 
109 	case VM_REG_GUEST_DR6:
110 		res = &state->dr6;
111 		dirty = VMCB_CACHE_DR;
112 		break;
113 
114 	case VM_REG_GUEST_DR7:
115 		res = &state->dr7;
116 		dirty = VMCB_CACHE_DR;
117 		break;
118 
119 	case VM_REG_GUEST_EFER:
120 		res = &state->efer;
121 		dirty = VMCB_CACHE_CR;
122 		break;
123 
124 	case VM_REG_GUEST_RAX:
125 		res = &state->rax;
126 		break;
127 
128 	case VM_REG_GUEST_RFLAGS:
129 		res = &state->rflags;
130 		break;
131 
132 	case VM_REG_GUEST_RIP:
133 		res = &state->rip;
134 		break;
135 
136 	case VM_REG_GUEST_RSP:
137 		res = &state->rsp;
138 		break;
139 
140 	default:
141 		panic("unexpected register %d", ident);
142 		break;
143 	}
144 
145 	ASSERT(res != NULL);
146 	if (dirtyp != NULL) {
147 		*dirtyp |= dirty;
148 	}
149 	return (res);
150 }
151