Message ID | 1401723251-8034-10-git-send-email-namit@cs.technion.ac.il (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Il 02/06/2014 17:34, Nadav Amit ha scritto: > In 64-bit mode, when the destination is a register, the assignment is done > according to the operand size. Otherwise (memory operand or no 64-bit mode), a > 16-bit assignment is performed. I'm sorry, I'm missing the place where 64-bit mode is taken into account? Paolo -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Jun 5, 2014, at 5:53 PM, Paolo Bonzini <pbonzini@redhat.com> wrote: > Il 02/06/2014 17:34, Nadav Amit ha scritto: >> In 64-bit mode, when the destination is a register, the assignment is done >> according to the operand size. Otherwise (memory operand or no 64-bit mode), a >> 16-bit assignment is performed. > > I'm sorry, I'm missing the place where 64-bit mode is taken into account? It is not, since on 32-bit mode the high-order 16 bits of a register destination are undefined. If I recall correctly, in this case the high-order 16-bits on native system actually reflect the high-order 16-bits of CR0. Therefore, regardless to the mode of operation: 1. If the target is memory - the destination is 16-bit 2. If the target is a register - the register is written according to the operand size. Nadav-- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 06/05/2014 08:02 AM, Nadav Amit wrote: >> I'm sorry, I'm missing the place where 64-bit mode is taken into account? > It is not, since on 32-bit mode the high-order 16 bits of a register destination are undefined. > If I recall correctly, in this case the high-order 16-bits on native system actually reflect the high-order 16-bits of CR0. This sounds like something that really should be verified experimentally. The above claim seems... odd. -hpa -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Il 05/06/2014 17:04, H. Peter Anvin ha scritto: > On 06/05/2014 08:02 AM, Nadav Amit wrote: >>> I'm sorry, I'm missing the place where 64-bit mode is taken into account? >> It is not, since on 32-bit mode the high-order 16 bits of a register destination are undefined. >> If I recall correctly, in this case the high-order 16-bits on native > system actually reflect the high-order 16-bits of CR0. > > This sounds like something that really should be verified > experimentally. The above claim seems... odd. Here is a test program: #if __SIZEOF_LONG__ == 4 #define V "12345678" #define R "e" #else #define V "1234567812345678" #define R "r" #endif #include <stdio.h> int main() { register volatile unsigned long ecx asm("ecx"); #if __SIZEOF_LONG__ > 4 asm volatile("mov $0x" V ", %%" R "cx; smswq %%rcx": : :"ecx"); printf("smswq: %lx\n", ecx); #endif asm volatile("mov $0x" V ", %%" R "cx; smswl %%ecx": : :"ecx"); printf("smswl: %lx\n", ecx); asm volatile("mov $0x" V ", %%" R "cx; smsww %%cx": : :"ecx"); printf("smsww: %lx\n", ecx); } Output in 32-bit mode: smswq: 80050033 smswl: 12340033 Output in 64-bit mode: smswq: 80050033 smswl: 80050033 smsww: 1234567812340033 Can you please make a test case for kvm-unit-tests (x86/emulator.c), in order to check the validity of the patch? Paolo -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
This patch set adds two tests for smsw. The first one is intended to add coverage of smsw. It covers the case smsw is executed with memory operand in a page which is write-protected by the hypervisor. Note that the existing smsw tests are not supposed to be trapped by the hypervisor. This test was added just for additional coverage. The realmode smsw test covers the recent patch that saves the high 16-bits to 32-bit register operand. Implementing a long-mode test is difficult since we need to cause an "invalid guest state" in long-mode. Nadav Amit (2): x86: emulator: additional smsw test-case x86: realmode: test smsw behavior with register operand x86/emulator.c | 10 ++++++++-- x86/realmode.c | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-)
Il 06/06/2014 01:56, Nadav Amit ha scritto: > This patch set adds two tests for smsw. The first one is intended to add > coverage of smsw. It covers the case smsw is executed with memory operand in a > page which is write-protected by the hypervisor. Note that the existing smsw > tests are not supposed to be trapped by the hypervisor. This test was added > just for additional coverage. > > The realmode smsw test covers the recent patch that saves the high 16-bits to > 32-bit register operand. Implementing a long-mode test is difficult since we > need to cause an "invalid guest state" in long-mode. You can use emulator.flat to test the emulator in long mode. See test_movabs for an example. Paolo > Nadav Amit (2): > x86: emulator: additional smsw test-case > x86: realmode: test smsw behavior with register operand > > x86/emulator.c | 10 ++++++++-- > x86/realmode.c | 15 +++++++++++++++ > 2 files changed, 23 insertions(+), 2 deletions(-) > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a151f8d..9b5d97d 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -3235,7 +3235,8 @@ static int em_lidt(struct x86_emulate_ctxt *ctxt) static int em_smsw(struct x86_emulate_ctxt *ctxt) { - ctxt->dst.bytes = 2; + if (ctxt->dst.type == OP_MEM) + ctxt->dst.bytes = 2; ctxt->dst.val = ctxt->ops->get_cr(ctxt, 0); return X86EMUL_CONTINUE; }
In 64-bit mode, when the destination is a register, the assignment is done according to the operand size. Otherwise (memory operand or no 64-bit mode), a 16-bit assignment is performed. Currently, 16-bit assignment is always done to the destination. Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> --- arch/x86/kvm/emulate.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)