diff --git a/private/file_contexts b/private/file_contexts
index 0ce3dbce8944ff1747ac01178d913caad759ee4b..33b201e1dd33ded5f0eaf42586e138d4716e4783 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -75,6 +75,7 @@
 /dev/cpuctl(/.*)?	u:object_r:cpuctl_device:s0
 /dev/device-mapper	u:object_r:dm_device:s0
 /dev/eac		u:object_r:audio_device:s0
+/dev/event-log-tags     u:object_r:runtime_event_log_tags_file:s0
 /dev/fscklogs(/.*)?	u:object_r:fscklogs:s0
 /dev/full		u:object_r:full_device:s0
 /dev/fuse		u:object_r:fuse_device:s0
diff --git a/private/logd.te b/private/logd.te
index 73a3febb4387bd7045a9d6027bd8b85f6f3c26c5..35117d043d09ce6d2ca739a556dc88a1d88eb4bb 100644
--- a/private/logd.te
+++ b/private/logd.te
@@ -5,4 +5,34 @@ init_daemon_domain(logd)
 # logd is not allowed to write anywhere other than /data/misc/logd, and then
 # only on userdebug or eng builds
 # TODO: deal with tmpfs_domain pub/priv split properly
-neverallow logd { file_type -logd_tmpfs userdebug_or_eng(`-coredump_file') }:file { create write append };
+neverallow logd {
+  file_type
+  -logd_tmpfs
+  -runtime_event_log_tags_file
+  userdebug_or_eng(`-coredump_file')
+}:file { create write append };
+
+# protect the event-log-tags file
+neverallow {
+  domain
+  -appdomain # covered below
+  -bootstat
+  -dumpstate
+  -logd
+  userdebug_or_eng(`-logpersist')
+  -servicemanager
+  -system_server
+  -surfaceflinger
+  -zygote
+} runtime_event_log_tags_file:file no_rw_file_perms;
+
+neverallow {
+  appdomain
+  -bluetooth
+  -platform_app
+  -priv_app
+  -radio
+  -shell
+  userdebug_or_eng(`-su')
+  -system_app
+} runtime_event_log_tags_file:file no_rw_file_perms;
diff --git a/private/logpersist.te b/private/logpersist.te
index 88733de12758c6fc39d8fc4fe5eef88bc69636e5..5f4da0e4221c41ce587a3e3cf42b688e0c6327b7 100644
--- a/private/logpersist.te
+++ b/private/logpersist.te
@@ -12,6 +12,7 @@ userdebug_or_eng(`
 
   control_logd(logpersist)
   unix_socket_connect(logpersist, logdr, logd)
+  read_runtime_log_tags(logpersist)
 
 ')
 
diff --git a/private/platform_app.te b/private/platform_app.te
index 8d03251b405ceb34fc68973eee456f96f7ca7249..674784846eaaec4e891cdc3e1b06d1d2a63e63bc 100644
--- a/private/platform_app.te
+++ b/private/platform_app.te
@@ -59,3 +59,5 @@ allow platform_app preloads_data_file:dir r_dir_perms;
 # Access to ephemeral APKs
 allow platform_app ephemeral_apk_data_file:dir r_dir_perms;
 allow platform_app ephemeral_apk_data_file:file r_file_perms;
+
+read_runtime_log_tags(platform_app)
diff --git a/private/priv_app.te b/private/priv_app.te
index 568afe6a0a7c03b07c933df001132c347fd9dd3d..dd4ac2ced1208d094d2c87d71efacf1ed6bd8bfb 100644
--- a/private/priv_app.te
+++ b/private/priv_app.te
@@ -110,6 +110,8 @@ allow priv_app functionfs:file rw_file_perms;
 # TODO: narrow this to just MediaProvider
 allow priv_app mnt_media_rw_file:dir search;
 
+read_runtime_log_tags(priv_app)
+
 ###
 ### neverallow rules
 ###
diff --git a/private/radio.te b/private/radio.te
index 76dbf1cdbbd555532d90100868a14cbac792f69e..95e7f0a47fac0ae379921dfb66e428b2774f16b9 100644
--- a/private/radio.te
+++ b/private/radio.te
@@ -1 +1,3 @@
 app_domain(radio)
+
+read_runtime_log_tags(radio)
diff --git a/private/servicemanager.te b/private/servicemanager.te
index 1514b0f3773e8646b6a3957475f441a4f346efa1..6f382a7c326e0800dbfedcdc8370277ab97b970a 100644
--- a/private/servicemanager.te
+++ b/private/servicemanager.te
@@ -1,3 +1,5 @@
 # type_transition must be private policy the domain_trans rules could stay
 # public, but conceptually should go with this
 init_daemon_domain(servicemanager)
+
+read_runtime_log_tags(servicemanager)
diff --git a/private/system_app.te b/private/system_app.te
index c53f7a81d0cc002b5c473e07c27f8c494f96d33e..66c1e4dd1f3cc71134f47cbcc42903af9872994a 100644
--- a/private/system_app.te
+++ b/private/system_app.te
@@ -79,3 +79,4 @@ allow system_app keystore:keystore_key {
 r_dir_file(system_app, sysfs_type)
 
 control_logd(system_app)
+read_runtime_log_tags(system_app)
diff --git a/private/zygote.te b/private/zygote.te
index 5d55b1e44e99471d7669a92ca2be6ec9f1428763..f9213cedf81f3d70ffd4ef734370f13c8e70cb33 100644
--- a/private/zygote.te
+++ b/private/zygote.te
@@ -4,6 +4,8 @@ typeattribute zygote mlstrustedsubject;
 
 init_daemon_domain(zygote)
 
+read_runtime_log_tags(zygote)
+
 # Override DAC on files and switch uid/gid.
 allow zygote self:capability { dac_override setgid setuid fowner chown };
 
diff --git a/public/bluetooth.te b/public/bluetooth.te
index 209a68b69e3dab56954758d50a354ad7165f1009..eda60de89e9e21366c102ccd46abb403abe5174b 100644
--- a/public/bluetooth.te
+++ b/public/bluetooth.te
@@ -63,6 +63,8 @@ hwbinder_use(bluetooth)
 binder_call(bluetooth, hal_bluetooth)
 binder_call(bluetooth, hal_telephony)
 
+read_runtime_log_tags(bluetooth)
+
 ###
 ### Neverallow rules
 ###
diff --git a/public/bootstat.te b/public/bootstat.te
index 7fc589235fd8489bb857dad352b1f4aa3d2c892d..f5c7268e0be590f2a1dd1920baf50bc8d2833724 100644
--- a/public/bootstat.te
+++ b/public/bootstat.te
@@ -2,6 +2,8 @@
 type bootstat, domain;
 type bootstat_exec, exec_type, file_type;
 
+read_runtime_log_tags(bootstat)
+
 # Allow persistent storage in /data/misc/bootstat.
 allow bootstat bootstat_data_file:dir rw_dir_perms;
 allow bootstat bootstat_data_file:file create_file_perms;
diff --git a/public/dumpstate.te b/public/dumpstate.te
index 4882b98144bdb1e530904c7d53f326bc34882703..a70614dab691d122754335a4ba8a2d4dd668963e 100644
--- a/public/dumpstate.te
+++ b/public/dumpstate.te
@@ -130,6 +130,7 @@ allow dumpstate gpu_device:chr_file rw_file_perms;
 # logd access
 read_logd(dumpstate)
 control_logd(dumpstate)
+read_runtime_log_tags(dumpstate)
 
 # Read /proc/net
 allow dumpstate proc_net:file r_file_perms;
diff --git a/public/file.te b/public/file.te
index 527e496bf97b279d874dae453f5e4a08dc3c8ead..7bf44ccb49c89c6ff65d95a7cd2428d1200e2ba0 100644
--- a/public/file.te
+++ b/public/file.te
@@ -76,6 +76,8 @@ type app_fusefs, fs_type, contextmount_type;
 type unlabeled, file_type;
 # Default type for anything under /system.
 type system_file, file_type;
+# Speedup access for trusted applications to the runtime event tags
+type runtime_event_log_tags_file, file_type;
 # Type for /system/*/libart*
 type libart_file, file_type;
 # Type for /system/bin/logcat.
diff --git a/public/init.te b/public/init.te
index 1d984c2505442f4059a3978c0e2eab73a7406288..4b29891a763d0d1dbcde0f23fcfd0240a3b52603 100644
--- a/public/init.te
+++ b/public/init.te
@@ -138,6 +138,7 @@ allow init {
 allow init {
   file_type
   -app_data_file
+  -runtime_event_log_tags_file
   -exec_type
   -keystore_data_file
   -misc_logd_file
diff --git a/public/logd.te b/public/logd.te
index b7fc11ac1941fb0e335b46479151fee023d07257..5defed5ab39a1ecf3d8b272dafca6ef84fc23eb9 100644
--- a/public/logd.te
+++ b/public/logd.te
@@ -23,6 +23,15 @@ r_dir_file(logd, domain)
 allow logd kernel:system syslog_mod;
 
 control_logd(logd)
+read_runtime_log_tags(logd)
+
+allow runtime_event_log_tags_file tmpfs:filesystem associate;
+# Typically harmlessly blindly trying to access via liblog
+# event tag mapping while in the untrusted_app domain.
+# Access for that domain is controlled and gated via the
+# event log tag service (albeit at a performance penalty,
+# expected to be locally cached).
+dontaudit domain runtime_event_log_tags_file:file { open read };
 
 ###
 ### Neverallow rules
@@ -47,3 +56,6 @@ neverallow logd { app_data_file system_data_file }:dir_file_class_set write;
 # Only init is allowed to enter the logd domain via exec()
 neverallow { domain -init } logd:process transition;
 neverallow * logd:process dyntransition;
+
+# protect the event-log-tags file
+neverallow * runtime_event_log_tags_file:file no_w_file_perms;
diff --git a/public/surfaceflinger.te b/public/surfaceflinger.te
index 68e86b1070a98992a349be84c3e03ba3eacd8ec3..d09a350f7a4201128c03730f9e3b80125ff9501e 100644
--- a/public/surfaceflinger.te
+++ b/public/surfaceflinger.te
@@ -4,6 +4,8 @@ type surfaceflinger_exec, exec_type, file_type;
 
 typeattribute surfaceflinger mlstrustedsubject;
 
+read_runtime_log_tags(surfaceflinger)
+
 # Perform HwBinder IPC.
 hwbinder_use(surfaceflinger)
 binder_call(surfaceflinger, hal_graphics_allocator)
diff --git a/public/system_server.te b/public/system_server.te
index aef97b54eb154d29c3794660f597afd67e1ac53a..24262832a7255b46bc3352f68319366c5d77013c 100644
--- a/public/system_server.te
+++ b/public/system_server.te
@@ -464,6 +464,7 @@ allow system_server zygote:unix_dgram_socket write;
 
 # Read from log daemon.
 read_logd(system_server)
+read_runtime_log_tags(system_server)
 
 # Be consistent with DAC permissions. Allow system_server to write to
 # /sys/module/lowmemorykiller/parameters/adj
diff --git a/public/te_macros b/public/te_macros
index 0a423acf0b8538ba1fa1687912b5284eb09543b7..c9ab6e0cced0700036a975a899fa46757dbc7e93 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -344,6 +344,13 @@ allow $1 logcat_exec:file rx_file_perms;
 unix_socket_connect($1, logdr, logd)
 ')
 
+#####################################
+# read_runtime_log_tags(domain)
+# ability to directly map the runtime event log tags
+define(`read_runtime_log_tags', `
+allow $1 runtime_event_log_tags_file:file r_file_perms;
+')
+
 #####################################
 # control_logd(domain)
 # Ability to control