[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 |