* [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
@ 2015-05-29 21:58 Andy Lutomirski
2015-06-01 16:02 ` Shuah Khan
2015-06-02 5:37 ` [tip:x86/urgent] x86/asm/entry/32, selftests: Add a selftest for kernel entries from VM86 mode tip-bot for Andy Lutomirski
0 siblings, 2 replies; 7+ messages in thread
From: Andy Lutomirski @ 2015-05-29 21:58 UTC (permalink / raw)
To: Ingo Molnar
Cc: Jan Beulich, x86, linux-kernel@vger.kernel.org, Shuah Khan,
Andy Lutomirski
Test a couple of special cases in 32-bit kernels for entries from
vm86 mode. This will OOPS both old kernels due to a bug and and
4.1-rc5 due to a regression I introduced, and it should make sure
that the SYSENTER-from-vm86-mode hack in the kernel keeps working.
Tests: 394838c96013 x86/asm/entry/32: Fix user_mode() misuses
Tests: 7ba554b5ac69 x86/asm/entry/32: Really make user_mode() work correctly for VM86 mode
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
Ingo, Shuah: I think this should go in through -tip. (In general, I think
new x86 tests that don't have interesting interactions with the kselftest
infrastructure should go in through -tip, especially tests such as this one
that are related to recent regressions.)
tools/testing/selftests/x86/Makefile | 6 +-
tools/testing/selftests/x86/entry_from_vm86.c | 114 ++++++++++++++++++++++++++
2 files changed, 118 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/x86/entry_from_vm86.c
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 5bdb781163d1..9b0d8baf2934 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -5,8 +5,10 @@ include ../lib.mk
.PHONY: all all_32 all_64 warn_32bit_failure clean
TARGETS_C_BOTHBITS := sigreturn single_step_syscall
+TARGETS_C_32BIT_ONLY := entry_from_vm86
-BINARIES_32 := $(TARGETS_C_BOTHBITS:%=%_32)
+TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY)
+BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32)
BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64)
CFLAGS := -O2 -g -std=gnu99 -pthread -Wall
@@ -32,7 +34,7 @@ all_64: $(BINARIES_64)
clean:
$(RM) $(BINARIES_32) $(BINARIES_64)
-$(TARGETS_C_BOTHBITS:%=%_32): %_32: %.c
+$(TARGETS_C_32BIT_ALL:%=%_32): %_32: %.c
$(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
$(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c
diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c
new file mode 100644
index 000000000000..5c38a187677b
--- /dev/null
+++ b/tools/testing/selftests/x86/entry_from_vm86.c
@@ -0,0 +1,114 @@
+/*
+ * entry_from_vm86.c - tests kernel entries from vm86 mode
+ * Copyright (c) 2014-2015 Andrew Lutomirski
+ *
+ * This exercises a few paths that need to special-case vm86 mode.
+ *
+ * GPL v2.
+ */
+
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <sys/signal.h>
+#include <sys/ucontext.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/mman.h>
+#include <err.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <sys/vm86.h>
+
+static unsigned long load_addr = 0x10000;
+static int nerrs = 0;
+
+asm (
+ ".pushsection .rodata\n\t"
+ ".type vmcode_bound, @object\n\t"
+ "vmcode:\n\t"
+ "vmcode_bound:\n\t"
+ ".code16\n\t"
+ "bound %ax, (2048)\n\t"
+ "int3\n\t"
+ "vmcode_sysenter:\n\t"
+ "sysenter\n\t"
+ ".size vmcode, . - vmcode\n\t"
+ "end_vmcode:\n\t"
+ ".code32\n\t"
+ ".popsection"
+ );
+
+extern unsigned char vmcode[], end_vmcode[];
+extern unsigned char vmcode_bound[], vmcode_sysenter[];
+
+static void do_test(struct vm86plus_struct *v86, unsigned long eip,
+ const char *text)
+{
+ long ret;
+
+ printf("[RUN]\t%s from vm86 mode\n", text);
+ v86->regs.eip = eip;
+ ret = vm86(VM86_ENTER, v86);
+
+ if (ret == -1 && errno == ENOSYS) {
+ printf("[SKIP]\tvm86 not supported\n");
+ return;
+ }
+
+ if (VM86_TYPE(ret) == VM86_INTx) {
+ char trapname[32];
+ int trapno = VM86_ARG(ret);
+ if (trapno == 13)
+ strcpy(trapname, "GP");
+ else if (trapno == 5)
+ strcpy(trapname, "BR");
+ else if (trapno == 14)
+ strcpy(trapname, "PF");
+ else
+ sprintf(trapname, "%d", trapno);
+
+ printf("[OK]\tExited vm86 mode due to #%s\n", trapname);
+ } else if (VM86_TYPE(ret) == VM86_UNKNOWN) {
+ printf("[OK]\tExited vm86 mode due to unhandled GP fault\n");
+ } else {
+ printf("[OK]\tExited vm86 mode due to type %ld, arg %ld\n",
+ VM86_TYPE(ret), VM86_ARG(ret));
+ }
+}
+
+int main(void)
+{
+ struct vm86plus_struct v86;
+ unsigned char *addr = mmap((void *)load_addr, 4096,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1,0);
+ if (addr != (unsigned char *)load_addr)
+ err(1, "mmap");
+
+ memcpy(addr, vmcode, end_vmcode - vmcode);
+ addr[2048] = 2;
+ addr[2050] = 3;
+
+ memset(&v86, 0, sizeof(v86));
+
+ v86.regs.cs = load_addr / 16;
+ v86.regs.ss = load_addr / 16;
+ v86.regs.ds = load_addr / 16;
+ v86.regs.es = load_addr / 16;
+
+ assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */
+
+ /* #BR -- should deliver SIG??? */
+ do_test(&v86, vmcode_bound - vmcode, "#BR");
+
+ /* SYSENTER -- should cause #GP or #UD depending on CPU */
+ do_test(&v86, vmcode_sysenter - vmcode, "SYSENTER");
+
+ return (nerrs == 0 ? 0 : 1);
+}
--
2.3.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
2015-05-29 21:58 [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode Andy Lutomirski
@ 2015-06-01 16:02 ` Shuah Khan
2015-06-01 22:54 ` Andy Lutomirski
2015-06-02 5:37 ` [tip:x86/urgent] x86/asm/entry/32, selftests: Add a selftest for kernel entries from VM86 mode tip-bot for Andy Lutomirski
1 sibling, 1 reply; 7+ messages in thread
From: Shuah Khan @ 2015-06-01 16:02 UTC (permalink / raw)
To: Andy Lutomirski, Ingo Molnar
Cc: Jan Beulich, x86, linux-kernel@vger.kernel.org
On 05/29/2015 03:58 PM, Andy Lutomirski wrote:
> Test a couple of special cases in 32-bit kernels for entries from
> vm86 mode. This will OOPS both old kernels due to a bug and and
> 4.1-rc5 due to a regression I introduced, and it should make sure
> that the SYSENTER-from-vm86-mode hack in the kernel keeps working.
>
> Tests: 394838c96013 x86/asm/entry/32: Fix user_mode() misuses
> Tests: 7ba554b5ac69 x86/asm/entry/32: Really make user_mode() work correctly for VM86 mode
> Signed-off-by: Andy Lutomirski <luto@kernel.org>
> ---
>
> Ingo, Shuah: I think this should go in through -tip. (In general, I think
> new x86 tests that don't have interesting interactions with the kselftest
> infrastructure should go in through -tip, especially tests such as this one
> that are related to recent regressions.)
No problem going through tip. Could you please make sure
"make kselftest" run from top level and
tools/testing/selftests/kselftest_install.sh
don't break?
Once the above are verified, here is my
Acked-by: Shuah Khan <shuahkh@osg.samsung.com>
Thanks,
-- Shuah
>
> tools/testing/selftests/x86/Makefile | 6 +-
> tools/testing/selftests/x86/entry_from_vm86.c | 114 ++++++++++++++++++++++++++
> 2 files changed, 118 insertions(+), 2 deletions(-)
> create mode 100644 tools/testing/selftests/x86/entry_from_vm86.c
>
> diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
> index 5bdb781163d1..9b0d8baf2934 100644
> --- a/tools/testing/selftests/x86/Makefile
> +++ b/tools/testing/selftests/x86/Makefile
> @@ -5,8 +5,10 @@ include ../lib.mk
> .PHONY: all all_32 all_64 warn_32bit_failure clean
>
> TARGETS_C_BOTHBITS := sigreturn single_step_syscall
> +TARGETS_C_32BIT_ONLY := entry_from_vm86
>
> -BINARIES_32 := $(TARGETS_C_BOTHBITS:%=%_32)
> +TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY)
> +BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32)
> BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64)
>
> CFLAGS := -O2 -g -std=gnu99 -pthread -Wall
> @@ -32,7 +34,7 @@ all_64: $(BINARIES_64)
> clean:
> $(RM) $(BINARIES_32) $(BINARIES_64)
>
> -$(TARGETS_C_BOTHBITS:%=%_32): %_32: %.c
> +$(TARGETS_C_32BIT_ALL:%=%_32): %_32: %.c
> $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
>
> $(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c
> diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c
> new file mode 100644
> index 000000000000..5c38a187677b
> --- /dev/null
> +++ b/tools/testing/selftests/x86/entry_from_vm86.c
> @@ -0,0 +1,114 @@
> +/*
> + * entry_from_vm86.c - tests kernel entries from vm86 mode
> + * Copyright (c) 2014-2015 Andrew Lutomirski
> + *
> + * This exercises a few paths that need to special-case vm86 mode.
> + *
> + * GPL v2.
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include <assert.h>
> +#include <stdlib.h>
> +#include <sys/syscall.h>
> +#include <sys/signal.h>
> +#include <sys/ucontext.h>
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <inttypes.h>
> +#include <sys/mman.h>
> +#include <err.h>
> +#include <stddef.h>
> +#include <stdbool.h>
> +#include <errno.h>
> +#include <sys/vm86.h>
> +
> +static unsigned long load_addr = 0x10000;
> +static int nerrs = 0;
> +
> +asm (
> + ".pushsection .rodata\n\t"
> + ".type vmcode_bound, @object\n\t"
> + "vmcode:\n\t"
> + "vmcode_bound:\n\t"
> + ".code16\n\t"
> + "bound %ax, (2048)\n\t"
> + "int3\n\t"
> + "vmcode_sysenter:\n\t"
> + "sysenter\n\t"
> + ".size vmcode, . - vmcode\n\t"
> + "end_vmcode:\n\t"
> + ".code32\n\t"
> + ".popsection"
> + );
> +
> +extern unsigned char vmcode[], end_vmcode[];
> +extern unsigned char vmcode_bound[], vmcode_sysenter[];
> +
> +static void do_test(struct vm86plus_struct *v86, unsigned long eip,
> + const char *text)
> +{
> + long ret;
> +
> + printf("[RUN]\t%s from vm86 mode\n", text);
> + v86->regs.eip = eip;
> + ret = vm86(VM86_ENTER, v86);
> +
> + if (ret == -1 && errno == ENOSYS) {
> + printf("[SKIP]\tvm86 not supported\n");
> + return;
> + }
> +
> + if (VM86_TYPE(ret) == VM86_INTx) {
> + char trapname[32];
> + int trapno = VM86_ARG(ret);
> + if (trapno == 13)
> + strcpy(trapname, "GP");
> + else if (trapno == 5)
> + strcpy(trapname, "BR");
> + else if (trapno == 14)
> + strcpy(trapname, "PF");
> + else
> + sprintf(trapname, "%d", trapno);
> +
> + printf("[OK]\tExited vm86 mode due to #%s\n", trapname);
> + } else if (VM86_TYPE(ret) == VM86_UNKNOWN) {
> + printf("[OK]\tExited vm86 mode due to unhandled GP fault\n");
> + } else {
> + printf("[OK]\tExited vm86 mode due to type %ld, arg %ld\n",
> + VM86_TYPE(ret), VM86_ARG(ret));
> + }
> +}
> +
> +int main(void)
> +{
> + struct vm86plus_struct v86;
> + unsigned char *addr = mmap((void *)load_addr, 4096,
> + PROT_READ | PROT_WRITE | PROT_EXEC,
> + MAP_ANONYMOUS | MAP_PRIVATE, -1,0);
> + if (addr != (unsigned char *)load_addr)
> + err(1, "mmap");
> +
> + memcpy(addr, vmcode, end_vmcode - vmcode);
> + addr[2048] = 2;
> + addr[2050] = 3;
> +
> + memset(&v86, 0, sizeof(v86));
> +
> + v86.regs.cs = load_addr / 16;
> + v86.regs.ss = load_addr / 16;
> + v86.regs.ds = load_addr / 16;
> + v86.regs.es = load_addr / 16;
> +
> + assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */
> +
> + /* #BR -- should deliver SIG??? */
> + do_test(&v86, vmcode_bound - vmcode, "#BR");
> +
> + /* SYSENTER -- should cause #GP or #UD depending on CPU */
> + do_test(&v86, vmcode_sysenter - vmcode, "SYSENTER");
> +
> + return (nerrs == 0 ? 0 : 1);
> +}
>
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@osg.samsung.com | (970) 217-8978
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
2015-06-01 16:02 ` Shuah Khan
@ 2015-06-01 22:54 ` Andy Lutomirski
2015-06-01 23:27 ` Shuah Khan
0 siblings, 1 reply; 7+ messages in thread
From: Andy Lutomirski @ 2015-06-01 22:54 UTC (permalink / raw)
To: Shuah Khan
Cc: Andy Lutomirski, Ingo Molnar, Jan Beulich, X86 ML,
linux-kernel@vger.kernel.org
On Mon, Jun 1, 2015 at 9:02 AM, Shuah Khan <shuahkh@osg.samsung.com> wrote:
> On 05/29/2015 03:58 PM, Andy Lutomirski wrote:
>> Test a couple of special cases in 32-bit kernels for entries from
>> vm86 mode. This will OOPS both old kernels due to a bug and and
>> 4.1-rc5 due to a regression I introduced, and it should make sure
>> that the SYSENTER-from-vm86-mode hack in the kernel keeps working.
>>
>> Tests: 394838c96013 x86/asm/entry/32: Fix user_mode() misuses
>> Tests: 7ba554b5ac69 x86/asm/entry/32: Really make user_mode() work correctly for VM86 mode
>> Signed-off-by: Andy Lutomirski <luto@kernel.org>
>> ---
>>
>> Ingo, Shuah: I think this should go in through -tip. (In general, I think
>> new x86 tests that don't have interesting interactions with the kselftest
>> infrastructure should go in through -tip, especially tests such as this one
>> that are related to recent regressions.)
>
> No problem going through tip. Could you please make sure
>
> "make kselftest" run from top level and
> tools/testing/selftests/kselftest_install.sh
>
> don't break?
Both 'make kselftest -j12 TARGETS=x86' and
../../../tools/testing/selftests/kselftest_install.sh work for me.
(The .. thing is annoying -- would it make sense to fix it to work
from the kernel tree root?)
--Andy
>
> Once the above are verified, here is my
>
> Acked-by: Shuah Khan <shuahkh@osg.samsung.com>
>
> Thanks,
> -- Shuah
>
>>
>> tools/testing/selftests/x86/Makefile | 6 +-
>> tools/testing/selftests/x86/entry_from_vm86.c | 114 ++++++++++++++++++++++++++
>> 2 files changed, 118 insertions(+), 2 deletions(-)
>> create mode 100644 tools/testing/selftests/x86/entry_from_vm86.c
>>
>> diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
>> index 5bdb781163d1..9b0d8baf2934 100644
>> --- a/tools/testing/selftests/x86/Makefile
>> +++ b/tools/testing/selftests/x86/Makefile
>> @@ -5,8 +5,10 @@ include ../lib.mk
>> .PHONY: all all_32 all_64 warn_32bit_failure clean
>>
>> TARGETS_C_BOTHBITS := sigreturn single_step_syscall
>> +TARGETS_C_32BIT_ONLY := entry_from_vm86
>>
>> -BINARIES_32 := $(TARGETS_C_BOTHBITS:%=%_32)
>> +TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY)
>> +BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32)
>> BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64)
>>
>> CFLAGS := -O2 -g -std=gnu99 -pthread -Wall
>> @@ -32,7 +34,7 @@ all_64: $(BINARIES_64)
>> clean:
>> $(RM) $(BINARIES_32) $(BINARIES_64)
>>
>> -$(TARGETS_C_BOTHBITS:%=%_32): %_32: %.c
>> +$(TARGETS_C_32BIT_ALL:%=%_32): %_32: %.c
>> $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
>>
>> $(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c
>> diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c
>> new file mode 100644
>> index 000000000000..5c38a187677b
>> --- /dev/null
>> +++ b/tools/testing/selftests/x86/entry_from_vm86.c
>> @@ -0,0 +1,114 @@
>> +/*
>> + * entry_from_vm86.c - tests kernel entries from vm86 mode
>> + * Copyright (c) 2014-2015 Andrew Lutomirski
>> + *
>> + * This exercises a few paths that need to special-case vm86 mode.
>> + *
>> + * GPL v2.
>> + */
>> +
>> +#define _GNU_SOURCE
>> +
>> +#include <assert.h>
>> +#include <stdlib.h>
>> +#include <sys/syscall.h>
>> +#include <sys/signal.h>
>> +#include <sys/ucontext.h>
>> +#include <unistd.h>
>> +#include <stdio.h>
>> +#include <string.h>
>> +#include <inttypes.h>
>> +#include <sys/mman.h>
>> +#include <err.h>
>> +#include <stddef.h>
>> +#include <stdbool.h>
>> +#include <errno.h>
>> +#include <sys/vm86.h>
>> +
>> +static unsigned long load_addr = 0x10000;
>> +static int nerrs = 0;
>> +
>> +asm (
>> + ".pushsection .rodata\n\t"
>> + ".type vmcode_bound, @object\n\t"
>> + "vmcode:\n\t"
>> + "vmcode_bound:\n\t"
>> + ".code16\n\t"
>> + "bound %ax, (2048)\n\t"
>> + "int3\n\t"
>> + "vmcode_sysenter:\n\t"
>> + "sysenter\n\t"
>> + ".size vmcode, . - vmcode\n\t"
>> + "end_vmcode:\n\t"
>> + ".code32\n\t"
>> + ".popsection"
>> + );
>> +
>> +extern unsigned char vmcode[], end_vmcode[];
>> +extern unsigned char vmcode_bound[], vmcode_sysenter[];
>> +
>> +static void do_test(struct vm86plus_struct *v86, unsigned long eip,
>> + const char *text)
>> +{
>> + long ret;
>> +
>> + printf("[RUN]\t%s from vm86 mode\n", text);
>> + v86->regs.eip = eip;
>> + ret = vm86(VM86_ENTER, v86);
>> +
>> + if (ret == -1 && errno == ENOSYS) {
>> + printf("[SKIP]\tvm86 not supported\n");
>> + return;
>> + }
>> +
>> + if (VM86_TYPE(ret) == VM86_INTx) {
>> + char trapname[32];
>> + int trapno = VM86_ARG(ret);
>> + if (trapno == 13)
>> + strcpy(trapname, "GP");
>> + else if (trapno == 5)
>> + strcpy(trapname, "BR");
>> + else if (trapno == 14)
>> + strcpy(trapname, "PF");
>> + else
>> + sprintf(trapname, "%d", trapno);
>> +
>> + printf("[OK]\tExited vm86 mode due to #%s\n", trapname);
>> + } else if (VM86_TYPE(ret) == VM86_UNKNOWN) {
>> + printf("[OK]\tExited vm86 mode due to unhandled GP fault\n");
>> + } else {
>> + printf("[OK]\tExited vm86 mode due to type %ld, arg %ld\n",
>> + VM86_TYPE(ret), VM86_ARG(ret));
>> + }
>> +}
>> +
>> +int main(void)
>> +{
>> + struct vm86plus_struct v86;
>> + unsigned char *addr = mmap((void *)load_addr, 4096,
>> + PROT_READ | PROT_WRITE | PROT_EXEC,
>> + MAP_ANONYMOUS | MAP_PRIVATE, -1,0);
>> + if (addr != (unsigned char *)load_addr)
>> + err(1, "mmap");
>> +
>> + memcpy(addr, vmcode, end_vmcode - vmcode);
>> + addr[2048] = 2;
>> + addr[2050] = 3;
>> +
>> + memset(&v86, 0, sizeof(v86));
>> +
>> + v86.regs.cs = load_addr / 16;
>> + v86.regs.ss = load_addr / 16;
>> + v86.regs.ds = load_addr / 16;
>> + v86.regs.es = load_addr / 16;
>> +
>> + assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */
>> +
>> + /* #BR -- should deliver SIG??? */
>> + do_test(&v86, vmcode_bound - vmcode, "#BR");
>> +
>> + /* SYSENTER -- should cause #GP or #UD depending on CPU */
>> + do_test(&v86, vmcode_sysenter - vmcode, "SYSENTER");
>> +
>> + return (nerrs == 0 ? 0 : 1);
>> +}
>>
>
>
> --
> Shuah Khan
> Sr. Linux Kernel Developer
> Open Source Innovation Group
> Samsung Research America (Silicon Valley)
> shuahkh@osg.samsung.com | (970) 217-8978
--
Andy Lutomirski
AMA Capital Management, LLC
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
2015-06-01 22:54 ` Andy Lutomirski
@ 2015-06-01 23:27 ` Shuah Khan
2015-06-01 23:45 ` Andy Lutomirski
0 siblings, 1 reply; 7+ messages in thread
From: Shuah Khan @ 2015-06-01 23:27 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Andy Lutomirski, Ingo Molnar, Jan Beulich, X86 ML,
linux-kernel@vger.kernel.org, Shuah Khan
On 06/01/2015 04:54 PM, Andy Lutomirski wrote:
> On Mon, Jun 1, 2015 at 9:02 AM, Shuah Khan <shuahkh@osg.samsung.com> wrote:
>> On 05/29/2015 03:58 PM, Andy Lutomirski wrote:
>>> Test a couple of special cases in 32-bit kernels for entries from
>>> vm86 mode. This will OOPS both old kernels due to a bug and and
>>> 4.1-rc5 due to a regression I introduced, and it should make sure
>>> that the SYSENTER-from-vm86-mode hack in the kernel keeps working.
>>>
>>> Tests: 394838c96013 x86/asm/entry/32: Fix user_mode() misuses
>>> Tests: 7ba554b5ac69 x86/asm/entry/32: Really make user_mode() work correctly for VM86 mode
>>> Signed-off-by: Andy Lutomirski <luto@kernel.org>
>>> ---
>>>
>>> Ingo, Shuah: I think this should go in through -tip. (In general, I think
>>> new x86 tests that don't have interesting interactions with the kselftest
>>> infrastructure should go in through -tip, especially tests such as this one
>>> that are related to recent regressions.)
>>
>> No problem going through tip. Could you please make sure
>>
>> "make kselftest" run from top level and
>> tools/testing/selftests/kselftest_install.sh
>>
>> don't break?
>
> Both 'make kselftest -j12 TARGETS=x86' and
> ../../../tools/testing/selftests/kselftest_install.sh work for me.
> (The .. thing is annoying -- would it make sense to fix it to work
> from the kernel tree root?)
>
What is annoying about it and how would it get solved by making it
run from the kernel tree root?
-- Shuah
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@osg.samsung.com | (970) 217-8978
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
2015-06-01 23:27 ` Shuah Khan
@ 2015-06-01 23:45 ` Andy Lutomirski
2015-06-01 23:58 ` Shuah Khan
0 siblings, 1 reply; 7+ messages in thread
From: Andy Lutomirski @ 2015-06-01 23:45 UTC (permalink / raw)
To: Shuah Khan
Cc: Andy Lutomirski, Ingo Molnar, Jan Beulich, X86 ML,
linux-kernel@vger.kernel.org
On Mon, Jun 1, 2015 at 4:27 PM, Shuah Khan <shuahkh@osg.samsung.com> wrote:
> On 06/01/2015 04:54 PM, Andy Lutomirski wrote:
>> On Mon, Jun 1, 2015 at 9:02 AM, Shuah Khan <shuahkh@osg.samsung.com> wrote:
>>> On 05/29/2015 03:58 PM, Andy Lutomirski wrote:
>>>> Test a couple of special cases in 32-bit kernels for entries from
>>>> vm86 mode. This will OOPS both old kernels due to a bug and and
>>>> 4.1-rc5 due to a regression I introduced, and it should make sure
>>>> that the SYSENTER-from-vm86-mode hack in the kernel keeps working.
>>>>
>>>> Tests: 394838c96013 x86/asm/entry/32: Fix user_mode() misuses
>>>> Tests: 7ba554b5ac69 x86/asm/entry/32: Really make user_mode() work correctly for VM86 mode
>>>> Signed-off-by: Andy Lutomirski <luto@kernel.org>
>>>> ---
>>>>
>>>> Ingo, Shuah: I think this should go in through -tip. (In general, I think
>>>> new x86 tests that don't have interesting interactions with the kselftest
>>>> infrastructure should go in through -tip, especially tests such as this one
>>>> that are related to recent regressions.)
>>>
>>> No problem going through tip. Could you please make sure
>>>
>>> "make kselftest" run from top level and
>>> tools/testing/selftests/kselftest_install.sh
>>>
>>> don't break?
>>
>> Both 'make kselftest -j12 TARGETS=x86' and
>> ../../../tools/testing/selftests/kselftest_install.sh work for me.
>> (The .. thing is annoying -- would it make sense to fix it to work
>> from the kernel tree root?)
>>
>
> What is annoying about it and how would it get solved by making it
> run from the kernel tree root?
>
I ran it from the kernel tree root and it told me to change my
directory. I think it should have changed the directory itself :)
--Andy
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
2015-06-01 23:45 ` Andy Lutomirski
@ 2015-06-01 23:58 ` Shuah Khan
0 siblings, 0 replies; 7+ messages in thread
From: Shuah Khan @ 2015-06-01 23:58 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Andy Lutomirski, Ingo Molnar, Jan Beulich, X86 ML,
linux-kernel@vger.kernel.org, Shuah Khan
On 06/01/2015 05:45 PM, Andy Lutomirski wrote:
> On Mon, Jun 1, 2015 at 4:27 PM, Shuah Khan <shuahkh@osg.samsung.com> wrote:
>> On 06/01/2015 04:54 PM, Andy Lutomirski wrote:
>>> On Mon, Jun 1, 2015 at 9:02 AM, Shuah Khan <shuahkh@osg.samsung.com> wrote:
>>>> On 05/29/2015 03:58 PM, Andy Lutomirski wrote:
>>>>> Test a couple of special cases in 32-bit kernels for entries from
>>>>> vm86 mode. This will OOPS both old kernels due to a bug and and
>>>>> 4.1-rc5 due to a regression I introduced, and it should make sure
>>>>> that the SYSENTER-from-vm86-mode hack in the kernel keeps working.
>>>>>
>>>>> Tests: 394838c96013 x86/asm/entry/32: Fix user_mode() misuses
>>>>> Tests: 7ba554b5ac69 x86/asm/entry/32: Really make user_mode() work correctly for VM86 mode
>>>>> Signed-off-by: Andy Lutomirski <luto@kernel.org>
>>>>> ---
>>>>>
>>>>> Ingo, Shuah: I think this should go in through -tip. (In general, I think
>>>>> new x86 tests that don't have interesting interactions with the kselftest
>>>>> infrastructure should go in through -tip, especially tests such as this one
>>>>> that are related to recent regressions.)
>>>>
>>>> No problem going through tip. Could you please make sure
>>>>
>>>> "make kselftest" run from top level and
>>>> tools/testing/selftests/kselftest_install.sh
>>>>
>>>> don't break?
>>>
>>> Both 'make kselftest -j12 TARGETS=x86' and
>>> ../../../tools/testing/selftests/kselftest_install.sh work for me.
>>> (The .. thing is annoying -- would it make sense to fix it to work
>>> from the kernel tree root?)
>>>
>>
>> What is annoying about it and how would it get solved by making it
>> run from the kernel tree root?
>>
>
> I ran it from the kernel tree root and it told me to change my
> directory. I think it should have changed the directory itself :)
>
ok that makes sense. I can make it do that. :)
thanks,
-- Shuah
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@osg.samsung.com | (970) 217-8978
^ permalink raw reply [flat|nested] 7+ messages in thread
* [tip:x86/urgent] x86/asm/entry/32, selftests: Add a selftest for kernel entries from VM86 mode
2015-05-29 21:58 [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode Andy Lutomirski
2015-06-01 16:02 ` Shuah Khan
@ 2015-06-02 5:37 ` tip-bot for Andy Lutomirski
1 sibling, 0 replies; 7+ messages in thread
From: tip-bot for Andy Lutomirski @ 2015-06-02 5:37 UTC (permalink / raw)
To: linux-tip-commits
Cc: peterz, luto, linux-kernel, mingo, shuahkh, JBeulich, tglx, hpa,
torvalds
Commit-ID: c2affbf9a50882572e04645d5946ab0a921f061f
Gitweb: http://git.kernel.org/tip/c2affbf9a50882572e04645d5946ab0a921f061f
Author: Andy Lutomirski <luto@kernel.org>
AuthorDate: Fri, 29 May 2015 14:58:24 -0700
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Sat, 30 May 2015 10:21:32 +0200
x86/asm/entry/32, selftests: Add a selftest for kernel entries from VM86 mode
Test a couple of special cases in 32-bit kernels for entries
from vm86 mode. This will OOPS both old kernels due to a bug
and and 4.1-rc5 due to a regression I introduced, and it should
make sure that the SYSENTER-from-vm86-mode hack in the kernel
keeps working.
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Shuah Khan <shuahkh@osg.samsung.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/09a9916761e0a9e42d4922f147af45a0079cc1e8.1432936374.git.luto@kernel.org
Tests: 394838c96013 x86/asm/entry/32: Fix user_mode() misuses
Tests: 7ba554b5ac69 x86/asm/entry/32: Really make user_mode() work correctly for VM86 mode
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
tools/testing/selftests/x86/Makefile | 6 +-
tools/testing/selftests/x86/entry_from_vm86.c | 114 ++++++++++++++++++++++++++
2 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 5bdb781..9b0d8ba 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -5,8 +5,10 @@ include ../lib.mk
.PHONY: all all_32 all_64 warn_32bit_failure clean
TARGETS_C_BOTHBITS := sigreturn single_step_syscall
+TARGETS_C_32BIT_ONLY := entry_from_vm86
-BINARIES_32 := $(TARGETS_C_BOTHBITS:%=%_32)
+TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY)
+BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32)
BINARIES_64 := $(TARGETS_C_BOTHBITS:%=%_64)
CFLAGS := -O2 -g -std=gnu99 -pthread -Wall
@@ -32,7 +34,7 @@ all_64: $(BINARIES_64)
clean:
$(RM) $(BINARIES_32) $(BINARIES_64)
-$(TARGETS_C_BOTHBITS:%=%_32): %_32: %.c
+$(TARGETS_C_32BIT_ALL:%=%_32): %_32: %.c
$(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
$(TARGETS_C_BOTHBITS:%=%_64): %_64: %.c
diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c
new file mode 100644
index 0000000..5c38a18
--- /dev/null
+++ b/tools/testing/selftests/x86/entry_from_vm86.c
@@ -0,0 +1,114 @@
+/*
+ * entry_from_vm86.c - tests kernel entries from vm86 mode
+ * Copyright (c) 2014-2015 Andrew Lutomirski
+ *
+ * This exercises a few paths that need to special-case vm86 mode.
+ *
+ * GPL v2.
+ */
+
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <sys/signal.h>
+#include <sys/ucontext.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/mman.h>
+#include <err.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <sys/vm86.h>
+
+static unsigned long load_addr = 0x10000;
+static int nerrs = 0;
+
+asm (
+ ".pushsection .rodata\n\t"
+ ".type vmcode_bound, @object\n\t"
+ "vmcode:\n\t"
+ "vmcode_bound:\n\t"
+ ".code16\n\t"
+ "bound %ax, (2048)\n\t"
+ "int3\n\t"
+ "vmcode_sysenter:\n\t"
+ "sysenter\n\t"
+ ".size vmcode, . - vmcode\n\t"
+ "end_vmcode:\n\t"
+ ".code32\n\t"
+ ".popsection"
+ );
+
+extern unsigned char vmcode[], end_vmcode[];
+extern unsigned char vmcode_bound[], vmcode_sysenter[];
+
+static void do_test(struct vm86plus_struct *v86, unsigned long eip,
+ const char *text)
+{
+ long ret;
+
+ printf("[RUN]\t%s from vm86 mode\n", text);
+ v86->regs.eip = eip;
+ ret = vm86(VM86_ENTER, v86);
+
+ if (ret == -1 && errno == ENOSYS) {
+ printf("[SKIP]\tvm86 not supported\n");
+ return;
+ }
+
+ if (VM86_TYPE(ret) == VM86_INTx) {
+ char trapname[32];
+ int trapno = VM86_ARG(ret);
+ if (trapno == 13)
+ strcpy(trapname, "GP");
+ else if (trapno == 5)
+ strcpy(trapname, "BR");
+ else if (trapno == 14)
+ strcpy(trapname, "PF");
+ else
+ sprintf(trapname, "%d", trapno);
+
+ printf("[OK]\tExited vm86 mode due to #%s\n", trapname);
+ } else if (VM86_TYPE(ret) == VM86_UNKNOWN) {
+ printf("[OK]\tExited vm86 mode due to unhandled GP fault\n");
+ } else {
+ printf("[OK]\tExited vm86 mode due to type %ld, arg %ld\n",
+ VM86_TYPE(ret), VM86_ARG(ret));
+ }
+}
+
+int main(void)
+{
+ struct vm86plus_struct v86;
+ unsigned char *addr = mmap((void *)load_addr, 4096,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1,0);
+ if (addr != (unsigned char *)load_addr)
+ err(1, "mmap");
+
+ memcpy(addr, vmcode, end_vmcode - vmcode);
+ addr[2048] = 2;
+ addr[2050] = 3;
+
+ memset(&v86, 0, sizeof(v86));
+
+ v86.regs.cs = load_addr / 16;
+ v86.regs.ss = load_addr / 16;
+ v86.regs.ds = load_addr / 16;
+ v86.regs.es = load_addr / 16;
+
+ assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */
+
+ /* #BR -- should deliver SIG??? */
+ do_test(&v86, vmcode_bound - vmcode, "#BR");
+
+ /* SYSENTER -- should cause #GP or #UD depending on CPU */
+ do_test(&v86, vmcode_sysenter - vmcode, "SYSENTER");
+
+ return (nerrs == 0 ? 0 : 1);
+}
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-06-02 5:38 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-29 21:58 [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode Andy Lutomirski
2015-06-01 16:02 ` Shuah Khan
2015-06-01 22:54 ` Andy Lutomirski
2015-06-01 23:27 ` Shuah Khan
2015-06-01 23:45 ` Andy Lutomirski
2015-06-01 23:58 ` Shuah Khan
2015-06-02 5:37 ` [tip:x86/urgent] x86/asm/entry/32, selftests: Add a selftest for kernel entries from VM86 mode tip-bot for Andy Lutomirski
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.