diff options
author | Ganapatrao Kulkarni <ganapatrao.kulkarni@cavium.com> | 2017-05-02 12:29:34 -0400 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2017-05-15 13:30:37 -0400 |
commit | 78a19cfdf37d19002c83c8790853c1cc10feccdc (patch) | |
tree | 6e38f50adf729eac3552bba63eae030b0b07cb97 | |
parent | 8df728e1ae614f592961e51f65d3e3212ede5a75 (diff) |
arm64: perf: Ignore exclude_hv when kernel is running in HYP
commit d98ecdaca296 ("arm64: perf: Count EL2 events if the kernel is
running in HYP") returns -EINVAL when perf system call perf_event_open is
called with exclude_hv != exclude_kernel. This change breaks applications
on VHE enabled ARMv8.1 platforms. The issue was observed with HHVM
application, which calls perf_event_open with exclude_hv = 1 and
exclude_kernel = 0.
There is no separate hypervisor privilege level when VHE is enabled, the
host kernel runs at EL2. So when VHE is enabled, we should ignore
exclude_hv from the application. This behaviour is consistent with PowerPC
where the exclude_hv is ignored when the hypervisor is not present and with
x86 where this flag is ignored.
Signed-off-by: Ganapatrao Kulkarni <ganapatrao.kulkarni@cavium.com>
[will: added comment to justify the behaviour of exclude_hv]
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r-- | arch/arm64/kernel/perf_event.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index bcc79471b38e..83a1b1ad189f 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c | |||
@@ -877,15 +877,24 @@ static int armv8pmu_set_event_filter(struct hw_perf_event *event, | |||
877 | 877 | ||
878 | if (attr->exclude_idle) | 878 | if (attr->exclude_idle) |
879 | return -EPERM; | 879 | return -EPERM; |
880 | if (is_kernel_in_hyp_mode() && | 880 | |
881 | attr->exclude_kernel != attr->exclude_hv) | 881 | /* |
882 | return -EINVAL; | 882 | * If we're running in hyp mode, then we *are* the hypervisor. |
883 | * Therefore we ignore exclude_hv in this configuration, since | ||
884 | * there's no hypervisor to sample anyway. This is consistent | ||
885 | * with other architectures (x86 and Power). | ||
886 | */ | ||
887 | if (is_kernel_in_hyp_mode()) { | ||
888 | if (!attr->exclude_kernel) | ||
889 | config_base |= ARMV8_PMU_INCLUDE_EL2; | ||
890 | } else { | ||
891 | if (attr->exclude_kernel) | ||
892 | config_base |= ARMV8_PMU_EXCLUDE_EL1; | ||
893 | if (!attr->exclude_hv) | ||
894 | config_base |= ARMV8_PMU_INCLUDE_EL2; | ||
895 | } | ||
883 | if (attr->exclude_user) | 896 | if (attr->exclude_user) |
884 | config_base |= ARMV8_PMU_EXCLUDE_EL0; | 897 | config_base |= ARMV8_PMU_EXCLUDE_EL0; |
885 | if (!is_kernel_in_hyp_mode() && attr->exclude_kernel) | ||
886 | config_base |= ARMV8_PMU_EXCLUDE_EL1; | ||
887 | if (!attr->exclude_hv) | ||
888 | config_base |= ARMV8_PMU_INCLUDE_EL2; | ||
889 | 898 | ||
890 | /* | 899 | /* |
891 | * Install the filter into config_base as this is used to | 900 | * Install the filter into config_base as this is used to |