Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/x86/include/asm/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  debugreg.h   Sprache: C

 
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_X86_DEBUGREG_H
#define _ASM_X86_DEBUGREG_H

#include <linux/bug.h>
#include <linux/percpu.h>
#include <uapi/asm/debugreg.h>

#include <asm/cpufeature.h>
#include <asm/msr.h>

/*
 * Define bits that are always set to 1 in DR7, only bit 10 is
 * architecturally reserved to '1'.
 *
 * This is also the init/reset value for DR7.
 */

#define DR7_FIXED_1 0x00000400

DECLARE_PER_CPU(unsigned long, cpu_dr7);

#ifndef CONFIG_PARAVIRT_XXL
/*
 * These special macros can be used to get or set a debugging register
 */

#define get_debugreg(var, register)    \
 (var) = native_get_debugreg(register)
#define set_debugreg(value, register)    \
 native_set_debugreg(register, value)
#endif

static __always_inline unsigned long native_get_debugreg(int regno)
{
 unsigned long val;

 switch (regno) {
 case 0:
  asm("mov %%db0, %0" :"=r" (val));
  break;
 case 1:
  asm("mov %%db1, %0" :"=r" (val));
  break;
 case 2:
  asm("mov %%db2, %0" :"=r" (val));
  break;
 case 3:
  asm("mov %%db3, %0" :"=r" (val));
  break;
 case 6:
  asm("mov %%db6, %0" :"=r" (val));
  break;
 case 7:
  /*
 * Use "asm volatile" for DR7 reads to forbid re-ordering them
 * with other code.
 *
 * This is needed because a DR7 access can cause a #VC exception
 * when running under SEV-ES. Taking a #VC exception is not a
 * safe thing to do just anywhere in the entry code and
 * re-ordering might place the access into an unsafe location.
 *
 * This happened in the NMI handler, where the DR7 read was
 * re-ordered to happen before the call to sev_es_ist_enter(),
 * causing stack recursion.
 */

  asm volatile("mov %%db7, %0" : "=r" (val));
  break;
 default:
  BUG();
 }
 return val;
}

static __always_inline void native_set_debugreg(int regno, unsigned long value)
{
 switch (regno) {
 case 0:
  asm("mov %0, %%db0" ::"r" (value));
  break;
 case 1:
  asm("mov %0, %%db1" ::"r" (value));
  break;
 case 2:
  asm("mov %0, %%db2" ::"r" (value));
  break;
 case 3:
  asm("mov %0, %%db3" ::"r" (value));
  break;
 case 6:
  asm("mov %0, %%db6" ::"r" (value));
  break;
 case 7:
  /*
 * Use "asm volatile" for DR7 writes to forbid re-ordering them
 * with other code.
 *
 * While is didn't happen with a DR7 write (see the DR7 read
 * comment above which explains where it happened), add the
 * "asm volatile" here too to avoid similar problems in the
 * future.
 */

  asm volatile("mov %0, %%db7" ::"r" (value));
  break;
 default:
  BUG();
 }
}

static inline void hw_breakpoint_disable(void)
{
 /* Reset the control register for HW Breakpoint */
 set_debugreg(DR7_FIXED_1, 7);

 /* Zero-out the individual HW breakpoint address registers */
 set_debugreg(0UL, 0);
 set_debugreg(0UL, 1);
 set_debugreg(0UL, 2);
 set_debugreg(0UL, 3);
}

static __always_inline bool hw_breakpoint_active(void)
{
 return __this_cpu_read(cpu_dr7) & DR_GLOBAL_ENABLE_MASK;
}

extern void hw_breakpoint_restore(void);

static __always_inline unsigned long local_db_save(void)
{
 unsigned long dr7;

 if (static_cpu_has(X86_FEATURE_HYPERVISOR) && !hw_breakpoint_active())
  return 0;

 get_debugreg(dr7, 7);

 /* Architecturally set bit */
 dr7 &= ~DR7_FIXED_1;
 if (dr7)
  set_debugreg(DR7_FIXED_1, 7);

 /*
 * Ensure the compiler doesn't lower the above statements into
 * the critical section; disabling breakpoints late would not
 * be good.
 */

 barrier();

 return dr7;
}

static __always_inline void local_db_restore(unsigned long dr7)
{
 /*
 * Ensure the compiler doesn't raise this statement into
 * the critical section; enabling breakpoints early would
 * not be good.
 */

 barrier();
 if (dr7)
  set_debugreg(dr7, 7);
}

#ifdef CONFIG_CPU_SUP_AMD
extern void amd_set_dr_addr_mask(unsigned long mask, unsigned int dr);
extern unsigned long amd_get_dr_addr_mask(unsigned int dr);
#else
static inline void amd_set_dr_addr_mask(unsigned long mask, unsigned int dr) { }
static inline unsigned long amd_get_dr_addr_mask(unsigned int dr)
{
 return 0;
}
#endif

static inline unsigned long get_debugctlmsr(void)
{
 unsigned long debugctlmsr = 0;

#ifndef CONFIG_X86_DEBUGCTLMSR
 if (boot_cpu_data.x86 < 6)
  return 0;
#endif
 rdmsrq(MSR_IA32_DEBUGCTLMSR, debugctlmsr);

 return debugctlmsr;
}

static inline void update_debugctlmsr(unsigned long debugctlmsr)
{
#ifndef CONFIG_X86_DEBUGCTLMSR
 if (boot_cpu_data.x86 < 6)
  return;
#endif
 wrmsrq(MSR_IA32_DEBUGCTLMSR, debugctlmsr);
}

#endif /* _ASM_X86_DEBUGREG_H */

Messung V0.5
C=95 H=78 G=86

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.