1 // SPDX-License-Identifier: GPL-2.0+
5 * Copyright 2019, Michael Neuling, IBM Corporation.
8 #include <linux/types.h>
9 #include <linux/export.h>
11 #include <linux/debugfs.h>
12 #include <asm/debugfs.h>
13 #include <asm/machdep.h>
14 #include <asm/hvcall.h>
16 bool dawr_force_enable
;
17 EXPORT_SYMBOL_GPL(dawr_force_enable
);
19 int set_dawr(int nr
, struct arch_hw_breakpoint
*brk
)
21 unsigned long dawr
, dawrx
, mrd
;
25 dawrx
= (brk
->type
& (HW_BRK_TYPE_READ
| HW_BRK_TYPE_WRITE
))
27 dawrx
|= ((brk
->type
& (HW_BRK_TYPE_TRANSLATE
)) >> 2) << (63 - 59);
28 dawrx
|= (brk
->type
& (HW_BRK_TYPE_PRIV_ALL
)) >> 3;
30 * DAWR length is stored in field MDR bits 48:53. Matches range in
31 * doublewords (64 bits) baised by -1 eg. 0b000000=1DW and
33 * brk->hw_len is in bytes.
34 * This aligns up to double word size, shifts and does the bias.
36 mrd
= ((brk
->hw_len
+ 7) >> 3) - 1;
37 dawrx
|= (mrd
& 0x3f) << (63 - 53);
40 return ppc_md
.set_dawr(nr
, dawr
, dawrx
);
43 mtspr(SPRN_DAWR0
, dawr
);
44 mtspr(SPRN_DAWRX0
, dawrx
);
46 mtspr(SPRN_DAWR1
, dawr
);
47 mtspr(SPRN_DAWRX1
, dawrx
);
53 static void disable_dawrs_cb(void *info
)
55 struct arch_hw_breakpoint null_brk
= {0};
58 for (i
= 0; i
< nr_wp_slots(); i
++)
59 set_dawr(i
, &null_brk
);
62 static ssize_t
dawr_write_file_bool(struct file
*file
,
63 const char __user
*user_buf
,
64 size_t count
, loff_t
*ppos
)
66 struct arch_hw_breakpoint null_brk
= {0};
69 /* Send error to user if they hypervisor won't allow us to write DAWR */
70 if (!dawr_force_enable
&&
71 firmware_has_feature(FW_FEATURE_LPAR
) &&
72 set_dawr(0, &null_brk
) != H_SUCCESS
)
75 rc
= debugfs_write_file_bool(file
, user_buf
, count
, ppos
);
79 /* If we are clearing, make sure all CPUs have the DAWR cleared */
80 if (!dawr_force_enable
)
81 smp_call_function(disable_dawrs_cb
, NULL
, 0);
86 static const struct file_operations dawr_enable_fops
= {
87 .read
= debugfs_read_file_bool
,
88 .write
= dawr_write_file_bool
,
90 .llseek
= default_llseek
,
93 static int __init
dawr_force_setup(void)
95 if (cpu_has_feature(CPU_FTR_DAWR
)) {
96 /* Don't setup sysfs file for user control on P8 */
97 dawr_force_enable
= true;
101 if (PVR_VER(mfspr(SPRN_PVR
)) == PVR_POWER9
) {
102 /* Turn DAWR off by default, but allow admin to turn it on */
103 debugfs_create_file_unsafe("dawr_enable_dangerous", 0600,
104 powerpc_debugfs_root
,
110 arch_initcall(dawr_force_setup
);