[PATCH RFC 0/5] Eliminate double-copying of FP/VMX/VSX state

2013-08-07 Thread Paul Mackerras
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

2013-08-07 Thread Paul Mackerras
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

2013-08-07 Thread Paul Mackerras
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

2013-08-07 Thread Paul Mackerras
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

2013-08-07 Thread Paul Mackerras
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()

2013-08-07 Thread Paul Mackerras
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()

2013-08-07 Thread Bhushan Bharat-R65777


 -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

2013-08-07 Thread Caraman Mihai Claudiu-B02008
 -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

2013-08-07 Thread Bharat Bhushan
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

2013-08-07 Thread Bharat Bhushan
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