|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC v2 10/12] x86: allocate per-vcpu stacks for interrupt entries
In case of XPTI being active for a pv-domain allocate and initialize
per-vcpu stacks. The stacks are added to the per-domain mappings of
the pv-domain.
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
xen/arch/x86/pv/domain.c | 72 +++++++++++++++++++++++++++++++++++++++++++
xen/include/asm-x86/config.h | 13 +++++++-
xen/include/asm-x86/current.h | 39 ++++++++++++++++++++---
xen/include/asm-x86/domain.h | 3 ++
4 files changed, 121 insertions(+), 6 deletions(-)
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 7d50f9bc19..834be96ed8 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -156,6 +156,75 @@ void pv_vcpu_destroy(struct vcpu *v)
pv_destroy_gdt_ldt_l1tab(v);
xfree(v->arch.pv_vcpu.trap_ctxt);
v->arch.pv_vcpu.trap_ctxt = NULL;
+
+ if ( v->domain->arch.pv_domain.xpti )
+ {
+ free_xenheap_page(v->arch.pv_vcpu.stack_regs);
+ v->arch.pv_vcpu.stack_regs = NULL;
+ destroy_perdomain_mapping(v->domain, XPTI_START(v), STACK_PAGES);
+ }
+}
+
+static int pv_vcpu_init_xpti(struct vcpu *v)
+{
+ struct domain *d = v->domain;
+ struct page_info *pg;
+ void *ptr;
+ struct cpu_info *info;
+ unsigned long stack_bottom;
+ int rc;
+
+ /* Populate page tables. */
+ rc = create_perdomain_mapping(d, XPTI_START(v), STACK_PAGES,
+ NIL(l1_pgentry_t *), NULL);
+ if ( rc )
+ goto done;
+
+ /* Map stacks. */
+ rc = create_perdomain_mapping(d, XPTI_START(v), IST_MAX,
+ NULL, NIL(struct page_info *));
+ if ( rc )
+ goto done;
+
+ ptr = alloc_xenheap_page();
+ if ( !ptr )
+ {
+ rc = -ENOMEM;
+ goto done;
+ }
+ clear_page(ptr);
+ addmfn_to_perdomain_mapping(d, XPTI_START(v) + STACK_SIZE - PAGE_SIZE,
+ _mfn(virt_to_mfn(ptr)));
+ info = (struct cpu_info *)((unsigned long)ptr + PAGE_SIZE) - 1;
+ info->flags = ON_VCPUSTACK;
+ v->arch.pv_vcpu.stack_regs = &info->guest_cpu_user_regs;
+
+ /* Map TSS. */
+ rc = create_perdomain_mapping(d, XPTI_TSS(v), 1, NULL, &pg);
+ if ( rc )
+ goto done;
+ info = (struct cpu_info *)(XPTI_START(v) + STACK_SIZE) - 1;
+ stack_bottom = (unsigned long)&info->guest_cpu_user_regs.es;
+ ptr = __map_domain_page(pg);
+ tss_init(ptr, stack_bottom);
+ unmap_domain_page(ptr);
+
+ /* Map stub trampolines. */
+ rc = create_perdomain_mapping(d, XPTI_TRAMPOLINE(v), 1, NULL, &pg);
+ if ( rc )
+ goto done;
+ ptr = __map_domain_page(pg);
+ write_stub_trampoline((unsigned char *)ptr, XPTI_TRAMPOLINE(v),
+ stack_bottom, (unsigned long)lstar_enter);
+ write_stub_trampoline((unsigned char *)ptr + STUB_TRAMPOLINE_SIZE_PERVCPU,
+ XPTI_TRAMPOLINE(v) + STUB_TRAMPOLINE_SIZE_PERVCPU,
+ stack_bottom, (unsigned long)cstar_enter);
+ unmap_domain_page(ptr);
+ flipflags_perdomain_mapping(d, XPTI_TRAMPOLINE(v),
+ _PAGE_NX | _PAGE_RW | _PAGE_DIRTY);
+
+ done:
+ return rc;
}
int pv_vcpu_initialise(struct vcpu *v)
@@ -195,6 +264,9 @@ int pv_vcpu_initialise(struct vcpu *v)
goto done;
}
+ if ( d->arch.pv_domain.xpti )
+ rc = pv_vcpu_init_xpti(v);
+
done:
if ( rc )
pv_vcpu_destroy(v);
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index 9ef9d03ca7..cb107255af 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -66,6 +66,7 @@
#endif
#define STACK_ORDER 3
+#define STACK_PAGES (1 << STACK_ORDER)
#define STACK_SIZE (PAGE_SIZE << STACK_ORDER)
#define TRAMPOLINE_STACK_SPACE PAGE_SIZE
@@ -202,7 +203,7 @@ extern unsigned char boot_edid_info[128];
/* Slot 260: per-domain mappings (including map cache). */
#define PERDOMAIN_VIRT_START (PML4_ADDR(260))
#define PERDOMAIN_SLOT_MBYTES (PML4_ENTRY_BYTES >> (20 + PAGETABLE_ORDER))
-#define PERDOMAIN_SLOTS 3
+#define PERDOMAIN_SLOTS 4
#define PERDOMAIN_VIRT_SLOT(s) (PERDOMAIN_VIRT_START + (s) * \
(PERDOMAIN_SLOT_MBYTES << 20))
/* Slot 261: machine-to-phys conversion table (256GB). */
@@ -310,6 +311,16 @@ extern unsigned long xen_phys_start;
#define ARG_XLAT_START(v) \
(ARG_XLAT_VIRT_START + ((v)->vcpu_id << ARG_XLAT_VA_SHIFT))
+/* Per-vcpu XPTI pages. The fourth per-domain-mapping sub-area. */
+#define XPTI_VIRT_START PERDOMAIN_VIRT_SLOT(3)
+#define XPTI_VA_SHIFT (PAGE_SHIFT + STACK_ORDER)
+#define XPTI_TRAMPOLINE_OFF (IST_MAX << PAGE_SHIFT)
+#define XPTI_TSS_OFF ((IST_MAX + 2) << PAGE_SHIFT)
+#define XPTI_START(v) (XPTI_VIRT_START + \
+ ((v)->vcpu_id << XPTI_VA_SHIFT))
+#define XPTI_TRAMPOLINE(v) (XPTI_START(v) + XPTI_TRAMPOLINE_OFF)
+#define XPTI_TSS(v) (XPTI_START(v) + XPTI_TSS_OFF)
+
#define NATIVE_VM_ASSIST_VALID ((1UL << VMASST_TYPE_4gb_segments) | \
(1UL << VMASST_TYPE_4gb_segments_notify) | \
(1UL << VMASST_TYPE_writable_pagetables) | \
diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h
index c7acbb97da..6ae0931a59 100644
--- a/xen/include/asm-x86/current.h
+++ b/xen/include/asm-x86/current.h
@@ -12,7 +12,7 @@
#include <asm/page.h>
/*
- * Xen's cpu stacks are 8 pages (8-page aligned), arranged as:
+ * Xen's physical cpu stacks are 8 pages (8-page aligned), arranged as:
*
* 7 - Primary stack (with a struct cpu_info at the top)
* 6 - Primary stack
@@ -25,6 +25,21 @@
*/
/*
+ * The vcpu stacks used for XPTI are arranged similar to the physical cpu
+ * stacks with some modifications. The main difference are the primary stack
+ * size (only 1 page) and usage of the unused mappings for TSS and IDT.
+ *
+ * 7 - Primary stack (with a struct cpu_info at the top)
+ * 6 - unused
+ * 5 - TSS
+ * 4 - unused
+ * 3 - Syscall trampolines
+ * 2 - MCE IST stack
+ * 1 - NMI IST stack
+ * 0 - Double Fault IST stack
+ */
+
+/*
* Identify which stack page the stack pointer is on. Returns an index
* as per the comment above.
*/
@@ -37,10 +52,24 @@ struct vcpu;
struct cpu_info {
struct cpu_user_regs guest_cpu_user_regs;
- unsigned int processor_id;
- struct vcpu *current_vcpu;
- unsigned long per_cpu_offset;
- unsigned long cr4;
+ union {
+ /* per physical cpu mapping */
+ struct {
+ struct vcpu *current_vcpu;
+ unsigned long per_cpu_offset;
+ unsigned long cr4;
+ };
+ /* per vcpu mapping (xpti) */
+ struct {
+ unsigned long pad1;
+ unsigned long pad2;
+ unsigned long stack_bottom_cpu;
+ };
+ };
+ unsigned int processor_id; /* per physical cpu mapping only */
+ unsigned int flags;
+#define ON_VCPUSTACK 0x00000001
+#define VCPUSTACK_ACTIVE 0x00000002
/* get_stack_bottom() must be 16-byte aligned */
};
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index f1230ac621..5eb67f4f4c 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -503,6 +503,9 @@ struct pv_vcpu
/* Deferred VA-based update state. */
bool_t need_update_runstate_area;
struct vcpu_time_info pending_system_time;
+
+ /* If XPTI is active: pointer to user regs on stack. */
+ struct cpu_user_regs *stack_regs;
};
typedef enum __packed {
--
2.13.6
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |