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 <andre.przywara@xxxxxxx> --- 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 kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm