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