hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
 * SPDX-License-Identifier: GPL-2.0
 *
 * Copyright (C) 2016 Philippe Gerum  <rpm@xenomai.org>.
 */
#ifndef __ASM_GENERIC_IRQ_PIPELINE_H
#define __ASM_GENERIC_IRQ_PIPELINE_H
 
#include <linux/kconfig.h>
#include <linux/types.h>
 
#ifdef CONFIG_IRQ_PIPELINE
 
unsigned long inband_irq_save(void);
void inband_irq_restore(unsigned long flags);
void inband_irq_enable(void);
void inband_irq_disable(void);
int inband_irqs_disabled(void);
 
#define hard_cond_local_irq_enable()        hard_local_irq_enable()
#define hard_cond_local_irq_disable()        hard_local_irq_disable()
#define hard_cond_local_irq_save()        hard_local_irq_save()
#define hard_cond_local_irq_restore(__flags)    hard_local_irq_restore(__flags)
 
#define hard_local_irq_save()            native_irq_save()
#define hard_local_irq_restore(__flags)        native_irq_restore(__flags)
#define hard_local_irq_enable()            native_irq_enable()
#define hard_local_irq_disable()        native_irq_disable()
#define hard_local_save_flags()            native_save_flags()
 
#define hard_irqs_disabled()            native_irqs_disabled()
#define hard_irqs_disabled_flags(__flags)    native_irqs_disabled_flags(__flags)
 
void irq_pipeline_nmi_enter(void);
void irq_pipeline_nmi_exit(void);
 
/* Swap then merge virtual and hardware interrupt states. */
#define irqs_merge_flags(__flags, __stalled)                \
   ({                                \
       unsigned long __combo =                    \
           arch_irqs_virtual_to_native_flags(__stalled) |    \
           arch_irqs_native_to_virtual_flags(__flags);    \
       __combo;                        \
   })
 
/* Extract swap virtual and hardware interrupt states. */
#define irqs_split_flags(__combo, __stall_r)                \
   ({                                \
       unsigned long __virt = (__combo);            \
       *(__stall_r) = hard_irqs_disabled_flags(__combo);    \
       __virt &= ~arch_irqs_virtual_to_native_flags(*(__stall_r)); \
       arch_irqs_virtual_to_native_flags(__virt);        \
   })
 
#define hard_local_irq_sync()            native_irq_sync()
 
#else /* !CONFIG_IRQ_PIPELINE */
 
#define hard_local_save_flags()            ({ unsigned long __flags; \
                       raw_local_save_flags(__flags); __flags; })
#define hard_local_irq_enable()            raw_local_irq_enable()
#define hard_local_irq_disable()        raw_local_irq_disable()
#define hard_local_irq_save()            ({ unsigned long __flags; \
                       raw_local_irq_save(__flags); __flags; })
#define hard_local_irq_restore(__flags)        raw_local_irq_restore(__flags)
 
#define hard_cond_local_irq_enable()        do { } while(0)
#define hard_cond_local_irq_disable()        do { } while(0)
#define hard_cond_local_irq_save()        0
#define hard_cond_local_irq_restore(__flags)    do { (void)(__flags); } while(0)
 
#define hard_irqs_disabled()            irqs_disabled()
#define hard_irqs_disabled_flags(__flags)    raw_irqs_disabled_flags(__flags)
 
static inline void irq_pipeline_nmi_enter(void) { }
static inline void irq_pipeline_nmi_exit(void) { }
 
#define hard_local_irq_sync()            do { } while (0)
 
#endif /* !CONFIG_IRQ_PIPELINE */
 
#ifdef CONFIG_DEBUG_IRQ_PIPELINE
void check_inband_stage(void);
#define check_hard_irqs_disabled()        \
   WARN_ON_ONCE(!hard_irqs_disabled())
#else
static inline void check_inband_stage(void) { }
static inline int check_hard_irqs_disabled(void) { return 0; }
#endif
 
extern bool irq_pipeline_oopsing;
 
static __always_inline bool irqs_pipelined(void)
{
   return IS_ENABLED(CONFIG_IRQ_PIPELINE);
}
 
static __always_inline bool irq_pipeline_debug(void)
{
   return IS_ENABLED(CONFIG_DEBUG_IRQ_PIPELINE) &&
       !irq_pipeline_oopsing;
}
 
static __always_inline bool irq_pipeline_debug_locking(void)
{
   return IS_ENABLED(CONFIG_DEBUG_HARD_LOCKS);
}
 
#endif /* __ASM_GENERIC_IRQ_PIPELINE_H */