Skip to content

Commit c00a4cb

Browse files
AntonioBorneoKAGA-KOKO
authored andcommitted
irqchip/stm32-exti: Skip secure events
Secure OS can reserve some EXTI events, marking them as "secure" by setting the corresponding bit in register SECCFGR (aka TZENR). These events cannot be used by Linux. Read the list of reserved events and check it during interrupt domain allocation. Signed-off-by: Antonio Borneo <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 06d7e91 commit c00a4cb

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

drivers/irqchip/irq-stm32-exti.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct stm32_exti_bank {
3636
u32 rpr_ofst;
3737
u32 fpr_ofst;
3838
u32 trg_ofst;
39+
u32 seccfgr_ofst;
3940
};
4041

4142
#define UNDEF_REG ~0
@@ -54,10 +55,12 @@ struct stm32_exti_chip_data {
5455
u32 mask_cache;
5556
u32 rtsr_cache;
5657
u32 ftsr_cache;
58+
u32 event_reserved;
5759
};
5860

5961
struct stm32_exti_host_data {
6062
void __iomem *base;
63+
struct device *dev;
6164
struct stm32_exti_chip_data *chips_data;
6265
const struct stm32_exti_drv_data *drv_data;
6366
struct hwspinlock *hwlock;
@@ -73,6 +76,7 @@ static const struct stm32_exti_bank stm32f4xx_exti_b1 = {
7376
.rpr_ofst = 0x14,
7477
.fpr_ofst = UNDEF_REG,
7578
.trg_ofst = UNDEF_REG,
79+
.seccfgr_ofst = UNDEF_REG,
7680
};
7781

7882
static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = {
@@ -93,6 +97,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b1 = {
9397
.rpr_ofst = 0x88,
9498
.fpr_ofst = UNDEF_REG,
9599
.trg_ofst = UNDEF_REG,
100+
.seccfgr_ofst = UNDEF_REG,
96101
};
97102

98103
static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
@@ -104,6 +109,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b2 = {
104109
.rpr_ofst = 0x98,
105110
.fpr_ofst = UNDEF_REG,
106111
.trg_ofst = UNDEF_REG,
112+
.seccfgr_ofst = UNDEF_REG,
107113
};
108114

109115
static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
@@ -115,6 +121,7 @@ static const struct stm32_exti_bank stm32h7xx_exti_b3 = {
115121
.rpr_ofst = 0xA8,
116122
.fpr_ofst = UNDEF_REG,
117123
.trg_ofst = UNDEF_REG,
124+
.seccfgr_ofst = UNDEF_REG,
118125
};
119126

120127
static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = {
@@ -137,6 +144,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b1 = {
137144
.rpr_ofst = 0x0C,
138145
.fpr_ofst = 0x10,
139146
.trg_ofst = 0x3EC,
147+
.seccfgr_ofst = 0x14,
140148
};
141149

142150
static const struct stm32_exti_bank stm32mp1_exti_b2 = {
@@ -148,6 +156,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b2 = {
148156
.rpr_ofst = 0x2C,
149157
.fpr_ofst = 0x30,
150158
.trg_ofst = 0x3E8,
159+
.seccfgr_ofst = 0x34,
151160
};
152161

153162
static const struct stm32_exti_bank stm32mp1_exti_b3 = {
@@ -159,6 +168,7 @@ static const struct stm32_exti_bank stm32mp1_exti_b3 = {
159168
.rpr_ofst = 0x4C,
160169
.fpr_ofst = 0x50,
161170
.trg_ofst = 0x3E4,
171+
.seccfgr_ofst = 0x54,
162172
};
163173

164174
static const struct stm32_exti_bank *stm32mp1_exti_banks[] = {
@@ -706,6 +716,12 @@ static int stm32_exti_h_domain_alloc(struct irq_domain *dm,
706716
bank = hwirq / IRQS_PER_BANK;
707717
chip_data = &host_data->chips_data[bank];
708718

719+
/* Check if event is reserved (Secure) */
720+
if (chip_data->event_reserved & BIT(hwirq % IRQS_PER_BANK)) {
721+
dev_err(host_data->dev, "event %lu is reserved, secure\n", hwirq);
722+
return -EPERM;
723+
}
724+
709725
event_trg = readl_relaxed(host_data->base + chip_data->reg_bank->trg_ofst);
710726
chip = (event_trg & BIT(hwirq % IRQS_PER_BANK)) ?
711727
&stm32_exti_h_chip : &stm32_exti_h_chip_direct;
@@ -803,6 +819,10 @@ stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data,
803819
if (stm32_bank->emr_ofst != UNDEF_REG)
804820
writel_relaxed(0, base + stm32_bank->emr_ofst);
805821

822+
/* reserve Secure events */
823+
if (stm32_bank->seccfgr_ofst != UNDEF_REG)
824+
chip_data->event_reserved = readl_relaxed(base + stm32_bank->seccfgr_ofst);
825+
806826
pr_info("%pOF: bank%d\n", node, bank_idx);
807827

808828
return chip_data;
@@ -908,6 +928,7 @@ static int stm32_exti_probe(struct platform_device *pdev)
908928
return -ENOMEM;
909929

910930
dev_set_drvdata(dev, host_data);
931+
host_data->dev = dev;
911932

912933
/* check for optional hwspinlock which may be not available yet */
913934
ret = of_hwspin_lock_get_id(np, 0);

0 commit comments

Comments
 (0)