Patch "KVM: arm64: Fix host stage-2 finalization" has been added to the 5.15-stable tree

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

 



This is a note to let you know that I've just added the patch titled

    KVM: arm64: Fix host stage-2 finalization

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     kvm-arm64-fix-host-stage-2-finalization.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 5fa615cf33cdb5f7132f470d043ae395e88bcfab
Author: Quentin Perret <qperret@xxxxxxxxxx>
Date:   Mon Nov 8 15:46:32 2021 +0000

    KVM: arm64: Fix host stage-2 finalization
    
    [ Upstream commit 50a8d3315960c74095c59e204db44abd937d4b5d ]
    
    We currently walk the hypervisor stage-1 page-table towards the end of
    hyp init in nVHE protected mode and adjust the host page ownership
    attributes in its stage-2 in order to get a consistent state from both
    point of views. The walk is done on the entire hyp VA space, and expects
    to only ever find page-level mappings. While this expectation is
    reasonable in the half of hyp VA space that maps memory with a fixed
    offset (see the loop in pkvm_create_mappings_locked()), it can be
    incorrect in the other half where nothing prevents the usage of block
    mappings. For instance, on systems where memory is physically aligned at
    an address that happens to maps to a PMD aligned VA in the hyp_vmemmap,
    kvm_pgtable_hyp_map() will install block mappings when backing the
    hyp_vmemmap, which will later cause finalize_host_mappings() to fail.
    Furthermore, it should be noted that all pages backing the hyp_vmemmap
    are also mapped in the 'fixed offset range' of the hypervisor, which
    implies that finalize_host_mappings() will walk both aliases and update
    the host stage-2 attributes twice. The order in which this happens is
    unpredictable, though, since the hyp VA layout is highly dependent on
    the position of the idmap page, hence resulting in a fragile mess at
    best.
    
    In order to fix all of this, let's restrict the finalization walk to
    only cover memory regions in the 'fixed-offset range' of the hyp VA
    space and nothing else. This not only fixes a correctness issue, but
    will also result in a slighlty faster hyp initialization overall.
    
    Fixes: 2c50166c62ba ("KVM: arm64: Mark host bss and rodata section as shared")
    Signed-off-by: Quentin Perret <qperret@xxxxxxxxxx>
    Signed-off-by: Marc Zyngier <maz@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20211108154636.393384-1-qperret@xxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index 57c27846320f4..58ad9c5ba3112 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -177,7 +177,7 @@ static int finalize_host_mappings_walker(u64 addr, u64 end, u32 level,
 
 	phys = kvm_pte_to_phys(pte);
 	if (!addr_is_memory(phys))
-		return 0;
+		return -EINVAL;
 
 	/*
 	 * Adjust the host stage-2 mappings to match the ownership attributes
@@ -206,8 +206,18 @@ static int finalize_host_mappings(void)
 		.cb	= finalize_host_mappings_walker,
 		.flags	= KVM_PGTABLE_WALK_LEAF,
 	};
+	int i, ret;
+
+	for (i = 0; i < hyp_memblock_nr; i++) {
+		struct memblock_region *reg = &hyp_memory[i];
+		u64 start = (u64)hyp_phys_to_virt(reg->base);
+
+		ret = kvm_pgtable_walk(&pkvm_pgtable, start, reg->size, &walker);
+		if (ret)
+			return ret;
+	}
 
-	return kvm_pgtable_walk(&pkvm_pgtable, 0, BIT(pkvm_pgtable.ia_bits), &walker);
+	return 0;
 }
 
 void __noreturn __pkvm_init_finalise(void)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux