|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] xen/arm: Register re-mapped Xen area as a temporary virtual region
While we're doing apply_alternatives, we will generate new instructions
if required. The new instructions need to update the Xen text section,
but Xen text section is read-only. So we re-map Xen to a new virtual
address to enable write access.
The targets of the new generated instructions are located in this
re-mapped Xen area. But we haven't register this area as a virtual
region, so the checking code determines the targets are not in the
Xen text section, the new instructions could not be generated.
In this patch, we register the re-mapped Xen area as a temporary
virtual region to make the new instructions can be generated
successfully.
Signed-off-by: Wei Chen <Wei.Chen@xxxxxxx>
---
xen/arch/arm/alternative.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/alternative.c b/xen/arch/arm/alternative.c
index 1d10f51..96859fc 100644
--- a/xen/arch/arm/alternative.c
+++ b/xen/arch/arm/alternative.c
@@ -24,6 +24,7 @@
#include <xen/vmap.h>
#include <xen/smp.h>
#include <xen/stop_machine.h>
+#include <xen/virtual_region.h>
#include <asm/alternative.h>
#include <asm/atomic.h>
#include <asm/byteorder.h>
@@ -154,8 +155,12 @@ static int __apply_alternatives_multi_stop(void *unused)
int ret;
struct alt_region region;
mfn_t xen_mfn = _mfn(virt_to_mfn(_start));
- unsigned int xen_order = get_order_from_bytes(_end - _start);
+ unsigned int xen_size = _end - _start;
+ unsigned int xen_order = get_order_from_bytes(xen_size);
void *xenmap;
+ struct virtual_region patch_region = {
+ .list = LIST_HEAD_INIT(patch_region.list),
+ };
BUG_ON(patched);
@@ -169,6 +174,15 @@ static int __apply_alternatives_multi_stop(void *unused)
BUG_ON(!xenmap);
/*
+ * If we generate a new branch instruction, the target will be
+ * calculated in this re-mapped Xen region. So we have to register
+ * this re-mapped Xen region as a virtual region temporarily.
+ */
+ patch_region.start = xenmap;
+ patch_region.end = xenmap + xen_size;
+ register_virtual_region(&patch_region);
+
+ /*
* Find the virtual address of the alternative region in the new
* mapping.
* alt_instr contains relative offset, so the function
@@ -182,6 +196,8 @@ static int __apply_alternatives_multi_stop(void *unused)
/* The patching is not expected to fail during boot. */
BUG_ON(ret != 0);
+ unregister_virtual_region(&patch_region);
+
vunmap(xenmap);
/* Barriers provided by the cache flushing */
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |