ANDROID: BACKPORT: KVM: arm64: Always unmap the pvmfw region at stage-2
The donation of the pvmfw region to pKVM is currently done transparently as part of fix_host_ownership(). However, this function only runs over PA ranges covered by the memblock list, although there is no guarantee for the pvmfw region to be advertised in a memory node in DT. In this case, the pKVM init will appear to succeed while silently keeping valid host stage-2 mappings to the pvmfw region. Fix this by forcefully registering the pvmfw region in the pKVM memblock list. BACKPORT: Fix usage of pvmfw_size and pvmfw_base which are pointers in 6.6 and earlier. Bug: 278749606 Bug: 424382332 Reported-by: Bartłomiej Grzesik <bgrzesik@google.com> Suggested-by: Will Deacon <willdeacon@google.com> Change-Id: I8f5498df25debb432b7dffd1e40a8910bcec7b49 Signed-off-by: Quentin Perret <qperret@google.com>
This commit is contained in:
committed by
Treehugger Robot
parent
3a0107a38e
commit
56cc224601
@@ -65,6 +65,7 @@ static void __init sort_memblock_regions(void)
|
|||||||
static int __init register_memblock_regions(void)
|
static int __init register_memblock_regions(void)
|
||||||
{
|
{
|
||||||
struct memblock_region *reg;
|
struct memblock_region *reg;
|
||||||
|
bool pvmfw_in_mem = false;
|
||||||
|
|
||||||
for_each_mem_region(reg) {
|
for_each_mem_region(reg) {
|
||||||
if (*hyp_memblock_nr_ptr >= HYP_MEMBLOCK_REGIONS)
|
if (*hyp_memblock_nr_ptr >= HYP_MEMBLOCK_REGIONS)
|
||||||
@@ -72,6 +73,27 @@ static int __init register_memblock_regions(void)
|
|||||||
|
|
||||||
hyp_memory[*hyp_memblock_nr_ptr] = *reg;
|
hyp_memory[*hyp_memblock_nr_ptr] = *reg;
|
||||||
(*hyp_memblock_nr_ptr)++;
|
(*hyp_memblock_nr_ptr)++;
|
||||||
|
|
||||||
|
if (!*pvmfw_size || pvmfw_in_mem ||
|
||||||
|
!memblock_addrs_overlap(reg->base, reg->size, *pvmfw_base, *pvmfw_size))
|
||||||
|
continue;
|
||||||
|
/* If the pvmfw region overlaps a memblock, it must be a subset */
|
||||||
|
if (*pvmfw_base < reg->base ||
|
||||||
|
(*pvmfw_base + *pvmfw_size) > (reg->base + reg->size))
|
||||||
|
return -EINVAL;
|
||||||
|
pvmfw_in_mem = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*pvmfw_size && !pvmfw_in_mem) {
|
||||||
|
if (*hyp_memblock_nr_ptr >= HYP_MEMBLOCK_REGIONS)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
hyp_memory[*hyp_memblock_nr_ptr] = (struct memblock_region) {
|
||||||
|
.base = *pvmfw_base,
|
||||||
|
.size = *pvmfw_size,
|
||||||
|
.flags = MEMBLOCK_NOMAP,
|
||||||
|
};
|
||||||
|
(*hyp_memblock_nr_ptr)++;
|
||||||
}
|
}
|
||||||
sort_memblock_regions();
|
sort_memblock_regions();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user