Commit-ID: 26c6ccdf5c06aa83bb78518c72cb287f043db3df Gitweb: https://git.kernel.org/tip/26c6ccdf5c06aa83bb78518c72cb287f043db3df Author: Frederic Weisbecker <frede...@kernel.org> AuthorDate: Tue, 26 Jun 2018 04:58:59 +0200 Committer: Ingo Molnar <mi...@kernel.org> CommitDate: Tue, 26 Jun 2018 09:07:59 +0200
perf/hw_breakpoint: Clean up and consolidate modify_user_hw_breakpoint_check() Remove the dance around old and new attributes. Just don't modify the previous breakpoint at all until we have verified everything. Original-patch-by: Andy Lutomirski <l...@kernel.org> Reported-by: Linus Torvalds <torva...@linux-foundation.org> Signed-off-by: Frederic Weisbecker <frede...@kernel.org> Cc: Alexander Shishkin <alexander.shish...@linux.intel.com> Cc: Andy Lutomirski <l...@kernel.org> Cc: Arnaldo Carvalho de Melo <a...@kernel.org> Cc: Arnaldo Carvalho de Melo <a...@redhat.com> Cc: Benjamin Herrenschmidt <b...@kernel.crashing.org> Cc: Catalin Marinas <catalin.mari...@arm.com> Cc: Chris Zankel <ch...@zankel.net> Cc: Jiri Olsa <jo...@redhat.com> Cc: Joel Fernandes <joel.open...@gmail.com> Cc: Mark Rutland <mark.rutl...@arm.com> Cc: Max Filippov <jcmvb...@gmail.com> Cc: Michael Ellerman <m...@ellerman.id.au> Cc: Namhyung Kim <namhy...@kernel.org> Cc: Paul Mackerras <pau...@samba.org> Cc: Peter Zijlstra <pet...@infradead.org> Cc: Rich Felker <dal...@libc.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Will Deacon <will.dea...@arm.com> Cc: Yoshinori Sato <ys...@users.sourceforge.jp> Link: http://lkml.kernel.org/r/1529981939-8231-13-git-send-email-frede...@kernel.org Signed-off-by: Ingo Molnar <mi...@kernel.org> --- kernel/events/hw_breakpoint.c | 44 ++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index 71387703b5f1..b3814fce5ecb 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -461,37 +461,43 @@ register_user_hw_breakpoint(struct perf_event_attr *attr, } EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); +static void hw_breakpoint_copy_attr(struct perf_event_attr *to, + struct perf_event_attr *from) +{ + to->bp_addr = from->bp_addr; + to->bp_type = from->bp_type; + to->bp_len = from->bp_len; + to->disabled = from->disabled; +} + int modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *attr, bool check) { - u64 old_addr = bp->attr.bp_addr; - u64 old_len = bp->attr.bp_len; - int old_type = bp->attr.bp_type; - bool modify = attr->bp_type != old_type; struct arch_hw_breakpoint hw; - int err = 0; + int err; - bp->attr.bp_addr = attr->bp_addr; - bp->attr.bp_type = attr->bp_type; - bp->attr.bp_len = attr->bp_len; + err = hw_breakpoint_parse(bp, attr, &hw); + if (err) + return err; - if (check && memcmp(&bp->attr, attr, sizeof(*attr))) - return -EINVAL; + if (check) { + struct perf_event_attr old_attr; - err = hw_breakpoint_parse(bp, attr, &hw); - if (!err && modify) - err = modify_bp_slot(bp, old_type, bp->attr.bp_type); + old_attr = bp->attr; + hw_breakpoint_copy_attr(&old_attr, attr); + if (memcmp(&old_attr, attr, sizeof(*attr))) + return -EINVAL; + } - if (err) { - bp->attr.bp_addr = old_addr; - bp->attr.bp_type = old_type; - bp->attr.bp_len = old_len; - return err; + if (bp->attr.bp_type != attr->bp_type) { + err = modify_bp_slot(bp, bp->attr.bp_type, attr->bp_type); + if (err) + return err; } + hw_breakpoint_copy_attr(&bp->attr, attr); bp->hw.info = hw; - bp->attr.disabled = attr->disabled; return 0; }