Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F96479166
D33333.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D33333.diff
View Options
diff --git a/sys/amd64/vmm/amd/svm_msr.c b/sys/amd64/vmm/amd/svm_msr.c
--- a/sys/amd64/vmm/amd/svm_msr.c
+++ b/sys/amd64/vmm/amd/svm_msr.c
@@ -120,9 +120,14 @@
break;
case MSR_MTRRcap:
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_rdmtrr(&sc->mtrr[vcpu], num, result) != 0) {
+ vm_inject_gp(sc->vm, vcpu);
+ }
+ break;
case MSR_SYSCFG:
case MSR_AMDK8_IPM:
case MSR_EXTFEATURES:
@@ -146,12 +151,15 @@
case MSR_MCG_STATUS:
break; /* ignore writes */
case MSR_MTRRcap:
- vm_inject_gp(sc->vm, vcpu);
- break;
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_wrmtrr(&sc->mtrr[vcpu], num, val) != 0) {
+ vm_inject_gp(sc->vm, vcpu);
+ }
+ break;
case MSR_SYSCFG:
break; /* Ignore writes */
case MSR_AMDK8_IPM:
diff --git a/sys/amd64/vmm/amd/svm_softc.h b/sys/amd64/vmm/amd/svm_softc.h
--- a/sys/amd64/vmm/amd/svm_softc.h
+++ b/sys/amd64/vmm/amd/svm_softc.h
@@ -31,6 +31,8 @@
#ifndef _SVM_SOFTC_H_
#define _SVM_SOFTC_H_
+#include "x86.h"
+
#define SVM_IO_BITMAP_SIZE (3 * PAGE_SIZE)
#define SVM_MSR_BITMAP_SIZE (2 * PAGE_SIZE)
@@ -64,6 +66,7 @@
uint8_t *iopm_bitmap; /* shared by all vcpus */
uint8_t *msr_bitmap; /* shared by all vcpus */
struct vm *vm;
+ struct vm_mtrr mtrr[VM_MAXCPU];
};
CTASSERT((offsetof(struct svm_softc, nptp) & PAGE_MASK) == 0);
diff --git a/sys/amd64/vmm/intel/vmx.h b/sys/amd64/vmm/intel/vmx.h
--- a/sys/amd64/vmm/intel/vmx.h
+++ b/sys/amd64/vmm/intel/vmx.h
@@ -32,6 +32,7 @@
#define _VMX_H_
#include "vmcs.h"
+#include "x86.h"
struct pmap;
@@ -134,6 +135,7 @@
uint64_t eptp;
struct vm *vm;
long eptgen[MAXCPU]; /* cached pmap->pm_eptgen */
+ struct vm_mtrr mtrr[VM_MAXCPU];
};
CTASSERT((offsetof(struct vmx, vmcs) & PAGE_MASK) == 0);
CTASSERT((offsetof(struct vmx, msr_bitmap) & PAGE_MASK) == 0);
diff --git a/sys/amd64/vmm/intel/vmx_msr.c b/sys/amd64/vmm/intel/vmx_msr.c
--- a/sys/amd64/vmm/intel/vmx_msr.c
+++ b/sys/amd64/vmm/intel/vmx_msr.c
@@ -425,10 +425,13 @@
break;
case MSR_MTRRcap:
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
- *val = 0;
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_rdmtrr(&vmx->mtrr[vcpuid], num, val) != 0) {
+ vm_inject_gp(vmx->vm, vcpuid);
+ }
break;
case MSR_IA32_MISC_ENABLE:
*val = misc_enable;
@@ -465,13 +468,15 @@
case MSR_MCG_STATUS:
break; /* ignore writes */
case MSR_MTRRcap:
- vm_inject_gp(vmx->vm, vcpuid);
- break;
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
- break; /* Ignore writes */
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_wrmtrr(&vmx->mtrr[vcpuid], num, val) != 0) {
+ vm_inject_gp(vmx->vm, vcpuid);
+ }
+ break;
case MSR_IA32_MISC_ENABLE:
changed = val ^ misc_enable;
/*
diff --git a/sys/amd64/vmm/x86.h b/sys/amd64/vmm/x86.h
--- a/sys/amd64/vmm/x86.h
+++ b/sys/amd64/vmm/x86.h
@@ -80,4 +80,24 @@
* and 'false' otherwise.
*/
bool vm_cpuid_capability(struct vm *vm, int vcpuid, enum vm_cpuid_capability);
+
+#define VMM_MTRR_VAR_MAX 10
+#define VMM_MTRR_DEF_MASK \
+ (MTRR_DEF_ENABLE | MTRR_DEF_FIXED_ENABLE | MTRR_DEF_TYPE)
+#define VMM_MTRR_PHYSBASE_MASK (MTRR_PHYSBASE_PHYSBASE | MTRR_PHYSBASE_TYPE)
+#define VMM_MTRR_PHYSMASK_MASK (MTRR_PHYSMASK_PHYSMASK | MTRR_PHYSMASK_VALID)
+struct vm_mtrr {
+ uint64_t def_type;
+ uint64_t fixed4k[8];
+ uint64_t fixed16k[2];
+ uint64_t fixed64k;
+ struct {
+ uint64_t base;
+ uint64_t mask;
+ } var[VMM_MTRR_VAR_MAX];
+};
+
+int vm_rdmtrr(struct vm_mtrr *mtrr, u_int num, uint64_t *val);
+int vm_wrmtrr(struct vm_mtrr *mtrr, u_int num, uint64_t val);
+
#endif
diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c
--- a/sys/amd64/vmm/x86.c
+++ b/sys/amd64/vmm/x86.c
@@ -648,3 +648,85 @@
}
return (rv);
}
+
+int
+vm_rdmtrr(struct vm_mtrr *mtrr, u_int num, uint64_t *val)
+{
+ switch (num) {
+ case MSR_MTRRcap:
+ *val = MTRR_CAP_WC | MTRR_CAP_FIXED | VMM_MTRR_VAR_MAX;
+ break;
+ case MSR_MTRRdefType:
+ *val = mtrr->def_type;
+ break;
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
+ *val = mtrr->fixed4k[num - MSR_MTRR4kBase];
+ break;
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ *val = mtrr->fixed16k[num - MSR_MTRR16kBase];
+ break;
+ case MSR_MTRR64kBase:
+ *val = mtrr->fixed64k;
+ break;
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1: {
+ u_int offset = num - MSR_MTRRVarBase;
+ if (offset % 2 == 0) {
+ *val = mtrr->var[offset / 2].base;
+ } else {
+ *val = mtrr->var[offset / 2].mask;
+ }
+ break;
+ }
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+vm_wrmtrr(struct vm_mtrr *mtrr, u_int num, uint64_t val)
+{
+ switch (num) {
+ case MSR_MTRRcap:
+ /* MTRRCAP is read only */
+ return (-1);
+ case MSR_MTRRdefType:
+ if (val & ~VMM_MTRR_DEF_MASK) {
+ /* generate #GP on writes to reserved fields */
+ return (-1);
+ }
+ mtrr->def_type = val;
+ break;
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
+ mtrr->fixed4k[num - MSR_MTRR4kBase] = val;
+ break;
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ mtrr->fixed16k[num - MSR_MTRR16kBase] = val;
+ break;
+ case MSR_MTRR64kBase:
+ mtrr->fixed64k = val;
+ break;
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1: {
+ u_int offset = num - MSR_MTRRVarBase;
+ if (offset % 2 == 0) {
+ if (val & ~VMM_MTRR_PHYSBASE_MASK) {
+ /* generate #GP on writes to reserved fields */
+ return (-1);
+ }
+ mtrr->var[offset / 2].base = val;
+ } else {
+ if (val & ~VMM_MTRR_PHYSMASK_MASK) {
+ /* generate #GP on writes to reserved fields */
+ return (-1);
+ }
+ mtrr->var[offset / 2].mask = val;
+ }
+ break;
+ }
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 26, 3:12 AM (21 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12808985
Default Alt Text
D33333.diff (6 KB)
Attached To
Mode
D33333: bhyve: add support for MTRR
Attached
Detach File
Event Timeline
Log In to Comment