Skip to content

Commit 1136b3b

Browse files
author
Lai Jiangshan
committed
pvm: Remove MSR_PVM_SUPERVISOR_RSP and PVCS:rsp
When supervisor event delivering is changed to use PVCS instead of the current stack, and a bit is added in event_vector to protect the supervisor's access to the PVCS from async events reentrance, %rsp doesn't require to be supervisor RSP in the process and %rsp can be keept as the value before the event, so MSR_PVM_SUPERVISOR_RSP and PVCS:rsp are unneeded. Signed-off-by: Lai Jiangshan <jiangshan.ljs@antgroup.com>
1 parent ae378e6 commit 1136b3b

8 files changed

Lines changed: 22 additions & 60 deletions

File tree

arch/x86/entry/entry_64_pvm.S

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,29 @@
99

1010
/* Construct struct pt_regs on stack */
1111
.macro PUSH_IRET_FRAME_FROM_PVCS user:req
12+
movq %rsp, %r11
1213
.if \user == 1
14+
movq PER_CPU_VAR(pcpu_hot + X86_top_of_stack), %rsp
15+
1316
movl PER_CPU_VAR(pvm_vcpu_struct + PVCS_user_ss), %ecx
1417
andl $0xFFFF, %ecx
1518
pushq %rcx /* pt_regs->ss */
1619
.else
20+
andq $-16, %rsp
21+
22+
/*
23+
* Reserve a fixed-size area in the current stack during an
24+
* event from supervisor mode. This is for the int3 handler
25+
* to emulate a call instruction.
26+
*/
27+
subq $16, %rsp
28+
29+
/* TODO: check stack overflow */
30+
1731
pushq $__KERNEL_DS
1832
.endif
1933

20-
pushq PER_CPU_VAR(pvm_vcpu_struct + PVCS_rsp) /* pt_regs->sp */
34+
pushq %r11 /* pt_regs->sp */
2135
movl PER_CPU_VAR(pvm_vcpu_struct + PVCS_eflags), %ecx
2236
pushq %rcx /* pt_regs->flags */
2337

@@ -67,10 +81,10 @@
6781
movw %cx, PER_CPU_VAR(pvm_vcpu_struct + PVCS_user_cs)
6882
movq 3*8(%rsp), %rcx /* RFLAGS */
6983
movl %ecx, PER_CPU_VAR(pvm_vcpu_struct + PVCS_eflags)
70-
movq 4*8(%rsp), %rcx /* RSP */
71-
movq %rcx, PER_CPU_VAR(pvm_vcpu_struct + PVCS_rsp)
7284
movq 5*8(%rsp), %rcx /* SS */
7385
movw %cx, PER_CPU_VAR(pvm_vcpu_struct + PVCS_user_ss)
86+
87+
movq 4*8(%rsp), %rsp /* RSP */
7488
.endm
7589

7690
.code64
@@ -143,15 +157,8 @@ SYM_CODE_START(pvm_user_event_entry)
143157
PUSH_REGS_AND_HANDLE_EVENT handler=pvm_event
144158

145159
SYM_INNER_LABEL(pvm_restore_regs_and_return_to_usermode, SYM_L_GLOBAL)
160+
STACKLEAK_ERASE
146161
POP_REGS_AND_LOAD_IRET_FRAME_INTO_PVCS
147-
148-
/*
149-
* We are on the trampoline stack. All regs are live.
150-
* We can do future final exit work right here.
151-
*/
152-
STACKLEAK_ERASE_NOCLOBBER
153-
154-
addq $6*8, %rsp
155162
SYM_INNER_LABEL(pvm_retu_rip, SYM_L_GLOBAL)
156163
ANNOTATE_NOENDBR
157164
syscall
@@ -166,19 +173,9 @@ SYM_CODE_START(pvm_kernel_event_entry)
166173
UNWIND_HINT_ENTRY
167174
ENDBR
168175

169-
/*
170-
* Reserve a fixed-size area in the current stack during an event from
171-
* supervisor mode. This is for the int3 handler to emulate a call instruction.
172-
*/
173-
subq $16, %rsp
174-
175-
/* TODO: check stack overflow */
176-
177176
PUSH_IRET_FRAME_FROM_PVCS user=0
178177
PUSH_REGS_AND_HANDLE_EVENT handler=pvm_event
179178
POP_REGS_AND_LOAD_IRET_FRAME_INTO_PVCS
180-
181-
addq $(6*8+16), %rsp
182179
SYM_INNER_LABEL(pvm_rets_rip, SYM_L_GLOBAL)
183180
ANNOTATE_NOENDBR
184181
syscall
@@ -194,7 +191,6 @@ SYM_CODE_START_NOALIGN(pvm_early_kernel_event_entry)
194191
PUSH_REGS_AND_HANDLE_EVENT handler=pvm_early_event
195192
POP_REGS_AND_LOAD_IRET_FRAME_INTO_PVCS
196193
decl early_recursion_flag(%rip)
197-
addq $6*8, %rsp
198194
jmp pvm_rets_rip
199195
SYM_CODE_END(pvm_early_kernel_event_entry)
200196
.popsection

arch/x86/entry/entry_64_switcher.S

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -147,17 +147,13 @@ SYM_INNER_LABEL(entry_SYSCALL_64_switcher_safe_stack, SYM_L_GLOBAL)
147147
movq %rcx, PVCS_rip(%rdi)
148148
movq %rcx, PVCS_rcx(%rdi)
149149
movq %r11, PVCS_r11(%rdi)
150-
movq RSP-ORIG_RAX(%rsp), %rcx
151-
movq %rcx, PVCS_rsp(%rdi)
152150

153151
/* switch umod to smod (switch_flags & cr3) */
154152
xorb $SWITCH_FLAGS_MOD_TOGGLE, TSS_extra(switch_flags)
155153
movq TSS_extra(smod_cr3), %rcx
156154
movq %rcx, %cr3
157155

158156
/* load smod registers from TSS_extra to sp0 stack or %r11 */
159-
movq TSS_extra(smod_rsp), %rcx
160-
movq %rcx, RSP-ORIG_RAX(%rsp)
161157
movq TSS_extra(smod_entry), %rcx
162158
movq %rcx, RIP-ORIG_RAX(%rsp)
163159
movq TSS_extra(smod_gsbase), %r11
@@ -203,10 +199,6 @@ SYM_INNER_LABEL(entry_SYSRETQ_switcher_unsafe_stack, SYM_L_GLOBAL)
203199
cmpl $((__USER_DS << 16) | __USER_CS), PVCS_user_cs(%rdi)
204200
jne .L_switcher_return_to_hypervisor
205201

206-
/* Switcher and the PVM specification requires the smod RSP to be saved */
207-
movq RSP-ORIG_RAX(%rsp), %rcx
208-
movq %rcx, TSS_extra(smod_rsp)
209-
210202
/* switch smod to umod (switch_flags & cr3) */
211203
xorb $SWITCH_FLAGS_MOD_TOGGLE, TSS_extra(switch_flags)
212204
movq TSS_extra(umod_cr3), %rcx
@@ -220,9 +212,7 @@ SYM_INNER_LABEL(entry_SYSRETQ_switcher_unsafe_stack, SYM_L_GLOBAL)
220212
canonical_rcx
221213
wrgsbase %rcx
222214

223-
/* load sp, flags, ip to sp0 stack and cx, r11, rdi to registers */
224-
movq PVCS_rsp(%rdi), %rcx
225-
movq %rcx, RSP-ORIG_RAX(%rsp)
215+
/* load flags, ip to sp0 stack and cx, r11, rdi to registers */
226216
movl PVCS_eflags(%rdi), %r11d
227217
movq %r11, EFLAGS-ORIG_RAX(%rsp)
228218
movq PVCS_rip(%rdi), %rcx

arch/x86/include/asm/switcher.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ struct tss_extra {
105105
unsigned long retu_rip;
106106
unsigned long smod_entry;
107107
unsigned long smod_gsbase;
108-
unsigned long smod_rsp;
109108
} ____cacheline_aligned;
110109

111110
extern struct pt_regs *switcher_enter_guest(void);

