xen/x86-64: fix breakpoints and hardware watchpoints
Native x86-64 uses the IST mechanism to run int3 and debug traps on an alternative stack. Xen does not do this, and so the frames were being misinterpreted by the ptrace code. This change special-cases these two exceptions by using Xen variants which run on the normal kernel stack properly. Impact: avoid crash or bad data when IST trap is invoked under Xen Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
This commit is contained in:
parent
6b2e8523df
commit
6cac5a9246
3 changed files with 26 additions and 1 deletions
|
@ -13,6 +13,9 @@ asmlinkage void divide_error(void);
|
|||
asmlinkage void debug(void);
|
||||
asmlinkage void nmi(void);
|
||||
asmlinkage void int3(void);
|
||||
asmlinkage void xen_debug(void);
|
||||
asmlinkage void xen_int3(void);
|
||||
asmlinkage void xen_stack_segment(void);
|
||||
asmlinkage void overflow(void);
|
||||
asmlinkage void bounds(void);
|
||||
asmlinkage void invalid_op(void);
|
||||
|
|
|
@ -1379,6 +1379,11 @@ END(xen_failsafe_callback)
|
|||
paranoidzeroentry_ist debug do_debug DEBUG_STACK
|
||||
paranoidzeroentry_ist int3 do_int3 DEBUG_STACK
|
||||
paranoiderrorentry stack_segment do_stack_segment
|
||||
#ifdef CONFIG_XEN
|
||||
zeroentry xen_debug do_debug
|
||||
zeroentry xen_int3 do_int3
|
||||
errorentry xen_stack_segment do_stack_segment
|
||||
#endif
|
||||
errorentry general_protection do_general_protection
|
||||
errorentry page_fault do_page_fault
|
||||
#ifdef CONFIG_X86_MCE
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/start_kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
|
@ -44,6 +45,7 @@
|
|||
#include <asm/processor.h>
|
||||
#include <asm/proto.h>
|
||||
#include <asm/msr-index.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/desc.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
@ -428,11 +430,26 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
|
|||
static int cvt_gate_to_trap(int vector, const gate_desc *val,
|
||||
struct trap_info *info)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT)
|
||||
return 0;
|
||||
|
||||
info->vector = vector;
|
||||
info->address = gate_offset(*val);
|
||||
|
||||
addr = gate_offset(*val);
|
||||
#ifdef CONFIG_X86_64
|
||||
if (addr == (unsigned long)debug)
|
||||
addr = (unsigned long)xen_debug;
|
||||
else if (addr == (unsigned long)int3)
|
||||
addr = (unsigned long)xen_int3;
|
||||
else if (addr == (unsigned long)stack_segment)
|
||||
addr = (unsigned long)xen_stack_segment;
|
||||
else
|
||||
WARN_ON(val->ist != 0);
|
||||
#endif /* CONFIG_X86_64 */
|
||||
info->address = addr;
|
||||
|
||||
info->cs = gate_segment(*val);
|
||||
info->flags = val->dpl;
|
||||
/* interrupt gates clear IF */
|
||||
|
|
Loading…
Reference in a new issue