Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
On 06/01/2015 05:45 PM, Andy Lutomirski wrote: > On Mon, Jun 1, 2015 at 4:27 PM, Shuah Khan wrote: >> On 06/01/2015 04:54 PM, Andy Lutomirski wrote: >>> On Mon, Jun 1, 2015 at 9:02 AM, Shuah Khan 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 > --- > > 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) shua...@osg.samsung.com | (970) 217-8978 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
On Mon, Jun 1, 2015 at 4:27 PM, Shuah Khan wrote: > On 06/01/2015 04:54 PM, Andy Lutomirski wrote: >> On Mon, Jun 1, 2015 at 9:02 AM, Shuah Khan 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 --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
On 06/01/2015 04:54 PM, Andy Lutomirski wrote: > On Mon, Jun 1, 2015 at 9:02 AM, Shuah Khan 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 >>> --- >>> >>> 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) shua...@osg.samsung.com | (970) 217-8978 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
On Mon, Jun 1, 2015 at 9:02 AM, Shuah Khan 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 >> --- >> >> 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 > > 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 ..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 >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +static unsigned long load_addr = 0x1; >> +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]\tE
Re: [PATCH] x86_32, entry, selftests: Add a selftest for kernel entries from vm86 mode
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 > --- > > 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 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 ..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 > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +static unsigned long load_addr = 0x1; > +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, > +
[PATCH] x86_32, entry, 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. 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 --- 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 ..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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned long load_addr = 0x1; +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); /*