arch/x86/include/uapi/asm/pvm_para.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#define MSR_PVM_LINEAR_ADDRESS_RANGE 0x4b564df0
3838
#define MSR_PVM_VCPU_STRUCT 0x4b564df1
3939
#define MSR_PVM_SWITCH_CR3 0x4b564df2
40-
#define MSR_PVM_SUPERVISOR_RSP 0x4b564df3
40+
// #define MSR_PVM_SUPERVISOR_RSP 0x4b564df3 // deprecated, FIXME: reordering when sending v2
4141
#define MSR_PVM_EVENT_ENTRY 0x4b564df4
4242
#define MSR_PVM_RETU_RIP 0x4b564df5
4343
#define MSR_PVM_RETS_RIP 0x4b564df6
@@ -136,14 +136,13 @@ struct pvm_vcpu_struct {
136136
u16 user_cs, user_ss;
137137
u16 event_errcode;
138138
u16 event_vector;
139-
u64 reserved2;
140139
u64 user_gsbase;
141140
u32 eflags;
142141
u32 pkru;
143142
u64 rip;
144-
u64 rsp;
145143
u64 rcx;
146144
u64 r11;
145+
u64 reserved1[2];
147146
};
148147

149148
#endif /* __ASSEMBLY__ */

arch/x86/kernel/asm-offsets_64.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ int main(void)
7373
ENTRY(retu_rip);
7474
ENTRY(smod_entry);
7575
ENTRY(smod_gsbase);
76-
ENTRY(smod_rsp);
7776
BLANK();
7877
#undef ENTRY
7978

@@ -84,7 +83,6 @@ int main(void)
8483
ENTRY(user_cs);
8584
ENTRY(user_ss);
8685
ENTRY(user_gsbase);
87-
ENTRY(rsp);
8886
ENTRY(eflags);
8987
ENTRY(rip);
9088
ENTRY(rcx);

arch/x86/kvm/pvm/pvm.c

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,6 @@ static inline void switch_to_smod(struct kvm_vcpu *vcpu)
342342
swap(pvm->msr_switch_cr3, vcpu->arch.cr3);
343343

344344
pvm_write_guest_gs_base(pvm, pvm->msr_kernel_gs_base);
345-
kvm_rsp_write(vcpu, pvm->msr_supervisor_rsp);
346345

