svn commit: r269080 - head/sys/amd64/vmm
Neel Natu
neel at FreeBSD.org
Thu Jul 24 23:01:54 UTC 2014
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) {
More information about the svn-src-head
mailing list