Hi, I'm doing an experiment in which I try to pass through a PCI
Express graphics card to a Windows DomU via VT-D. There is another
thread in which the overall feasibility of this is discussed, but here
I'd at least like to better understand the crash I'm seeing when I do
this. (I can pass through a PCI NIC via VT-D no problem).
I hide the graphics card from Dom0 (and I have Xen and Grub using the
serial port rather than than the graphics card for output) and pass it
through to my Windows DomU. About 20 seconds or so after I create my
Windows DomU, the (physical) machine reboots. I found that when I'm
lucky I get this message from Xen right before the reboot, which I'm
assuming is related:
[root@localhost xen]# (XEN) mtrr.c:552:d1 Conflict occurs for a given
guest l1e flags:63 at 10000000 (the effective mm type:6), because the
host mtrr type is:0
(XEN) CPU 1: Machine Check Exception: 0000000000000005
(XEN) Bank 0: b200004000000800
(XEN) Bank 5: b200121020080400
(XEN)
(XEN) ****************************************
(XEN) Panic on CPU 1:
(XEN) CPU context corrupt****************************************
(XEN)
(XEN) Reboot in five seconds..
I'd like to better understand how Xen handles MTRR/PAT in its page
table shadowing. I do generally understand page table shadowing, and
just now having read the relevant section of the Intel System
Programming maual, so I have good idea of what MTRR and PAT is about.
I looked at the code that generates the "Conflict" message above...is
is contained in get_pat_flags() .../xen/arch/x86/hvm/mtrr.c
(reproduced below) and is getting called from _sh_propagate(). I can
more-or-less follow the code...I guess it's figuring out what the
guest thinks the MTRR/PAT memory type should be, "combining" this with
what the host says the memory type actually is according to the real
MTRR, and using that to create the real ("shadow") PTE. The error
message shows that the guest wants the memory to be write-back
cacheable, which doesn't match the real MTRR for that system memory
address which is uncacheable.
I guess my question is can someone give a higher-level explaination of
how MTRR/PAT is supposed to work between Xen (the real MTRRs and real
PATs in the real ("shadow") PTEs) and an HVM DomU (virtual MTRRs and
fake PATs in the fake PTEs)?
Thanks,
Dave
uint32_t get_pat_flags(struct vcpu *v,
uint32_t gl1e_flags,
paddr_t gpaddr,
paddr_t spaddr)
{
uint8_t guest_eff_mm_type;
uint8_t shadow_mtrr_type;
uint8_t pat_entry_value;
uint64_t pat = v->arch.hvm_vcpu.pat_cr;
struct mtrr_state *g = &v->arch.hvm_vcpu.mtrr;
/* 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);
/* 2. Get the memory type of host physical address, with MTRR */
shadow_mtrr_type = get_mtrr_type(&mtrr_state, spaddr);
/* 3. Find the memory type in PAT, with host MTRR memory type
* and guest effective memory type.
*/
pat_entry_value = mtrr_epat_tbl[shadow_mtrr_type][guest_eff_mm_type];
/* If conflit occurs(e.g host MTRR is UC, guest memory type is
* WB),set UC as effective memory. Here, returning PAT_TYPE_UNCACHABLE will
* always set effective memory as UC.
*/
if ( pat_entry_value == INVALID_MEM_TYPE )
{
gdprintk(XENLOG_WARNING,
"Conflict occurs for a given guest l1e flags:%x "
"at %"PRIx64" (the effective mm type:%d), "
"because the host mtrr type is:%d\n",
gl1e_flags, (uint64_t)gpaddr, guest_eff_mm_type,
shadow_mtrr_type);
pat_entry_value = PAT_TYPE_UNCACHABLE;
}
/* 4. Get the pte flags */
return pat_type_2_pte_flags(pat_entry_value);
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|