347346
pvm->hw_cs = __USER_CS;
348347
pvm->hw_ss = __USER_DS;
@@ -352,8 +351,6 @@ static inline void switch_to_umod(struct kvm_vcpu *vcpu)
352351
{
353352
struct vcpu_pvm *pvm = to_pvm(vcpu);
354353

355-
pvm->msr_supervisor_rsp = kvm_rsp_read(vcpu);
356-
357354
pvm_switch_flags_toggle_mod(pvm);
358355
kvm_mmu_new_pgd(vcpu, pvm->msr_switch_cr3);
359356
swap(pvm->msr_switch_cr3, vcpu->arch.cr3);
@@ -1101,9 +1098,6 @@ static int pvm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
11011098
case MSR_PVM_VCPU_STRUCT:
11021099
msr_info->data = pvm->msr_vcpu_struct;
11031100
break;
1104-
case MSR_PVM_SUPERVISOR_RSP:
1105-
msr_info->data = pvm->msr_supervisor_rsp;
1106-
break;
11071101
case MSR_PVM_EVENT_ENTRY:
11081102
msr_info->data = pvm->msr_event_entry;
11091103
break;
@@ -1251,9 +1245,6 @@ static int pvm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
12511245
kvm_make_request(KVM_REQ_GPC_REFRESH, vcpu);
12521246
}
12531247
break;
1254-
case MSR_PVM_SUPERVISOR_RSP:
1255-
pvm->msr_supervisor_rsp = msr_info->data;
1256-
break;
12571248
case MSR_PVM_EVENT_ENTRY:
12581249
if (is_noncanonical_address(data, vcpu) ||
12591250
is_noncanonical_address(data + 256, vcpu) ||
@@ -1565,7 +1556,6 @@ static int __do_pvm_event(struct kvm_vcpu *vcpu, bool user, int vector,
15651556
bool has_err_code, u64 err_code)
15661557
{
15671558
struct vcpu_pvm *pvm = to_pvm(vcpu);
1568-
unsigned long rsp = kvm_rsp_read(vcpu);
15691559
unsigned long entry;
15701560
struct pvm_vcpu_struct *pvcs;
15711561

@@ -1622,7 +1612,6 @@ static int __do_pvm_event(struct kvm_vcpu *vcpu, bool user, int vector,
16221612

16231613
pvcs->eflags = kvm_get_rflags(vcpu);
16241614
pvcs->rip = kvm_rip_read(vcpu);
1625-
pvcs->rsp = rsp;
16261615
pvcs->rcx = kvm_rcx_read(vcpu);
16271616
pvcs->r11 = kvm_r11_read(vcpu);
16281617

@@ -1643,8 +1632,6 @@ static int __do_pvm_event(struct kvm_vcpu *vcpu, bool user, int vector,
16431632

16441633
if (user)
16451634
switch_to_smod(vcpu);
1646-
else
1647-
kvm_rsp_write(vcpu, rsp & ~15UL);
16481635

16491636
if (vector == PVM_SYSCALL_VECTOR)
16501637
entry = pvm->msr_lstar;
@@ -1839,7 +1826,6 @@ static int handle_synthetic_instruction_return(struct kvm_vcpu *vcpu, bool user)
18391826
pvcs->event_vector = 0;
18401827

18411828
kvm_rip_write(vcpu, pvcs->rip);
1842-
kvm_rsp_write(vcpu, pvcs->rsp);
18431829
kvm_rcx_write(vcpu, pvcs->rcx);
18441830
kvm_r11_write(vcpu, pvcs->r11);
18451831
rflags = pvcs->eflags;
@@ -2656,18 +2642,15 @@ static noinstr void pvm_vcpu_run_noinstr(struct kvm_vcpu *vcpu)
26562642
tss_ex->retu_rip = pvm->msr_retu_rip_plus2;
26572643
tss_ex->smod_entry = pvm->msr_lstar;
26582644
tss_ex->smod_gsbase = pvm->msr_kernel_gs_base;
2659-
tss_ex->smod_rsp = pvm->msr_supervisor_rsp;
26602645

26612646
if (unlikely(pvm->guest_dr7 & DR7_BP_EN_MASK))
26622647
set_debugreg(pvm_eff_dr7(vcpu), 7);
26632648

26642649
// Call into switcher and enter guest.
26652650
ret_regs = switcher_enter_guest();
26662651

2667-
// Get the resulted mode and PVM MSRs which might be changed
2668-
// when direct switching.
2652+
// Get the resulted mode
26692653
pvm->switch_flags = tss_ex->switch_flags;
2670-
pvm->msr_supervisor_rsp = tss_ex->smod_rsp;
26712654

26722655
// Get the guest registers from the host sp0 stack.
26732656
save_regs(vcpu, ret_regs);
@@ -2901,7 +2884,6 @@ static void pvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
29012884
memset(&pvm->tls_array[0], 0, sizeof(pvm->tls_array));
29022885

29032886
pvm->msr_vcpu_struct = 0;
2904-
pvm->msr_supervisor_rsp = 0;
29052887
pvm->msr_event_entry = 0;
29062888
pvm->msr_retu_rip_plus2 = 0;
29072889
pvm->msr_rets_rip_plus2 = 0;

arch/x86/kvm/pvm/pvm.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ struct vcpu_pvm {
134134

135135
// PVM paravirt MSRs
136136
unsigned long msr_vcpu_struct;
137-
unsigned long msr_supervisor_rsp;
138137
unsigned long msr_event_entry;
139138
unsigned long msr_retu_rip_plus2;
140139
unsigned long msr_rets_rip_plus2;

arch/x86/kvm/x86.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1529,7 +1529,6 @@ static const u32 emulated_msrs_all[] = {
15291529
MSR_PVM_LINEAR_ADDRESS_RANGE,
15301530
MSR_PVM_VCPU_STRUCT,
15311531
MSR_PVM_SWITCH_CR3,
1532-
MSR_PVM_SUPERVISOR_RSP,
15331532
MSR_PVM_EVENT_ENTRY,
15341533
MSR_PVM_RETU_RIP,
15351534
MSR_PVM_RETS_RIP,

0 commit comments

Comments
 (0)