A KVM memslot has a flags field, which allows to mark a region as
read-only.
Add another memory type bit to allow kvmtool-internal users to map a
write-protected region. Write access would trap and can be handled by
the MMIO emulation, which should register on the same guest address
region.

Signed-off-by: Andre Przywara <[email protected]>
---
 include/kvm/kvm.h | 12 ++++++++----
 kvm.c             |  5 +++++
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/include/kvm/kvm.h b/include/kvm/kvm.h
index 9428f57a..53373b08 100644
--- a/include/kvm/kvm.h
+++ b/include/kvm/kvm.h
@@ -40,10 +40,12 @@ enum kvm_mem_type {
        KVM_MEM_TYPE_RAM        = 1 << 0,
        KVM_MEM_TYPE_DEVICE     = 1 << 1,
        KVM_MEM_TYPE_RESERVED   = 1 << 2,
+       KVM_MEM_TYPE_READONLY   = 1 << 3,
 
        KVM_MEM_TYPE_ALL        = KVM_MEM_TYPE_RAM
                                | KVM_MEM_TYPE_DEVICE
                                | KVM_MEM_TYPE_RESERVED
+                               | KVM_MEM_TYPE_READONLY
 };
 
 struct kvm_ext {
@@ -158,17 +160,19 @@ u64 host_to_guest_flat(struct kvm *kvm, void *ptr);
 bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd,
                                 const char *kernel_cmdline);
 
+#define add_read_only(type, str)                                       \
+       (((type) & KVM_MEM_TYPE_READONLY) ? str " (read-only)" : str)
 static inline const char *kvm_mem_type_to_string(enum kvm_mem_type type)
 {
-       switch (type) {
+       switch (type & ~KVM_MEM_TYPE_READONLY) {
        case KVM_MEM_TYPE_ALL:
                return "(all)";
        case KVM_MEM_TYPE_RAM:
-               return "RAM";
+               return add_read_only(type, "RAM");
        case KVM_MEM_TYPE_DEVICE:
-               return "device";
+               return add_read_only(type, "device");
        case KVM_MEM_TYPE_RESERVED:
-               return "reserved";
+               return add_read_only(type, "reserved");
        }
 
        return "???";
diff --git a/kvm.c b/kvm.c
index 26f6b9bc..e327541d 100644
--- a/kvm.c
+++ b/kvm.c
@@ -242,6 +242,7 @@ int kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 
size,
        struct kvm_mem_bank *bank;
        struct list_head *prev_entry;
        u32 slot;
+       u32 flags = 0;
        int ret;
 
        mutex_lock(&kvm->mem_banks_lock);
@@ -313,9 +314,13 @@ int kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 
size,
        bank->type                      = type;
        bank->slot                      = slot;
 
+       if (type & KVM_MEM_TYPE_READONLY)
+               flags |= KVM_MEM_READONLY;
+
        if (type != KVM_MEM_TYPE_RESERVED) {
                mem = (struct kvm_userspace_memory_region) {
                        .slot                   = slot,
+                       .flags                  = flags,
                        .guest_phys_addr        = guest_phys,
                        .memory_size            = size,
                        .userspace_addr         = (unsigned long)userspace_addr,
-- 
2.17.1

_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to