[PATCH RFC 0/5] Eliminate double-copying of FP/VMX/VSX state
At present, PR KVM and BookE KVM does multiple copies of FP and related state because of the way that they use the arrays in the thread_struct as an intermediate staging post for the state. They do this so that they can use the existing system functions for loading and saving state, and so that they can keep guest state in the CPU registers while executing general kernel code. This patch series reorganizes things so that KVM and the main kernel use the same representation for FP/VMX/VSX state, and so that guest state can be loaded/save directly from/to the vcpu struct instead of having to go via the thread_struct. This simplifies things and should be a little faster. This series is against Alex Graf's kvm-ppc-queue branch plus my recent series of 23 patches to make PR and HV KVM coexist. Paul. -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC 5/5] KVM: PPC: Book3S: Load/save FP/VMX/VSX state directly to/from vcpu struct
Now that we have the vcpu floating-point and vector state stored in the same type of struct as the main kernel uses, we can load that state directly from the vcpu struct instead of having extra copies to/from the thread_struct. Similarly, when the guest state needs to be saved, we can have it saved it directly to the vcpu struct by setting the current-thread.fp_save_area and current-thread.vr_save_area pointers. That also means that we don't need to back up and restore userspace's FP/vector state. This all makes the code simpler and faster. Note that it's not necessary to save or modify current-thread.fpexc_mode, since nothing in KVM uses or is affected by its value. Nor is it necessary to touch used_vr or used_vsr. Signed-off-by: Paul Mackerras pau...@samba.org --- arch/powerpc/kvm/book3s_pr.c | 72 ++-- arch/powerpc/kvm/booke.c | 16 -- arch/powerpc/kvm/booke.h | 4 ++- 3 files changed, 19 insertions(+), 73 deletions(-) diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index fccbadf..df7d0ac 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -558,16 +558,16 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr) * both the traditional FP registers and the added VSX * registers into thread.fp_state.fpr[]. */ - if (current-thread.regs-msr MSR_FP) + if (t-regs-msr MSR_FP) giveup_fpu(current); - vcpu-arch.fp = t-fp_state; + t-fp_save_area = NULL; } #ifdef CONFIG_ALTIVEC if (msr MSR_VEC) { if (current-thread.regs-msr MSR_VEC) giveup_altivec(current); - vcpu-arch.vr = t-vr_state; + t-vr_save_area = NULL; } #endif @@ -652,22 +652,20 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr, #endif if (msr MSR_FP) { - t-fp_state = vcpu-arch.fp; - t-fpexc_mode = 0; enable_kernel_fp(); - load_fp_state(t-fp_state); + load_fp_state(vcpu-arch.fp); + t-fp_save_area = vcpu-arch.fp; } if (msr MSR_VEC) { #ifdef CONFIG_ALTIVEC - t-vr_state = vcpu-arch.vr; - t-vrsave = -1; enable_kernel_altivec(); - load_vr_state(t-vr_state); + load_vr_state(vcpu-arch.vr); + t-vr_save_area = vcpu-arch.vr; #endif } - current-thread.regs-msr |= msr; + t-regs-msr |= msr; vcpu-arch.guest_owned_ext |= msr; kvmppc_recalc_shadow_msr(vcpu); @@ -688,11 +686,11 @@ static void kvmppc_handle_lost_ext(struct kvm_vcpu *vcpu) if (lost_ext MSR_FP) { enable_kernel_fp(); - load_fp_state(current-thread.fp_state); + load_fp_state(vcpu-arch.fp); } if (lost_ext MSR_VEC) { enable_kernel_altivec(); - load_vr_state(current-thread.vr_state); + load_vr_state(vcpu-arch.vr); } current-thread.regs-msr |= lost_ext; } @@ -1249,17 +1247,9 @@ static void enable_relon_interrupts(struct kvm *kvm) int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) { int ret; - struct thread_fp_state fp; - int fpexc_mode; #ifdef CONFIG_ALTIVEC - struct thread_vr_state vr; unsigned long uninitialized_var(vrsave); - int used_vr; #endif -#ifdef CONFIG_VSX - int used_vsr; -#endif - ulong ext_msr; /* Check if we can run the vcpu at all */ if (!vcpu-arch.sane) { @@ -1284,33 +1274,22 @@ int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) if (!vcpu-kvm-arch.relon_disabled) disable_relon_interrupts(vcpu-kvm); - /* Save FPU state in stack */ + /* Save FPU state in thread_struct */ if (current-thread.regs-msr MSR_FP) giveup_fpu(current); - fp = current-thread.fp_state; - fpexc_mode = current-thread.fpexc_mode; #ifdef CONFIG_ALTIVEC - /* Save Altivec state in stack */ - used_vr = current-thread.used_vr; - if (used_vr) { - if (current-thread.regs-msr MSR_VEC) - giveup_altivec(current); - vr = current-thread.vr_state; - vrsave = current-thread.vrsave; - } + /* Save Altivec state in thread_struct */ + if (current-thread.regs-msr MSR_VEC) + giveup_altivec(current); #endif #ifdef CONFIG_VSX - /* Save VSX state in stack */ - used_vsr = current-thread.used_vsr; - if (used_vsr (current-thread.regs-msr MSR_VSX)) + /* Save VSX state in thread_struct */ + if (current-thread.regs-msr MSR_VSX) __giveup_vsx(current); #endif
[PATCH RFC 2/5] powerpc: Provide for giveup_fpu/altivec to save state in alternate location
This provides a facility which is intended for use by KVM, where the contents of the FP/VSX and VMX (Altivec) registers can be saved away to somewhere other than the thread_struct when kernel code wants to use floating point or VMX instructions. This is done by providing a pointer in the thread_struct to indicate where the state should be saved to. The giveup_fpu() and giveup_altivec() functions test these pointers and save state to the indicated location if they are non-NULL. Note that the MSR_FP/VEC bits in task-thread.regs-msr are still used to indicate whether the CPU register state is live, even when an alternate save location is being used. This also provides load_fp_state() and load_vr_state() functions, which load up FP/VSX and VMX state from memory into the CPU registers. Signed-off-by: Paul Mackerras pau...@samba.org --- arch/powerpc/include/asm/processor.h | 5 + arch/powerpc/kernel/asm-offsets.c| 2 ++ arch/powerpc/kernel/fpu.S| 15 ++- arch/powerpc/kernel/ppc_ksyms.c | 4 arch/powerpc/kernel/process.c| 7 +++ arch/powerpc/kernel/vector.S | 18 -- 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 68e676a..f5d78cb 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -212,6 +212,7 @@ struct thread_struct { #endif #endif struct thread_fp_state fp_state; + struct thread_fp_state *fp_save_area; int fpexc_mode; /* floating-point exception mode */ unsigned intalign_ctl; /* alignment handling control */ #ifdef CONFIG_PPC64 @@ -230,6 +231,7 @@ struct thread_struct { unsigned long trap_nr;/* last trap # on this thread */ #ifdef CONFIG_ALTIVEC struct thread_vr_state vr_state; + struct thread_vr_state *vr_save_area; unsigned long vrsave; int used_vr;/* set if process has used altivec */ #endif /* CONFIG_ALTIVEC */ @@ -355,6 +357,9 @@ extern int set_endian(struct task_struct *tsk, unsigned int val); extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr); extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val); +extern void load_fp_state(struct thread_fp_state *fp); +extern void load_vr_state(struct thread_vr_state *vr); + static inline unsigned int __unpack_fe01(unsigned long msr_bits) { return ((msr_bits MSR_FE0) 10) | ((msr_bits MSR_FE1) 8); diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 0235619..94a0002 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -90,9 +90,11 @@ int main(void) #endif DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode)); DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state)); + DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area)); DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr)); #ifdef CONFIG_ALTIVEC DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state)); + DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area)); DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave)); DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr)); DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr)); diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index 34b96e6..5697aed 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -81,6 +81,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */ /* + * Load state from memory into FP registers including FPSCR. + * Assumes the caller has enabled FP in the MSR. + */ +_GLOBAL(load_fp_state) + lfd fr0,FPSTATE_FPSCR(r3) + MTFSF_L(fr0) + REST_32FPVSRS(0, R4, R3) + blr + +/* * This task wants to use the FPU now. * On UP, disable FP for the task which had the FPU previously, * and save its floating-point registers in its thread_struct. @@ -172,9 +182,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) PPC_LCMPI 0,r3,0 beqlr- /* if no previous owner, done */ addir3,r3,THREAD/* want THREAD of task */ + PPC_LL r6,THREAD_FPSAVEAREA(r3) PPC_LL r5,PT_REGS(r3) - PPC_LCMPI 0,r5,0 + PPC_LCMPI 0,r6,0 + bne 2f addir6,r3,THREAD_FPSTATE +2: PPC_LCMPI 0,r5,0 SAVE_32FPVSRS(0, R4, R6) mffsfr0 stfdfr0,FPSTATE_FPSCR(r6) diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index c296665..030083e 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -97,8 +97,12 @@ EXPORT_SYMBOL(pci_dram_offset);
[PATCH RFC 1/5] powerpc: Put FP/VSX and VR state into structures
This creates new 'thread_fp_state' and 'thread_vr_state' structures to store FP/VSX state (including FPSCR) and Altivec/VSX state (including VSCR), and uses them in the thread_struct. In the thread_fp_state, the FPRs and VSRs are represented as u64 rather than double, since we rarely perform floating-point computations on the values, and this will enable the structures to be used in KVM code as well. Similarly FPSCR is now a u64 rather than a structure of two 32-bit values. This takes the offsets out of the macros such as SAVE_32FPRS, REST_32FPRS, etc. This enables the same macros to be used for normal and transactional state, enabling us to delete the transactional versions of the macros. This also removes the unused do_load_up_fpu and do_load_up_altivec, which were in fact buggy since they didn't create large enough stack frames to account for the fact that load_up_fpu and load_up_altivec are not designed to be called from C and assume that their caller's stack frame is an interrupt frame. Signed-off-by: Paul Mackerras pau...@samba.org --- Note that the removal of SAVE_VSRU, REST_VSRU etc. overlaps with a recent patch of Anton's removing the same things. arch/powerpc/include/asm/ppc_asm.h | 108 ++--- arch/powerpc/include/asm/processor.h | 40 ++-- arch/powerpc/include/asm/sfp-machine.h | 2 +- arch/powerpc/kernel/align.c| 6 +- arch/powerpc/kernel/asm-offsets.c | 25 +++- arch/powerpc/kernel/fpu.S | 59 -- arch/powerpc/kernel/process.c | 8 +-- arch/powerpc/kernel/ptrace.c | 49 +++ arch/powerpc/kernel/ptrace32.c | 11 ++-- arch/powerpc/kernel/signal_32.c| 72 +++--- arch/powerpc/kernel/signal_64.c| 29 - arch/powerpc/kernel/tm.S | 41 +++-- arch/powerpc/kernel/traps.c| 12 ++-- arch/powerpc/kernel/vecemu.c | 6 +- arch/powerpc/kernel/vector.S | 50 +-- arch/powerpc/kvm/book3s_pr.c | 36 +-- arch/powerpc/kvm/booke.c | 19 +++--- 17 files changed, 201 insertions(+), 372 deletions(-) diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 2f1b6c5..8d13b08 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -97,141 +97,45 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR) #define REST_8GPRS(n, base)REST_4GPRS(n, base); REST_4GPRS(n+4, base) #define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) -#define SAVE_FPR(n, base) stfdn,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) +#define SAVE_FPR(n, base) stfdn,8*TS_FPRWIDTH*(n)(base) #define SAVE_2FPRS(n, base)SAVE_FPR(n, base); SAVE_FPR(n+1, base) #define SAVE_4FPRS(n, base)SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base) #define SAVE_8FPRS(n, base)SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base) #define SAVE_16FPRS(n, base) SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base) #define SAVE_32FPRS(n, base) SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base) -#define REST_FPR(n, base) lfd n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base) +#define REST_FPR(n, base) lfd n,8*TS_FPRWIDTH*(n)(base) #define REST_2FPRS(n, base)REST_FPR(n, base); REST_FPR(n+1, base) #define REST_4FPRS(n, base)REST_2FPRS(n, base); REST_2FPRS(n+2, base) #define REST_8FPRS(n, base)REST_4FPRS(n, base); REST_4FPRS(n+4, base) #define REST_16FPRS(n, base) REST_8FPRS(n, base); REST_8FPRS(n+8, base) #define REST_32FPRS(n, base) REST_16FPRS(n, base); REST_16FPRS(n+16, base) -#define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); stvx n,base,b +#define SAVE_VR(n,b,base) li b,16*(n); stvx n,base,b #define SAVE_2VRS(n,b,base)SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) #define SAVE_4VRS(n,b,base)SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base) #define SAVE_8VRS(n,b,base)SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base) #define SAVE_16VRS(n,b,base) SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base) #define SAVE_32VRS(n,b,base) SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base) -#define REST_VR(n,b,base) li b,THREAD_VR0+(16*(n)); lvx n,base,b +#define REST_VR(n,b,base) li b,16*(n); lvx n,base,b #define REST_2VRS(n,b,base)REST_VR(n,b,base); REST_VR(n+1,b,base) #define REST_4VRS(n,b,base)REST_2VRS(n,b,base); REST_2VRS(n+2,b,base) #define REST_8VRS(n,b,base)REST_4VRS(n,b,base); REST_4VRS(n+4,b,base) #define REST_16VRS(n,b,base) REST_8VRS(n,b,base); REST_8VRS(n+8,b,base) #define REST_32VRS(n,b,base) REST_16VRS(n,b,base); REST_16VRS(n+16,b,base) -/* Save/restore FPRs, VRs and VSRs from their checkpointed backups in - * thread_struct: - */ -#define SAVE_FPR_TRANSACT(n, base) stfd n,THREAD_TRANSACT_FPR0+\ - 8*TS_FPRWIDTH*(n)(base) -#define SAVE_2FPRS_TRANSACT(n, base) SAVE_FPR_TRANSACT(n, base); \ -
[PATCH RFC 4/5] KVM: PPC: Store FP/VSX/VMX state in thread_fp/vr_state structures
This uses struct thread_fp_state and struct thread_vr_state to store the floating-point, VMX/Altivec and VSX state, rather than flat arrays. This makes transferring the state to/from the thread_struct simpler and allows us to unify the get/set_one_reg implementations for the VSX registers. Signed-off-by: Paul Mackerras pau...@samba.org --- arch/powerpc/include/asm/kvm_host.h | 12 +-- arch/powerpc/kernel/asm-offsets.c| 11 +- arch/powerpc/kvm/book3s.c| 38 +-- arch/powerpc/kvm/book3s_hv.c | 42 arch/powerpc/kvm/book3s_hv_rmhandlers.S | 4 +- arch/powerpc/kvm/book3s_paired_singles.c | 169 +++ arch/powerpc/kvm/book3s_pr.c | 63 +--- arch/powerpc/kvm/booke.c | 8 +- arch/powerpc/kvm/powerpc.c | 4 +- 9 files changed, 131 insertions(+), 220 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 52c7b80..c1d3675 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -427,8 +427,7 @@ struct kvm_vcpu_arch { ulong gpr[32]; - u64 fpr[32]; - u64 fpscr; + struct thread_fp_state fp; #ifdef CONFIG_SPE ulong evr[32]; @@ -437,12 +436,7 @@ struct kvm_vcpu_arch { u64 acc; #endif #ifdef CONFIG_ALTIVEC - vector128 vr[32]; - vector128 vscr; -#endif - -#ifdef CONFIG_VSX - u64 vsr[64]; + struct thread_vr_state vr; #endif #ifdef CONFIG_KVM_BOOKE_HV @@ -630,6 +624,8 @@ struct kvm_vcpu_arch { #endif }; +#define VCPU_FPR(vcpu, i) (vcpu)-arch.fp.fpr[i][TS_FPROFFSET] + /* Values for vcpu-arch.state */ #define KVMPPC_VCPU_NOTREADY 0 #define KVMPPC_VCPU_RUNNABLE 1 diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 94a0002..6c5a2d3 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -422,14 +422,11 @@ int main(void) DEFINE(VCPU_GUEST_PID, offsetof(struct kvm_vcpu, arch.pid)); DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr)); DEFINE(VCPU_VRSAVE, offsetof(struct kvm_vcpu, arch.vrsave)); - DEFINE(VCPU_FPRS, offsetof(struct kvm_vcpu, arch.fpr)); - DEFINE(VCPU_FPSCR, offsetof(struct kvm_vcpu, arch.fpscr)); + DEFINE(VCPU_FPRS, offsetof(struct kvm_vcpu, arch.fp.fpr)); + DEFINE(VCPU_FPSCR, offsetof(struct kvm_vcpu, arch.fp.fpscr)); #ifdef CONFIG_ALTIVEC - DEFINE(VCPU_VRS, offsetof(struct kvm_vcpu, arch.vr)); - DEFINE(VCPU_VSCR, offsetof(struct kvm_vcpu, arch.vscr)); -#endif -#ifdef CONFIG_VSX - DEFINE(VCPU_VSRS, offsetof(struct kvm_vcpu, arch.vsr)); + DEFINE(VCPU_VRS, offsetof(struct kvm_vcpu, arch.vr.vr)); + DEFINE(VCPU_VSCR, offsetof(struct kvm_vcpu, arch.vr.vscr)); #endif DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer)); DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr)); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index f0896b4..2262117 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -582,10 +582,10 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) break; case KVM_REG_PPC_FPR0 ... KVM_REG_PPC_FPR31: i = reg-id - KVM_REG_PPC_FPR0; - val = get_reg_val(reg-id, vcpu-arch.fpr[i]); + val = get_reg_val(reg-id, VCPU_FPR(vcpu, i)); break; case KVM_REG_PPC_FPSCR: - val = get_reg_val(reg-id, vcpu-arch.fpscr); + val = get_reg_val(reg-id, vcpu-arch.fp.fpscr); break; #ifdef CONFIG_ALTIVEC case KVM_REG_PPC_VR0 ... KVM_REG_PPC_VR31: @@ -593,16 +593,27 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) r = -ENXIO; break; } - val.vval = vcpu-arch.vr[reg-id - KVM_REG_PPC_VR0]; + val.vval = vcpu-arch.vr.vr[reg-id - KVM_REG_PPC_VR0]; break; case KVM_REG_PPC_VSCR: if (!cpu_has_feature(CPU_FTR_ALTIVEC)) { r = -ENXIO; break; } - val = get_reg_val(reg-id, vcpu-arch.vscr.u[3]); + val = get_reg_val(reg-id, vcpu-arch.vr.vscr.u[3]); break; #endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_VSX + case KVM_REG_PPC_VSR0 ... KVM_REG_PPC_VSR31: + if (cpu_has_feature(CPU_FTR_VSX)) { + long int i = reg-id - KVM_REG_PPC_VSR0; + val.vsxval[0] = vcpu-arch.fp.fpr[i][0]; +
Re: [PATCH 21/23] KVM: PPC: Book3S PR: Use mmu_notifier_retry() in kvmppc_mmu_map_page()
On Wed, Aug 07, 2013 at 05:17:29AM +, Bhushan Bharat-R65777 wrote: Pauls, I am trying to understand the flow; does retry mean that we do not create the mapping and return to guest, which will fault again and then we will retry? Yes, and you do put_page or kvm_release_pfn_clean for any page that you got. Paul. -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 21/23] KVM: PPC: Book3S PR: Use mmu_notifier_retry() in kvmppc_mmu_map_page()
-Original Message- From: Paul Mackerras [mailto:pau...@samba.org] Sent: Wednesday, August 07, 2013 1:58 PM To: Bhushan Bharat-R65777 Cc: Alexander Graf; Benjamin Herrenschmidt; kvm-ppc@vger.kernel.org; k...@vger.kernel.org Subject: Re: [PATCH 21/23] KVM: PPC: Book3S PR: Use mmu_notifier_retry() in kvmppc_mmu_map_page() On Wed, Aug 07, 2013 at 05:17:29AM +, Bhushan Bharat-R65777 wrote: Pauls, I am trying to understand the flow; does retry mean that we do not create the mapping and return to guest, which will fault again and then we will retry? Yes, and you do put_page or kvm_release_pfn_clean for any page that you got. Ok, but what is the value to return back to guest when we know it is again going to generate fault. Cannot we retry within KVM? Thanks -Bharat Paul. -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH RFC 0/5] Eliminate double-copying of FP/VMX/VSX state
-Original Message- From: kvm-ow...@vger.kernel.org [mailto:kvm-ow...@vger.kernel.org] On Behalf Of Paul Mackerras Sent: Wednesday, August 07, 2013 9:52 AM To: Alexander Graf; Benjamin Herrenschmidt Cc: kvm-ppc@vger.kernel.org; k...@vger.kernel.org Subject: [PATCH RFC 0/5] Eliminate double-copying of FP/VMX/VSX state At present, PR KVM and BookE KVM does multiple copies of FP and related state because of the way that they use the arrays in the thread_struct as an intermediate staging post for the state. They do this so that they can use the existing system functions for loading and saving state, and so that they can keep guest state in the CPU registers while executing general kernel code. This patch series reorganizes things so that KVM and the main kernel use the same representation for FP/VMX/VSX state, and so that guest state can be loaded/save directly from/to the vcpu struct instead of having to go via the thread_struct. This simplifies things and should be a little faster. This series is against Alex Graf's kvm-ppc-queue branch plus my recent series of 23 patches to make PR and HV KVM coexist. Nice work Paul! What do you suggest for KVM BookE AltiVec v2 patchset, should I wait for this RFC or should I go ahead with the version based on the existing infrastructure? -Mike -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] kvm: ppc: booke: check range page invalidation progress on page setup
When the MM code is invalidating a range of pages, it calls the KVM kvm_mmu_notifier_invalidate_range_start() notifier function, which calls kvm_unmap_hva_range(), which arranges to flush all the TLBs for guest pages. However, the Linux PTEs for the range being flushed are still valid at that point. We are not supposed to establish any new references to pages in the range until the ...range_end() notifier gets called. The PPC-specific KVM code doesn't get any explicit notification of that; instead, we are supposed to use mmu_notifier_retry() to test whether we are or have been inside a range flush notifier pair while we have been referencing a page. This patch calls the mmu_notifier_retry() while mapping the guest page to ensure we are not referencing a page when in range invalidation. This call is inside a region locked with kvm-mmu_lock, which is the same lock that is called by the KVM MMU notifier functions, thus ensuring that no new notification can proceed while we are in the locked region. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/kvm/e500_mmu_host.c | 19 +-- 1 files changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index ff6dd66..ae4eaf6 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c @@ -329,8 +329,14 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, int tsize = BOOK3E_PAGESZ_4K; unsigned long tsize_pages = 0; pte_t *ptep; - int wimg = 0; + int wimg = 0, ret = 0; pgd_t *pgdir; + unsigned long mmu_seq; + struct kvm *kvm = vcpu_e500-vcpu.kvm; + + /* used to check for invalidations in progress */ + mmu_seq = kvm-mmu_notifier_seq; + smp_rmb(); /* * Translate guest physical to true physical, acquiring @@ -458,6 +464,13 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, (long)gfn, pfn); return -EINVAL; } + + spin_lock(kvm-mmu_lock); + if (mmu_notifier_retry(kvm, mmu_seq)) { + ret = -EAGAIN; + goto out; + } + kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg); kvmppc_e500_setup_stlbe(vcpu_e500-vcpu, gtlbe, tsize, @@ -466,10 +479,12 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, /* Clear i-cache for new pages */ kvmppc_mmu_flush_icache(pfn); +out: + spin_unlock(kvm-mmu_lock); /* Drop refcount on page, so that mmu notifiers can clear it */ kvm_release_pfn_clean(pfn); - return 0; + return ret; } /* XXX only map the one-one case, for now use TLB0 */ -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] kvm: powerpc: mark page accessed when mapping a guest page
Mark the guest page as accessed so that there is likely less chances of this page getting swap-out. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/kvm/e500_mmu_host.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index 001a2b0..ff6dd66 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c @@ -246,6 +246,9 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, /* Use guest supplied MAS2_G and MAS2_E */ ref-flags |= (gtlbe-mas2 MAS2_ATTRIB_MASK) | wimg; + /* Mark the page accessed */ + kvm_set_pfn_accessed(pfn); + if (tlbe_is_writable(gtlbe)) kvm_set_pfn_dirty(pfn); } -- 1.7.0.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html