# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1224673159 -3600
# Node ID 007a5df1d45b96df0992912195836bba3059f0d0
# Parent 96d8b7f40dc71aeb5f630fcedefd47e724aa3ec8
EPT: tidy exception handler to give more useful errors
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---
xen/arch/x86/hvm/vmx/vmx.c | 75 ++++++++++++++++++++++++++++-----------------
1 files changed, 48 insertions(+), 27 deletions(-)
diff -r 96d8b7f40dc7 -r 007a5df1d45b xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Wed Oct 22 11:58:20 2008 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Oct 22 11:59:19 2008 +0100
@@ -1964,27 +1964,25 @@ static void ept_handle_violation(unsigne
{
unsigned long gla_validity = qualification & EPT_GLA_VALIDITY_MASK;
struct domain *d = current->domain;
- unsigned long gfn = gpa >> PAGE_SHIFT;
+ unsigned long gla, gfn = gpa >> PAGE_SHIFT;
mfn_t mfn;
p2m_type_t t;
- if ( unlikely(qualification & EPT_GAW_VIOLATION) )
- {
- gdprintk(XENLOG_ERR, "EPT violation: guest physical address %"PRIpaddr
- " exceeded its width limit.\n", gpa);
- goto crash;
- }
-
- if ( unlikely(gla_validity == EPT_GLA_VALIDITY_RSVD) ||
- unlikely(gla_validity == EPT_GLA_VALIDITY_PDPTR_LOAD) )
- {
- gdprintk(XENLOG_ERR, "EPT violation: reserved bit or "
- "pdptr load violation.\n");
- goto crash;
- }
-
mfn = gfn_to_mfn(d, gfn, &t);
- if ( (t != p2m_ram_ro) && p2m_is_ram(t) && paging_mode_log_dirty(d) )
+
+ /* There are two legitimate reasons for taking an EPT violation.
+ * One is a guest access to MMIO space. */
+ if ( gla_validity == EPT_GLA_VALIDITY_MATCH && p2m_is_mmio(t) )
+ {
+ handle_mmio();
+ return;
+ }
+
+ /* The other is log-dirty mode, writing to a read-only page */
+ if ( paging_mode_log_dirty(d)
+ && (gla_validity == EPT_GLA_VALIDITY_MATCH
+ || gla_validity == EPT_GLA_VALIDITY_GPT_WALK)
+ && p2m_is_ram(t) && (t != p2m_ram_ro) )
{
paging_mark_dirty(d, mfn_x(mfn));
p2m_change_type(d, gfn, p2m_ram_logdirty, p2m_ram_rw);
@@ -1992,16 +1990,39 @@ static void ept_handle_violation(unsigne
return;
}
- /* This can only happen in log-dirty mode, writing back A/D bits. */
- if ( unlikely(gla_validity == EPT_GLA_VALIDITY_GPT_WALK) )
- goto crash;
-
- ASSERT(gla_validity == EPT_GLA_VALIDITY_MATCH);
- handle_mmio();
-
- return;
-
- crash:
+ /* Everything else is an error. */
+ gla = __vmread(GUEST_LINEAR_ADDRESS);
+ gdprintk(XENLOG_ERR, "EPT violation %#lx (%c%c%c/%c%c%c), "
+ "gpa %#"PRIpaddr", mfn %#lx, type %i.\n",
+ qualification,
+ (qualification & EPT_READ_VIOLATION) ? 'r' : '-',
+ (qualification & EPT_WRITE_VIOLATION) ? 'w' : '-',
+ (qualification & EPT_EXEC_VIOLATION) ? 'x' : '-',
+ (qualification & EPT_EFFECTIVE_READ) ? 'r' : '-',
+ (qualification & EPT_EFFECTIVE_WRITE) ? 'w' : '-',
+ (qualification & EPT_EFFECTIVE_EXEC) ? 'x' : '-',
+ gpa, mfn_x(mfn), t);
+
+ if ( qualification & EPT_GAW_VIOLATION )
+ gdprintk(XENLOG_ERR, " --- GPA too wide (max %u bits)\n",
+ 9 * (unsigned) d->arch.hvm_domain.vmx.ept_control.gaw + 21);
+
+ switch ( gla_validity )
+ {
+ case EPT_GLA_VALIDITY_PDPTR_LOAD:
+ gdprintk(XENLOG_ERR, " --- PDPTR load failed\n");
+ break;
+ case EPT_GLA_VALIDITY_GPT_WALK:
+ gdprintk(XENLOG_ERR, " --- guest PT walk to %#lx failed\n", gla);
+ break;
+ case EPT_GLA_VALIDITY_RSVD:
+ gdprintk(XENLOG_ERR, " --- GLA_validity 2 (reserved)\n");
+ break;
+ case EPT_GLA_VALIDITY_MATCH:
+ gdprintk(XENLOG_ERR, " --- guest access to %#lx failed\n", gla);
+ break;
+ }
+
domain_crash(d);
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|