diff --git a/Documentation/ABI/testing/evm b/Documentation/ABI/testing/evm
index 9578247e17929bf4fcd6bd50b185f955031dc96d..d12cb2eae9ee658e552c81c9009e2759a9142d58 100644
--- a/Documentation/ABI/testing/evm
+++ b/Documentation/ABI/testing/evm
@@ -14,30 +14,46 @@ Description:
 		generated either locally or remotely using an
 		asymmetric key. These keys are loaded onto root's
 		keyring using keyctl, and EVM is then enabled by
-		echoing a value to <securityfs>/evm:
+		echoing a value to <securityfs>/evm made up of the
+		following bits:
 
-		1: enable HMAC validation and creation
-		2: enable digital signature validation
-		3: enable HMAC and digital signature validation and HMAC
-		   creation
+		Bit	  Effect
+		0	  Enable HMAC validation and creation
+		1	  Enable digital signature validation
+		2	  Permit modification of EVM-protected metadata at
+			  runtime. Not supported if HMAC validation and
+			  creation is enabled.
+		31	  Disable further runtime modification of EVM policy
 
-		Further writes will be blocked if HMAC support is enabled or
-		if bit 32 is set:
+		For example:
 
-		echo 0x80000002 ><securityfs>/evm
+		echo 1 ><securityfs>/evm
 
-		will enable digital signature validation and block
-		further writes to <securityfs>/evm.
+		will enable HMAC validation and creation
 
-		Until this is done, EVM can not create or validate the
-		'security.evm' xattr, but returns INTEGRITY_UNKNOWN.
-		Loading keys and signaling EVM should be done as early
-		as possible.  Normally this is done in the initramfs,
-		which has already been measured as part of the trusted
-		boot.  For more information on creating and loading
-		existing trusted/encrypted keys, refer to:
+		echo 0x80000003 ><securityfs>/evm
 
-		Documentation/security/keys/trusted-encrypted.rst. Both dracut
-		(via 97masterkey and 98integrity) and systemd (via
+		will enable HMAC and digital signature validation and
+		HMAC creation and disable all further modification of policy.
+
+		echo 0x80000006 ><securityfs>/evm
+
+		will enable digital signature validation, permit
+		modification of EVM-protected metadata and
+		disable all further modification of policy
+
+		Note that once a key has been loaded, it will no longer be
+		possible to enable metadata modification.
+
+		Until key loading has been signaled EVM can not create
+		or validate the 'security.evm' xattr, but returns
+		INTEGRITY_UNKNOWN.  Loading keys and signaling EVM
+		should be done as early as possible.  Normally this is
+		done in the initramfs, which has already been measured
+		as part of the trusted boot.  For more information on
+		creating and loading existing trusted/encrypted keys,
+		refer to:
+		Documentation/security/keys/trusted-encrypted.rst. Both
+		dracut (via 97masterkey and 98integrity) and systemd (via
 		core/ima-setup) have support for loading keys at boot
 		time.
diff --git a/security/integrity/evm/evm.h b/security/integrity/evm/evm.h
index 241aca315b0c351d6897e4e6d9ee2261cbbb3bcb..3d05250e831394a50242da89843e2db62aca8c6c 100644
--- a/security/integrity/evm/evm.h
+++ b/security/integrity/evm/evm.h
@@ -23,9 +23,12 @@
 
 #define EVM_INIT_HMAC	0x0001
 #define EVM_INIT_X509	0x0002
-#define EVM_SETUP       0x80000000 /* userland has signaled key load */
+#define EVM_ALLOW_METADATA_WRITES	0x0004
+#define EVM_SETUP_COMPLETE 0x80000000 /* userland has signaled key load */
 
-#define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP)
+#define EVM_KEY_MASK (EVM_INIT_HMAC | EVM_INIT_X509)
+#define EVM_INIT_MASK (EVM_INIT_HMAC | EVM_INIT_X509 | EVM_SETUP_COMPLETE | \
+		       EVM_ALLOW_METADATA_WRITES)
 
 extern int evm_initialized;
 extern char *evm_hmac;
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 9826c02e2db8f789eea2dc9d209db7e605839de0..ba89c246829837b00510d5244387db10d9172375 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -76,6 +76,11 @@ static void __init evm_init_config(void)
 	pr_info("HMAC attrs: 0x%x\n", evm_hmac_attrs);
 }
 
