When an mmu_notifier invalidation only upgrades permissions (MMU_NOTIFIER_RANGE_PERM_UPGRADE), keep the existing gmap entries instead of unmapping them. The PFN is unchanged and no access is revoked, so an existing entry is no more permissive than the new host PTE. A write to an entry that is still read-only causes a protection exception, which kvm_s390_faultin_gfn() handles as a write fault, picking up the new permissions. This applies to both s390 and arm64 guests. Signed-off-by: Carlos López --- arch/s390/kvm/arm64/arm.c | 7 +++++++ arch/s390/kvm/s390/s390.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/arch/s390/kvm/arm64/arm.c b/arch/s390/kvm/arm64/arm.c index bd9d85235f43..5aee1817aad8 100644 --- a/arch/s390/kvm/arm64/arm.c +++ b/arch/s390/kvm/arm64/arm.c @@ -678,6 +678,13 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, struct kvm_memory_slot *old, bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) { + /* + * Do not bother unmapping if this is only a protection upgrade. + * Permissions will be faulted-in on demand. + */ + if (range->flags & MMU_NOTIFIER_RANGE_PERM_UPGRADE) + return false; + return gmap_unmap_gfn_range(kvm->arch.gmap, range->slot, range->start, range->end); } diff --git a/arch/s390/kvm/s390/s390.c b/arch/s390/kvm/s390/s390.c index 18fb200f854a..954bf6b64683 100644 --- a/arch/s390/kvm/s390/s390.c +++ b/arch/s390/kvm/s390/s390.c @@ -5871,6 +5871,13 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) */ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) { + /* + * Do not bother unmapping if this is only a protection upgrade. + * Permissions will be faulted-in on demand. + */ + if (range->flags & MMU_NOTIFIER_RANGE_PERM_UPGRADE) + return false; + return gmap_unmap_gfn_range(kvm->arch.gmap, range->slot, range->start, range->end); } -- 2.51.0