2014-12-09 23:45:17 +08:00
|
|
|
#ifndef __LINUX_KBUILD_H
|
|
|
|
# error "Please do not build this file directly, build asm-offsets.c instead"
|
|
|
|
#endif
|
|
|
|
|
2007-10-11 17:12:08 +08:00
|
|
|
#include <asm/ucontext.h>
|
|
|
|
|
|
|
|
#include <linux/lguest.h>
|
|
|
|
#include "../../../drivers/lguest/lg.h"
|
|
|
|
|
2016-01-29 07:11:24 +08:00
|
|
|
#define __SYSCALL_I386(nr, sym, qual) [nr] = 1,
|
2011-11-12 08:07:41 +08:00
|
|
|
static char syscalls[] = {
|
|
|
|
#include <asm/syscalls_32.h>
|
|
|
|
};
|
|
|
|
|
2007-10-11 17:12:08 +08:00
|
|
|
/* workaround for a warning with -Wmissing-prototypes */
|
|
|
|
void foo(void);
|
|
|
|
|
|
|
|
void foo(void)
|
|
|
|
{
|
|
|
|
OFFSET(CPUINFO_x86, cpuinfo_x86, x86);
|
|
|
|
OFFSET(CPUINFO_x86_vendor, cpuinfo_x86, x86_vendor);
|
|
|
|
OFFSET(CPUINFO_x86_model, cpuinfo_x86, x86_model);
|
|
|
|
OFFSET(CPUINFO_x86_mask, cpuinfo_x86, x86_mask);
|
|
|
|
OFFSET(CPUINFO_cpuid_level, cpuinfo_x86, cpuid_level);
|
|
|
|
OFFSET(CPUINFO_x86_capability, cpuinfo_x86, x86_capability);
|
|
|
|
OFFSET(CPUINFO_x86_vendor_id, cpuinfo_x86, x86_vendor_id);
|
|
|
|
BLANK();
|
|
|
|
|
2008-01-30 20:30:56 +08:00
|
|
|
OFFSET(PT_EBX, pt_regs, bx);
|
|
|
|
OFFSET(PT_ECX, pt_regs, cx);
|
|
|
|
OFFSET(PT_EDX, pt_regs, dx);
|
|
|
|
OFFSET(PT_ESI, pt_regs, si);
|
|
|
|
OFFSET(PT_EDI, pt_regs, di);
|
|
|
|
OFFSET(PT_EBP, pt_regs, bp);
|
|
|
|
OFFSET(PT_EAX, pt_regs, ax);
|
|
|
|
OFFSET(PT_DS, pt_regs, ds);
|
|
|
|
OFFSET(PT_ES, pt_regs, es);
|
|
|
|
OFFSET(PT_FS, pt_regs, fs);
|
2009-02-09 21:17:40 +08:00
|
|
|
OFFSET(PT_GS, pt_regs, gs);
|
2008-01-30 20:30:56 +08:00
|
|
|
OFFSET(PT_ORIG_EAX, pt_regs, orig_ax);
|
|
|
|
OFFSET(PT_EIP, pt_regs, ip);
|
|
|
|
OFFSET(PT_CS, pt_regs, cs);
|
|
|
|
OFFSET(PT_EFLAGS, pt_regs, flags);
|
|
|
|
OFFSET(PT_OLDESP, pt_regs, sp);
|
|
|
|
OFFSET(PT_OLDSS, pt_regs, ss);
|
2007-10-11 17:12:08 +08:00
|
|
|
BLANK();
|
|
|
|
|
2013-05-02 09:53:30 +08:00
|
|
|
OFFSET(saved_context_gdt_desc, saved_context, gdt_desc);
|
|
|
|
BLANK();
|
|
|
|
|
2008-01-30 20:31:02 +08:00
|
|
|
/* Offset from the sysenter stack to tss.sp0 */
|
|
|
|
DEFINE(TSS_sysenter_sp0, offsetof(struct tss_struct, x86_tss.sp0) -
|
2015-03-09 22:52:18 +08:00
|
|
|
offsetofend(struct tss_struct, SYSENTER_stack));
|
2007-10-11 17:12:08 +08:00
|
|
|
|
x86/entry/32: Simplify and fix up the SYSENTER stack #DB/NMI fixup
Right after SYSENTER, we can get a #DB or NMI. On x86_32, there's no IST,
so the exception handler is invoked on the temporary SYSENTER stack.
Because the SYSENTER stack is very small, we have a fixup to switch
off the stack quickly when this happens. The old fixup had several issues:
1. It checked the interrupt frame's CS and EIP. This wasn't
obviously correct on Xen or if vm86 mode was in use [1].
2. In the NMI handler, it did some frightening digging into the
stack frame. I'm not convinced this digging was correct.
3. The fixup didn't switch stacks and then switch back. Instead, it
synthesized a brand new stack frame that would redirect the IRET
back to the SYSENTER code. That frame was highly questionable.
For one thing, if NMI nested inside #DB, we would effectively
abort the #DB prologue, which was probably safe but was
frightening. For another, the code used PUSHFL to write the
FLAGS portion of the frame, which was simply bogus -- by the time
PUSHFL was called, at least TF, NT, VM, and all of the arithmetic
flags were clobbered.
Simplify this considerably. Instead of looking at the saved frame
to see where we came from, check the hardware ESP register against
the SYSENTER stack directly. Malicious user code cannot spoof the
kernel ESP register, and by moving the check after SAVE_ALL, we can
use normal PER_CPU accesses to find all the relevant addresses.
With this patch applied, the improved syscall_nt_32 test finally
passes on 32-bit kernels.
[1] It isn't obviously correct, but it is nonetheless safe from vm86
shenanigans as far as I can tell. A user can't point EIP at
entry_SYSENTER_32 while in vm86 mode because entry_SYSENTER_32,
like all kernel addresses, is greater than 0xffff and would thus
violate the CS segment limit.
Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/b2cdbc037031c07ecf2c40a96069318aec0e7971.1457578375.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
2016-03-10 11:00:32 +08:00
|
|
|
/* Offset from cpu_tss to SYSENTER_stack */
|
|
|
|
OFFSET(CPU_TSS_SYSENTER_stack, tss_struct, SYSENTER_stack);
|
|
|
|
/* Size of SYSENTER_stack */
|
|
|
|
DEFINE(SIZEOF_SYSENTER_stack, sizeof(((struct tss_struct *)0)->SYSENTER_stack));
|
|
|
|
|
2008-02-19 15:16:03 +08:00
|
|
|
#if defined(CONFIG_LGUEST) || defined(CONFIG_LGUEST_GUEST) || defined(CONFIG_LGUEST_MODULE)
|
2007-10-11 17:12:08 +08:00
|
|
|
BLANK();
|
|
|
|
OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
|
lguest: optimize by coding restore_flags and irq_enable in assembler.
The downside of the last patch which made restore_flags and irq_enable
check interrupts is that they are now too big to be patched directly
into the callsites, so the C versions are always used.
But the C versions go via PV_CALLEE_SAVE_REGS_THUNK which saves all
the registers. In fact, we don't need any registers in the fast path,
so we can do better than this if we actually code them in assembler.
The results are in the noise, but since it's about the same amount of
code, it's worth applying.
1GB Guest->Host: input(suppressed),output(suppressed)
Before:
Seconds: 0:16.53
Packets: 377268,753673
Interrupts: 22461,24297
Notifications: 1(5245),21303(732370)
Net IRQs triggered: 377023(245),42578(711095)
After:
Seconds: 0:16.48
Packets: 377289,753673
Interrupts: 22281,24465
Notifications: 1(5245),21296(732377)
Net IRQs triggered: 377060(229),42564(711109)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2009-06-13 12:27:03 +08:00
|
|
|
OFFSET(LGUEST_DATA_irq_pending, lguest_data, irq_pending);
|
2008-02-04 04:11:10 +08:00
|
|
|
|
|
|
|
BLANK();
|
2007-10-11 17:12:08 +08:00
|
|
|
OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc);
|
|
|
|
OFFSET(LGUEST_PAGES_host_idt_desc, lguest_pages, state.host_idt_desc);
|
|
|
|
OFFSET(LGUEST_PAGES_host_cr3, lguest_pages, state.host_cr3);
|
|
|
|
OFFSET(LGUEST_PAGES_host_sp, lguest_pages, state.host_sp);
|
|
|
|
OFFSET(LGUEST_PAGES_guest_gdt_desc, lguest_pages,state.guest_gdt_desc);
|
|
|
|
OFFSET(LGUEST_PAGES_guest_idt_desc, lguest_pages,state.guest_idt_desc);
|
|
|
|
OFFSET(LGUEST_PAGES_guest_gdt, lguest_pages, state.guest_gdt);
|
|
|
|
OFFSET(LGUEST_PAGES_regs_trapnum, lguest_pages, regs.trapnum);
|
|
|
|
OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode);
|
|
|
|
OFFSET(LGUEST_PAGES_regs, lguest_pages, regs);
|
|
|
|
#endif
|
2011-11-12 08:07:41 +08:00
|
|
|
BLANK();
|
|
|
|
DEFINE(__NR_syscall_max, sizeof(syscalls) - 1);
|
|
|
|
DEFINE(NR_syscalls, sizeof(syscalls));
|
2007-10-11 17:12:08 +08:00
|
|
|
}
|