[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] EPT: tidy exception handler to give more useful errors
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |