[RFC PATCH v1 33/34] KVM: introspection: mask out non-rwx flags when reading/writing from/to the internal database

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is needed because the KVMI_VM_SET_PAGE_SVE command we will use
the same database to keep the suppress #VE bit requested by the
introspection tool.

Signed-off-by: Adalbert Lazăr <alazar@xxxxxxxxxxxxxxx>
---
 virt/kvm/introspection/kvmi.c | 36 ++++++++++++++++++++++++-----------
 1 file changed, 25 insertions(+), 11 deletions(-)

diff --git a/virt/kvm/introspection/kvmi.c b/virt/kvm/introspection/kvmi.c
index f3bdef3c54e6..6bae2981cda7 100644
--- a/virt/kvm/introspection/kvmi.c
+++ b/virt/kvm/introspection/kvmi.c
@@ -23,9 +23,12 @@ static struct kmem_cache *msg_cache;
 static struct kmem_cache *job_cache;
 static struct kmem_cache *radix_cache;
 
-static const u8 full_access  =	KVMI_PAGE_ACCESS_R |
-				KVMI_PAGE_ACCESS_W |
-				KVMI_PAGE_ACCESS_X;
+static const u8 rwx_access = KVMI_PAGE_ACCESS_R |
+			     KVMI_PAGE_ACCESS_W |
+			     KVMI_PAGE_ACCESS_X;
+static const u8 full_access = KVMI_PAGE_ACCESS_R |
+			     KVMI_PAGE_ACCESS_W |
+			     KVMI_PAGE_ACCESS_X;
 
 void *kvmi_msg_alloc(void)
 {
@@ -1100,7 +1103,7 @@ static void kvmi_insert_mem_access(struct kvm *kvm, struct kvmi_mem_access *m,
 }
 
 static void kvmi_set_mem_access(struct kvm *kvm, struct kvmi_mem_access *m,
-				u16 view, bool *used)
+				u8 mask, u16 view, bool *used)
 {
 	struct kvm_introspection *kvmi = KVMI(kvm);
 	struct kvmi_mem_access *found;
@@ -1112,11 +1115,14 @@ static void kvmi_set_mem_access(struct kvm *kvm, struct kvmi_mem_access *m,
 
 	found = __kvmi_get_gfn_access(kvmi, m->gfn, view);
 	if (found) {
-		found->access = m->access;
+		found->access = (m->access & mask) | (found->access & ~mask);
 		kvmi_update_mem_access(kvm, found, view);
-	} else if (m->access != full_access) {
-		kvmi_insert_mem_access(kvm, m, view);
-		*used = true;
+	} else {
+		m->access |= full_access & ~mask;
+		if (m->access != full_access) {
+			kvmi_insert_mem_access(kvm, m, view);
+			*used = true;
+		}
 	}
 
 	write_unlock(&kvmi->access_tree_lock);
@@ -1141,7 +1147,7 @@ static int kvmi_set_gfn_access(struct kvm *kvm, gfn_t gfn, u8 access,
 	if (radix_tree_preload(GFP_KERNEL))
 		err = -KVM_ENOMEM;
 	else
-		kvmi_set_mem_access(kvm, m, view, &used);
+		kvmi_set_mem_access(kvm, m, rwx_access, view, &used);
 
 	radix_tree_preload_end();
 
@@ -1216,14 +1222,22 @@ static int kvmi_get_gfn_access(struct kvm_introspection *kvmi, const gfn_t gfn,
 			       u8 *access, u16 view)
 {
 	struct kvmi_mem_access *m;
+	u8 allowed = rwx_access;
+	bool restricted;
 
 	read_lock(&kvmi->access_tree_lock);
 	m = __kvmi_get_gfn_access(kvmi, gfn, view);
 	if (m)
-		*access = m->access;
+		allowed = m->access;
 	read_unlock(&kvmi->access_tree_lock);
 
-	return m ? 0 : -1;
+	restricted = (allowed & rwx_access) != rwx_access;
+
+	if (!restricted)
+		return -1;
+
+	*access = allowed;
+	return 0;
 }
 
 bool kvmi_restricted_page_access(struct kvm_introspection *kvmi, gpa_t gpa,



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux