Re: preempt notifier emulation host crash fix

Izik Eidus
2008-02-04T13:27:15Z

On Sun, 2008-02-03 at 23:45 +0100, Andrea Arcangeli wrote:
> Hello,
>
> there's a small glitch in the preempt notifier external module
> emulation. The overloaded debug handler will not detect when a debug
> exception has been generated by ptrace and it'll crash the host by
> calling the preempt emulator like if this was a KVM preempt emulated
> exception, instead of notifying userland.

ouch

>
> To detect when the preempt emulation is needed and when the exception
> should be bypassed to the original handler, I decided to use bit 10 of
> db7 that can't be set to 1 by ptrace, the mask against the userland
> passed db7 value is 0xfc00, so bit 10 is forbidden to be on unless it
> was KVM setting it manually with 0x701 (kvm really only needs 0x301 to
> get exact exception, dunno what 0x400 means, it's defined reserved,
> but it doesn't matter what it means as long as ptrace can't set it ;).

that make sense, lets wait to avi.

>
> So this fixes the host crash for me:
>
> Signed-off-by: Andrea Arcangeli <andrea-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
>
> diff --git a/kernel/preempt.c b/kernel/preempt.c
> index ed5d1c1..0ae69d7 100644
> --- a/kernel/preempt.c
> +++ b/kernel/preempt.c
> @@ -143,10 +143,10 @@ unsigned long orig_int1_handler;
>
> asm ("pn_int1_handler: \n\t"
> "push " TMP " \n\t"
> - "mov %db6, " TMP " \n\t"
> - "test $1, " TMP " \n\t"
> + "mov %db7, " TMP " \n\t"
> + "cmp $0x701, " TMP " \n\t"
> "pop " TMP " \n\t"
> - "jz .Lnotme \n\t"
> + "jnz .Lnotme \n\t"
> SAVE_REGS "\n\t"
> #ifdef CONFIG_X86_64
> "leaq 120(%rsp),%rdi\n\t"
>
>
> Testing is very easy, after loading kvm:
>
> andrea@svm ~ $ cat main.c
> main() {}
> andrea@svm ~ $ gcc main.c -g
> andrea@svm ~ $ gdb a.out
> GNU gdb 6.7.1
> Copyright (C) 2007 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later
> <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law. Type "show
> copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-pc-linux-gnu"...
> Using host libthread_db library "/lib/libthread_db.so.1".
> (gdb) hbreak main
> Hardware assisted breakpoint 1 at 0x4004bc: file main.c, line 1.
> (gdb) r
> Starting program: /home/andrea/a.out
>
> Breakpoint 1, main () at main.c:1
> 1 main() {}
>
>
> Whenever the external module was loaded host would reboot instantly
> after "r". To test it further I added the WARN_ON back to vcpu_put
> handler to verify the vcpu->cpu matches smp_processor_id the whole
> time (so preempt emulation is working ok, with SVM that would be
> visible only with rdtsc not being monotone from the point of view of
> each vcpu in smp host w/o taskset binding the vcpu to a single
> host-cpu, only vmx would crash the host if preempt notifiers don't
> fire).
>
> I suppose the bug existed way before I rewritten the sched_in
> emulation, because I didn't touch or pay attention to the ptrace
> bypass.
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> kvm-devel mailing list
> kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> https://lists.sourceforge.net/lists/listinfo/kvm-devel