mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-09-22 01:07:57 +00:00
hv: basic MTRR virtualization
Linux commit edfe63ec97ed ("x86/mtrr: Fix Xorg crashes in Qemu sessions") disables PAT feature if MTRR is not enabled. This patch does partial emulation of MTRR to prevent this from happening: enable fixed-range MTRRs and disable virable range MTRRs By default IA32_PAT MSR (SDM Vol3 11.12.4, Table 11-12) doesn't include 'WC' type. If MTRR is disabled from the guests, Linux doesn't allow writing IA32_PAT MSR so WC type can't be enabled. This creates some performance issues for certian applications that rely on WC memory type. Implementation summary: - Enable MTRR feature: MTRRdefType.E=1 - Enable fixed range MTRRs: MTRRCAP.fix=1, MTRRdefType.FE=1 - For simplicity, disable variable range MTRRs: MTRRCAP.vcnt=0. It's expected that this bit is honored by the guests and they won't change the guest memory type through variable MTRRs. Signed-off-by: bliu11 <baohong.liu@intel.com> Signed-off-by: Zide Chen <zide.chen@intel.com> Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
@@ -246,6 +246,9 @@ struct vcpu {
|
||||
*/
|
||||
uint64_t msr_tsc_aux_guest;
|
||||
uint64_t *guest_msrs;
|
||||
#ifdef CONFIG_MTRR_ENABLED
|
||||
struct mtrr_state mtrr;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define is_vcpu_bsp(vcpu) ((vcpu)->vcpu_id == 0)
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include <lapic.h>
|
||||
#include <msr.h>
|
||||
#include <io.h>
|
||||
#include <mtrr.h>
|
||||
#include <vcpu.h>
|
||||
#include <trusty.h>
|
||||
#include <pm.h>
|
||||
|
51
hypervisor/include/arch/x86/mtrr.h
Executable file
51
hypervisor/include/arch/x86/mtrr.h
Executable file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) <2018> Intel Corporation
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MTRR_H
|
||||
#define MTRR_H
|
||||
|
||||
#define FIXED_RANGE_MTRR_NUM 11
|
||||
#define MTRR_SUB_RANGE_NUM 8
|
||||
|
||||
union mtrr_cap_reg {
|
||||
uint64_t value;
|
||||
struct {
|
||||
uint64_t vcnt:8;
|
||||
uint64_t fix:1;
|
||||
uint64_t res0:1;
|
||||
uint64_t wc:1;
|
||||
uint64_t res1:21;
|
||||
uint64_t res2:32;
|
||||
} bits;
|
||||
};
|
||||
|
||||
union mtrr_def_type_reg {
|
||||
uint64_t value;
|
||||
struct {
|
||||
uint64_t type:8;
|
||||
uint64_t res0:2;
|
||||
uint64_t fixed_enable:1;
|
||||
uint64_t enable:1;
|
||||
uint64_t res1:20;
|
||||
uint64_t res2:32;
|
||||
} bits;
|
||||
};
|
||||
|
||||
union mtrr_fixed_range_reg {
|
||||
uint64_t value;
|
||||
uint8_t type[MTRR_SUB_RANGE_NUM];
|
||||
};
|
||||
|
||||
struct mtrr_state {
|
||||
union mtrr_cap_reg cap;
|
||||
union mtrr_def_type_reg def_type;
|
||||
union mtrr_fixed_range_reg fixed_range[FIXED_RANGE_MTRR_NUM];
|
||||
};
|
||||
|
||||
void mtrr_wrmsr(struct vcpu *vcpu, uint32_t msr, uint64_t value);
|
||||
uint64_t mtrr_rdmsr(struct vcpu *vcpu, uint32_t msr);
|
||||
void init_mtrr(struct vcpu *vcpu);
|
||||
|
||||
#endif /* MTRR_H */
|
Reference in New Issue
Block a user