On 01/12/15 15:29, Christoffer Dall wrote: > On Fri, Nov 27, 2015 at 06:50:03PM +0000, Marc Zyngier wrote: >> Contrary to the previous patch, the guest entry is fairly different >> from its assembly counterpart, mostly because it is only concerned >> with saving/restoring the GP registers, and nothing else. >> >> Signed-off-by: Marc Zyngier <marc.zyng...@arm.com> >> --- >> arch/arm64/kvm/hyp/Makefile | 1 + >> arch/arm64/kvm/hyp/entry.S | 155 >> ++++++++++++++++++++++++++++++++++++++++++++ >> arch/arm64/kvm/hyp/hyp.h | 2 + >> 3 files changed, 158 insertions(+) >> create mode 100644 arch/arm64/kvm/hyp/entry.S >> >> diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile >> index ec14cac..1e1ff06 100644 >> --- a/arch/arm64/kvm/hyp/Makefile >> +++ b/arch/arm64/kvm/hyp/Makefile >> @@ -7,3 +7,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o >> obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o >> obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o >> obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o >> +obj-$(CONFIG_KVM_ARM_HOST) += entry.o >> diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S >> new file mode 100644 >> index 0000000..2c4449a >> --- /dev/null >> +++ b/arch/arm64/kvm/hyp/entry.S >> @@ -0,0 +1,155 @@ >> +/* >> + * Copyright (C) 2015 - ARM Ltd >> + * Author: Marc Zyngier <marc.zyng...@arm.com> >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + * >> + * You should have received a copy of the GNU General Public License >> + * along with this program. If not, see <http://www.gnu.org/licenses/>. >> + */ >> + >> +#include <linux/linkage.h> >> + >> +#include <asm/asm-offsets.h> >> +#include <asm/assembler.h> >> +#include <asm/fpsimdmacros.h> >> +#include <asm/kvm.h> >> +#include <asm/kvm_arm.h> >> +#include <asm/kvm_asm.h> >> +#include <asm/kvm_mmu.h> >> + >> +#define CPU_GP_REG_OFFSET(x) (CPU_GP_REGS + x) >> +#define CPU_XREG_OFFSET(x) CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x) >> + >> + .text >> + .pushsection .hyp.text, "ax" >> + >> +.macro save_common_regs ctxt >> + stp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)] >> + stp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)] >> + stp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)] >> + stp x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)] >> + stp x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)] >> + stp x29, lr, [\ctxt, #CPU_XREG_OFFSET(29)] >> +.endm >> + >> +.macro restore_common_regs ctxt >> + ldp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)] >> + ldp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)] >> + ldp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)] >> + ldp x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)] >> + ldp x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)] >> + ldp x29, lr, [\ctxt, #CPU_XREG_OFFSET(29)] >> +.endm >> + >> +.macro save_host_regs reg >> + save_common_regs \reg >> +.endm >> + >> +.macro restore_host_regs reg >> + restore_common_regs \reg >> +.endm >> + >> +.macro save_guest_regs >> + // x0 is the vcpu address >> + // x1 is the return code, do not corrupt! >> + // x2 is the cpu context > > this is confusing because the caller says x2 is free, so are these the > inputs or invariants preserved in the function, or? > > note that you'll avoid this kind of confusion by inlining this stuff in > __guest_exit.
Indeed. I might just do that. >> + // x3 is a tmp register >> + // Guest's x0-x3 are on the stack >> + >> + add x2, x0, #VCPU_CONTEXT >> + >> + // Compute base to save registers > > misleading comment? Of course. Isn't that the very purpose of a comment? I'm confused... ;-) >> + stp x4, x5, [x2, #CPU_XREG_OFFSET(4)] >> + stp x6, x7, [x2, #CPU_XREG_OFFSET(6)] >> + stp x8, x9, [x2, #CPU_XREG_OFFSET(8)] >> + stp x10, x11, [x2, #CPU_XREG_OFFSET(10)] >> + stp x12, x13, [x2, #CPU_XREG_OFFSET(12)] >> + stp x14, x15, [x2, #CPU_XREG_OFFSET(14)] >> + stp x16, x17, [x2, #CPU_XREG_OFFSET(16)] >> + str x18, [x2, #CPU_XREG_OFFSET(18)] >> + >> + pop x6, x7 // x2, x3 >> + pop x4, x5 // x0, x1 > > hard to review when I haven't seen the code that calls this, but I'll > assume we store things in register order on the stack. Indeed. I've basically lifted that code from the previous version, so some things may have stuck... >> + >> + stp x4, x5, [x2, #CPU_XREG_OFFSET(0)] >> + stp x6, x7, [x2, #CPU_XREG_OFFSET(2)] >> + >> + save_common_regs x2 >> +.endm >> + >> +.macro restore_guest_regs >> + // Assume vcpu in x0, clobbers everything else > > nit: clobbers everything (x0 gets nuked too) > >> + >> + add x2, x0, #VCPU_CONTEXT >> + >> + // Prepare x0-x3 for later restore >> + ldp x4, x5, [x2, #CPU_XREG_OFFSET(0)] >> + ldp x6, x7, [x2, #CPU_XREG_OFFSET(2)] >> + push x4, x5 // Push x0-x3 on the stack >> + push x6, x7 > > why do you need x2 and x3 later? can't you just make do with x0 and x1 > and move the cpu context pointer to x1 ? Maybe I can optimize this a bit indeed. >> + >> + // x4-x18 >> + ldp x4, x5, [x2, #CPU_XREG_OFFSET(4)] >> + ldp x6, x7, [x2, #CPU_XREG_OFFSET(6)] >> + ldp x8, x9, [x2, #CPU_XREG_OFFSET(8)] >> + ldp x10, x11, [x2, #CPU_XREG_OFFSET(10)] >> + ldp x12, x13, [x2, #CPU_XREG_OFFSET(12)] >> + ldp x14, x15, [x2, #CPU_XREG_OFFSET(14)] >> + ldp x16, x17, [x2, #CPU_XREG_OFFSET(16)] >> + ldr x18, [x2, #CPU_XREG_OFFSET(18)] >> + >> + // x19-x29, lr >> + restore_common_regs x2 >> + >> + // Last bits of the 64bit state >> + pop x2, x3 >> + pop x0, x1 >> + >> + // Do not touch any register after this! >> +.endm >> + >> +/* >> + * u64 __guest_enter(struct kvm_vcpu *vcpu, >> + * struct kvm_cpu_context *host_ctxt); >> + */ >> +ENTRY(__guest_enter) >> + // x0: vcpu >> + // x1: host_ctxt >> + // x2, x3: parameter registers >> + // x4-x18: clobbered by macros >> + >> + save_host_regs x1 >> + >> + // Preserve vcpu & host_ctxt for use at exit time >> + stp x0, x1, [sp, #-16]! > > why is this not a simple push? This *is* a simple push. Catalin has been threatening me to remove push/pop from the convenience macros, and I've started toying with the idea. Maybe I'll should bite the bullet and convert them all. > >> + >> + restore_guest_regs > > do we ever reuse any of the above macros? If not, perhaps it's more > clear to simply inline them here? Yeah, that's clearly better. >> + eret >> +ENDPROC(__guest_enter) >> + >> +ENTRY(__guest_exit) >> + // x0: vcpu >> + // x1: return code >> + // x2-x3: free >> + // x4-x29,lr: vcpu regs >> + // vcpu x0-x3 on the stack >> + save_guest_regs >> + >> + // Restore vcpu & host_ctxt from the stack >> + // (preserving return code in x1) >> + ldp x0, x2, [sp], #16 > > why is this not a regular pop? See above. >> + restore_host_regs x2 >> + >> + mov x0, x1 >> + ret >> +ENDPROC(__guest_exit) >> + >> + /* Insert fault handling here */ >> diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h >> index 2581232..7ac8e11 100644 >> --- a/arch/arm64/kvm/hyp/hyp.h >> +++ b/arch/arm64/kvm/hyp/hyp.h >> @@ -50,5 +50,7 @@ void __debug_restore_state(struct kvm_vcpu *vcpu, >> void __debug_cond_save_host_state(struct kvm_vcpu *vcpu); >> void __debug_cond_restore_host_state(struct kvm_vcpu *vcpu); >> >> +u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt); >> + >> #endif /* __ARM64_KVM_HYP_H__ */ >> >> -- >> 2.1.4 >> > > Thanks, > -Christoffer > Thanks, M. -- Jazz is not dead. It just smells funny... -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html