|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 1/7] x86: provide executable fixmap facility
This allows us to set aside some address space for executable mapping.
This fixed map range starts from XEN_VIRT_END so that it is within reach
of the .text section.
Shift the percpu stub range and livepatch range accordingly.
Signed-off-by: Wei Liu <liuwe@xxxxxxxxxxxxx>
---
xen/arch/x86/boot/x86_64.S | 10 +++++++++-
xen/arch/x86/livepatch.c | 3 ++-
xen/arch/x86/mm.c | 9 +++++++++
xen/arch/x86/smpboot.c | 2 +-
xen/arch/x86/xen.lds.S | 3 +++
xen/include/asm-x86/config.h | 2 +-
xen/include/asm-x86/fixmap.h | 28 ++++++++++++++++++++++++++++
7 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S
index 1cbf5acdfb..605d01f1dd 100644
--- a/xen/arch/x86/boot/x86_64.S
+++ b/xen/arch/x86/boot/x86_64.S
@@ -85,7 +85,15 @@ GLOBAL(l2_directmap)
* 4k page.
*/
GLOBAL(l2_xenmap)
- .fill L2_PAGETABLE_ENTRIES, 8, 0
+ idx = 0
+ .rept L2_PAGETABLE_ENTRIES
+ .if idx == l2_table_offset(FIXADDR_X_TOP - 1)
+ .quad sym_offs(l1_fixmap_x) + __PAGE_HYPERVISOR
+ .else
+ .quad 0
+ .endif
+ idx = idx + 1
+ .endr
.size l2_xenmap, . - l2_xenmap
/* L2 mapping the fixmap. Uses 1x 4k page. */
diff --git a/xen/arch/x86/livepatch.c b/xen/arch/x86/livepatch.c
index 2749cbc5cf..513b0f3841 100644
--- a/xen/arch/x86/livepatch.c
+++ b/xen/arch/x86/livepatch.c
@@ -12,6 +12,7 @@
#include <xen/livepatch.h>
#include <xen/sched.h>
+#include <asm/fixmap.h>
#include <asm/nmi.h>
#include <asm/livepatch.h>
@@ -311,7 +312,7 @@ void __init arch_livepatch_init(void)
void *start, *end;
start = (void *)xen_virt_end;
- end = (void *)(XEN_VIRT_END - NR_CPUS * PAGE_SIZE);
+ end = (void *)(XEN_VIRT_END - FIXADDR_X_SIZE - NR_CPUS * PAGE_SIZE);
BUG_ON(end <= start);
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 654190e9e9..aabe1a4c64 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -157,6 +157,8 @@
/* Mapping of the fixmap space needed early. */
l1_pgentry_t __section(".bss.page_aligned") __aligned(PAGE_SIZE)
l1_fixmap[L1_PAGETABLE_ENTRIES];
+l1_pgentry_t __section(".bss.page_aligned") __aligned(PAGE_SIZE)
+ l1_fixmap_x[L1_PAGETABLE_ENTRIES];
paddr_t __read_mostly mem_hotplug;
@@ -5763,6 +5765,13 @@ void __set_fixmap(
map_pages_to_xen(__fix_to_virt(idx), _mfn(mfn), 1, flags);
}
+void __set_fixmap_x(
+ enum fixed_addresses_x idx, unsigned long mfn, unsigned long flags)
+{
+ BUG_ON(idx >= __end_of_fixed_addresses_x);
+ map_pages_to_xen(__fix_x_to_virt(idx), _mfn(mfn), 1, flags);
+}
+
void *__init arch_vmap_virt_end(void)
{
return fix_to_virt(__end_of_fixed_addresses);
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index c9d1ab4423..2da42fb691 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -640,7 +640,7 @@ unsigned long alloc_stub_page(unsigned int cpu, unsigned
long *mfn)
unmap_domain_page(memset(__map_domain_page(pg), 0xcc, PAGE_SIZE));
}
- stub_va = XEN_VIRT_END - (cpu + 1) * PAGE_SIZE;
+ stub_va = XEN_VIRT_END - FIXADDR_X_SIZE - (cpu + 1) * PAGE_SIZE;
if ( map_pages_to_xen(stub_va, page_to_mfn(pg), 1,
PAGE_HYPERVISOR_RX | MAP_SMALL_PAGES) )
{
diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S
index 07c6448dbb..cbc5701214 100644
--- a/xen/arch/x86/xen.lds.S
+++ b/xen/arch/x86/xen.lds.S
@@ -3,6 +3,8 @@
#include <xen/cache.h>
#include <xen/lib.h>
+
+#include <asm/fixmap.h>
#include <asm/page.h>
#undef ENTRY
#undef ALIGN
@@ -353,6 +355,7 @@ SECTIONS
}
ASSERT(__2M_rwdata_end <= XEN_VIRT_END - XEN_VIRT_START + __XEN_VIRT_START -
+ MAX_FIXADDR_X_SIZE -
DIV_ROUND_UP(NR_CPUS, STUBS_PER_PAGE) * PAGE_SIZE,
"Xen image overlaps stubs area")
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index d0cfbb70a8..4fa56ea0a9 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -218,7 +218,7 @@ extern unsigned char boot_edid_info[128];
/* Slot 261: high read-only compat machine-to-phys conversion table (1GB). */
#define HIRO_COMPAT_MPT_VIRT_START RDWR_COMPAT_MPT_VIRT_END
#define HIRO_COMPAT_MPT_VIRT_END (HIRO_COMPAT_MPT_VIRT_START + GB(1))
-/* Slot 261: xen text, static data and bss (1GB). */
+/* Slot 261: xen text, static data, bss and executable fixmap (1GB). */
#define XEN_VIRT_START (HIRO_COMPAT_MPT_VIRT_END)
#define XEN_VIRT_END (XEN_VIRT_START + GB(1))
diff --git a/xen/include/asm-x86/fixmap.h b/xen/include/asm-x86/fixmap.h
index 9fb2f47946..c2a9d2b50a 100644
--- a/xen/include/asm-x86/fixmap.h
+++ b/xen/include/asm-x86/fixmap.h
@@ -15,6 +15,9 @@
#include <asm/page.h>
#define FIXADDR_TOP (VMAP_VIRT_END - PAGE_SIZE)
+#define FIXADDR_X_TOP (XEN_VIRT_END - PAGE_SIZE)
+/* This constant is derived from enum fixed_addresses_x below */
+#define MAX_FIXADDR_X_SIZE (2 << PAGE_SHIFT)
#ifndef __ASSEMBLY__
@@ -89,6 +92,31 @@ static inline unsigned long virt_to_fix(const unsigned long
vaddr)
return __virt_to_fix(vaddr);
}
+enum fixed_addresses_x {
+ /* Index 0 is reserved since fix_x_to_virt(0) == FIXADDR_X_TOP. */
+ FIX_X_RESERVED,
+#ifdef CONFIG_HYPERV_GUEST
+ FIX_X_HYPERV_HCALL,
+#endif
+ __end_of_fixed_addresses_x
+};
+
+#define FIXADDR_X_SIZE (__end_of_fixed_addresses_x << PAGE_SHIFT)
+#define FIXADDR_X_START (FIXADDR_X_TOP - FIXADDR_X_SIZE)
+
+extern void __set_fixmap_x(
+ enum fixed_addresses_x idx, unsigned long mfn, unsigned long flags);
+
+#define set_fixmap_x(idx, phys) \
+ __set_fixmap_x(idx, (phys)>>PAGE_SHIFT, PAGE_HYPERVISOR_RX |
MAP_SMALL_PAGES)
+
+#define clear_fixmap_x(idx) __set_fixmap_x(idx, 0, 0)
+
+#define __fix_x_to_virt(x) (FIXADDR_X_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix_x(x) ((FIXADDR_X_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
+#define fix_x_to_virt(x) ((void *)__fix_x_to_virt(x))
+
#endif /* __ASSEMBLY__ */
#endif
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |