[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/HVM: don't #GP/#SS on wrapping virt->linear translations
commit f710919994de7b0dc9a334a7440f8c6cce30d5cd Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Sep 11 15:06:23 2018 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Sep 11 15:06:23 2018 +0200 x86/HVM: don't #GP/#SS on wrapping virt->linear translations Real hardware wraps silently in most cases, so we should behave the same. Also split real and VM86 mode handling, as the latter really ought to have limit checks applied. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/hvm/hvm.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 72c24db0f4..062872cb71 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2439,16 +2439,21 @@ bool_t hvm_virtual_to_linear_addr( */ ASSERT(seg < x86_seg_none); - if ( !(curr->arch.hvm.guest_cr[0] & X86_CR0_PE) || - (guest_cpu_user_regs()->eflags & X86_EFLAGS_VM) ) + if ( !(curr->arch.hvm.guest_cr[0] & X86_CR0_PE) ) { /* - * REAL/VM86 MODE: Don't bother with segment access checks. + * REAL MODE: Don't bother with segment access checks. * Certain of them are not done in native real mode anyway. */ addr = (uint32_t)(addr + reg->base); - last_byte = (uint32_t)addr + bytes - !!bytes; - if ( last_byte < addr ) + } + else if ( (guest_cpu_user_regs()->eflags & X86_EFLAGS_VM) && + is_x86_user_segment(seg) ) + { + /* VM86 MODE: Fixed 64k limits on all user segments. */ + addr = (uint32_t)(addr + reg->base); + last_byte = (uint32_t)offset + bytes - !!bytes; + if ( max(offset, last_byte) >> 16 ) goto out; } else if ( hvm_long_mode_active(curr) && @@ -2470,8 +2475,7 @@ bool_t hvm_virtual_to_linear_addr( addr += reg->base; last_byte = addr + bytes - !!bytes; - if ( !is_canonical_address(addr) || last_byte < addr || - !is_canonical_address(last_byte) ) + if ( !is_canonical_address((long)addr < 0 ? addr : last_byte) ) goto out; } else @@ -2521,8 +2525,11 @@ bool_t hvm_virtual_to_linear_addr( if ( (offset <= reg->limit) || (last_byte < offset) ) goto out; } - else if ( (last_byte > reg->limit) || (last_byte < offset) ) - goto out; /* last byte is beyond limit or wraps 0xFFFFFFFF */ + else if ( last_byte > reg->limit ) + goto out; /* last byte is beyond limit */ + else if ( last_byte < offset && + curr->domain->arch.cpuid->x86_vendor == X86_VENDOR_AMD ) + goto out; /* access wraps */ } /* All checks ok. */ -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |