diff --git a/private/atrace.te b/private/atrace.te
index 3d7902fe982ad866862344bb71603242ddf27553..630935da02fc62a006e66749c3c278c2f03cce1f 100644
--- a/private/atrace.te
+++ b/private/atrace.te
@@ -1,28 +1,46 @@
-# Domain for atrace process spawned by boottrace service.
+# Domain for atrace process.
+# It is spawned either by traced_probes or by init for the boottrace service.
 
+type atrace, domain, coredomain;
 type atrace_exec, exec_type, file_type;
 
-userdebug_or_eng(`
-  type atrace, domain, coredomain;
+# boottrace services uses /data/misc/boottrace/categories
+allow atrace boottrace_data_file:dir search;
+allow atrace boottrace_data_file:file r_file_perms;
 
-  init_daemon_domain(atrace)
+# Allow atrace to access tracefs.
+allow atrace debugfs_tracing:dir r_dir_perms;
+allow atrace debugfs_tracing:file rw_file_perms;
+allow atrace debugfs_trace_marker:file getattr;
 
-  # boottrace services uses /data/misc/boottrace/categories
-  allow atrace boottrace_data_file:dir search;
-  allow atrace boottrace_data_file:file r_file_perms;
+# atrace sets debug.atrace.* properties
+set_prop(atrace, debug_prop)
 
-  # Allow atrace to access tracefs.
-  allow atrace debugfs_tracing:dir r_dir_perms;
-  allow atrace debugfs_tracing:file rw_file_perms;
-  allow atrace debugfs_tracing_debug:dir r_dir_perms;
-  allow atrace debugfs_tracing_debug:file rw_file_perms;
-  allow atrace debugfs_trace_marker:file getattr;
+# atrace pokes all the binder-enabled processes at startup with a
+# SYSPROPS_TRANSACTION, to tell them to reload the debug.atrace.* properties.
+
+binder_use(atrace)
+allow atrace healthd:binder call;
+allow atrace surfaceflinger:binder call;
+get_prop(atrace, hwservicemanager_prop)
 
-  # atrace sets debug.atrace.* properties
-  set_prop(atrace, debug_prop)
+allow atrace {
+  service_manager_type
+  -incident_service
+  -netd_service
+  -stats_service
+  -dumpstate_service
+  -installd_service
+  -vold_service
+}:service_manager { find };
+allow atrace servicemanager:service_manager list;
 
-  # atrace pokes all the binder-enabled processes at startup.
-  binder_use(atrace)
-  allow atrace healthd:binder call;
-  allow atrace surfaceflinger:binder call;
+userdebug_or_eng(`
+  # atrace is generally invoked as a standalone binary from shell or perf
+  # daemons like Perfetto traced_probes. However, in userdebug builds, there is
+  # a further option to run atrace as an init daemon for boot tracing.
+  init_daemon_domain(atrace)
+
+  allow atrace debugfs_tracing_debug:dir r_dir_perms;
+  allow atrace debugfs_tracing_debug:file rw_file_perms;
 ')
diff --git a/private/domain.te b/private/domain.te
index 614e4c71f26b50ca7270b0119ca945039da7cd0b..093e3026fadb94191ac7db3ea9dcc9161318fd3b 100644
--- a/private/domain.te
+++ b/private/domain.te
@@ -61,7 +61,7 @@ full_treble_only(`
   # tracefs
   neverallow {
     coredomain
-    userdebug_or_eng(`-atrace')
+    -atrace
     -dumpstate
     -init
     userdebug_or_eng(`-perfprofd')
diff --git a/private/traced_probes.te b/private/traced_probes.te
index 22746e76bb93dcbbade870f68b3404071a236e89..46d92f7139019a251b81cf27a7700ef9679b58ca 100644
--- a/private/traced_probes.te
+++ b/private/traced_probes.te
@@ -35,6 +35,14 @@ allow traced_probes kmsg_device:chr_file write;
 # Allow traced_probes to list the system partition.
 allow traced_probes system_file:dir { open read };
 
+# Allow traced_probes to run atrace. atrace pokes at system services to enable
+# their userspace TRACE macros.
+domain_auto_trans(traced_probes, atrace_exec, atrace);
+
+# This is needed for: path="/system/bin/linker64"
+# scontext=u:r:atrace:s0 tcontext=u:r:traced_probes:s0 tclass=fd
+allow atrace traced_probes:fd use;
+
 ###
 ### Neverallow rules
 ###