1 | // Copyright (c) 2023 Apple Inc. All rights reserved. |
2 | // |
3 | // @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
4 | // |
5 | // This file contains Original Code and/or Modifications of Original Code |
6 | // as defined in and that are subject to the Apple Public Source License |
7 | // Version 2.0 (the 'License'). You may not use this file except in |
8 | // compliance with the License. The rights granted to you under the License |
9 | // may not be used to create, or enable the creation or redistribution of, |
10 | // unlawful or unlicensed copies of an Apple operating system, or to |
11 | // circumvent, violate, or enable the circumvention or violation of, any |
12 | // terms of an Apple operating system software license agreement. |
13 | // |
14 | // Please obtain a copy of the License at |
15 | // http://www.opensource.apple.com/apsl/ and read it before using this file. |
16 | // |
17 | // The Original Code and all software distributed under the License are |
18 | // distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
19 | // EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
20 | // INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
21 | // FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
22 | // Please see the License for the specific language governing rights and |
23 | // limitations under the License. |
24 | // |
25 | // @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
26 | |
27 | #include <kern/cpc.h> |
28 | #include <stdbool.h> |
29 | #include <kern/assert.h> |
30 | #include <kern/debug.h> |
31 | #include <os/atomic.h> |
32 | #include <os/atomic_private.h> |
33 | |
34 | #if __arm64__ |
35 | #include <arm64/cpc_arm64.h> |
36 | #endif // __arm64__ |
37 | |
38 | #pragma mark - Ownership |
39 | |
40 | #if CONFIG_CPU_COUNTERS |
41 | static const char * _Atomic _cpc_hw_owners[CPC_HW_COUNT] = { NULL }; |
42 | #endif // CONFIG_CPU_COUNTERS |
43 | |
44 | __result_use_check bool |
45 | cpc_hw_acquire(cpc_hw_t hw, const char *owner_name) |
46 | { |
47 | #if CONFIG_CPU_COUNTERS |
48 | assert3u(hw, <, CPC_HW_COUNT); |
49 | extern int kpc_get_force_all_ctrs(void); |
50 | if (hw == CPC_HW_CPMU && kpc_get_force_all_ctrs()) { |
51 | return false; |
52 | } |
53 | return os_atomic_cmpxchg(&_cpc_hw_owners[hw], NULL, owner_name, acq_rel); |
54 | #else // CONFIG_CPU_COUNTERS |
55 | #pragma unused(hw, owner_name) |
56 | return false; |
57 | #endif // !CONFIG_CPU_COUNTERS |
58 | } |
59 | |
60 | bool |
61 | cpc_hw_in_use(cpc_hw_t hw) |
62 | { |
63 | #if CONFIG_CPU_COUNTERS |
64 | assert3u(hw, <, CPC_HW_COUNT); |
65 | return os_atomic_load(&_cpc_hw_owners[hw], acquire) != NULL; |
66 | #else // CONFIG_CPU_COUNTERS |
67 | #pragma unused(hw) |
68 | return false; |
69 | #endif // !CONFIG_CPU_COUNTERS |
70 | } |
71 | |
72 | void |
73 | cpc_hw_release(cpc_hw_t hw, const char *owner_name) |
74 | { |
75 | #if CONFIG_CPU_COUNTERS |
76 | assert3u(hw, <, CPC_HW_COUNT); |
77 | if (!os_atomic_cmpxchg(&_cpc_hw_owners[hw], owner_name, NULL, acq_rel)) { |
78 | panic("CPC: unpaired HW release: %s on %u" , owner_name, hw); |
79 | } |
80 | #else // CONFIG_CPU_COUNTERS |
81 | #pragma unused(hw, owner_name) |
82 | #endif // !CONFIG_CPU_COUNTERS |
83 | } |
84 | |
85 | bool |
86 | cpc_is_secure(void) |
87 | { |
88 | #if CONFIG_CPU_COUNTERS |
89 | #if __arm64__ |
90 | cpc_event_policy_t policy = cpc_get_event_policy(); |
91 | return policy == CPC_EVPOL_RESTRICT_TO_KNOWN || policy == CPC_EVPOL_DENY_ALL; |
92 | #else // __arm64__ |
93 | return false; |
94 | #endif // !__arm64__ |
95 | #else // CONFIG_CPU_COUNTERS |
96 | return true; |
97 | #endif // !CONFIG_CPU_COUNTERS |
98 | } |
99 | |
100 | #if CPC_INSECURE |
101 | |
102 | void |
103 | cpc_change_security(bool enforce_security) |
104 | { |
105 | #if CONFIG_CPU_COUNTERS |
106 | #if __arm64__ |
107 | cpc_set_event_policy(enforce_security ? CPC_EVPOL_RESTRICT_TO_KNOWN : CPC_EVPOL_DEFAULT); |
108 | #else // __arm64__ |
109 | #pragma unused(enforce_security) |
110 | // Intel has no event policy or other security features. |
111 | #endif // !__arm64__ |
112 | #else // CONFIG_CPU_COUNTERS |
113 | #pragma unused(enforce_security) |
114 | #endif // !CONFIG_CPU_COUNTERS |
115 | } |
116 | |
117 | #endif // CPC_INSECURE |
118 | |