From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>,
wei.liu2@citrix.com, George.Dunlap@eu.citrix.com,
andrew.cooper3@citrix.com, ian.jackson@eu.citrix.com,
dfaggioli@suse.com, jbeulich@suse.com
Subject: [PATCH RFC v2 12/12] x86: activate per-vcpu stacks in case of xpti
Date: Mon, 22 Jan 2018 13:32:56 +0100 [thread overview]
Message-ID: <20180122123256.1431-13-jgross@suse.com> (raw)
In-Reply-To: <20180122123256.1431-1-jgross@suse.com>
When scheduling a vcpu subject to xpti activate the per-vcpu stacks
by loading the vcpu specific gdt and tss. When de-scheduling such a
vcpu switch back to the per physical cpu gdt and tss.
Accessing the user registers on the stack is done via helpers as
depending on XPTI active or not the registers are located either on
the per-vcpu stack or on the default stack.
Signed-off-by: Juergen Gross <jgross@suse.com>
---
xen/arch/x86/domain.c | 76 +++++++++++++++++++++++++++++++++++---
xen/arch/x86/pv/domain.c | 34 +++++++++++++++--
xen/include/asm-x86/desc.h | 5 +++
xen/include/asm-x86/regs.h | 2 +
4 files changed, 107 insertions(+), 10 deletions(-)
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index da1bf1a97b..d75234ca35 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1585,9 +1585,28 @@ static inline bool need_full_gdt(const struct domain *d)
return is_pv_domain(d) && !is_idle_domain(d);
}
+static void copy_user_regs_from_stack(struct vcpu *v)
+{
+ struct cpu_user_regs *stack_regs;
+
+ stack_regs = (is_pv_vcpu(v) && v->domain->arch.pv_domain.xpti)
+ ? v->arch.pv_vcpu.stack_regs
+ : &get_cpu_info()->guest_cpu_user_regs;
+ memcpy(&v->arch.user_regs, stack_regs, CTXT_SWITCH_STACK_BYTES);
+}
+
+static void copy_user_regs_to_stack(struct vcpu *v)
+{
+ struct cpu_user_regs *stack_regs;
+
+ stack_regs = (is_pv_vcpu(v) && v->domain->arch.pv_domain.xpti)
+ ? v->arch.pv_vcpu.stack_regs
+ : &get_cpu_info()->guest_cpu_user_regs;
+ memcpy(stack_regs, &v->arch.user_regs, CTXT_SWITCH_STACK_BYTES);
+}
+
static void __context_switch(void)
{
- struct cpu_user_regs *stack_regs = guest_cpu_user_regs();
unsigned int cpu = smp_processor_id();
struct vcpu *p = per_cpu(curr_vcpu, cpu);
struct vcpu *n = current;
@@ -1600,7 +1619,7 @@ static void __context_switch(void)
if ( !is_idle_domain(pd) )
{
- memcpy(&p->arch.user_regs, stack_regs, CTXT_SWITCH_STACK_BYTES);
+ copy_user_regs_from_stack(p);
vcpu_save_fpu(p);
pd->arch.ctxt_switch->from(p);
}
@@ -1616,7 +1635,7 @@ static void __context_switch(void)
if ( !is_idle_domain(nd) )
{
- memcpy(stack_regs, &n->arch.user_regs, CTXT_SWITCH_STACK_BYTES);
+ copy_user_regs_to_stack(n);
if ( cpu_has_xsave )
{
u64 xcr0 = n->arch.xcr0 ?: XSTATE_FP_SSE;
@@ -1635,7 +1654,7 @@ static void __context_switch(void)
gdt = !is_pv_32bit_domain(nd) ? per_cpu(gdt_table, cpu) :
per_cpu(compat_gdt_table, cpu);
- if ( need_full_gdt(nd) )
+ if ( need_full_gdt(nd) && !nd->arch.pv_domain.xpti )
{
unsigned long mfn = virt_to_mfn(gdt);
l1_pgentry_t *pl1e = pv_gdt_ptes(n);
@@ -1647,23 +1666,68 @@ static void __context_switch(void)
}
if ( need_full_gdt(pd) &&
- ((p->vcpu_id != n->vcpu_id) || !need_full_gdt(nd)) )
+ ((p->vcpu_id != n->vcpu_id) || !need_full_gdt(nd) ||
+ pd->arch.pv_domain.xpti) )
{
gdt_desc.limit = LAST_RESERVED_GDT_BYTE;
gdt_desc.base = (unsigned long)(gdt - FIRST_RESERVED_GDT_ENTRY);
+ if ( pd->arch.pv_domain.xpti )
+ _set_tssldt_type(gdt + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
+ SYS_DESC_tss_avail);
+
lgdt(&gdt_desc);
+
+ if ( pd->arch.pv_domain.xpti )
+ {
+ unsigned long stub_va = this_cpu(stubs.addr);
+
+ ltr(TSS_ENTRY << 3);
+ get_cpu_info()->flags &= ~VCPUSTACK_ACTIVE;
+ wrmsrl(MSR_LSTAR, stub_va);
+ wrmsrl(MSR_CSTAR, stub_va + STUB_TRAMPOLINE_SIZE_PERCPU);
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR )
+ wrmsrl(MSR_IA32_SYSENTER_ESP,
+ (unsigned long)&get_cpu_info()->guest_cpu_user_regs.es);
+ }
}
write_ptbase(n);
if ( need_full_gdt(nd) &&
- ((p->vcpu_id != n->vcpu_id) || !need_full_gdt(pd)) )
+ ((p->vcpu_id != n->vcpu_id) || !need_full_gdt(pd) ||
+ nd->arch.pv_domain.xpti) )
{
gdt_desc.limit = LAST_RESERVED_GDT_BYTE;
gdt_desc.base = GDT_VIRT_START(n);
+ if ( nd->arch.pv_domain.xpti )
+ {
+ struct cpu_info *info;
+
+ gdt = (struct desc_struct *)GDT_VIRT_START(n);
+ gdt[PER_CPU_GDT_ENTRY].a = cpu;
+ _set_tssldt_type(gdt + TSS_ENTRY, SYS_DESC_tss_avail);
+ info = (struct cpu_info *)(XPTI_START(n) + STACK_SIZE) - 1;
+ info->stack_bottom_cpu = (unsigned long)guest_cpu_user_regs();
+ }
+
lgdt(&gdt_desc);
+
+ if ( nd->arch.pv_domain.xpti )
+ {
+ unsigned long stub_va = XPTI_TRAMPOLINE(n);
+
+ ltr(TSS_ENTRY << 3);
+ get_cpu_info()->flags |= VCPUSTACK_ACTIVE;
+ wrmsrl(MSR_LSTAR, stub_va);
+ wrmsrl(MSR_CSTAR, stub_va + STUB_TRAMPOLINE_SIZE_PERVCPU);
+ if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR )
+ wrmsrl(MSR_IA32_SYSENTER_ESP,
+ (unsigned long)&guest_cpu_user_regs()->es);
+ }
}
if ( pd != nd )
diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c
index 834be96ed8..6158086087 100644
--- a/xen/arch/x86/pv/domain.c
+++ b/xen/arch/x86/pv/domain.c
@@ -133,10 +133,36 @@ int switch_compat(struct domain *d)
static int pv_create_gdt_ldt_l1tab(struct vcpu *v)
{
- return create_perdomain_mapping(v->domain, GDT_VIRT_START(v),
- 1U << GDT_LDT_VCPU_SHIFT,
- v->domain->arch.pv_domain.gdt_ldt_l1tab,
- NULL);
+ int rc;
+
+ rc = create_perdomain_mapping(v->domain, GDT_VIRT_START(v),
+ 1U << GDT_LDT_VCPU_SHIFT,
+ v->domain->arch.pv_domain.gdt_ldt_l1tab,
+ NULL);
+ if ( !rc && v->domain->arch.pv_domain.xpti )
+ {
+ struct desc_struct *gdt;
+ struct page_info *gdt_pg;
+
+ BUILD_BUG_ON(NR_RESERVED_GDT_PAGES > 1);
+ gdt = (struct desc_struct *)GDT_VIRT_START(v) +
+ FIRST_RESERVED_GDT_ENTRY;
+ rc = create_perdomain_mapping(v->domain, (unsigned long)gdt,
+ NR_RESERVED_GDT_PAGES,
+ NULL, &gdt_pg);
+ if ( !rc )
+ {
+ gdt = __map_domain_page(gdt_pg);
+ memcpy(gdt, boot_cpu_gdt_table, NR_RESERVED_GDT_BYTES);
+ _set_tssldt_desc(gdt + TSS_ENTRY - FIRST_RESERVED_GDT_ENTRY,
+ XPTI_TSS(v),
+ offsetof(struct tss_struct, __cacheline_filler) - 1,
+ SYS_DESC_tss_avail);
+ unmap_domain_page(gdt);
+ }
+ }
+
+ return rc;
}
static void pv_destroy_gdt_ldt_l1tab(struct vcpu *v)
diff --git a/xen/include/asm-x86/desc.h b/xen/include/asm-x86/desc.h
index 4093c65faa..d5fff4cce5 100644
--- a/xen/include/asm-x86/desc.h
+++ b/xen/include/asm-x86/desc.h
@@ -185,6 +185,11 @@ do { \
(((u32)(addr) & 0x00FF0000U) >> 16); \
} while (0)
+#define _set_tssldt_type(desc,type) \
+do { \
+ ((u8 *)&(desc)[0].b)[1] = (type) | 0x80; \
+} while (0)
+
struct __packed desc_ptr {
unsigned short limit;
unsigned long base;
diff --git a/xen/include/asm-x86/regs.h b/xen/include/asm-x86/regs.h
index 725a664e0a..361de4c54e 100644
--- a/xen/include/asm-x86/regs.h
+++ b/xen/include/asm-x86/regs.h
@@ -7,6 +7,8 @@
#define guest_mode(r) \
({ \
unsigned long diff = (char *)guest_cpu_user_regs() - (char *)(r); \
+ if ( diff >= STACK_SIZE ) \
+ diff = (char *)&get_cpu_info()->guest_cpu_user_regs - (char *)(r); \
/* Frame pointer must point into current CPU stack. */ \
ASSERT(diff < STACK_SIZE); \
/* If not a guest frame, it must be a hypervisor frame. */ \
--
2.13.6
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2018-01-22 12:33 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-22 12:32 [PATCH RFC v2 00/12] xen/x86: use per-vcpu stacks for 64 bit pv domains Juergen Gross
2018-01-22 12:32 ` [PATCH RFC v2 01/12] x86: cleanup processor.h Juergen Gross
2018-01-22 12:52 ` Jan Beulich
[not found] ` <5A65ECA502000078001A111C@suse.com>
2018-01-22 14:10 ` Juergen Gross
2018-01-22 14:25 ` Andrew Cooper
2018-01-22 14:32 ` Jan Beulich
2018-01-22 12:32 ` [PATCH RFC v2 02/12] x86: don't use hypervisor stack size for dumping guest stacks Juergen Gross
2018-01-23 9:26 ` Jan Beulich
[not found] ` <5A670DEF02000078001A16AF@suse.com>
2018-01-23 9:58 ` Juergen Gross
2018-01-23 10:11 ` Jan Beulich
[not found] ` <5A67187C02000078001A1742@suse.com>
2018-01-23 10:19 ` Juergen Gross
2018-01-22 12:32 ` [PATCH RFC v2 03/12] x86: do a revert of e871e80c38547d9faefc6604532ba3e985e65873 Juergen Gross
2018-01-22 12:32 ` [PATCH RFC v2 04/12] x86: revert 5784de3e2067ed73efc2fe42e62831e8ae7f46c4 Juergen Gross
2018-01-22 12:32 ` [PATCH RFC v2 05/12] x86: don't access saved user regs via rsp in trap handlers Juergen Gross
2018-01-30 14:49 ` Jan Beulich
[not found] ` <5A70941B02000078001A3BF0@suse.com>
2018-01-30 16:33 ` Juergen Gross
2018-01-22 12:32 ` [PATCH RFC v2 06/12] x86: add a xpti command line parameter Juergen Gross
2018-01-30 15:39 ` Jan Beulich
[not found] ` <5A709FDF02000078001A3C2C@suse.com>
2018-01-30 16:51 ` Juergen Gross
2018-01-22 12:32 ` [PATCH RFC v2 07/12] x86: allow per-domain mappings without NX bit or with specific mfn Juergen Gross
2018-01-29 17:06 ` Jan Beulich
[not found] ` <5A6F62B602000078001A3810@suse.com>
2018-01-30 8:02 ` Juergen Gross
2018-01-30 8:41 ` Jan Beulich
2018-01-31 10:30 ` Jan Beulich
2018-01-22 12:32 ` [PATCH RFC v2 08/12] xen/x86: use dedicated function for tss initialization Juergen Gross
2018-01-22 12:32 ` [PATCH RFC v2 09/12] x86: enhance syscall stub to work in per-domain mapping Juergen Gross
2018-01-30 15:11 ` Jan Beulich
[not found] ` <5A70991902000078001A3C16@suse.com>
2018-01-30 16:50 ` Juergen Gross
2018-01-22 12:32 ` [PATCH RFC v2 10/12] x86: allocate per-vcpu stacks for interrupt entries Juergen Gross
2018-01-30 15:40 ` Jan Beulich
2018-02-09 12:35 ` Juergen Gross
2018-02-13 9:10 ` Jan Beulich
[not found] ` <5A70A01402000078001A3C30@suse.com>
2018-01-30 17:12 ` Juergen Gross
2018-01-31 10:18 ` Jan Beulich
2018-01-22 12:32 ` [PATCH RFC v2 11/12] x86: modify interrupt handlers to support stack switching Juergen Gross
2018-01-30 16:07 ` Jan Beulich
[not found] ` <5A70A63D02000078001A3C7C@suse.com>
2018-01-30 17:19 ` Juergen Gross
2018-01-31 10:36 ` Jan Beulich
[not found] ` <5A71AA4202000078001A3F56@suse.com>
2018-02-02 15:42 ` Juergen Gross
2018-01-22 12:32 ` Juergen Gross [this message]
2018-01-30 16:33 ` [PATCH RFC v2 12/12] x86: activate per-vcpu stacks in case of xpti Jan Beulich
[not found] ` <5A70AC7F02000078001A3CA6@suse.com>
2018-01-30 17:33 ` Juergen Gross
2018-01-31 10:40 ` Jan Beulich
2018-01-22 12:50 ` [PATCH RFC v2 00/12] xen/x86: use per-vcpu stacks for 64 bit pv domains Jan Beulich
[not found] ` <5A65EC0A02000078001A1118@suse.com>
2018-01-22 14:18 ` Juergen Gross
2018-01-22 14:22 ` Jan Beulich
[not found] ` <5A6601D302000078001A1230@suse.com>
2018-01-22 14:38 ` Juergen Gross
2018-01-22 14:48 ` Jan Beulich
[not found] ` <5A6607DB02000078001A127B@suse.com>
2018-01-22 15:00 ` Juergen Gross
2018-01-22 16:51 ` Jan Beulich
2018-01-22 18:39 ` Andrew Cooper
2018-01-22 18:48 ` George Dunlap
2018-01-22 19:02 ` Andrew Cooper
2018-01-23 8:36 ` Jan Beulich
2018-01-23 11:23 ` Andrew Cooper
2018-01-23 11:06 ` George Dunlap
2018-01-23 6:34 ` Juergen Gross
2018-01-23 7:21 ` Juergen Gross
2018-01-23 8:53 ` Jan Beulich
[not found] ` <5A67061F02000078001A1669@suse.com>
2018-01-23 9:24 ` Juergen Gross
2018-01-23 9:31 ` Jan Beulich
[not found] ` <5A670F0E02000078001A16C9@suse.com>
2018-01-23 10:10 ` Juergen Gross
2018-01-23 11:45 ` Andrew Cooper
2018-01-23 13:31 ` Juergen Gross
2018-01-23 13:24 ` Dario Faggioli
2018-01-23 16:45 ` George Dunlap
2018-01-23 16:56 ` Juergen Gross
2018-01-23 17:33 ` George Dunlap
2018-01-24 7:37 ` Jan Beulich
[not found] ` <5A6624A602000078001A1375@suse.com>
2018-01-23 5:50 ` Juergen Gross
2018-01-23 8:40 ` Jan Beulich
[not found] ` <5A67030F02000078001A164B@suse.com>
2018-01-23 9:45 ` Juergen Gross
2018-01-22 21:45 ` Konrad Rzeszutek Wilk
2018-01-23 6:38 ` Juergen Gross
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180122123256.1431-13-jgross@suse.com \
--to=jgross@suse.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=dfaggioli@suse.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).