Date: Thu, 24 Jul 2014 23:01:54 +0000 (UTC) From: Neel Natu <neel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r269080 - head/sys/amd64/vmm Message-ID: <201407242301.s6ON1sQ3050462@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: neel Date: Thu Jul 24 23:01:53 2014 New Revision: 269080 URL: http://svnweb.freebsd.org/changeset/base/269080 Log: Fix a couple of issues in the PUSH emulation: It is not possible to PUSH a 32-bit operand on the stack in 64-bit mode. The default operand size for PUSH is 64-bits and the operand size override prefix changes that to 16-bits. vm_copy_setup() can return '1' if it encounters a fault when walking the guest page tables. This is a guest issue and is now handled properly by resuming the guest to handle the fault. Modified: head/sys/amd64/vmm/vmm_instruction_emul.c Modified: head/sys/amd64/vmm/vmm_instruction_emul.c ============================================================================== --- head/sys/amd64/vmm/vmm_instruction_emul.c Thu Jul 24 20:44:30 2014 (r269079) +++ head/sys/amd64/vmm/vmm_instruction_emul.c Thu Jul 24 23:01:53 2014 (r269080) @@ -726,11 +726,19 @@ emulate_push(void *vm, int vcpuid, uint6 /* * From "Address-Size Attributes for Stack Accesses", Intel SDL, Vol 1 */ - if (paging->cpu_mode == CPU_MODE_REAL) + if (paging->cpu_mode == CPU_MODE_REAL) { stackaddrsize = 2; - else if (paging->cpu_mode == CPU_MODE_64BIT) + } else if (paging->cpu_mode == CPU_MODE_64BIT) { + /* + * "Stack Manipulation Instructions in 64-bit Mode", SDM, Vol 3 + * - Stack pointer size is always 64-bits. + * - PUSH/POP of 32-bit values is not possible in 64-bit mode. + * - 16-bit PUSH/POP is supported by using the operand size + * override prefix (66H). + */ stackaddrsize = 8; - else { + size = vie->opsize_override ? 2 : 8; + } else { /* * In protected or compability mode the 'B' flag in the * stack-segment descriptor determines the size of the @@ -773,8 +781,10 @@ emulate_push(void *vm, int vcpuid, uint6 error = vm_copy_setup(vm, vcpuid, paging, stack_gla, size, PROT_WRITE, copyinfo, nitems(copyinfo)); - if (error) - return (error); + if (error == -1) + return (-1); /* Unrecoverable error */ + else if (error == 1) + return (0); /* Return to guest to handle page fault */ error = memread(vm, vcpuid, mmio_gpa, &val, size, arg); if (error == 0) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407242301.s6ON1sQ3050462>