From a9ad81b8d42190ff10aa0ce72bdf31bb313408b1 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 27 Feb 2011 05:27:06 +0100 Subject: Add x86 debug register Xen support * i386/xen/xen_boothdr.S: Add global visibility to __hyp_* symbols. * i386/i386/locore.S [MACH_XEN] (dr6,dr0,dr1,dr2,dr3): Make get_debugreg and set_debugreg hypercalls to manipulate debug registers. (dr0,dr1,dr2,dr3): Fix dr7 field shift. * i386/i386/xen.h (hyp_set_debugreg, hyp_get_debugreg): New prototypes. --- i386/i386/locore.S | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ i386/i386/xen.h | 5 ++++- i386/xen/xen_boothdr.S | 3 ++- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/i386/i386/locore.S b/i386/i386/locore.S index c640191..c1e6448 100644 --- a/i386/i386/locore.S +++ b/i386/i386/locore.S @@ -1419,7 +1419,14 @@ _inst_fetch_fault: ENTRY(dr6) +#ifdef MACH_XEN + pushl %ebx + movl $6, %ebx + call __hyp_get_debugreg + popl %ebx +#else /* MACH_XEN */ movl %db6, %eax +#endif /* MACH_XEN */ ret /* dr(address, type, len, persistence) @@ -1427,33 +1434,67 @@ ENTRY(dr6) ENTRY(dr0) movl S_ARG0, %eax movl %eax,EXT(dr_addr) +#ifdef MACH_XEN + pushl %ebx + movl $0,%ebx + movl %eax,%ecx + call __hyp_set_debugreg +#else /* MACH_XEN */ movl %eax, %db0 +#endif /* MACH_XEN */ movl $0, %ecx jmp 0f ENTRY(dr1) movl S_ARG0, %eax movl %eax,EXT(dr_addr)+1*4 +#ifdef MACH_XEN + pushl %ebx + movl $1,%ebx + movl %eax,%ecx + call __hyp_set_debugreg +#else /* MACH_XEN */ movl %eax, %db1 +#endif /* MACH_XEN */ movl $2, %ecx jmp 0f ENTRY(dr2) movl S_ARG0, %eax movl %eax,EXT(dr_addr)+2*4 +#ifdef MACH_XEN + pushl %ebx + movl $2,%ebx + movl %eax,%ecx + call __hyp_set_debugreg +#else /* MACH_XEN */ movl %eax, %db2 +#endif /* MACH_XEN */ movl $4, %ecx jmp 0f ENTRY(dr3) movl S_ARG0, %eax movl %eax,EXT(dr_addr)+3*4 +#ifdef MACH_XEN + pushl %ebx + movl $3,%ebx + movl %eax,%ecx + call __hyp_set_debugreg +#else /* MACH_XEN */ movl %eax, %db3 +#endif /* MACH_XEN */ movl $6, %ecx 0: pushl %ebp movl %esp, %ebp +#ifdef MACH_XEN + movl $7,%ebx + call __hyp_get_debugreg + movl %eax, %edx +#else /* MACH_XEN */ movl %db7, %edx +#endif /* MACH_XEN */ movl %edx,EXT(dr_addr)+4*4 andl dr_msk(,%ecx,2),%edx /* clear out new entry */ movl %edx,EXT(dr_addr)+5*4 @@ -1464,6 +1505,7 @@ ENTRY(dr3) movzbl B_ARG1, %eax andb $3, %al + addb %cl, %cl addb $0x10, %cl shll %cl, %eax orl %eax, %edx @@ -1474,7 +1516,14 @@ ENTRY(dr3) shll %cl, %eax orl %eax, %edx +#ifdef MACH_XEN + movl $7,%ebx + movl %edx, %ecx + call __hyp_set_debugreg + popl %ebx +#else /* MACH_XEN */ movl %edx, %db7 +#endif /* MACH_XEN */ movl %edx,EXT(dr_addr)+7*4 movl %edx, %eax leave diff --git a/i386/i386/xen.h b/i386/i386/xen.h index 8094d34..731e5a2 100644 --- a/i386/i386/xen.h +++ b/i386/i386/xen.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Samuel Thibault + * Copyright (C) 2006, 2009, 2010, 2011 Samuel Thibault * * This program is free software ; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -345,6 +345,9 @@ MACH_INLINE void __attribute__((noreturn)) hyp_reboot(void) for(;;); } +_hypcall2(int, set_debugreg, int, reg, unsigned long, value); +_hypcall1(unsigned long, get_debugreg, int, reg); + /* x86-specific */ MACH_INLINE unsigned64_t hyp_cpu_clock(void) { unsigned64_t tsc; diff --git a/i386/xen/xen_boothdr.S b/i386/xen/xen_boothdr.S index 6d595ab..1b32efb 100644 --- a/i386/xen/xen_boothdr.S +++ b/i386/xen/xen_boothdr.S @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Samuel Thibault + * Copyright (C) 2006, 2009, 2010, 2011 Samuel Thibault * * This program is free software ; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -124,6 +124,7 @@ hyp_shared_info: /* Labels just for debuggers */ #define hypcall(name, n) \ .org hypcalls + n*32 ; \ +.globl __hyp_##name ; \ __hyp_##name: hypcalls: -- cgit v1.2.3