Skip to content

Commit a878957

Browse files
committed
Merge remote-tracking branch 'remotes/powerpc/topic/ppc-kvm' into kvm-ppc-next
This merges in the ppc-kvm topic branch from the powerpc tree to get patches which touch both general powerpc code and KVM code, one of which is a prerequisite for following patches. Signed-off-by: Paul Mackerras <[email protected]>
2 parents 44b198a + c1fe190 commit a878957

File tree

12 files changed

+250
-20
lines changed

12 files changed

+250
-20
lines changed

Documentation/powerpc/DAWR-POWER9.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,35 @@ POWER9. Loads and stores to the watchpoint locations will not be
5656
trapped in GDB. The watchpoint is remembered, so if the guest is
5757
migrated back to the POWER8 host, it will start working again.
5858

59+
Force enabling the DAWR
60+
=============================
61+
Kernels (since ~v5.2) have an option to force enable the DAWR via:
62+
63+
echo Y > /sys/kernel/debug/powerpc/dawr_enable_dangerous
64+
65+
This enables the DAWR even on POWER9.
66+
67+
This is a dangerous setting, USE AT YOUR OWN RISK.
68+
69+
Some users may not care about a bad user crashing their box
70+
(ie. single user/desktop systems) and really want the DAWR. This
71+
allows them to force enable DAWR.
72+
73+
This flag can also be used to disable DAWR access. Once this is
74+
cleared, all DAWR access should be cleared immediately and your
75+
machine once again safe from crashing.
76+
77+
Userspace may get confused by toggling this. If DAWR is force
78+
enabled/disabled between getting the number of breakpoints (via
79+
PTRACE_GETHWDBGINFO) and setting the breakpoint, userspace will get an
80+
inconsistent view of what's available. Similarly for guests.
81+
82+
For the DAWR to be enabled in a KVM guest, the DAWR needs to be force
83+
enabled in the host AND the guest. For this reason, this won't work on
84+
POWERVM as it doesn't allow the HCALL to work. Writes of 'Y' to the
85+
dawr_enable_dangerous file will fail if the hypervisor doesn't support
86+
writing the DAWR.
87+
88+
To double check the DAWR is working, run this kernel selftest:
89+
tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c
90+
Any errors/failures/skips mean something is wrong.

arch/powerpc/include/asm/hw_breakpoint.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,18 @@ static inline void hw_breakpoint_disable(void)
9090
extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
9191
int hw_breakpoint_handler(struct die_args *args);
9292

93+
extern int set_dawr(struct arch_hw_breakpoint *brk);
94+
extern bool dawr_force_enable;
95+
static inline bool dawr_enabled(void)
96+
{
97+
return dawr_force_enable;
98+
}
99+
93100
#else /* CONFIG_HAVE_HW_BREAKPOINT */
94101
static inline void hw_breakpoint_disable(void) { }
95102
static inline void thread_change_pc(struct task_struct *tsk,
96103
struct pt_regs *regs) { }
104+
static inline bool dawr_enabled(void) { return false; }
97105
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
98106
#endif /* __KERNEL__ */
99107
#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */

arch/powerpc/include/asm/opal-api.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@
186186
#define OPAL_XIVE_FREE_IRQ 140
187187
#define OPAL_XIVE_SYNC 141
188188
#define OPAL_XIVE_DUMP 142
189-
#define OPAL_XIVE_RESERVED3 143
190-
#define OPAL_XIVE_RESERVED4 144
189+
#define OPAL_XIVE_GET_QUEUE_STATE 143
190+
#define OPAL_XIVE_SET_QUEUE_STATE 144
191191
#define OPAL_SIGNAL_SYSTEM_RESET 145
192192
#define OPAL_NPU_INIT_CONTEXT 146
193193
#define OPAL_NPU_DESTROY_CONTEXT 147
@@ -210,7 +210,8 @@
210210
#define OPAL_PCI_GET_PBCQ_TUNNEL_BAR 164
211211
#define OPAL_PCI_SET_PBCQ_TUNNEL_BAR 165
212212
#define OPAL_NX_COPROC_INIT 167
213-
#define OPAL_LAST 167
213+
#define OPAL_XIVE_GET_VP_STATE 170
214+
#define OPAL_LAST 170
214215

