[PATCH V2 0/3] perf/x86/intel: Add Branch Monitoring support

From: Megha Dey
Date: Fri Nov 17 2017 - 20:38:58 EST

This patchset adds support for Intel's branch monitoring feature. This
feature uses heuristics to detect the occurrence of an ROP(Return Oriented
Programming) or ROP like(JOP: Jump oriented programming) attack. These
heuristics are based off certain performance monitoring statistics,
measured dynamically over a short configurable window period. ROP is a
malware trend in which the attacker can compromise a return pointer held
on the stack to redirect execution to a different desired instruction.

Currently, only the Cannonlake family of Intel processors support this
feature. This feature is enabled by CONFIG_PERF_EVENTS_INTEL_BM.

Once the kernel is compiled with CONFIG_PERF_EVENTS_INTEL_BM=y on a
Cannonlake system, the following perf events are added which can be viewed
with perf list:
intel_bm/branch-misp/ [Kernel PMU event]
intel_bm/call-ret/ [Kernel PMU event]
intel_bm/far-branch/ [Kernel PMU event]
intel_bm/indirect-branch-misp/ [Kernel PMU event]
intel_bm/ret-misp/ [Kernel PMU event]
intel_bm/rets/ [Kernel PMU event]

A perf-based kernel driver has been used to monitor the occurrence of
one of the 6 branch monitoring events. There are 2 counters that each
can select between one of these events for evaluation over a specified
instruction window size (0 to 1023). For each counter, a threshold value
(0 to 127) can be configured to set a point at which an interrupt is
generated. Each task can monitor a maximum of 2 events at any given time.

Apart from the kernel driver, this patchset adds CPUID of Cannonlake
processors to Intel family list and the Documentation/x86/intel_bm.txt
file with some information about Intel Branch monitoring.

Changes V0->V1:
1. Used the 'is_sampling_event' function
2. Added support to monitor 2 events for every task
3. Corrected typos
4. Added a lock to prevent race condition in concurrent perf_event_open()s
5. Got rid of start()/stop() and added its functionality in add()/del()
6. Removed read() callback as it was not doing anything.
6. Removed code for sampling events as we do not support sampling.
7. Added 'id' member to hw_perf_event::intel_bm to track which counter the
event is using.
8. Moved MSR accesses to the add()/del() callbacks

Changes V1->V2:
1. Edited commit message to make things less ambiguous
2. Corrected the Signed-off-by chain
3. Used a named construct for the counter enable bit
4. Added the corrected logic to unmask NMI bit of local APIC only for the
first time a task is scheduled on a CPU. Removed the separate function
5. Restructured code in the NMI handler to save convoluted indentation
6. Removed the redundant read of the status register in add()
7. Removed the update function as it did not do what it is supposed to do
Added this code to del() instead
8. Corrected the polarity of 'is_sampling_event' function when used
9. Removed the setting of event->count to 0 in event_init. This is
redundant as this is its default value
10. Do not allow threshold to be set as 0

Megha Dey (3):
x86/cpu/intel: Add Cannonlake to Intel family
perf/x86/intel/bm.c: Add Intel Branch Monitoring support
x86, bm: Add documentation on Intel Branch Monitoring

Documentation/x86/intel_bm.txt | 216 +++++++++++++
arch/x86/events/Kconfig | 10 +
arch/x86/events/intel/Makefile | 2 +
arch/x86/events/intel/bm.c | 605 ++++++++++++++++++++++++++++++++++++
arch/x86/include/asm/intel-family.h | 2 +
arch/x86/include/asm/msr-index.h | 5 +
arch/x86/include/asm/processor.h | 4 +
include/linux/perf_event.h | 9 +-
kernel/events/core.c | 16 +
9 files changed, 868 insertions(+), 1 deletion(-)
create mode 100644 Documentation/x86/intel_bm.txt
create mode 100644 arch/x86/events/intel/bm.c