| 116 | } |
| 117 | |
| 118 | static int |
| 119 | vmcb_access(struct svm_softc *softc, int vcpu, int write, int ident, |
| 120 | uint64_t *val) |
| 121 | { |
| 122 | struct vmcb *vmcb; |
| 123 | int off, bytes; |
| 124 | char *ptr; |
| 125 | |
| 126 | vmcb = svm_get_vmcb(softc, vcpu); |
| 127 | off = VMCB_ACCESS_OFFSET(ident); |
| 128 | bytes = VMCB_ACCESS_BYTES(ident); |
| 129 | |
| 130 | if ((off + bytes) >= sizeof (struct vmcb)) |
| 131 | return (EINVAL); |
| 132 | |
| 133 | ptr = (char *)vmcb; |
| 134 | |
| 135 | if (!write) |
| 136 | *val = 0; |
| 137 | |
| 138 | switch (bytes) { |
| 139 | case 8: |
| 140 | case 4: |
| 141 | case 2: |
| 142 | if (write) |
| 143 | memcpy(ptr + off, val, bytes); |
| 144 | else |
| 145 | memcpy(val, ptr + off, bytes); |
| 146 | break; |
| 147 | default: |
| 148 | VCPU_CTR1(softc->vm, vcpu, |
| 149 | "Invalid size %d for VMCB access: %d", bytes); |
| 150 | return (EINVAL); |
| 151 | } |
| 152 | |
| 153 | /* Invalidate all VMCB state cached by h/w. */ |
| 154 | if (write) |
| 155 | svm_set_dirty(softc, vcpu, 0xffffffff); |
| 156 | |
| 157 | return (0); |
| 158 | } |
| 159 | |
| 160 | /* |
| 161 | * Read from segment selector, control and general purpose register of VMCB. |
no test coverage detected