215216
#define QUIESCE_HOLD 1 /* Spin all calls at entry */
216217
#define QUIESCE_REJECT 2 /* Fail all calls with OPAL_BUSY */

arch/powerpc/include/asm/opal.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,13 @@ int64_t opal_xive_allocate_irq(uint32_t chip_id);
279279
int64_t opal_xive_free_irq(uint32_t girq);
280280
int64_t opal_xive_sync(uint32_t type, uint32_t id);
281281
int64_t opal_xive_dump(uint32_t type, uint32_t id);
282+
int64_t opal_xive_get_queue_state(uint64_t vp, uint32_t prio,
283+
__be32 *out_qtoggle,
284+
__be32 *out_qindex);
285+
int64_t opal_xive_set_queue_state(uint64_t vp, uint32_t prio,
286+
uint32_t qtoggle,
287+
uint32_t qindex);
288+
int64_t opal_xive_get_vp_state(uint64_t vp, __be64 *out_w01);
282289
int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target,
283290
uint64_t desc, uint16_t pe_number);
284291

arch/powerpc/include/asm/xive.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,26 @@ extern int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio,
109109
extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
110110

111111
extern void xive_native_sync_source(u32 hw_irq);
112+
extern void xive_native_sync_queue(u32 hw_irq);
112113
extern bool is_xive_irq(struct irq_chip *chip);
113114
extern int xive_native_enable_vp(u32 vp_id, bool single_escalation);
114115
extern int xive_native_disable_vp(u32 vp_id);
115116
extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id);
116117
extern bool xive_native_has_single_escalation(void);
117118

119+
extern int xive_native_get_queue_info(u32 vp_id, uint32_t prio,
120+
u64 *out_qpage,
121+
u64 *out_qsize,
122+
u64 *out_qeoi_page,
123+
u32 *out_escalate_irq,
124+
u64 *out_qflags);
125+
126+
extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle,
127+
u32 *qindex);
128+
extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle,
129+
u32 qindex);
130+
extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state);
131+
118132
#else
119133

120134
static inline bool xive_enabled(void) { return false; }

arch/powerpc/kernel/hw_breakpoint.c

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@
2929
#include <linux/kernel.h>
3030
#include <linux/sched.h>
3131
#include <linux/smp.h>
32+
#include <linux/debugfs.h>
33+
#include <linux/init.h>
3234

3335
#include <asm/hw_breakpoint.h>
3436
#include <asm/processor.h>
3537
#include <asm/sstep.h>
3638
#include <asm/debug.h>
39+
#include <asm/debugfs.h>
40+
#include <asm/hvcall.h>
3741
#include <linux/uaccess.h>
3842

