x86/svm: Provide EXITINFO decodes for Exceptions/NPF intercepts

Exceptions and NPF intercepts almost have the same layout, but NPF has bits
above 31 in the error code, and the name for exitinfo2 really does want
distinguishing between cr2 and gpa.

In nsvm_vcpu_vmexit_inject() rearrange VMEXIT_NPF to fall through instead of
repeating the exitinfo1 write.  Use the fallthrough pseudo keyword instead of
a comment.

In VMEXIT_NPF, as we're editing the printk() anyway, switch to using the newer
domain_crash() form.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2023-04-06 15:39:12 +01:00
1 parent a5087069a8
commit ddaf7bb0cf
3 files changed
+23 -19

No files matched your search

+3 -6
View File
@@ -824,14 +824,11 @@ nsvm_vcpu_vmexit_inject(struct vcpu *v, struct cpu_user_regs *regs,
ns_vmcb->exit_int_info = ns_vmcb->event_inj;
break;
case VMEXIT_EXCEPTION_PF:
ns_vmcb->_cr2 = ns_vmcb->exitinfo2;
/* fall through */
ns_vmcb->_cr2 = ns_vmcb->ei.exc.cr2;
fallthrough;
case VMEXIT_NPF:
/* PF error code */
ns_vmcb->exitinfo1 = svm->ns_vmexit.exitinfo1;
/* fault address */
ns_vmcb->exitinfo2 = svm->ns_vmexit.exitinfo2;
break;
fallthrough;
case VMEXIT_EXCEPTION_NP:
case VMEXIT_EXCEPTION_SS:
case VMEXIT_EXCEPTION_GP:
+10 -13
View File
@@ -2808,9 +2808,9 @@ void svm_vmexit_handler(void)
case VMEXIT_EXCEPTION_PF:
{
unsigned long va;
va = vmcb->exitinfo2;
regs->error_code = vmcb->exitinfo1;
unsigned long va = vmcb->ei.exc.cr2;
regs->error_code = vmcb->ei.exc.ec;
HVM_DBG_LOG(DBG_LEVEL_VMMU,
"eax=%lx, ebx=%lx, ecx=%lx, edx=%lx, esi=%lx, edi=%lx",
regs->rax, regs->rbx, regs->rcx,
@@ -2838,7 +2838,7 @@ void svm_vmexit_handler(void)
case VMEXIT_EXCEPTION_AC:
HVMTRACE_1D(TRAP, X86_EXC_AC);
hvm_inject_hw_exception(X86_EXC_AC, vmcb->exitinfo1);
hvm_inject_hw_exception(X86_EXC_AC, vmcb->ei.exc.ec);
break;
case VMEXIT_EXCEPTION_UD:
@@ -3051,18 +3051,15 @@ void svm_vmexit_handler(void)
case VMEXIT_NPF:
if ( cpu_has_svm_decode )
v->arch.hvm.svm.cached_insn_len = vmcb->guest_ins_len & 0xf;
rc = vmcb->exitinfo1 & PFEC_page_present
? p2m_pt_handle_deferred_changes(vmcb->exitinfo2) : 0;
rc = vmcb->ei.npf.ec & PFEC_page_present
? p2m_pt_handle_deferred_changes(vmcb->ei.npf.gpa) : 0;
if ( rc == 0 )
/* If no recal adjustments were being made - handle this fault */
svm_do_nested_pgfault(v, regs, vmcb->exitinfo1, vmcb->exitinfo2);
svm_do_nested_pgfault(v, regs, vmcb->ei.npf.ec, vmcb->ei.npf.gpa);
else if ( rc < 0 )
{
printk(XENLOG_G_ERR
"%pv: Error %d handling NPF (gpa=%08lx ec=%04lx)\n",
v, rc, vmcb->exitinfo2, vmcb->exitinfo1);
domain_crash(v->domain);
}
domain_crash(v->domain,
"%pv: Error %d handling NPF (gpa=%08lx ec=%04lx)\n",
v, rc, vmcb->ei.npf.gpa, vmcb->ei.npf.ec);
v->arch.hvm.svm.cached_insn_len = 0;
break;
+10
View File
@@ -436,6 +436,12 @@ struct vmcb_struct {
uint64_t exitinfo2; /* offset 0x80 */
};
union {
struct {
uint32_t ec; /* #NP, #SS, #GP, #PF, #AC */
uint32_t :32;
uint64_t cr2; /* #PF */
} exc;
struct {
bool in:1;
bool :1;
@@ -455,6 +461,10 @@ struct vmcb_struct {
uint64_t :59;
bool mov_insn:1; /* MOV, as opposed to LMSW, CLTS, etc */
} mov_cr;
struct {
uint64_t ec;
uint64_t gpa;
} npf;
struct {
uint16_t sel;
uint64_t :48;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.