0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/types.h>
0009 #include <linux/export.h>
0010 #include <linux/fs.h>
0011 #include <linux/debugfs.h>
0012 #include <asm/machdep.h>
0013 #include <asm/hvcall.h>
0014 #include <asm/firmware.h>
0015
0016 bool dawr_force_enable;
0017 EXPORT_SYMBOL_GPL(dawr_force_enable);
0018
0019 int set_dawr(int nr, struct arch_hw_breakpoint *brk)
0020 {
0021 unsigned long dawr, dawrx, mrd;
0022
0023 dawr = brk->address;
0024
0025 dawrx = (brk->type & (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE))
0026 << (63 - 58);
0027 dawrx |= ((brk->type & (HW_BRK_TYPE_TRANSLATE)) >> 2) << (63 - 59);
0028 dawrx |= (brk->type & (HW_BRK_TYPE_PRIV_ALL)) >> 3;
0029
0030
0031
0032
0033
0034
0035
0036 mrd = ((brk->hw_len + 7) >> 3) - 1;
0037 dawrx |= (mrd & 0x3f) << (63 - 53);
0038
0039 if (ppc_md.set_dawr)
0040 return ppc_md.set_dawr(nr, dawr, dawrx);
0041
0042 if (nr == 0) {
0043 mtspr(SPRN_DAWR0, dawr);
0044 mtspr(SPRN_DAWRX0, dawrx);
0045 } else {
0046 mtspr(SPRN_DAWR1, dawr);
0047 mtspr(SPRN_DAWRX1, dawrx);
0048 }
0049
0050 return 0;
0051 }
0052
0053 static void disable_dawrs_cb(void *info)
0054 {
0055 struct arch_hw_breakpoint null_brk = {0};
0056 int i;
0057
0058 for (i = 0; i < nr_wp_slots(); i++)
0059 set_dawr(i, &null_brk);
0060 }
0061
0062 static ssize_t dawr_write_file_bool(struct file *file,
0063 const char __user *user_buf,
0064 size_t count, loff_t *ppos)
0065 {
0066 struct arch_hw_breakpoint null_brk = {0};
0067 size_t rc;
0068
0069
0070 if (!dawr_force_enable &&
0071 firmware_has_feature(FW_FEATURE_LPAR) &&
0072 set_dawr(0, &null_brk) != H_SUCCESS)
0073 return -ENODEV;
0074
0075 rc = debugfs_write_file_bool(file, user_buf, count, ppos);
0076 if (rc)
0077 return rc;
0078
0079
0080 if (!dawr_force_enable)
0081 smp_call_function(disable_dawrs_cb, NULL, 0);
0082
0083 return rc;
0084 }
0085
0086 static const struct file_operations dawr_enable_fops = {
0087 .read = debugfs_read_file_bool,
0088 .write = dawr_write_file_bool,
0089 .open = simple_open,
0090 .llseek = default_llseek,
0091 };
0092
0093 static int __init dawr_force_setup(void)
0094 {
0095 if (cpu_has_feature(CPU_FTR_DAWR)) {
0096
0097 dawr_force_enable = true;
0098 return 0;
0099 }
0100
0101 if (PVR_VER(mfspr(SPRN_PVR)) == PVR_POWER9) {
0102
0103 debugfs_create_file_unsafe("dawr_enable_dangerous", 0600,
0104 arch_debugfs_dir,
0105 &dawr_force_enable,
0106 &dawr_enable_fops);
0107 }
0108 return 0;
0109 }
0110 arch_initcall(dawr_force_setup);