+static bool evm_key_loaded(void)
+{
+	return (bool)(evm_initialized & EVM_KEY_MASK);
+}
+
 static int evm_find_protected_xattrs(struct dentry *dentry)
 {
 	struct inode *inode = d_backing_inode(dentry);
@@ -241,7 +246,7 @@ enum integrity_status evm_verifyxattr(struct dentry *dentry,
 				      void *xattr_value, size_t xattr_value_len,
 				      struct integrity_iint_cache *iint)
 {
-	if (!evm_initialized || !evm_protected_xattr(xattr_name))
+	if (!evm_key_loaded() || !evm_protected_xattr(xattr_name))
 		return INTEGRITY_UNKNOWN;
 
 	if (!iint) {
@@ -265,7 +270,7 @@ static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
 {
 	struct inode *inode = d_backing_inode(dentry);
 
-	if (!evm_initialized || !S_ISREG(inode->i_mode) || evm_fixmode)
+	if (!evm_key_loaded() || !S_ISREG(inode->i_mode) || evm_fixmode)
 		return 0;
 	return evm_verify_hmac(dentry, NULL, NULL, 0, NULL);
 }
@@ -299,6 +304,7 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
 			return 0;
 		goto out;
 	}
+
 	evm_status = evm_verify_current_integrity(dentry);
 	if (evm_status == INTEGRITY_NOXATTRS) {
 		struct integrity_iint_cache *iint;
@@ -345,6 +351,12 @@ int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 {
 	const struct evm_ima_xattr_data *xattr_data = xattr_value;
 
+	/* Policy permits modification of the protected xattrs even though
+	 * there's no HMAC key loaded
+	 */
+	if (evm_initialized & EVM_ALLOW_METADATA_WRITES)
+		return 0;
+
 	if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
 		if (!xattr_value_len)
 			return -EINVAL;
@@ -365,6 +377,12 @@ int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
  */
 int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name)
 {
+	/* Policy permits modification of the protected xattrs even though
+	 * there's no HMAC key loaded
+	 */
+	if (evm_initialized & EVM_ALLOW_METADATA_WRITES)
+		return 0;
+
 	return evm_protect_xattr(dentry, xattr_name, NULL, 0);
 }
 
@@ -393,8 +411,8 @@ static void evm_reset_status(struct inode *inode)
 void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
 			     const void *xattr_value, size_t xattr_value_len)
 {
-	if (!evm_initialized || (!evm_protected_xattr(xattr_name)
-				 && !posix_xattr_acl(xattr_name)))
+	if (!evm_key_loaded() || (!evm_protected_xattr(xattr_name)
+				  && !posix_xattr_acl(xattr_name)))
 		return;
 
 	evm_reset_status(dentry->d_inode);
@@ -414,7 +432,7 @@ void evm_inode_post_setxattr(struct dentry *dentry, const char *xattr_name,
  */
 void evm_inode_post_removexattr(struct dentry *dentry, const char *xattr_name)
 {
-	if (!evm_initialized || !evm_protected_xattr(xattr_name))
+	if (!evm_key_loaded() || !evm_protected_xattr(xattr_name))
 		return;
 
 	evm_reset_status(dentry->d_inode);
@@ -431,6 +449,12 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
 	unsigned int ia_valid = attr->ia_valid;
 	enum integrity_status evm_status;
 
+	/* Policy permits modification of the protected attrs even though
+	 * there's no HMAC key loaded
+	 */
+	if (evm_initialized & EVM_ALLOW_METADATA_WRITES)
+		return 0;
+
 	if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
 		return 0;
 	evm_status = evm_verify_current_integrity(dentry);
@@ -456,7 +480,7 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
  */
 void evm_inode_post_setattr(struct dentry *dentry, int ia_valid)
 {
-	if (!evm_initialized)
+	if (!evm_key_loaded())
 		return;
 
 	if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
@@ -473,7 +497,7 @@ int evm_inode_init_security(struct inode *inode,
 	struct evm_ima_xattr_data *xattr_data;
 	int rc;
 
-	if (!evm_initialized || !evm_protected_xattr(lsm_xattr->name))
+	if (!evm_key_loaded() || !evm_protected_xattr(lsm_xattr->name))
 		return 0;
 
 	xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS);
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
index 319cf16d6603050f4ac6fef1f3e2aa31c7a941ce..feba03bbedae25f4a4e6b89cfda2990451c41391 100644
--- a/security/integrity/evm/evm_secfs.c
+++ b/security/integrity/evm/evm_secfs.c
@@ -40,7 +40,7 @@ static ssize_t evm_read_key(struct file *filp, char __user *buf,
 	if (*ppos != 0)
 		return 0;
 
-	sprintf(temp, "%d", (evm_initialized & ~EVM_SETUP));
+	sprintf(temp, "%d", (evm_initialized & ~EVM_SETUP_COMPLETE));
 	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));
 
 	return rc;
@@ -63,7 +63,7 @@ static ssize_t evm_write_key(struct file *file, const char __user *buf,
 {
 	int i, ret;
 
-	if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP))
+	if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP_COMPLETE))
 		return -EPERM;
 
 	ret = kstrtoint_from_user(buf, count, 0, &i);
@@ -75,16 +75,30 @@ static ssize_t evm_write_key(struct file *file, const char __user *buf,
 	if (!i || (i & ~EVM_INIT_MASK) != 0)
 		return -EINVAL;
 
+	/* Don't allow a request to freshly enable metadata writes if
+	 * keys are loaded.
+	 */
+	if ((i & EVM_ALLOW_METADATA_WRITES) &&
+	    ((evm_initialized & EVM_KEY_MASK) != 0) &&
+	    !(evm_initialized & EVM_ALLOW_METADATA_WRITES))
+		return -EPERM;
+
 	if (i & EVM_INIT_HMAC) {
 		ret = evm_init_key();
 		if (ret != 0)
 			return ret;
 		/* Forbid further writes after the symmetric key is loaded */
-		i |= EVM_SETUP;
+		i |= EVM_SETUP_COMPLETE;
 	}
 
 	evm_initialized |= i;
 
+	/* Don't allow protected metadata modification if a symmetric key
+	 * is loaded
+	 */
+	if (evm_initialized & EVM_INIT_HMAC)
+		evm_initialized &= ~(EVM_ALLOW_METADATA_WRITES);
+
 	return count;
 }