From: "Jan Beulich" Subject: [PATCH] x86/svm: adjust VM entry/exit code Date: Mon, 14 May 2007 17:40:59 +0200 Message-ID: <46489F2B.76E4.0078.0@novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Return-path: Content-Disposition: inline List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com List-Id: xen-devel@lists.xenproject.org Move saving of rAX into assembly code, to match its restoration. Simplify assembly code, at once reducing the delta between 32- and 64-bit variants. Eliminate save_svm_cpu_user_regs() - as on VMX all consumers are required to call hvm_store_cpu_guest_regs(). Signed-off-by: Jan Beulich Index: 2007-05-14/xen/arch/x86/hvm/svm/svm.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 2007-05-14.orig/xen/arch/x86/hvm/svm/svm.c 2007-05-14 14:28:19.0000000= 00 +0200 +++ 2007-05-14/xen/arch/x86/hvm/svm/svm.c 2007-05-14 14:33:08.0000000= 00 +0200 @@ -747,28 +747,10 @@ static void svm_init_hypercall_page(stru *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) =3D 0x0b0f; /* = ud2 */ } =20 -static void save_svm_cpu_user_regs(struct vcpu *v, struct cpu_user_regs = *ctxt) -{ - struct vmcb_struct *vmcb =3D v->arch.hvm_svm.vmcb; - - ctxt->eax =3D vmcb->rax; - ctxt->ss =3D vmcb->ss.sel; - ctxt->esp =3D vmcb->rsp; - ctxt->eflags =3D vmcb->rflags; - ctxt->cs =3D vmcb->cs.sel; - ctxt->eip =3D vmcb->rip; - =20 - ctxt->gs =3D vmcb->gs.sel; - ctxt->fs =3D vmcb->fs.sel; - ctxt->es =3D vmcb->es.sel; - ctxt->ds =3D vmcb->ds.sel; -} - static void svm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs = *regs) { struct vmcb_struct *vmcb =3D v->arch.hvm_svm.vmcb; =20 - vmcb->rax =3D regs->eax; vmcb->ss.sel =3D regs->ss; vmcb->rsp =3D regs->esp; =20 vmcb->rflags =3D regs->eflags | 2UL; @@ -1408,7 +1390,7 @@ static void svm_io_instruction(struct vc =20 /* Copy current guest state into io instruction state structure. */ memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES); - hvm_store_cpu_guest_regs(v, regs, NULL); + svm_store_cpu_guest_regs(v, regs, NULL); =20 info.bytes =3D vmcb->exitinfo1; =20 @@ -2236,7 +2218,6 @@ asmlinkage void svm_vmexit_handler(struc int inst_len, rc; =20 exit_reason =3D vmcb->exitcode; - save_svm_cpu_user_regs(v, regs); =20 HVMTRACE_2D(VMEXIT, v, vmcb->rip, exit_reason); =20 Index: 2007-05-14/xen/arch/x86/hvm/svm/x86_32/exits.S =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 2007-05-14.orig/xen/arch/x86/hvm/svm/x86_32/exits.S 2007-04-23 = 10:01:41.000000000 +0200 +++ 2007-05-14/xen/arch/x86/hvm/svm/x86_32/exits.S 2007-05-14 = 14:33:08.000000000 +0200 @@ -61,8 +61,11 @@ #define HVM_SAVE_ALL_NOSEGREGS \ pushl $HVM_MONITOR_EFLAGS; \ popf; \ - subl $(NR_SKIPPED_REGS*4), %esp; \ - pushl %eax; \ + /* \ + * Skip %eax, we need have vmcb address in there. \ + * Don't worry, EAX is saved during #VMEXIT. \ + */ \ + subl $4+(NR_SKIPPED_REGS*4), %esp; \ pushl %ebp; \ pushl %edi; \ pushl %esi; \ @@ -77,8 +80,11 @@ popl %esi; \ popl %edi; \ popl %ebp; \ - popl %eax; \ - addl $(NR_SKIPPED_REGS*4), %esp + /* \ + * Skip %eax, we need to have vmcb address in there. \ + * Don't worry, EAX is restored through the VMRUN instruction. \ + */ \ + addl $4+(NR_SKIPPED_REGS*4), %esp =20 #define VMRUN .byte 0x0F,0x01,0xD8 #define VMLOAD .byte 0x0F,0x01,0xDA @@ -88,63 +94,53 @@ =20 ENTRY(svm_asm_do_resume) GET_CURRENT(%ebx) - xorl %ecx,%ecx - notl %ecx +.Lresume: cli # tests must not race interrupts movl VCPU_processor(%ebx),%eax shl $IRQSTAT_shift,%eax - test %ecx,irq_stat(%eax,1) - jnz svm_process_softirqs + cmpl $0,irq_stat(%eax) + jne svm_process_softirqs call svm_intr_assist call svm_load_cr2 =20 CLGI =20 sti - GET_CURRENT(%ebx) movl VCPU_svm_vmcb(%ebx), %ecx - movl 24(%esp), %eax + movl UREGS_eax(%esp), %eax + movl VCPU_processor(%ebx), %edx movl %eax, VMCB_rax(%ecx) - movl VCPU_processor(%ebx), %eax - movl root_vmcb_pa(,%eax,8), %eax + movl root_vmcb_pa(,%edx,8), %eax VMSAVE =20 movl VCPU_svm_vmcb_pa(%ebx), %eax - popl %ebx - popl %ecx - popl %edx - popl %esi - popl %edi - popl %ebp - - /*=20 - * Skip %eax, we need to have vmcb address in there. - * Don't worry, EAX is restored through the VMRUN instruction. - */ - addl $4, %esp =20 - addl $(NR_SKIPPED_REGS*4), %esp + HVM_RESTORE_ALL_NOSEGREGS + VMLOAD VMRUN VMSAVE - /* eax is the only register we're allowed to touch here... */ =20 - GET_CURRENT(%eax) + HVM_SAVE_ALL_NOSEGREGS =20 - movl VCPU_processor(%eax), %eax - movl root_vmcb_pa(,%eax,8), %eax + GET_CURRENT(%ebx) + movl VCPU_processor(%ebx), %ecx + movl VCPU_svm_vmcb(%ebx), %edx + movl root_vmcb_pa(,%ecx,8), %eax VMLOAD + movl VMCB_rax(%edx), %eax =20 - HVM_SAVE_ALL_NOSEGREGS STGI .globl svm_stgi_label; svm_stgi_label: + + movl %eax, UREGS_eax(%esp) movl %esp,%eax push %eax call svm_vmexit_handler addl $4,%esp - jmp svm_asm_do_resume + jmp .Lresume =20 ALIGN svm_process_softirqs: sti =20 call do_softirq - jmp svm_asm_do_resume + jmp .Lresume Index: 2007-05-14/xen/arch/x86/hvm/svm/x86_64/exits.S =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 2007-05-14.orig/xen/arch/x86/hvm/svm/x86_64/exits.S 2007-04-23 = 10:01:41.000000000 +0200 +++ 2007-05-14/xen/arch/x86/hvm/svm/x86_64/exits.S 2007-05-14 = 14:33:08.000000000 +0200 @@ -85,7 +85,11 @@ popq %r10; \ popq %r9; \ popq %r8; \ - popq %rax; \ + /* \ + * Discard %rax, we need to have vmcb address in there. \ + * Don't worry, RAX is restored through the VMRUN instruction. \ + */ \ + addq $8, %rsp; \ popq %rcx; \ popq %rdx; \ popq %rsi; \ @@ -100,68 +104,54 @@ =20 ENTRY(svm_asm_do_resume) GET_CURRENT(%rbx) +.Lresume: cli # tests must not race interrupts movl VCPU_processor(%rbx),%eax shl $IRQSTAT_shift, %rax leaq irq_stat(%rip), %rdx - testl $~0, (%rdx, %rax, 1) - jnz svm_process_softirqs + cmpl $0, (%rdx, %rax) + jne svm_process_softirqs call svm_intr_assist call svm_load_cr2 =20 CLGI =20 sti - GET_CURRENT(%rbx) movq VCPU_svm_vmcb(%rbx), %rcx movq UREGS_rax(%rsp), %rax + movl VCPU_processor(%rbx), %edx movq %rax, VMCB_rax(%rcx) leaq root_vmcb_pa(%rip), %rax - movl VCPU_processor(%rbx), %ecx - movq (%rax,%rcx,8), %rax + movq (%rax,%rdx,8), %rax VMSAVE =20 movq VCPU_svm_vmcb_pa(%rbx), %rax - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %rbp - popq %rbx - popq %r11 - popq %r10 - popq %r9 - popq %r8 - /* - * Skip %rax, we need to have vmcb address in there. - * Don't worry, RAX is restored through the VMRUN instruction. - */ - addq $8, %rsp - popq %rcx - popq %rdx - popq %rsi - popq %rdi - addq $(NR_SKIPPED_REGS*8), %rsp + HVM_RESTORE_ALL_NOSEGREGS =20 VMLOAD VMRUN VMSAVE + HVM_SAVE_ALL_NOSEGREGS =20 GET_CURRENT(%rbx) - leaq root_vmcb_pa(%rip), %rax movl VCPU_processor(%rbx), %ecx + leaq root_vmcb_pa(%rip), %rax + movq VCPU_svm_vmcb(%rbx), %rdx movq (%rax,%rcx,8), %rax VMLOAD + movq VMCB_rax(%rdx), %rax =20 STGI .globl svm_stgi_label; svm_stgi_label: + + movq %rax, UREGS_rax(%rsp) movq %rsp,%rdi call svm_vmexit_handler - jmp svm_asm_do_resume + jmp .Lresume =20 ALIGN svm_process_softirqs: sti call do_softirq - jmp svm_asm_do_resume + jmp .Lresume