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:
Zide Chen
2018-05-29 17:41:52 -07:00
committed by lijinxia
parent 5d2ab4d9ef
commit c2283743f0
5 changed files with 219 additions and 0 deletions

View File

@@ -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)

View File

@@ -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>

View 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 */