# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1235128300 0
# Node ID 07e65892fc8eba020f2596a97956aaee30c717a1
# Parent 9559343fe5e835092a76af0988e49b99c4342714
[VTD] Utilise the snoop control capability in shadow with VT-d code
We compute the shadow PAT index in leaf page entries now as:
1) No VT-d assigned: let shadow PAT index as WB, handled already
in shadow code before.
2) direct assigned MMIO area: let shadow code compute the shadow
PAT with gMTRR=UC and gPAT value.
3) Snoop control enable: let shadow PAT index as WB.
4) Snoop control disable: let shadow code compute the shadow
PAT with gMTRR and gPAT, handled already in shadow code before
Signed-off-by: Xin, Xiaohui <xiaohui.xin@xxxxxxxxx>
---
xen/arch/x86/hvm/mtrr.c | 19 ++++++++++++++-----
xen/arch/x86/mm/shadow/multi.c | 19 ++++++++++++++++++-
xen/include/asm-x86/mtrr.h | 3 ++-
3 files changed, 34 insertions(+), 7 deletions(-)
diff -r 9559343fe5e8 -r 07e65892fc8e xen/arch/x86/hvm/mtrr.c
--- a/xen/arch/x86/hvm/mtrr.c Fri Feb 20 11:09:46 2009 +0000
+++ b/xen/arch/x86/hvm/mtrr.c Fri Feb 20 11:11:40 2009 +0000
@@ -351,11 +351,18 @@ static uint8_t effective_mm_type(struct
static uint8_t effective_mm_type(struct mtrr_state *m,
uint64_t pat,
paddr_t gpa,
- uint32_t pte_flags)
+ uint32_t pte_flags,
+ uint8_t gmtrr_mtype)
{
uint8_t mtrr_mtype, pat_value, effective;
-
- mtrr_mtype = get_mtrr_type(m, gpa);
+
+ /* if get_pat_flags() gives a dedicated MTRR type,
+ * just use it
+ */
+ if ( gmtrr_mtype == NO_HARDCODE_MEM_TYPE )
+ mtrr_mtype = get_mtrr_type(m, gpa);
+ else
+ mtrr_mtype = gmtrr_mtype;
pat_value = page_pat_type(pat, pte_flags);
@@ -367,7 +374,8 @@ uint32_t get_pat_flags(struct vcpu *v,
uint32_t get_pat_flags(struct vcpu *v,
uint32_t gl1e_flags,
paddr_t gpaddr,
- paddr_t spaddr)
+ paddr_t spaddr,
+ uint8_t gmtrr_mtype)
{
uint8_t guest_eff_mm_type;
uint8_t shadow_mtrr_type;
@@ -378,7 +386,8 @@ uint32_t get_pat_flags(struct vcpu *v,
/* 1. Get the effective memory type of guest physical address,
* with the pair of guest MTRR and PAT
*/
- guest_eff_mm_type = effective_mm_type(g, pat, gpaddr, gl1e_flags);
+ guest_eff_mm_type = effective_mm_type(g, pat, gpaddr,
+ gl1e_flags, gmtrr_mtype);
/* 2. Get the memory type of host physical address, with MTRR */
shadow_mtrr_type = get_mtrr_type(&mtrr_state, spaddr);
diff -r 9559343fe5e8 -r 07e65892fc8e xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c Fri Feb 20 11:09:46 2009 +0000
+++ b/xen/arch/x86/mm/shadow/multi.c Fri Feb 20 11:11:40 2009 +0000
@@ -546,15 +546,32 @@ _sh_propagate(struct vcpu *v,
!is_xen_heap_mfn(mfn_x(target_mfn)) )
{
unsigned int type;
+
+ /* compute the PAT index for shadow page entry when VT-d is enabled
+ * and device assigned.
+ * 1) direct MMIO: compute the PAT index with gMTRR=UC and gPAT.
+ * 2) if enables snoop control, compute the PAT index as WB.
+ * 3) if disables snoop control, compute the PAT index with
+ * gMTRR and gPAT.
+ */
if ( hvm_get_mem_pinned_cacheattr(d, gfn_x(target_gfn), &type) )
sflags |= pat_type_2_pte_flags(type);
else if ( d->arch.hvm_domain.is_in_uc_mode )
sflags |= pat_type_2_pte_flags(PAT_TYPE_UNCACHABLE);
+ else if ( p2mt == p2m_mmio_direct )
+ sflags |= get_pat_flags(v,
+ gflags,
+ gfn_to_paddr(target_gfn),
+ ((paddr_t)mfn_x(target_mfn)) << PAGE_SHIFT,
+ MTRR_TYPE_UNCACHABLE);
+ else if ( iommu_snoop )
+ sflags |= pat_type_2_pte_flags(PAT_TYPE_WRBACK);
else
sflags |= get_pat_flags(v,
gflags,
gfn_to_paddr(target_gfn),
- ((paddr_t)mfn_x(target_mfn)) <<
PAGE_SHIFT);
+ ((paddr_t)mfn_x(target_mfn)) << PAGE_SHIFT,
+ NO_HARDCODE_MEM_TYPE);
}
// Set the A&D bits for higher level shadows.
diff -r 9559343fe5e8 -r 07e65892fc8e xen/include/asm-x86/mtrr.h
--- a/xen/include/asm-x86/mtrr.h Fri Feb 20 11:09:46 2009 +0000
+++ b/xen/include/asm-x86/mtrr.h Fri Feb 20 11:11:40 2009 +0000
@@ -11,6 +11,7 @@
#define MTRR_TYPE_WRBACK 6
#define MTRR_NUM_TYPES 7
#define MEMORY_NUM_TYPES MTRR_NUM_TYPES
+#define NO_HARDCODE_MEM_TYPE MTRR_NUM_TYPES
#define NORMAL_CACHE_MODE 0
#define NO_FILL_CACHE_MODE 2
@@ -63,7 +64,7 @@ extern int mtrr_del_page(int reg, unsign
extern int mtrr_del_page(int reg, unsigned long base, unsigned long size);
extern void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi);
extern u32 get_pat_flags(struct vcpu *v, u32 gl1e_flags, paddr_t gpaddr,
- paddr_t spaddr);
+ paddr_t spaddr, uint8_t gmtrr_mtype);
extern uint8_t epte_get_entry_emt(
struct domain *d, unsigned long gfn, unsigned long mfn,
uint8_t *igmt, int direct_mmio);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|