11965aae3c98397aad957412413c07e97b1bd4e64H. Peter Anvin#ifndef _ASM_X86_DEBUGREG_H 21965aae3c98397aad957412413c07e97b1bd4e64H. Peter Anvin#define _ASM_X86_DEBUGREG_H 321ebddd3efd3aff961153f1bac4793218dfaea9cThomas Gleixner 421ebddd3efd3aff961153f1bac4793218dfaea9cThomas Gleixner 5f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker#include <linux/bug.h> 6af170c5061dd78512c469e6e2d211980cdb2c193David Howells#include <uapi/asm/debugreg.h> 7f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker 828b4e0d86acf59ae3bc422921138a4958458326eTejun HeoDECLARE_PER_CPU(unsigned long, cpu_dr7); 9b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad 10f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker#ifndef CONFIG_PARAVIRT 11f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker/* 12f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker * These special macros can be used to get or set a debugging register 13f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker */ 14f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker#define get_debugreg(var, register) \ 15f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker (var) = native_get_debugreg(register) 16f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker#define set_debugreg(value, register) \ 17f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker native_set_debugreg(register, value) 18f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker#endif 19f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker 20f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmakerstatic inline unsigned long native_get_debugreg(int regno) 21f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker{ 22f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker unsigned long val = 0; /* Damn you, gcc! */ 23f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker 24f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker switch (regno) { 25f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 0: 26f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %%db0, %0" :"=r" (val)); 27f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 28f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 1: 29f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %%db1, %0" :"=r" (val)); 30f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 31f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 2: 32f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %%db2, %0" :"=r" (val)); 33f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 34f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 3: 35f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %%db3, %0" :"=r" (val)); 36f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 37f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 6: 38f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %%db6, %0" :"=r" (val)); 39f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 40f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 7: 41f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %%db7, %0" :"=r" (val)); 42f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 43f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker default: 44f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker BUG(); 45f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker } 46f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker return val; 47f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker} 48f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker 49f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmakerstatic inline void native_set_debugreg(int regno, unsigned long value) 50f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker{ 51f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker switch (regno) { 52f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 0: 53f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %0, %%db0" ::"r" (value)); 54f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 55f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 1: 56f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %0, %%db1" ::"r" (value)); 57f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 58f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 2: 59f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %0, %%db2" ::"r" (value)); 60f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 61f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 3: 62f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %0, %%db3" ::"r" (value)); 63f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 64f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 6: 65f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %0, %%db6" ::"r" (value)); 66f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 67f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker case 7: 68f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker asm("mov %0, %%db7" ::"r" (value)); 69f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker break; 70f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker default: 71f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker BUG(); 72f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker } 73f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker} 74f649e9388cd46ad1634164e56f96ae092ca59e4aPaul Gortmaker 75b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasadstatic inline void hw_breakpoint_disable(void) 76b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad{ 77b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad /* Zero the control register for HW Breakpoint */ 78b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad set_debugreg(0UL, 7); 79b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad 80b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad /* Zero-out the individual HW breakpoint address registers */ 81b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad set_debugreg(0UL, 0); 82b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad set_debugreg(0UL, 1); 83b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad set_debugreg(0UL, 2); 84b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad set_debugreg(0UL, 3); 85b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad} 86b332828c39326b1dca617f387dd15d12e81cd5f0K.Prasad 8759d8eb53ea9947db7cad8ebc31b0fb54f23a9851Frederic Weisbeckerstatic inline int hw_breakpoint_active(void) 8859d8eb53ea9947db7cad8ebc31b0fb54f23a9851Frederic Weisbecker{ 890a3aee0da4402aa19b66e458038533c896fb80c6Tejun Heo return __this_cpu_read(cpu_dr7) & DR_GLOBAL_ENABLE_MASK; 9059d8eb53ea9947db7cad8ebc31b0fb54f23a9851Frederic Weisbecker} 9159d8eb53ea9947db7cad8ebc31b0fb54f23a9851Frederic Weisbecker 929f6b3c2c30cfbb1166ce7e74a8f9fd93ae19d2deFrederic Weisbeckerextern void aout_dump_debugregs(struct user *dump); 939f6b3c2c30cfbb1166ce7e74a8f9fd93ae19d2deFrederic Weisbecker 9424f1e32c60c45c89a997c73395b69c8af6f0a84eFrederic Weisbeckerextern void hw_breakpoint_restore(void); 9524f1e32c60c45c89a997c73395b69c8af6f0a84eFrederic Weisbecker 9642181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedt#ifdef CONFIG_X86_64 9742181186ad4db986fcaa40ca95c6e407e9e79372Steven RostedtDECLARE_PER_CPU(int, debug_stack_usage); 9842181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtstatic inline void debug_stack_usage_inc(void) 9942181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedt{ 10089cbc76768c2fa4ed95545bf961f3a14ddfeed21Christoph Lameter __this_cpu_inc(debug_stack_usage); 10142181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedt} 10242181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtstatic inline void debug_stack_usage_dec(void) 10342181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedt{ 10489cbc76768c2fa4ed95545bf961f3a14ddfeed21Christoph Lameter __this_cpu_dec(debug_stack_usage); 10542181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedt} 10642181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtint is_debug_stack(unsigned long addr); 10742181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtvoid debug_stack_set_zero(void); 10842181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtvoid debug_stack_reset(void); 10942181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedt#else /* !X86_64 */ 11042181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtstatic inline int is_debug_stack(unsigned long addr) { return 0; } 11142181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtstatic inline void debug_stack_set_zero(void) { } 11242181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtstatic inline void debug_stack_reset(void) { } 11342181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtstatic inline void debug_stack_usage_inc(void) { } 11442181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedtstatic inline void debug_stack_usage_dec(void) { } 11542181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedt#endif /* X86_64 */ 11642181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedt 11742181186ad4db986fcaa40ca95c6e407e9e79372Steven Rostedt 1181965aae3c98397aad957412413c07e97b1bd4e64H. Peter Anvin#endif /* _ASM_X86_DEBUGREG_H */ 119