|
|
f522170 |
From 4426d993b7ee0966fb39531dc5a269ce8493ca97 Mon Sep 17 00:00:00 2001
|
|
|
f522170 |
From: Julien Grall <julien.grall@arm.com>
|
|
|
f522170 |
Date: Wed, 2 Oct 2019 12:35:59 +0100
|
|
|
f522170 |
Subject: [PATCH 2/3] xen/arm: p2m: Avoid off-by-one check on
|
|
|
f522170 |
p2m->max_mapped_gfn
|
|
|
f522170 |
|
|
|
f522170 |
The code base is using inconsistently the field p2m->max_mapped_gfn.
|
|
|
f522170 |
Some of the useres expect that p2m->max_guest_gfn contain the highest
|
|
|
f522170 |
mapped GFN while others expect highest + 1.
|
|
|
f522170 |
|
|
|
f522170 |
p2m->max_guest_gfn is set as highest + 1, because of that the sanity
|
|
|
f522170 |
check on the GFN in p2m_resolved_translation_fault() and
|
|
|
f522170 |
p2m_get_entry() can be bypassed when GFN == p2m->max_guest_gfn.
|
|
|
f522170 |
|
|
|
f522170 |
p2m_get_root_pointer(p2m->max_guest_gfn) may return NULL if it is
|
|
|
f522170 |
outside of address range supported and therefore the BUG_ON() could be
|
|
|
f522170 |
hit.
|
|
|
f522170 |
|
|
|
f522170 |
The current value hold in p2m->max_mapped_gfn is inconsistent with the
|
|
|
f522170 |
expectation of the common code (see domain_get_maximum_gpfn()) and also
|
|
|
f522170 |
the documentation of the field.
|
|
|
f522170 |
|
|
|
f522170 |
Rather than changing the check in p2m_translation_fault() and
|
|
|
f522170 |
p2m_get_entry(), p2m->max_mapped_gfn is now containing the highest
|
|
|
f522170 |
mapped GFN and the callers assuming "highest + 1" are now adjusted.
|
|
|
f522170 |
|
|
|
f522170 |
Take the opportunity to use 1UL rather than 1 as page_order could
|
|
|
f522170 |
theoritically big enough to overflow a 32-bit integer.
|
|
|
f522170 |
|
|
|
f522170 |
Lastly, the documentation of the field max_guest_gfn to reflect how it
|
|
|
f522170 |
is computed.
|
|
|
f522170 |
|
|
|
f522170 |
This is part of XSA-301.
|
|
|
f522170 |
|
|
|
f522170 |
Reported-by: Julien Grall <Julien.Grall@arm.com>
|
|
|
f522170 |
Signed-off-by: Julien Grall <julien.grall@arm.com>
|
|
|
f522170 |
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
|
|
|
f522170 |
---
|
|
|
f522170 |
xen/arch/arm/p2m.c | 6 +++---
|
|
|
f522170 |
xen/include/asm-arm/p2m.h | 5 +----
|
|
|
f522170 |
2 files changed, 4 insertions(+), 7 deletions(-)
|
|
|
f522170 |
|
|
|
f522170 |
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
|
|
|
f522170 |
index 3967ee7306..c7e049901d 100644
|
|
|
f522170 |
--- a/xen/arch/arm/p2m.c
|
|
|
f522170 |
+++ b/xen/arch/arm/p2m.c
|
|
|
f522170 |
@@ -931,7 +931,7 @@ static int __p2m_set_entry(struct p2m_domain *p2m,
|
|
|
f522170 |
p2m_write_pte(entry, pte, p2m->clean_pte);
|
|
|
f522170 |
|
|
|
f522170 |
p2m->max_mapped_gfn = gfn_max(p2m->max_mapped_gfn,
|
|
|
f522170 |
- gfn_add(sgfn, 1 << page_order));
|
|
|
f522170 |
+ gfn_add(sgfn, (1UL << page_order) - 1));
|
|
|
f522170 |
p2m->lowest_mapped_gfn = gfn_min(p2m->lowest_mapped_gfn, sgfn);
|
|
|
f522170 |
}
|
|
|
f522170 |
|
|
|
f522170 |
@@ -1291,7 +1291,7 @@ int relinquish_p2m_mapping(struct domain *d)
|
|
|
f522170 |
p2m_write_lock(p2m);
|
|
|
f522170 |
|
|
|
f522170 |
start = p2m->lowest_mapped_gfn;
|
|
|
f522170 |
- end = p2m->max_mapped_gfn;
|
|
|
f522170 |
+ end = gfn_add(p2m->max_mapped_gfn, 1);
|
|
|
f522170 |
|
|
|
f522170 |
for ( ; gfn_x(start) < gfn_x(end);
|
|
|
f522170 |
start = gfn_next_boundary(start, order) )
|
|
|
f522170 |
@@ -1356,7 +1356,7 @@ int p2m_cache_flush(struct domain *d, gfn_t start, unsigned long nr)
|
|
|
f522170 |
p2m_read_lock(p2m);
|
|
|
f522170 |
|
|
|
f522170 |
start = gfn_max(start, p2m->lowest_mapped_gfn);
|
|
|
f522170 |
- end = gfn_min(end, p2m->max_mapped_gfn);
|
|
|
f522170 |
+ end = gfn_min(end, gfn_add(p2m->max_mapped_gfn, 1));
|
|
|
f522170 |
|
|
|
f522170 |
for ( ; gfn_x(start) < gfn_x(end); start = next_gfn )
|
|
|
f522170 |
{
|
|
|
f522170 |
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
|
|
|
f522170 |
index 8823707c17..7f1f7e9109 100644
|
|
|
f522170 |
--- a/xen/include/asm-arm/p2m.h
|
|
|
f522170 |
+++ b/xen/include/asm-arm/p2m.h
|
|
|
f522170 |
@@ -38,10 +38,7 @@ struct p2m_domain {
|
|
|
f522170 |
/* Current Translation Table Base Register for the p2m */
|
|
|
f522170 |
uint64_t vttbr;
|
|
|
f522170 |
|
|
|
f522170 |
- /*
|
|
|
f522170 |
- * Highest guest frame that's ever been mapped in the p2m
|
|
|
f522170 |
- * Only takes into account ram and foreign mapping
|
|
|
f522170 |
- */
|
|
|
f522170 |
+ /* Highest guest frame that's ever been mapped in the p2m */
|
|
|
f522170 |
gfn_t max_mapped_gfn;
|
|
|
f522170 |
|
|
|
f522170 |
/*
|
|
|
f522170 |
--
|
|
|
f522170 |
2.11.0
|
|
|
f522170 |
|