3943
/*
@@ -174,7 +178,7 @@ int hw_breakpoint_arch_parse(struct perf_event *bp,
174178
if (!ppc_breakpoint_available())
175179
return -ENODEV;
176180
length_max = 8; /* DABR */
177-
if (cpu_has_feature(CPU_FTR_DAWR)) {
181+
if (dawr_enabled()) {
178182
length_max = 512 ; /* 64 doublewords */
179183
/* DAWR region can't cross 512 boundary */
180184
if ((attr->bp_addr >> 9) !=
@@ -376,3 +380,59 @@ void hw_breakpoint_pmu_read(struct perf_event *bp)
376380
{
377381
/* TODO */
378382
}
383+
384+
bool dawr_force_enable;
385+
EXPORT_SYMBOL_GPL(dawr_force_enable);
386+
387+
static ssize_t dawr_write_file_bool(struct file *file,
388+
const char __user *user_buf,
389+
size_t count, loff_t *ppos)
390+
{
391+
struct arch_hw_breakpoint null_brk = {0, 0, 0};
392+
size_t rc;
393+
394+
/* Send error to user if they hypervisor won't allow us to write DAWR */
395+
if ((!dawr_force_enable) &&
396+
(firmware_has_feature(FW_FEATURE_LPAR)) &&
397+
(set_dawr(&null_brk) != H_SUCCESS))
398+
return -1;
399+
400+
rc = debugfs_write_file_bool(file, user_buf, count, ppos);
401+
if (rc)
402+
return rc;
403+
404+
/* If we are clearing, make sure all CPUs have the DAWR cleared */
405+
if (!dawr_force_enable)
406+
smp_call_function((smp_call_func_t)set_dawr, &null_brk, 0);
407+
408+
return rc;
409+
}
410+
411+
static const struct file_operations dawr_enable_fops = {
412+
.read = debugfs_read_file_bool,
413+
.write = dawr_write_file_bool,
414+
.open = simple_open,
415+
.llseek = default_llseek,
416+
};
417+
418+
static int __init dawr_force_setup(void)
419+
{
420+
dawr_force_enable = false;
421+
422+
if (cpu_has_feature(CPU_FTR_DAWR)) {
423+
/* Don't setup sysfs file for user control on P8 */
424+
dawr_force_enable = true;
425+
return 0;
426+
}
427+
428+
if (PVR_VER(mfspr(SPRN_PVR)) == PVR_POWER9) {
429+
/* Turn DAWR off by default, but allow admin to turn it on */
430+
dawr_force_enable = false;
431+
debugfs_create_file_unsafe("dawr_enable_dangerous", 0600,
432+
powerpc_debugfs_root,
433+
&dawr_force_enable,
434+
&dawr_enable_fops);
435+
}
436+
return 0;
437+
}
438+
arch_initcall(dawr_force_setup);

arch/powerpc/kernel/process.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include <asm/cpu_has_feature.h>
6868
#include <asm/asm-prototypes.h>
6969
#include <asm/stacktrace.h>
70+
#include <asm/hw_breakpoint.h>
7071

7172
#include <linux/kprobes.h>
7273
#include <linux/kdebug.h>
@@ -784,7 +785,7 @@ static inline int set_dabr(struct arch_hw_breakpoint *brk)
784785
return __set_dabr(dabr, dabrx);
785786
}
786787

787-
static inline int set_dawr(struct arch_hw_breakpoint *brk)
788+
int set_dawr(struct arch_hw_breakpoint *brk)
788789
{
789790
unsigned long dawr, dawrx, mrd;
790791

@@ -816,7 +817,7 @@ void __set_breakpoint(struct arch_hw_breakpoint *brk)
816817
{
817818
memcpy(this_cpu_ptr(&current_brk), brk, sizeof(*brk));
818819

819-
if (cpu_has_feature(CPU_FTR_DAWR))
820+
if (dawr_enabled())
820821
// Power8 or later
821822
set_dawr(brk);
822823
else if (!cpu_has_feature(CPU_FTR_ARCH_207S))
@@ -830,8 +831,8 @@ void __set_breakpoint(struct arch_hw_breakpoint *brk)
830831
/* Check if we have DAWR or DABR hardware */
831832
bool ppc_breakpoint_available(void)
832833
{
833-
if (cpu_has_feature(CPU_FTR_DAWR))
834-
return true; /* POWER8 DAWR */
834+
if (dawr_enabled())
835+
return true; /* POWER8 DAWR or POWER9 forced DAWR */
835836
if (cpu_has_feature(CPU_FTR_ARCH_207S))
836837
return false; /* POWER9 with DAWR disabled */
837838
/* DABR: Everything but POWER8 and POWER9 */

arch/powerpc/kernel/ptrace.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <asm/tm.h>
4444
#include <asm/asm-prototypes.h>
4545
#include <asm/debug.h>
46+
#include <asm/hw_breakpoint.h>
4647

4748
#define CREATE_TRACE_POINTS
4849
#include <trace/events/syscalls.h>
@@ -3088,7 +3089,7 @@ long arch_ptrace(struct task_struct *child, long request,
30883089
dbginfo.sizeof_condition = 0;
30893090
#ifdef CONFIG_HAVE_HW_BREAKPOINT
30903091
dbginfo.features = PPC_DEBUG_FEATURE_DATA_BP_RANGE;
3091-
if (cpu_has_feature(CPU_FTR_DAWR))
3092+
if (dawr_enabled())
30923093
dbginfo.features |= PPC_DEBUG_FEATURE_DATA_BP_DAWR;
30933094
#else
30943095
dbginfo.features = 0;

arch/powerpc/kvm/book3s_hv.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
#include <asm/opal.h>
7575
#include <asm/xics.h>
7676
#include <asm/xive.h>
77+
#include <asm/hw_breakpoint.h>
7778

7879
#include "book3s.h"
7980

@@ -3410,7 +3411,7 @@ static int kvmhv_load_hv_regs_and_go(struct kvm_vcpu *vcpu, u64 time_limit,
34103411
mtspr(SPRN_PURR, vcpu->arch.purr);
34113412
mtspr(SPRN_SPURR, vcpu->arch.spurr);
34123413

3413-
if (cpu_has_feature(CPU_FTR_DAWR)) {
3414+
if (dawr_enabled()) {
34143415
mtspr(SPRN_DAWR, vcpu->arch.dawr);
34153416
mtspr(SPRN_DAWRX, vcpu->arch.dawrx);
34163417
}

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -794,18 +794,21 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
794794
mtspr SPRN_IAMR, r5
795795
mtspr SPRN_PSPB, r6
796796
mtspr SPRN_FSCR, r7
797-
ld r5, VCPU_DAWR(r4)
798-
ld r6, VCPU_DAWRX(r4)
799-
ld r7, VCPU_CIABR(r4)
800-
ld r8, VCPU_TAR(r4)
801797
/*
802798
* Handle broken DAWR case by not writing it. This means we
803799
* can still store the DAWR register for migration.
804800
*/
805-
BEGIN_FTR_SECTION
801+
LOAD_REG_ADDR(r5, dawr_force_enable)
802+
lbz r5, 0(r5)
803+
cmpdi r5, 0
804+
beq 1f
805+
ld r5, VCPU_DAWR(r4)
806+
ld r6, VCPU_DAWRX(r4)
806807
mtspr SPRN_DAWR, r5
807808
mtspr SPRN_DAWRX, r6
808-
END_FTR_SECTION_IFSET(CPU_FTR_DAWR)
809+
1:
810+
ld r7, VCPU_CIABR(r4)
811+
ld r8, VCPU_TAR(r4)
809812
mtspr SPRN_CIABR, r7
810813
mtspr SPRN_TAR, r8
811814
ld r5, VCPU_IC(r4)
@@ -2499,11 +2502,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
24992502
blr
25002503

25012504
2:
2502-
BEGIN_FTR_SECTION
2503-
/* POWER9 with disabled DAWR */
2505+
LOAD_REG_ADDR(r11, dawr_force_enable)
2506+
lbz r11, 0(r11)
2507+
cmpdi r11, 0
25042508
li r3, H_HARDWARE
2505-
blr
2506-
END_FTR_SECTION_IFCLR(CPU_FTR_DAWR)
2509+
beqlr
25072510
/* Emulate H_SET_DABR/X on P8 for the sake of compat mode guests */
25082511
rlwimi r5, r4, 5, DAWRX_DR | DAWRX_DW
25092512
rlwimi r5, r4, 2, DAWRX_WT

arch/powerpc/platforms/powernv/opal-call.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ OPAL_CALL(opal_xive_get_vp_info, OPAL_XIVE_GET_VP_INFO);
260260
OPAL_CALL(opal_xive_set_vp_info, OPAL_XIVE_SET_VP_INFO);
261261
OPAL_CALL(opal_xive_sync, OPAL_XIVE_SYNC);
262262
OPAL_CALL(opal_xive_dump, OPAL_XIVE_DUMP);
263+
OPAL_CALL(opal_xive_get_queue_state, OPAL_XIVE_GET_QUEUE_STATE);
264+
OPAL_CALL(opal_xive_set_queue_state, OPAL_XIVE_SET_QUEUE_STATE);
265+
OPAL_CALL(opal_xive_get_vp_state, OPAL_XIVE_GET_VP_STATE);
263266
OPAL_CALL(opal_signal_system_reset, OPAL_SIGNAL_SYSTEM_RESET);
264267
OPAL_CALL(opal_npu_init_context, OPAL_NPU_INIT_CONTEXT);
265268
OPAL_CALL(opal_npu_destroy_context, OPAL_NPU_DESTROY_CONTEXT);

0 commit comments

Comments
 (0)