On Mon, Mar 9, 2015 at 10:44 AM, H. Peter Anvin <[email protected]> wrote:
> On 03/09/2015 09:44 AM, Linus Torvalds wrote:
>>
>> And remember: those zero-cost out-of-order branches turn quite
>> expensive if they *ever* mispredict. Even a 5% mispredict rate is
>> likely to mean "it's better to have a data dependency chain".
>>
>> So it could easily go either way. I'm not convinced the old code is bad at 
>> all.
>>
>
> I'm inclined to side with Linus here.  I'm hesitant to change this based
> on pure speculation.
>
> To answer Andy's question: I do believe we need espfix for V86 mode as well.
>

I think we don't.  Did I screw up my test?

--Andy

>         -hpa
>
>



-- 
Andy Lutomirski
AMA Capital Management, LLC
/*
 * vm86 regs test.
 * Copyright (c) 2014-2015 Andrew Lutomirski.
 *
 * This tests that vm86 regs work as expected.
 *
 * GPL v2.
 */

#define _GNU_SOURCE

#include <time.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/signal.h>
#include <sys/ucontext.h>
#include <asm/ldt.h>
#include <err.h>
#include <setjmp.h>
#include <stddef.h>
#include <stdbool.h>
#include <sys/user.h>
#include <errno.h>

#include <asm/vm86.h>

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
		       int flags)
{
	struct sigaction sa;

	memset(&sa, 0, sizeof(sa));
	sa.sa_sigaction = handler;
	sa.sa_flags = SA_SIGINFO | flags;
	sigemptyset(&sa.sa_mask);
	if (sigaction(sig, &sa, 0))
		err(1, "sigaction");
}

static void sigsegv_vm86(int sig, siginfo_t *info, void *ctx_void)
{
	ucontext_t *ctx = (ucontext_t*)ctx_void;

	printf("Back from vm86.  EIP = %lx\n",
	       (unsigned long)ctx->uc_mcontext.gregs[REG_EIP]);
	
}

static void test_vm86(unsigned short cs, unsigned short ss)
{
	struct vm86plus_struct v86, req_v86;
	long ret;

	memset(&v86, 0, sizeof(v86));

	v86.regs.eip = 0;
	v86.regs.cs = cs;
	v86.regs.ss = ss;
	v86.regs.esp = 0xbaadf00d;

	req_v86 = v86;

	printf("[RUN]\tcs = 0x%hx, ss = 0x%hx\n", cs, ss);

	ret = syscall(SYS_vm86, VM86_ENTER, &v86);

	if (ret == -1 && errno == ENOSYS) {
		printf("[SKIP]\tvm86 not supported\n");
		return;
	}

	printf("[OK]\tSurvived vm86 roundtrip.  esp = %lx, should be %lx\n", v86.regs.esp, req_v86.regs.esp);
}

int main(void)
{
	sethandler(SIGSEGV, sigsegv_vm86, SA_ONSTACK);
	test_vm86(0, 0);
	test_vm86(0, 3);
	test_vm86(3, 0);
	test_vm86(3, 3);
	return 0;
}

Reply via email to