Re: [PATCH v1] kvm: Make vcpu->requests as 64 bit bitmap

2015-12-24 Thread James Hogan
Hi Andrey,

On Thu, Dec 24, 2015 at 12:30:26PM +0300, Andrey Smetanin wrote:
> Currently on x86 arch we has already 32 requests defined
> so the newer request bits can't be placed inside
> vcpu->requests(unsigned long) inside x86 32 bit system.
> But we are going to add a new request in x86 arch
> for Hyper-V tsc page support.
> 
> To solve the problem the patch replaces vcpu->requests by
> bitmap with 64 bit length and uses bitmap API.
> 
> The patch consists of:
> * announce kvm_vcpu_has_requests() to check whether vcpu has
> requests
> * announce kvm_vcpu_requests() to get vcpu requests pointer
> * announce kvm_clear_request() to clear particular vcpu request
> * replace if (vcpu->requests) by if (kvm_vcpu_has_requests(vcpu))
> * replace clear_bit(req, vcpu->requests) by
>  kvm_clear_request(req, vcpu)
> 
> Signed-off-by: Andrey Smetanin 
> CC: Paolo Bonzini 
> CC: Gleb Natapov 
> CC: James Hogan 
> CC: Paolo Bonzini 
> CC: Paul Burton 
> CC: Ralf Baechle 
> CC: Alexander Graf 
> CC: Christian Borntraeger 
> CC: Cornelia Huck 
> CC: linux-m...@linux-mips.org
> CC: kvm-...@vger.kernel.org
> CC: linux-s...@vger.kernel.org
> CC: Roman Kagan 
> CC: Denis V. Lunev 
> CC: qemu-de...@nongnu.org

For MIPS KVM bit:
Acked-by: James Hogan 

Thanks
James

> 
> ---
>  arch/mips/kvm/emulate.c   |  4 +---
>  arch/powerpc/kvm/book3s_pr.c  |  2 +-
>  arch/powerpc/kvm/book3s_pr_papr.c |  2 +-
>  arch/powerpc/kvm/booke.c  |  6 +++---
>  arch/powerpc/kvm/powerpc.c|  6 +++---
>  arch/powerpc/kvm/trace.h  |  2 +-
>  arch/s390/kvm/kvm-s390.c  |  4 ++--
>  arch/x86/kvm/vmx.c|  2 +-
>  arch/x86/kvm/x86.c| 14 +++---
>  include/linux/kvm_host.h  | 27 ++-
>  10 files changed, 42 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
> index 41b1b09..14aebe8 100644
> --- a/arch/mips/kvm/emulate.c
> +++ b/arch/mips/kvm/emulate.c
> @@ -774,10 +774,8 @@ enum emulation_result kvm_mips_emul_wait(struct kvm_vcpu 
> *vcpu)
>* We we are runnable, then definitely go off to user space to
>* check if any I/O interrupts are pending.
>*/
> - if (kvm_check_request(KVM_REQ_UNHALT, vcpu)) {
> - clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
> + if (kvm_check_request(KVM_REQ_UNHALT, vcpu))
>   vcpu->run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
> - }
>   }
>  
>   return EMULATE_DONE;
> diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
> index 64891b0..e975279 100644
> --- a/arch/powerpc/kvm/book3s_pr.c
> +++ b/arch/powerpc/kvm/book3s_pr.c
> @@ -349,7 +349,7 @@ static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 
> msr)
>   if (msr & MSR_POW) {
>   if (!vcpu->arch.pending_exceptions) {
>   kvm_vcpu_block(vcpu);
> - clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
> + kvm_clear_request(KVM_REQ_UNHALT, vcpu));
>   vcpu->stat.halt_wakeup++;
>  
>   /* Unset POW bit after we woke up */
> diff --git a/arch/powerpc/kvm/book3s_pr_papr.c 
> b/arch/powerpc/kvm/book3s_pr_papr.c
> index f2c75a1..60cf393 100644
> --- a/arch/powerpc/kvm/book3s_pr_papr.c
> +++ b/arch/powerpc/kvm/book3s_pr_papr.c
> @@ -309,7 +309,7 @@ int kvmppc_h_pr(struct kvm_vcpu *vcpu, unsigned long cmd)
>   case H_CEDE:
>   kvmppc_set_msr_fast(vcpu, kvmppc_get_msr(vcpu) | MSR_EE);
>   kvm_vcpu_block(vcpu);
> - clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
> + kvm_clear_request(KVM_REQ_UNHALT, vcpu);
>   vcpu->stat.halt_wakeup++;
>   return EMULATE_DONE;
>   case H_LOGICAL_CI_LOAD:
> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
> index fd58751..6bed382 100644
> --- a/arch/powerpc/kvm/booke.c
> +++ b/arch/powerpc/kvm/booke.c
> @@ -574,7 +574,7 @@ static void arm_next_watchdog(struct kvm_vcpu *vcpu)
>* userspace, so clear the KVM_REQ_WATCHDOG request.
>*/
>   if ((vcpu->arch.tsr & (TSR_ENW | TSR_WIS)) != (TSR_ENW | TSR_WIS))
> - clear_bit(KVM_REQ_WATCHDOG, &vcpu->requests);
> + kvm_clear_request(KVM_REQ_WATCHDOG, vcpu);
>  
>   spin_lock_irqsave(&vcpu->arch.wdt_lock, flags);
>   nr_jiffies = watchdog_next_timeout(vcpu);
> @@ -677,7 +677,7 @@ int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
>  
>   kvmppc_c

[PATCH v4 2/7] mips/kvm: Implement PRid CP0 register

2015-12-18 Thread James Hogan
Implement saving and restoring to KVM state of the Processor ID (PRid)
CP0 register. This allows QEMU to control the PRid exposed to the guest
instead of using the default set by KVM.

Signed-off-by: James Hogan 
Reviewed-by: Leon Alrae 
Cc: Paolo Bonzini 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 5cd65ad201ca..41abc8709d96 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -228,6 +228,7 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0)
 #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
+#define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
@@ -520,6 +521,11 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int 
level)
 DPRINTF("%s: Failed to put CP0_EPC (%d)\n", __func__, err);
 ret = err;
 }
+err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid);
+if (err < 0) {
+DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
+ret = err;
+}
 err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
  &env->CP0_ErrorEPC);
 if (err < 0) {
@@ -606,6 +612,11 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
 DPRINTF("%s: Failed to get CP0_EPC (%d)\n", __func__, err);
 ret = err;
 }
+err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid);
+if (err < 0) {
+DPRINTF("%s: Failed to get CP0_PRID (%d)\n", __func__, err);
+ret = err;
+}
 err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
  &env->CP0_ErrorEPC);
 if (err < 0) {
-- 
2.4.10

--
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


[PATCH v4 6/7] mips/kvm: Support FPU in MIPS KVM guests

2015-12-18 Thread James Hogan
Support the new KVM_CAP_MIPS_FPU capability, which allows the host's FPU
to be exposed to the KVM guest.

The capability is enabled if the guest core has an FPU according to its
Config1 register. Various config bits are now writeable so that KVM is
aware of the configuration (Config1.FP) and so that QEMU can
save/restore the guest modifiable bits (Config5.FRE, Config5.UFR,
Config5.UFE). The FCSR/FIR registers and the floating point registers
are now saved/restored (depending on the FR mode bit).

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
Changes in v2:
- Change (1 << x) to (1U << x) in important places to avoid compiler
  undefined behaviour (Leon).
- Removed update of linux-headers/linux/kvm.h (Paolo).
---
 target-mips/kvm.c | 124 --
 1 file changed, 120 insertions(+), 4 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 284b7a954ba2..f66347b8250a 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -30,6 +30,8 @@
 #define DPRINTF(fmt, ...) \
 do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0)
 
+static int kvm_mips_fpu_cap;
+
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
 };
@@ -46,16 +48,29 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 /* MIPS has 128 signals */
 kvm_set_sigmask_len(s, 16);
 
+kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU);
+
 DPRINTF("%s\n", __func__);
 return 0;
 }
 
 int kvm_arch_init_vcpu(CPUState *cs)
 {
+MIPSCPU *cpu = MIPS_CPU(cs);
+CPUMIPSState *env = &cpu->env;
 int ret = 0;
 
 qemu_add_vm_change_state_handler(kvm_mips_update_state, cs);
 
+if (kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) {
+ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_FPU, 0, 0);
+if (ret < 0) {
+/* mark unsupported so it gets disabled on reset */
+kvm_mips_fpu_cap = 0;
+ret = 0;
+}
+}
+
 DPRINTF("%s\n", __func__);
 return ret;
 }
@@ -64,8 +79,8 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu)
 {
 CPUMIPSState *env = &cpu->env;
 
-if (env->CP0_Config1 & (1 << CP0C1_FP)) {
-fprintf(stderr, "Warning: FPU not supported with KVM, disabling\n");
+if (!kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) {
+fprintf(stderr, "Warning: KVM does not support FPU, disabling\n");
 env->CP0_Config1 &= ~(1 << CP0C1_FP);
 }
 
@@ -355,11 +370,14 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, 
uint64 reg_id,
 }
 
 #define KVM_REG_MIPS_CP0_CONFIG_MASK(1U << CP0C0_M)
-#define KVM_REG_MIPS_CP0_CONFIG1_MASK   (1U << CP0C1_M)
+#define KVM_REG_MIPS_CP0_CONFIG1_MASK   ((1U << CP0C1_M) | \
+ (1U << CP0C1_FP))
 #define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1U << CP0C2_M)
 #define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1U << CP0C3_M)
 #define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1U << CP0C4_M)
-#define KVM_REG_MIPS_CP0_CONFIG5_MASK   0
+#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1U << CP0C5_UFE) | \
+ (1U << CP0C5_FRE) | \
+ (1U << CP0C5_UFR))
 
 static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
   int32_t *addr, int32_t mask)
@@ -521,6 +539,98 @@ static void kvm_mips_update_state(void *opaque, int 
running, RunState state)
 }
 }
 
+static int kvm_mips_put_fpu_registers(CPUState *cs, int level)
+{
+MIPSCPU *cpu = MIPS_CPU(cs);
+CPUMIPSState *env = &cpu->env;
+int err, ret = 0;
+unsigned int i;
+
+/* Only put FPU state if we're emulating a CPU with an FPU */
+if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+/* FPU Control Registers */
+if (level == KVM_PUT_FULL_STATE) {
+err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_IR,
+&env->active_fpu.fcr0);
+if (err < 0) {
+DPRINTF("%s: Failed to put FCR_IR (%d)\n", __func__, err);
+ret = err;
+}
+}
+err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_CSR,
+&env->active_fpu.fcr31);
+if (err < 0) {
+DPRINTF("%s: Failed to put FCR_CSR (%d)\n", __func__, err);
+ret = err;
+}
+
+/* Floating point registers */
+for (i = 0; i < 32; ++i) {
+if (env->CP0_Status & (1 << CP0St_FR)) {
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i),
+  &env->active_fp

[PATCH v4 7/7] mips/kvm: Support MSA in MIPS KVM guests

2015-12-18 Thread James Hogan
Support the new KVM_CAP_MIPS_MSA capability, which allows MIPS SIMD
Architecture (MSA) to be exposed to the KVM guest.

The capability is enabled if the guest core has MSA according to its
Config3 register. Various config bits are now writeable so that KVM is
aware of the configuration (Config3.MSAP) and so that QEMU can
save/restore the guest modifiable bits (Config5.MSAEn). The MSACSR/MSAIR
registers and the MSA vector registers are now saved/restored. Since the
FP registers are a subset of the vector registers, they are omitted if
the guest has MSA.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
Changes in v2:
- Change (1 << x) to (1U << x) in important places to avoid compiler
  undefined behaviour (Leon).
- Removed update of linux-headers/linux/kvm.h (Paolo).
---
 target-mips/kvm.c | 127 +-
 1 file changed, 107 insertions(+), 20 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index f66347b8250a..4404797261fd 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -31,6 +31,7 @@
 do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0)
 
 static int kvm_mips_fpu_cap;
+static int kvm_mips_msa_cap;
 
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
@@ -49,6 +50,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 kvm_set_sigmask_len(s, 16);
 
 kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU);
+kvm_mips_msa_cap = kvm_check_extension(s, KVM_CAP_MIPS_MSA);
 
 DPRINTF("%s\n", __func__);
 return 0;
@@ -71,6 +73,15 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 }
 
+if (kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_MSA, 0, 0);
+if (ret < 0) {
+/* mark unsupported so it gets disabled on reset */
+kvm_mips_msa_cap = 0;
+ret = 0;
+}
+}
+
 DPRINTF("%s\n", __func__);
 return ret;
 }
@@ -83,6 +94,10 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu)
 fprintf(stderr, "Warning: KVM does not support FPU, disabling\n");
 env->CP0_Config1 &= ~(1 << CP0C1_FP);
 }
+if (!kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+fprintf(stderr, "Warning: KVM does not support MSA, disabling\n");
+env->CP0_Config3 &= ~(1 << CP0C3_MSAP);
+}
 
 DPRINTF("%s\n", __func__);
 }
@@ -373,9 +388,11 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, 
uint64 reg_id,
 #define KVM_REG_MIPS_CP0_CONFIG1_MASK   ((1U << CP0C1_M) | \
  (1U << CP0C1_FP))
 #define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1U << CP0C2_M)
-#define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1U << CP0C3_M)
+#define KVM_REG_MIPS_CP0_CONFIG3_MASK   ((1U << CP0C3_M) | \
+ (1U << CP0C3_MSAP))
 #define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1U << CP0C4_M)
-#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1U << CP0C5_UFE) | \
+#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1U << CP0C5_MSAEn) | \
+ (1U << CP0C5_UFE) | \
  (1U << CP0C5_FRE) | \
  (1U << CP0C5_UFR))
 
@@ -564,17 +581,53 @@ static int kvm_mips_put_fpu_registers(CPUState *cs, int 
level)
 ret = err;
 }
 
-/* Floating point registers */
+/*
+ * FPU register state is a subset of MSA vector state, so don't put FPU
+ * registers if we're emulating a CPU with MSA.
+ */
+if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
+/* Floating point registers */
+for (i = 0; i < 32; ++i) {
+if (env->CP0_Status & (1 << CP0St_FR)) {
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i),
+  &env->active_fpu.fpr[i].d);
+} else {
+err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FPR_32(i),
+&env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]);
+}
+if (err < 0) {
+DPRINTF("%s: Failed to put FPR%u (%d)\n", __func__, i, 
err);
+ret = err;
+}
+}
+}
+}
+
+/* Only put MSA state if we're emulating a CPU with MSA */
+if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+/* MSA Control Registers */
+if (level == KVM_PUT_FULL_STATE) {
+err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_IR,
+   &env->msai

[PATCH v4 3/7] mips/kvm: Implement Config CP0 registers

2015-12-18 Thread James Hogan
Implement saving and restoring to KVM state of the Config CP0 registers
(namely Config, Config1, Config2, Config3, Config4, and Config5). These
control the features available to a guest, and a few of the fields will
soon be writeable by a guest so QEMU needs to know about them so as not
to clobber them on migration/savevm.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
Changes in v2:
- Fix line wrapping of kvm_mips_get_one_reg() calls from Config4 and
  Config5 (Leon).
- Change (1 << x) to (1U << x) in important places to avoid compiler
  defined behaviour (Leon).
---
 target-mips/kvm.c | 106 ++
 1 file changed, 106 insertions(+)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 41abc8709d96..b777a5e93fb1 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -229,6 +229,12 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
+#define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
+#define KVM_REG_MIPS_CP0_CONFIG1MIPS_CP0_32(16, 1)
+#define KVM_REG_MIPS_CP0_CONFIG2MIPS_CP0_32(16, 2)
+#define KVM_REG_MIPS_CP0_CONFIG3MIPS_CP0_32(16, 3)
+#define KVM_REG_MIPS_CP0_CONFIG4MIPS_CP0_32(16, 4)
+#define KVM_REG_MIPS_CP0_CONFIG5MIPS_CP0_32(16, 5)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
@@ -304,6 +310,34 @@ static inline int kvm_mips_get_one_reg64(CPUState *cs, 
uint64 reg_id,
 return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
 }
 
+#define KVM_REG_MIPS_CP0_CONFIG_MASK(1U << CP0C0_M)
+#define KVM_REG_MIPS_CP0_CONFIG1_MASK   (1U << CP0C1_M)
+#define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1U << CP0C2_M)
+#define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1U << CP0C3_M)
+#define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1U << CP0C4_M)
+#define KVM_REG_MIPS_CP0_CONFIG5_MASK   0
+
+static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
+  int32_t *addr, int32_t mask)
+{
+int err;
+int32_t tmp, change;
+
+err = kvm_mips_get_one_reg(cs, reg_id, &tmp);
+if (err < 0) {
+return err;
+}
+
+/* only change bits in mask */
+change = (*addr ^ tmp) & mask;
+if (!change) {
+return 0;
+}
+
+tmp = tmp ^ change;
+return kvm_mips_put_one_reg(cs, reg_id, &tmp);
+}
+
 /*
  * We freeze the KVM timer when either the VM clock is stopped or the state is
  * saved (the state is dirty).
@@ -526,6 +560,48 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int 
level)
 DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
 ret = err;
 }
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG,
+  &env->CP0_Config0,
+  KVM_REG_MIPS_CP0_CONFIG_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1,
+  &env->CP0_Config1,
+  KVM_REG_MIPS_CP0_CONFIG1_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG1 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2,
+  &env->CP0_Config2,
+  KVM_REG_MIPS_CP0_CONFIG2_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG2 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3,
+  &env->CP0_Config3,
+  KVM_REG_MIPS_CP0_CONFIG3_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG3 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG4,
+  &env->CP0_Config4,
+  KVM_REG_MIPS_CP0_CONFIG4_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG4 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG5,
+  &env->CP0_Config5,
+  KVM_REG_MIPS_CP0_CONFIG5_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG5 (%d)\n", __func__, err);
+ret = err;
+}
 err = kvm_mips_put_one_ulreg(cs, KVM_

[PATCH v4 5/7] mips/kvm: Support signed 64-bit KVM registers

2015-12-18 Thread James Hogan
Rename kvm_mips_{get,put}_one_reg64() to kvm_mips_{get,put}_one_ureg64()
since they take an int64_t pointer, and add separate signed 64-bit
accessors. These will be used for double precision floating point
registers.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 40 +++-
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index a11095f273f0..284b7a954ba2 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -272,7 +272,18 @@ static inline int kvm_mips_put_one_ulreg(CPUState *cs, 
uint64_t reg_id,
 }
 
 static inline int kvm_mips_put_one_reg64(CPUState *cs, uint64_t reg_id,
- uint64_t *addr)
+ int64_t *addr)
+{
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)addr
+};
+
+return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
+}
+
+static inline int kvm_mips_put_one_ureg64(CPUState *cs, uint64_t reg_id,
+  uint64_t *addr)
 {
 struct kvm_one_reg cp0reg = {
 .id = reg_id,
@@ -322,7 +333,18 @@ static inline int kvm_mips_get_one_ulreg(CPUState *cs, 
uint64 reg_id,
 }
 
 static inline int kvm_mips_get_one_reg64(CPUState *cs, uint64 reg_id,
- uint64_t *addr)
+ int64_t *addr)
+{
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)addr
+};
+
+return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
+}
+
+static inline int kvm_mips_get_one_ureg64(CPUState *cs, uint64 reg_id,
+  uint64_t *addr)
 {
 struct kvm_one_reg cp0reg = {
 .id = reg_id,
@@ -377,13 +399,13 @@ static int kvm_mips_save_count(CPUState *cs)
 int err, ret = 0;
 
 /* freeze KVM timer */
-err = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err);
 ret = err;
 } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
 count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
-err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
 ret = err;
@@ -419,14 +441,14 @@ static int kvm_mips_restore_count(CPUState *cs)
 int err_dc, err, ret = 0;
 
 /* check the timer is frozen */
-err_dc = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err_dc = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err_dc < 0) {
 DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err_dc);
 ret = err_dc;
 } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
 /* freeze timer (sets COUNT_RESUME for us) */
 count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
-err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
 ret = err;
@@ -450,7 +472,7 @@ static int kvm_mips_restore_count(CPUState *cs)
 /* resume KVM timer */
 if (err_dc >= 0) {
 count_ctl &= ~KVM_REG_MIPS_COUNT_CTL_DC;
-err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to set COUNT_CTL.DC=0 (%d)\n", __func__, err);
 ret = err;
@@ -483,8 +505,8 @@ static void kvm_mips_update_state(void *opaque, int 
running, RunState state)
 } else {
 /* Set clock restore time to now */
 count_resume = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-ret = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_RESUME,
- &count_resume);
+ret = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_RESUME,
+  &count_resume);
 if (ret < 0) {
 fprintf(stderr, "Failed setting COUNT_RESUME\n");
 return;
-- 
2.4.10

--
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


[PATCH v4 4/7] mips/kvm: Support unsigned KVM registers

2015-12-18 Thread James Hogan
Add KVM register access functions for the uint32_t type. This is
required for FP and MSA control registers, which are represented as
unsigned 32-bit integers.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
Changes in v3:
- Fix big endian (the pointer passed to the kernel must be for the
  actual 32-bit value, not a temporary 64-bit value, otherwise on big
  endian systems the kernel will only interpret the upper half).
---
 target-mips/kvm.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index b777a5e93fb1..a11095f273f0 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -248,6 +248,17 @@ static inline int kvm_mips_put_one_reg(CPUState *cs, 
uint64_t reg_id,
 return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
 }
 
+static inline int kvm_mips_put_one_ureg(CPUState *cs, uint64_t reg_id,
+uint32_t *addr)
+{
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)addr
+};
+
+return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
+}
+
 static inline int kvm_mips_put_one_ulreg(CPUState *cs, uint64_t reg_id,
  target_ulong *addr)
 {
@@ -282,6 +293,17 @@ static inline int kvm_mips_get_one_reg(CPUState *cs, 
uint64_t reg_id,
 return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
 }
 
+static inline int kvm_mips_get_one_ureg(CPUState *cs, uint64_t reg_id,
+uint32_t *addr)
+{
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)addr
+};
+
+return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
+}
+
 static inline int kvm_mips_get_one_ulreg(CPUState *cs, uint64 reg_id,
  target_ulong *addr)
 {
-- 
2.4.10

--
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


[PATCH v4 1/7] mips/kvm: Remove a couple of noisy DPRINTFs

2015-12-18 Thread James Hogan
The DPRINTFs in cpu_mips_io_interrupts_pending() and kvm_arch_pre_run()
are particularly noisy during normal execution, and also not
particularly helpful. Remove them so that more important debug messages
can be more easily seen.

Signed-off-by: James Hogan 
Reviewed-by: Leon Alrae 
Cc: Paolo Bonzini 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 12d7db311ece..5cd65ad201ca 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -88,7 +88,6 @@ static inline int cpu_mips_io_interrupts_pending(MIPSCPU *cpu)
 {
 CPUMIPSState *env = &cpu->env;
 
-DPRINTF("%s: %#x\n", __func__, env->CP0_Cause & (1 << (2 + CP0Ca_IP)));
 return env->CP0_Cause & (0x1 << (2 + CP0Ca_IP));
 }
 
@@ -117,7 +116,6 @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
 
 MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
 {
-DPRINTF("%s\n", __func__);
 return MEMTXATTRS_UNSPECIFIED;
 }
 
-- 
2.4.10

--
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


[PATCH v4 0/7] mips/kvm: Support FPU & SIMD (MSA) in MIPS KVM guests

2015-12-18 Thread James Hogan
Here's a v4 refresh of my FPU/MSA patchset for v2.6. Thanks to all who
have taken the time to review it so far.

This patchset primarily adds support for FPU and MIPS SIMD Architecture
(MSA) in MIPS KVM guests to QEMU. It depends on Linux v4.1, specifically
my KVM patchset to add the corresponding hypervisor support to KVM
("[PATCH 00/20] MIPS: KVM: Guest FPU & SIMD (MSA) support").

All comments welcome.

Changes in v4:
- Rebase on master (dropped patch 1 & 2).

Changes in v3 (patch 6 only):
- Fix big endian (the pointer passed to the kernel must be for the
  actual 32-bit value, not a temporary 64-bit value, otherwise on big
  endian systems the kernel will only interpret the upper half).

Changes in v2:
- Moved most of patch 7 and updates to linux-headers/linux/kvm.h from
  patches 8 and 9 into a new patch 1, which is purely for reference
  (Paolo).
- Add the changes to MIPS_CP0_{32,64} macros from v1 patch 7 to patch 2,
  since the rest of that patch is now unnecessary and the change is
  along the same lines as patch 2 (not added Leon's Reviewed-by to this
  patch due to that non-reviewed change).
- Fix line wrapping of kvm_mips_get_one_reg() calls from Config4 and
  Config5 in patch 5 (Leon).
- Change (1 << x) to (1U << x) in important places in patch 5, 8 & 9 to
  avoid compiler undefined behaviour (Leon).

James Hogan (7):
  mips/kvm: Remove a couple of noisy DPRINTFs
  mips/kvm: Implement PRid CP0 register
  mips/kvm: Implement Config CP0 registers
  mips/kvm: Support unsigned KVM registers
  mips/kvm: Support signed 64-bit KVM registers
  mips/kvm: Support FPU in MIPS KVM guests
  mips/kvm: Support MSA in MIPS KVM guests

 target-mips/kvm.c | 388 --
 1 file changed, 375 insertions(+), 13 deletions(-)

-- 
2.4.10

--
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


Re: [PATCH 00/16] MIPS: KVM: Misc trivial cleanups

2015-12-17 Thread James Hogan
Hi Paolo.

On Thu, Dec 17, 2015 at 11:39:14AM +0100, Paolo Bonzini wrote:
> 
> 
> On 17/12/2015 00:49, James Hogan wrote:
> > This patchset contains a bunch of miscellaneous cleanups (which are
> > mostly trivial) for MIPS KVM & MIPS headers, such as:
> > - Style/whitespace fixes
> > - General cleanup and removal of dead code.
> > - Moving/refactoring of general MIPS definitions out of arch/mips/kvm/
> >   and into arch/mips/include/asm/ so they can be shared with the rest of
> >   arch/mips. Specifically COP0 register bits, exception codes, cache
> >   ops, & instruction opcodes.
> > - Add MAINTAINERS entry for MIPS KVM.
> > 
> > Due to the interaction with other arch/mips/ code, I think it makes
> > sense for these to go via the MIPS tree.
> 
> No objection.
> 
> Acked-by: Paolo Bonzini 

Thanks!

> 
> I think I'd use s8/u8 instead of int8_t/uint8_t in patch 15, but really
> that's just me.  I'm fine either way, and that's really the only comment
> I have on the series. :)

I'm inclined to agree. u?int(8|16|32)_t all over arch/mips/kvm/ instead
of [us](8|16|32) irritates me as its not very kernel'y.

Ralf: Maybe don't apply patch 15 (I've marked rejected in patchwork),
and I'll do a wider cleanup at some point instead.

Cheers
James

> 
> Paolo
> 
> > James Hogan (16):
> >   MIPS: KVM: Trivial whitespace and style fixes
> >   MIPS: KVM: Drop some unused definitions from kvm_host.h
> >   MIPS: Move definition of DC bit to mipsregs.h
> >   MIPS: KVM: Drop unused kvm_mips_host_tlb_inv_index()
> >   MIPS: KVM: Convert EXPORT_SYMBOL to _GPL
> >   MIPS: KVM: Refactor added offsetof()s
> >   MIPS: KVM: Make kvm_mips_{init,exit}() static
> >   MIPS: Move Cause.ExcCode trap codes to mipsregs.h
> >   MIPS: Update trap codes
> >   MIPS: Use EXCCODE_ constants with set_except_vector()
> >   MIPS: Break down cacheops.h definitions
> >   MIPS: KVM: Use cacheops.h definitions
> >   MIPS: Move KVM specific opcodes into asm/inst.h
> >   MIPS: KVM: Add missing newline to kvm_err()
> >   MIPS: KVM: Consistent use of uint*_t in MMIO handling
> >   MAINTAINERS: Add KVM for MIPS entry
> > 
> >  MAINTAINERS   |   8 +++
> >  arch/mips/Kconfig |   3 +-
> >  arch/mips/include/asm/cacheops.h  | 106 --
> >  arch/mips/include/asm/kvm_host.h  |  39 +
> >  arch/mips/include/asm/mipsregs.h  |  34 +++
> >  arch/mips/include/uapi/asm/inst.h |   3 +-
> >  arch/mips/kernel/cpu-bugs64.c |   8 +--
> >  arch/mips/kernel/traps.c  |  52 -
> >  arch/mips/kvm/callback.c  |   2 +-
> >  arch/mips/kvm/dyntrans.c  |  10 +---
> >  arch/mips/kvm/emulate.c   | 118 
> > --
> >  arch/mips/kvm/interrupt.c |   8 +--
> >  arch/mips/kvm/locore.S|  12 ++--
> >  arch/mips/kvm/mips.c  |  38 ++--
> >  arch/mips/kvm/opcode.h|  22 ---
> >  arch/mips/kvm/tlb.c   |  77 +++--
> >  arch/mips/kvm/trap_emul.c |   1 -
> >  17 files changed, 245 insertions(+), 296 deletions(-)
> >  delete mode 100644 arch/mips/kvm/opcode.h
> > 
> > Cc: Ralf Baechle 
> > Cc: Paolo Bonzini 
> > Cc: Gleb Natapov 
> > Cc: linux-m...@linux-mips.org
> > Cc: kvm@vger.kernel.org
> > 


signature.asc
Description: Digital signature


[PATCH 01/16] MIPS: KVM: Trivial whitespace and style fixes

2015-12-16 Thread James Hogan
A bunch of misc whitespace and style fixes within arch/mips/kvm/.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: kvm@vger.kernel.org
Cc: linux-m...@linux-mips.org
---
 arch/mips/Kconfig|  3 ++-
 arch/mips/include/asm/kvm_host.h |  2 +-
 arch/mips/kvm/emulate.c  |  8 +++-
 arch/mips/kvm/locore.S   | 12 ++--
 arch/mips/kvm/tlb.c  |  4 ++--
 5 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 71683a853372..3aa967ff2c11 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2018,7 +2018,8 @@ config KVM_GUEST
bool "KVM Guest Kernel"
depends on BROKEN_ON_SMP
help
- Select this option if building a guest kernel for KVM (Trap & 
Emulate) mode
+ Select this option if building a guest kernel for KVM (Trap & Emulate)
+ mode.
 
 config KVM_GUEST_TIMER_FREQ
int "Count/Compare Timer Frequency (MHz)"
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 6ded8d347af9..6a313157db83 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -58,7 +58,7 @@
 #define KVM_MAX_VCPUS  1
 #define KVM_USER_MEM_SLOTS 8
 /* memory slots that does not exposed to userspace */
-#define KVM_PRIVATE_MEM_SLOTS  0
+#define KVM_PRIVATE_MEM_SLOTS  0
 
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 1
 #define KVM_HALT_POLL_NS_DEFAULT 50
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 41b1b090f56f..95b83a6582ef 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1243,10 +1243,9 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t 
inst, uint32_t *opc,
 #ifdef KVM_MIPS_DEBUG_COP0_COUNTERS
cop0->stat[MIPS_CP0_STATUS][0]++;
 #endif
-   if (rt != 0) {
+   if (rt != 0)
vcpu->arch.gprs[rt] =
kvm_read_c0_guest_status(cop0);
-   }
/* EI */
if (inst & 0x20) {
kvm_debug("[%#lx] mfmcz_op: EI\n",
@@ -2583,9 +2582,8 @@ enum emulation_result kvm_mips_handle_tlbmiss(unsigned 
long cause,
 * an entry into the guest TLB.
 */
index = kvm_mips_guest_tlb_lookup(vcpu,
- (va & VPN2_MASK) |
- (kvm_read_c0_guest_entryhi
-  (vcpu->arch.cop0) & ASID_MASK));
+ (va & VPN2_MASK) |
+ (kvm_read_c0_guest_entryhi(vcpu->arch.cop0) & ASID_MASK));
if (index < 0) {
if (exccode == T_TLB_LD_MISS) {
er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu);
diff --git a/arch/mips/kvm/locore.S b/arch/mips/kvm/locore.S
index 7e2210846b8b..81687ab1b523 100644
--- a/arch/mips/kvm/locore.S
+++ b/arch/mips/kvm/locore.S
@@ -335,7 +335,7 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
 
/* Now restore the host state just enough to run the handlers */
 
-   /* Swtich EBASE to the one used by Linux */
+   /* Switch EBASE to the one used by Linux */
/* load up the host EBASE */
mfc0v0, CP0_STATUS
 
@@ -490,11 +490,11 @@ __kvm_mips_return_to_guest:
REG_ADDU t3, t1, t2
LONG_L  k0, (t3)
andik0, k0, 0xff
-   mtc0k0,CP0_ENTRYHI
+   mtc0k0, CP0_ENTRYHI
ehb
 
/* Disable RDHWR access */
-   mtc0zero,  CP0_HWRENA
+   mtc0zero, CP0_HWRENA
 
/* load the guest context from VCPU and return */
LONG_L  $0, VCPU_R0(k1)
@@ -606,11 +606,11 @@ __kvm_mips_return_to_host:
 
/* Restore RDHWR access */
PTR_LI  k0, 0x200F
-   mtc0k0,  CP0_HWRENA
+   mtc0k0, CP0_HWRENA
 
/* Restore RA, which is the address we will return to */
-   LONG_L  ra, PT_R31(k1)
-   j   ra
+   LONG_L  ra, PT_R31(k1)
+   j   ra
 nop
 
 VECTOR_END(MIPSX(GuestExceptionEnd))
diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c
index aed0ac2a4972..3d3f22301a35 100644
--- a/arch/mips/kvm/tlb.c
+++ b/arch/mips/kvm/tlb.c
@@ -673,8 +673,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
local_irq_save(flags);
 
-   if (((vcpu->arch.
- guest_kernel_asid[cpu] ^ asid_cache(cpu)) & ASID_VERSION_MASK)) {
+   if ((vcpu->arch.guest_kernel_asid[cpu] ^ asid_cache(cpu)) &
+   ASID_VERSION_MASK) {
kvm_get_new_mmu_context(&vcpu->arch.guest_kernel_mm, cpu, vcpu);
vcpu->arch.guest_kernel_asid[cpu] =
vcpu->arch.guest_kernel_mm.context.asid[

[PATCH 07/16] MIPS: KVM: Make kvm_mips_{init,exit}() static

2015-12-16 Thread James Hogan
The module init and exit functions have no need to be global, so make
them static.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: kvm@vger.kernel.org
Cc: linux-m...@linux-mips.org
---
 arch/mips/kvm/mips.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index b9b803facdbf..5848b616d5a0 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -1620,7 +1620,7 @@ static struct notifier_block kvm_mips_csr_die_notifier = {
.notifier_call = kvm_mips_csr_die_notify,
 };
 
-int __init kvm_mips_init(void)
+static int __init kvm_mips_init(void)
 {
int ret;
 
@@ -1646,7 +1646,7 @@ int __init kvm_mips_init(void)
return 0;
 }
 
-void __exit kvm_mips_exit(void)
+static void __exit kvm_mips_exit(void)
 {
kvm_exit();
 
-- 
2.4.10

--
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


[PATCH 05/16] MIPS: KVM: Convert EXPORT_SYMBOL to _GPL

2015-12-16 Thread James Hogan
Export symbols only to GPL modules to match other KVM symbols in
virt/kvm/ and arch/*/kvm/.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/kvm/callback.c |  2 +-
 arch/mips/kvm/tlb.c  | 36 ++--
 2 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/mips/kvm/callback.c b/arch/mips/kvm/callback.c
index 313c2e37b978..d88aa2173fb0 100644
--- a/arch/mips/kvm/callback.c
+++ b/arch/mips/kvm/callback.c
@@ -11,4 +11,4 @@
 #include 
 
 struct kvm_mips_callbacks *kvm_mips_callbacks;
-EXPORT_SYMBOL(kvm_mips_callbacks);
+EXPORT_SYMBOL_GPL(kvm_mips_callbacks);
diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c
index 2c0997447448..0939b1d6f910 100644
--- a/arch/mips/kvm/tlb.c
+++ b/arch/mips/kvm/tlb.c
@@ -35,17 +35,17 @@
 #define PRIx64 "llx"
 
 atomic_t kvm_mips_instance;
-EXPORT_SYMBOL(kvm_mips_instance);
+EXPORT_SYMBOL_GPL(kvm_mips_instance);
 
 /* These function pointers are initialized once the KVM module is loaded */
 pfn_t (*kvm_mips_gfn_to_pfn)(struct kvm *kvm, gfn_t gfn);
-EXPORT_SYMBOL(kvm_mips_gfn_to_pfn);
+EXPORT_SYMBOL_GPL(kvm_mips_gfn_to_pfn);
 
 void (*kvm_mips_release_pfn_clean)(pfn_t pfn);
-EXPORT_SYMBOL(kvm_mips_release_pfn_clean);
+EXPORT_SYMBOL_GPL(kvm_mips_release_pfn_clean);
 
 bool (*kvm_mips_is_error_pfn)(pfn_t pfn);
-EXPORT_SYMBOL(kvm_mips_is_error_pfn);
+EXPORT_SYMBOL_GPL(kvm_mips_is_error_pfn);
 
 uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu)
 {
@@ -111,7 +111,7 @@ void kvm_mips_dump_host_tlbs(void)
mtc0_tlbw_hazard();
local_irq_restore(flags);
 }
-EXPORT_SYMBOL(kvm_mips_dump_host_tlbs);
+EXPORT_SYMBOL_GPL(kvm_mips_dump_host_tlbs);
 
 void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
 {
@@ -139,7 +139,7 @@ void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu)
 (tlb.tlb_lo1 >> 3) & 7, tlb.tlb_mask);
}
 }
-EXPORT_SYMBOL(kvm_mips_dump_guest_tlbs);
+EXPORT_SYMBOL_GPL(kvm_mips_dump_guest_tlbs);
 
 static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn)
 {
@@ -191,7 +191,7 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct 
kvm_vcpu *vcpu,
 
return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset;
 }
-EXPORT_SYMBOL(kvm_mips_translate_guest_kseg0_to_hpa);
+EXPORT_SYMBOL_GPL(kvm_mips_translate_guest_kseg0_to_hpa);
 
 /* XXXKYMA: Must be called with interrupts disabled */
 /* set flush_dcache_mask == 0 if no dcache flush required */
@@ -308,7 +308,7 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr,
return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
   flush_dcache_mask);
 }
-EXPORT_SYMBOL(kvm_mips_handle_kseg0_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_kseg0_tlb_fault);
 
 int kvm_mips_handle_commpage_tlb_fault(unsigned long badvaddr,
struct kvm_vcpu *vcpu)
@@ -351,7 +351,7 @@ int kvm_mips_handle_commpage_tlb_fault(unsigned long 
badvaddr,
 
return 0;
 }
-EXPORT_SYMBOL(kvm_mips_handle_commpage_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_commpage_tlb_fault);
 
 int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu,
 struct kvm_mips_tlb *tlb,
@@ -401,7 +401,7 @@ int kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu 
*vcpu,
return kvm_mips_host_tlb_write(vcpu, entryhi, entrylo0, entrylo1,
   tlb->tlb_mask);
 }
-EXPORT_SYMBOL(kvm_mips_handle_mapped_seg_tlb_fault);
+EXPORT_SYMBOL_GPL(kvm_mips_handle_mapped_seg_tlb_fault);
 
 int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long entryhi)
 {
@@ -422,7 +422,7 @@ int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu, 
unsigned long entryhi)
 
return index;
 }
-EXPORT_SYMBOL(kvm_mips_guest_tlb_lookup);
+EXPORT_SYMBOL_GPL(kvm_mips_guest_tlb_lookup);
 
 int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, unsigned long vaddr)
 {
@@ -458,7 +458,7 @@ int kvm_mips_host_tlb_lookup(struct kvm_vcpu *vcpu, 
unsigned long vaddr)
 
return idx;
 }
-EXPORT_SYMBOL(kvm_mips_host_tlb_lookup);
+EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_lookup);
 
 int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long va)
 {
@@ -505,7 +505,7 @@ int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned 
long va)
 
return 0;
 }
-EXPORT_SYMBOL(kvm_mips_host_tlb_inv);
+EXPORT_SYMBOL_GPL(kvm_mips_host_tlb_inv);
 
 void kvm_mips_flush_host_tlb(int skip_kseg0)
 {
@@ -557,7 +557,7 @@ void kvm_mips_flush_host_tlb(int skip_kseg0)
 
local_irq_restore(flags);
 }
-EXPORT_SYMBOL(kvm_mips_flush_host_tlb);
+EXPORT_SYMBOL_GPL(kvm_mips_flush_host_tlb);
 
 void kvm_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu,
 struct kvm_vcpu *vcpu)
@@ -605,7 +605,7 @@ void kvm_local_flush_tlb_all(void)
 
local_irq_restore(flags);
 }
-EXPORT_SYMBOL(kvm_local_fl

[PATCH 10/16] MIPS: Use EXCCODE_ constants with set_except_vector()

2015-12-16 Thread James Hogan
The first argument to set_except_vector is the ExcCode, which we now
have definitions for. Lets make use of them.

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: linux-m...@linux-mips.org
---
 arch/mips/kernel/cpu-bugs64.c |  8 +++
 arch/mips/kernel/traps.c  | 52 +--
 2 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index 09f4034f239f..6392dbe504fb 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -190,7 +190,7 @@ static inline void check_daddi(void)
printk("Checking for the daddi bug... ");
 
local_irq_save(flags);
-   handler = set_except_vector(12, handle_daddi_ov);
+   handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
/*
 * The following code fails to trigger an overflow exception
 * when executed on R4000 rev. 2.2 or 3.0 (PRId 0422 or
@@ -214,7 +214,7 @@ static inline void check_daddi(void)
".set   pop"
: "=r" (v), "=&r" (tmp)
: "I" (0xdb9aUL), "I" (0x1234));
-   set_except_vector(12, handler);
+   set_except_vector(EXCCODE_OV, handler);
local_irq_restore(flags);
 
if (daddi_ov) {
@@ -225,14 +225,14 @@ static inline void check_daddi(void)
printk("yes, workaround... ");
 
local_irq_save(flags);
-   handler = set_except_vector(12, handle_daddi_ov);
+   handler = set_except_vector(EXCCODE_OV, handle_daddi_ov);
asm volatile(
"addiu  %1, $0, %2\n\t"
"dsrl   %1, %1, 1\n\t"
"daddi  %0, %1, %3"
: "=r" (v), "=&r" (tmp)
: "I" (0xdb9aUL), "I" (0x1234));
-   set_except_vector(12, handler);
+   set_except_vector(EXCCODE_OV, handler);
local_irq_restore(flags);
 
if (daddi_ov) {
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 886cb1976e90..bafcb7ad5c85 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -2250,7 +2250,7 @@ void __init trap_init(void)
 * Only some CPUs have the watch exceptions.
 */
if (cpu_has_watch)
-   set_except_vector(23, handle_watch);
+   set_except_vector(EXCCODE_WATCH, handle_watch);
 
/*
 * Initialise interrupt handlers
@@ -2277,27 +2277,27 @@ void __init trap_init(void)
if (board_be_init)
board_be_init();
 
-   set_except_vector(0, using_rollback_handler() ? rollback_handle_int
- : handle_int);
-   set_except_vector(1, handle_tlbm);
-   set_except_vector(2, handle_tlbl);
-   set_except_vector(3, handle_tlbs);
+   set_except_vector(EXCCODE_INT, using_rollback_handler() ?
+   rollback_handle_int : handle_int);
+   set_except_vector(EXCCODE_MOD, handle_tlbm);
+   set_except_vector(EXCCODE_TLBL, handle_tlbl);
+   set_except_vector(EXCCODE_TLBS, handle_tlbs);
 
-   set_except_vector(4, handle_adel);
-   set_except_vector(5, handle_ades);
+   set_except_vector(EXCCODE_ADEL, handle_adel);
+   set_except_vector(EXCCODE_ADES, handle_ades);
 
-   set_except_vector(6, handle_ibe);
-   set_except_vector(7, handle_dbe);
+   set_except_vector(EXCCODE_IBE, handle_ibe);
+   set_except_vector(EXCCODE_DBE, handle_dbe);
 
-   set_except_vector(8, handle_sys);
-   set_except_vector(9, handle_bp);
-   set_except_vector(10, rdhwr_noopt ? handle_ri :
+   set_except_vector(EXCCODE_SYS, handle_sys);
+   set_except_vector(EXCCODE_BP, handle_bp);
+   set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri :
  (cpu_has_vtag_icache ?
   handle_ri_rdhwr_vivt : handle_ri_rdhwr));
-   set_except_vector(11, handle_cpu);
-   set_except_vector(12, handle_ov);
-   set_except_vector(13, handle_tr);
-   set_except_vector(14, handle_msa_fpe);
+   set_except_vector(EXCCODE_CPU, handle_cpu);
+   set_except_vector(EXCCODE_OV, handle_ov);
+   set_except_vector(EXCCODE_TR, handle_tr);
+   set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe);
 
if (current_cpu_type() == CPU_R6000 ||
current_cpu_type() == CPU_R6000A) {
@@ -2318,25 +2318,25 @@ void __init trap_init(void)
board_nmi_handler_setup();
 
if (cpu_has_fpu && !cpu_has_nofpuex)
-   set_except_vector(15, handle_fpe);
+   set_except_vector(EXCCODE_FPE, handle_fpe);
 
-   set_except_vector(16, handle_ftlb);
+   set_except_vector(MIPS_EXCCODE_TLBPAR, handle_ftlb);
 
if (cpu_has_rixiex) {
-   set_except_vecto

[PATCH 09/16] MIPS: Update trap codes

2015-12-16 Thread James Hogan
Add a few missing trap codes, and drop a couple of unused definitions
for virtual coherency that aren't in the latest architecture revisions.

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: linux-m...@linux-mips.org
---
 arch/mips/include/asm/mipsregs.h | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index eb89b877c6c9..3ad19ad04d8a 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -420,12 +420,20 @@
 #define EXCCODE_CPU11  /* Coprocessor unusable */
 #define EXCCODE_OV 12  /* Arithmetic overflow */
 #define EXCCODE_TR 13  /* Trap instruction */
-#define EXCCODE_VCEI   14  /* Virtual coherency exception */
 #define EXCCODE_MSAFPE 14  /* MSA floating point exception */
 #define EXCCODE_FPE15  /* Floating point exception */
+#define EXCCODE_TLBRI  19  /* TLB Read-Inhibit exception */
+#define EXCCODE_TLBXI  20  /* TLB Execution-Inhibit exception */
 #define EXCCODE_MSADIS 21  /* MSA disabled exception */
+#define EXCCODE_MDMX   22  /* MDMX unusable exception */
 #define EXCCODE_WATCH  23  /* Watch address reference */
-#define EXCCODE_VCED   31  /* Virtual coherency data */
+#define EXCCODE_MCHECK 24  /* Machine check */
+#define EXCCODE_THREAD 25  /* Thread exceptions (MT) */
+#define EXCCODE_DSPDIS 26  /* DSP disabled exception */
+#define EXCCODE_GE 27  /* Virtualized guest exception (VZ) */
+
+/* Implementation specific trap codes used by MIPS cores */
+#define MIPS_EXCCODE_TLBPAR16  /* TLB parity error exception */
 
 /*
  * Bits in the coprocessor 0 config register.
-- 
2.4.10

--
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


[PATCH 03/16] MIPS: Move definition of DC bit to mipsregs.h

2015-12-16 Thread James Hogan
The CAUSEB_DC and CAUSEF_DC definitions used by KVM are defined in
asm/kvm_host.h, but all the other Cause register field definitions are
found in asm/mipsregs.h.

Lets reunite the DC bit definitions with its friends in mipsregs.h.

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h | 3 ---
 arch/mips/include/asm/mipsregs.h | 2 ++
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 17782205c5db..b14265d8d606 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -92,9 +92,6 @@
 #define KVM_INVALID_INST   0xdeadbeef
 #define KVM_INVALID_ADDR   0xdeadbeef
 
-#define CAUSEB_DC  27
-#define CAUSEF_DC  (_ULCAST_(1) << 27)
-
 extern atomic_t kvm_mips_instance;
 extern pfn_t(*kvm_mips_gfn_to_pfn) (struct kvm *kvm, gfn_t gfn);
 extern void (*kvm_mips_release_pfn_clean) (pfn_t pfn);
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index e43aca183c99..af36d2be4d0d 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -394,6 +394,8 @@
 #define CAUSEF_IV  (_ULCAST_(1)   << 23)
 #define CAUSEB_PCI 26
 #define CAUSEF_PCI (_ULCAST_(1)   << 26)
+#define CAUSEB_DC  27
+#define CAUSEF_DC  (_ULCAST_(1)   << 27)
 #define CAUSEB_CE  28
 #define CAUSEF_CE  (_ULCAST_(3)   << 28)
 #define CAUSEB_TI  30
-- 
2.4.10

--
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


[PATCH 08/16] MIPS: Move Cause.ExcCode trap codes to mipsregs.h

2015-12-16 Thread James Hogan
Move the Cause.ExcCode trap code definitions from kvm_host.h to
mipsregs.h, since they describe architectural bits rather than KVM
specific constants, and change the prefix from T_ to EXCCODE_.

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h | 28 
 arch/mips/include/asm/mipsregs.h | 24 ++
 arch/mips/kvm/emulate.c  | 71 
 arch/mips/kvm/interrupt.c|  8 ++---
 arch/mips/kvm/mips.c | 32 +-
 5 files changed, 80 insertions(+), 83 deletions(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 16f647347357..ba8d9acdba30 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -281,34 +281,6 @@ enum mips_mmu_types {
MMU_TYPE_R8000
 };
 
-/*
- * Trap codes
- */
-#define T_INT  0   /* Interrupt pending */
-#define T_TLB_MOD  1   /* TLB modified fault */
-#define T_TLB_LD_MISS  2   /* TLB miss on load or ifetch */
-#define T_TLB_ST_MISS  3   /* TLB miss on a store */
-#define T_ADDR_ERR_LD  4   /* Address error on a load or ifetch */
-#define T_ADDR_ERR_ST  5   /* Address error on a store */
-#define T_BUS_ERR_IFETCH   6   /* Bus error on an ifetch */
-#define T_BUS_ERR_LD_ST7   /* Bus error on a load or store 
*/
-#define T_SYSCALL  8   /* System call */
-#define T_BREAK9   /* Breakpoint */
-#define T_RES_INST 10  /* Reserved instruction exception */
-#define T_COP_UNUSABLE 11  /* Coprocessor unusable */
-#define T_OVFLOW   12  /* Arithmetic overflow */
-
-/*
- * Trap definitions added for r4000 port.
- */
-#define T_TRAP 13  /* Trap instruction */
-#define T_VCEI 14  /* Virtual coherency exception */
-#define T_MSAFPE   14  /* MSA floating point exception */
-#define T_FPE  15  /* Floating point exception */
-#define T_MSADIS   21  /* MSA disabled exception */
-#define T_WATCH23  /* Watch address reference */
-#define T_VCED 31  /* Virtual coherency data */
-
 /* Resume Flags */
 #define RESUME_FLAG_DR (1<<0)  /* Reload guest nonvolatile state? */
 #define RESUME_FLAG_HOST   (1<<1)  /* Resume host? */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index af36d2be4d0d..eb89b877c6c9 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -404,6 +404,30 @@
 #define CAUSEF_BD  (_ULCAST_(1)   << 31)
 
 /*
+ * Cause.ExcCode trap codes.
+ */
+#define EXCCODE_INT0   /* Interrupt pending */
+#define EXCCODE_MOD1   /* TLB modified fault */
+#define EXCCODE_TLBL   2   /* TLB miss on load or ifetch */
+#define EXCCODE_TLBS   3   /* TLB miss on a store */
+#define EXCCODE_ADEL   4   /* Address error on a load or ifetch */
+#define EXCCODE_ADES   5   /* Address error on a store */
+#define EXCCODE_IBE6   /* Bus error on an ifetch */
+#define EXCCODE_DBE7   /* Bus error on a load or store */
+#define EXCCODE_SYS8   /* System call */
+#define EXCCODE_BP 9   /* Breakpoint */
+#define EXCCODE_RI 10  /* Reserved instruction exception */
+#define EXCCODE_CPU11  /* Coprocessor unusable */
+#define EXCCODE_OV 12  /* Arithmetic overflow */
+#define EXCCODE_TR 13  /* Trap instruction */
+#define EXCCODE_VCEI   14  /* Virtual coherency exception */
+#define EXCCODE_MSAFPE 14  /* MSA floating point exception */
+#define EXCCODE_FPE15  /* Floating point exception */
+#define EXCCODE_MSADIS 21  /* MSA disabled exception */
+#define EXCCODE_WATCH  23  /* Watch address reference */
+#define EXCCODE_VCED   31  /* Virtual coherency data */
+
+/*
  * Bits in the coprocessor 0 config register.
  */
 /* Generic bits.  */
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 95b83a6582ef..6ff1dcfc9ef1 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1780,7 +1780,7 @@ enum emulation_result kvm_mips_emulate_syscall(unsigned 
long cause,
kvm_debug("Delivering SYSCALL @ pc %#lx\n", arch->pc);
 
kvm_change_c0_guest_cause(cop0, (0xff),
- (T_SYSCALL << CAUSEB_EXCCODE));
+ (EXCCODE_SYS << CAUSEB_EXCCODE));
 
/* Set PC to the except

[PATCH 16/16] MAINTAINERS: Add KVM for MIPS entry

2015-12-16 Thread James Hogan
I've pretty much been maintaining KVM for MIPS for a while now. Lets
make it more official (and make sure I get Cc'd on relevant patches).

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9bff63cf326e..351944d81f7a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6119,6 +6119,14 @@ F:   arch/arm64/include/uapi/asm/kvm*
 F: arch/arm64/include/asm/kvm*
 F: arch/arm64/kvm/
 
+KERNEL VIRTUAL MACHINE FOR MIPS (KVM/mips)
+M: James Hogan 
+L: linux-m...@linux-mips.org
+S: Supported
+F: arch/mips/include/uapi/asm/kvm*
+F: arch/mips/include/asm/kvm*
+F: arch/mips/kvm/
+
 KEXEC
 M: Eric Biederman 
 W: http://kernel.org/pub/linux/utils/kernel/kexec/
-- 
2.4.10

--
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


[PATCH 15/16] MIPS: KVM: Consistent use of uint*_t in MMIO handling

2015-12-16 Thread James Hogan
Make consistent use of uint8_t in MMIO handling code.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/kvm/emulate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 845fd0d91040..912b39bb7f86 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -2401,7 +2401,7 @@ enum emulation_result kvm_mips_complete_mmio_load(struct 
kvm_vcpu *vcpu,
if (vcpu->mmio_needed == 2)
*gpr = *(int8_t *) run->mmio.data;
else
-   *gpr = *(u8 *) run->mmio.data;
+   *gpr = *(uint8_t *)run->mmio.data;
break;
}
 
-- 
2.4.10

--
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


[PATCH 14/16] MIPS: KVM: Add missing newline to kvm_err()

2015-12-16 Thread James Hogan
Add missing newline to end of kvm_err string when guest PMAP couldn't be
allocated.

Signed-off-by: James Hogan 
Cc: Gleb Natapov 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: kvm@vger.kernel.org
Cc: linux-m...@linux-mips.org
---
 arch/mips/kvm/mips.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 1b688faf2cf3..8bc3977576e6 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -229,7 +229,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
kzalloc(npages * sizeof(unsigned long), GFP_KERNEL);
 
if (!kvm->arch.guest_pmap) {
-   kvm_err("Failed to allocate guest PMAP");
+   kvm_err("Failed to allocate guest PMAP\n");
return;
}
 
-- 
2.4.10

--
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


[PATCH 04/16] MIPS: KVM: Drop unused kvm_mips_host_tlb_inv_index()

2015-12-16 Thread James Hogan
The function kvm_mips_host_tlb_inv_index() is unused, so drop it
completely.

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Paolo Bonzini 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h |  1 -
 arch/mips/kvm/tlb.c  | 37 -
 2 files changed, 38 deletions(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index b14265d8d606..16f647347357 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -678,7 +678,6 @@ extern void kvm_mips_dump_host_tlbs(void);
 extern void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu);
 extern void kvm_mips_flush_host_tlb(int skip_kseg0);
 extern int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned long entryhi);
-extern int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index);
 
 extern int kvm_mips_guest_tlb_lookup(struct kvm_vcpu *vcpu,
 unsigned long entryhi);
diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c
index 3d3f22301a35..2c0997447448 100644
--- a/arch/mips/kvm/tlb.c
+++ b/arch/mips/kvm/tlb.c
@@ -507,43 +507,6 @@ int kvm_mips_host_tlb_inv(struct kvm_vcpu *vcpu, unsigned 
long va)
 }
 EXPORT_SYMBOL(kvm_mips_host_tlb_inv);
 
-/* XXXKYMA: Fix Guest USER/KERNEL no longer share the same ASID */
-int kvm_mips_host_tlb_inv_index(struct kvm_vcpu *vcpu, int index)
-{
-   unsigned long flags, old_entryhi;
-
-   if (index >= current_cpu_data.tlbsize)
-   BUG();
-
-   local_irq_save(flags);
-
-   old_entryhi = read_c0_entryhi();
-
-   write_c0_entryhi(UNIQUE_ENTRYHI(index));
-   mtc0_tlbw_hazard();
-
-   write_c0_index(index);
-   mtc0_tlbw_hazard();
-
-   write_c0_entrylo0(0);
-   mtc0_tlbw_hazard();
-
-   write_c0_entrylo1(0);
-   mtc0_tlbw_hazard();
-
-   tlb_write_indexed();
-   mtc0_tlbw_hazard();
-   tlbw_use_hazard();
-
-   write_c0_entryhi(old_entryhi);
-   mtc0_tlbw_hazard();
-   tlbw_use_hazard();
-
-   local_irq_restore(flags);
-
-   return 0;
-}
-
 void kvm_mips_flush_host_tlb(int skip_kseg0)
 {
unsigned long flags;
-- 
2.4.10

--
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


[PATCH 11/16] MIPS: Break down cacheops.h definitions

2015-12-16 Thread James Hogan
Most of the cache op codes defined in cacheops.h are split into a 2-bit
cache identifier, and a 3-bit cache op code which does largely the same
thing semantically regardless of the cache identifier.

To allow the use of these definitions by KVM for decoding cache ops,
break the definitions down into parts where it makes sense to do so, and
add masks for the Cache and Op field within the cache op.

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: linux-m...@linux-mips.org
---
 arch/mips/include/asm/cacheops.h | 106 +++
 1 file changed, 64 insertions(+), 42 deletions(-)

diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h
index 06b9bc7ea14b..c3212ff26723 100644
--- a/arch/mips/include/asm/cacheops.h
+++ b/arch/mips/include/asm/cacheops.h
@@ -12,54 +12,76 @@
 #define __ASM_CACHEOPS_H
 
 /*
+ * Most cache ops are split into a 2 bit field identifying the cache, and a 3
+ * bit field identifying the cache operation.
+ */
+#define CacheOp_Cache  0x03
+#define CacheOp_Op 0x1c
+
+#define Cache_I0x00
+#define Cache_D0x01
+#define Cache_T0x02
+#define Cache_S0x03
+
+#define Index_Writeback_Inv0x00
+#define Index_Load_Tag 0x04
+#define Index_Store_Tag0x08
+#define Hit_Invalidate 0x10
+#define Hit_Writeback_Inv  0x14/* not with Cache_I though */
+#define Hit_Writeback  0x18
+
+/*
  * Cache Operations available on all MIPS processors with R4000-style caches
  */
-#define Index_Invalidate_I 0x00
-#define Index_Writeback_Inv_D  0x01
-#define Index_Load_Tag_I   0x04
-#define Index_Load_Tag_D   0x05
-#define Index_Store_Tag_I  0x08
-#define Index_Store_Tag_D  0x09
-#define Hit_Invalidate_I   0x10
-#define Hit_Invalidate_D   0x11
-#define Hit_Writeback_Inv_D0x15
+#define Index_Invalidate_I (Cache_I | Index_Writeback_Inv)
+#define Index_Writeback_Inv_D  (Cache_D | Index_Writeback_Inv)
+#define Index_Load_Tag_I   (Cache_I | Index_Load_Tag)
+#define Index_Load_Tag_D   (Cache_D | Index_Load_Tag)
+#define Index_Store_Tag_I  (Cache_I | Index_Store_Tag)
+#define Index_Store_Tag_D  (Cache_D | Index_Store_Tag)
+#define Hit_Invalidate_I   (Cache_I | Hit_Invalidate)
+#define Hit_Invalidate_D   (Cache_D | Hit_Invalidate)
+#define Hit_Writeback_Inv_D(Cache_D | Hit_Writeback_Inv)
 
 /*
  * R4000-specific cacheops
  */
-#define Create_Dirty_Excl_D0x0d
-#define Fill   0x14
-#define Hit_Writeback_I0x18
-#define Hit_Writeback_D0x19
+#define Create_Dirty_Excl_D(Cache_D | 0x0c)
+#define Fill   (Cache_I | 0x14)
+#define Hit_Writeback_I(Cache_I | Hit_Writeback)
+#define Hit_Writeback_D(Cache_D | Hit_Writeback)
 
 /*
  * R4000SC and R4400SC-specific cacheops
  */
-#define Index_Invalidate_SI0x02
-#define Index_Writeback_Inv_SD 0x03
-#define Index_Load_Tag_SI  0x06
-#define Index_Load_Tag_SD  0x07
-#define Index_Store_Tag_SI 0x0A
-#define Index_Store_Tag_SD 0x0B
-#define Create_Dirty_Excl_SD   0x0f
-#define Hit_Invalidate_SI  0x12
-#define Hit_Invalidate_SD  0x13
-#define Hit_Writeback_Inv_SD   0x17
-#define Hit_Writeback_SD   0x1b
-#define Hit_Set_Virtual_SI 0x1e
-#define Hit_Set_Virtual_SD 0x1f
+#define Cache_SI   0x02
+#define Cache_SD   0x03
+
+#define Index_Invalidate_SI(Cache_SI | Index_Writeback_Inv)
+#define Index_Writeback_Inv_SD (Cache_SD | Index_Writeback_Inv)
+#define Index_Load_Tag_SI  (Cache_SI | Index_Load_Tag)
+#define Index_Load_Tag_SD  (Cache_SD | Index_Load_Tag)
+#define Index_Store_Tag_SI (Cache_SI | Index_Store_Tag)
+#define Index_Store_Tag_SD (Cache_SD | Index_Store_Tag)
+#define Create_Dirty_Excl_SD   (Cache_SD | 0x0c)
+#define Hit_Invalidate_SI  (Cache_SI | Hit_Invalidate)
+#define Hit_Invalidate_SD  (Cache_SD | Hit_Invalidate)
+#define Hit_Writeback_Inv_SD   (Cache_SD | Hit_Writeback_Inv)
+#define Hit_Writeback_SD   (Cache_SD | Hit_Writeback)
+#define Hit_Set_Virtual_SI (Cache_SI | 0x1c)
+#define Hit_Set_Virtual_SD (Cache_SD | 0x1c)
 
 /*
  * R5000-specific cacheops
  */
-#define R5K_Page_Invalidate_S  0x17
+#define R5K_Page_Invalidate_S  (Cache_S | 0x14)
 
 /*
  * RM7000-specific cacheops

[PATCH 12/16] MIPS: KVM: Use cacheops.h definitions

2015-12-16 Thread James Hogan
Drop the custom cache operation code definitions used by KVM for
emulating guest CACHE instructions, and switch to use the existing
definitions in .

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: Ralf Baechle 
Cc: kvm@vger.kernel.org
Cc: linux-m...@linux-mips.org
---
 arch/mips/kvm/emulate.c | 30 --
 1 file changed, 8 insertions(+), 22 deletions(-)

diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 6ff1dcfc9ef1..0eb65668d2ab 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1544,19 +1545,6 @@ int kvm_mips_sync_icache(unsigned long va, struct 
kvm_vcpu *vcpu)
return 0;
 }
 
-#define MIPS_CACHE_OP_INDEX_INV 0x0
-#define MIPS_CACHE_OP_INDEX_LD_TAG  0x1
-#define MIPS_CACHE_OP_INDEX_ST_TAG  0x2
-#define MIPS_CACHE_OP_IMP   0x3
-#define MIPS_CACHE_OP_HIT_INV   0x4
-#define MIPS_CACHE_OP_FILL_WB_INV   0x5
-#define MIPS_CACHE_OP_HIT_HB0x6
-#define MIPS_CACHE_OP_FETCH_LOCK0x7
-
-#define MIPS_CACHE_ICACHE   0x0
-#define MIPS_CACHE_DCACHE   0x1
-#define MIPS_CACHE_SEC  0x3
-
 enum emulation_result kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc,
 uint32_t cause,
 struct kvm_run *run,
@@ -1581,8 +1569,8 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t 
inst, uint32_t *opc,
base = (inst >> 21) & 0x1f;
op_inst = (inst >> 16) & 0x1f;
offset = (int16_t)inst;
-   cache = (inst >> 16) & 0x3;
-   op = (inst >> 18) & 0x7;
+   cache = op_inst & CacheOp_Cache;
+   op = op_inst & CacheOp_Op;
 
va = arch->gprs[base] + offset;
 
@@ -1594,14 +1582,14 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t 
inst, uint32_t *opc,
 * invalidate the caches entirely by stepping through all the
 * ways/indexes
 */
-   if (op == MIPS_CACHE_OP_INDEX_INV) {
+   if (op == Index_Writeback_Inv) {
kvm_debug("@ %#lx/%#lx CACHE (cache: %#x, op: %#x, base[%d]: 
%#lx, offset: %#x\n",
  vcpu->arch.pc, vcpu->arch.gprs[31], cache, op, base,
  arch->gprs[base], offset);
 
-   if (cache == MIPS_CACHE_DCACHE)
+   if (cache == Cache_D)
r4k_blast_dcache();
-   else if (cache == MIPS_CACHE_ICACHE)
+   else if (cache == Cache_I)
r4k_blast_icache();
else {
kvm_err("%s: unsupported CACHE INDEX operation\n",
@@ -1674,9 +1662,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t 
inst, uint32_t *opc,
 
 skip_fault:
/* XXXKYMA: Only a subset of cache ops are supported, used by Linux */
-   if (cache == MIPS_CACHE_DCACHE
-   && (op == MIPS_CACHE_OP_FILL_WB_INV
-   || op == MIPS_CACHE_OP_HIT_INV)) {
+   if (op_inst == Hit_Writeback_Inv_D || op_inst == Hit_Invalidate_D) {
flush_dcache_line(va);
 
 #ifdef CONFIG_KVM_MIPS_DYN_TRANS
@@ -1686,7 +1672,7 @@ skip_fault:
 */
kvm_mips_trans_cache_va(inst, opc, vcpu);
 #endif
-   } else if (op == MIPS_CACHE_OP_HIT_INV && cache == MIPS_CACHE_ICACHE) {
+   } else if (op_inst == Hit_Invalidate_I) {
flush_dcache_line(va);
flush_icache_line(va);
 
-- 
2.4.10

--
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


[PATCH 13/16] MIPS: Move KVM specific opcodes into asm/inst.h

2015-12-16 Thread James Hogan
The header arch/mips/kvm/opcode.h defines a few extra opcodes which
aren't in arch/mips/include/uapi/asm/inst.h. There's nothing KVM
specific about them, so lets move them into inst.h where they belong and
delete the header.

Note that mfmcz_op is renamed to mfmc0_op to match the instruction set
manual, and wait_op was already added to inst.h in commit b0a3eae2b943
("MIPS: inst.h: define COP0 wait op"), merged in v3.16-rc1.

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/uapi/asm/inst.h |  3 ++-
 arch/mips/kvm/emulate.c   |  7 +++
 arch/mips/kvm/opcode.h| 22 --
 arch/mips/kvm/trap_emul.c |  1 -
 4 files changed, 5 insertions(+), 28 deletions(-)
 delete mode 100644 arch/mips/kvm/opcode.h

diff --git a/arch/mips/include/uapi/asm/inst.h 
b/arch/mips/include/uapi/asm/inst.h
index 9b44d5a816fa..b5e36a5d9e17 100644
--- a/arch/mips/include/uapi/asm/inst.h
+++ b/arch/mips/include/uapi/asm/inst.h
@@ -116,7 +116,8 @@ enum cop_op {
dmtc_op   = 0x05, ctc_op= 0x06,
mthc0_op  = 0x06, mthc_op   = 0x07,
bc_op = 0x08, bc1eqz_op = 0x09,
-   bc1nez_op = 0x0d, cop_op= 0x10,
+   mfmc0_op  = 0x0b, bc1nez_op = 0x0d,
+   wrpgpr_op = 0x0e, cop_op= 0x10,
copm_op   = 0x18
 };
 
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 0eb65668d2ab..845fd0d91040 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -30,7 +30,6 @@
 #include 
 #define CONFIG_MIPS_MT
 
-#include "opcode.h"
 #include "interrupt.h"
 #include "commpage.h"
 
@@ -1240,7 +1239,7 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, 
uint32_t *opc,
er = EMULATE_FAIL;
break;
 
-   case mfmcz_op:
+   case mfmc0_op:
 #ifdef KVM_MIPS_DEBUG_COP0_COUNTERS
cop0->stat[MIPS_CP0_STATUS][0]++;
 #endif
@@ -1249,11 +1248,11 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t 
inst, uint32_t *opc,
kvm_read_c0_guest_status(cop0);
/* EI */
if (inst & 0x20) {
-   kvm_debug("[%#lx] mfmcz_op: EI\n",
+   kvm_debug("[%#lx] mfmc0_op: EI\n",
  vcpu->arch.pc);
kvm_set_c0_guest_status(cop0, ST0_IE);
} else {
-   kvm_debug("[%#lx] mfmcz_op: DI\n",
+   kvm_debug("[%#lx] mfmc0_op: DI\n",
  vcpu->arch.pc);
kvm_clear_c0_guest_status(cop0, ST0_IE);
}
diff --git a/arch/mips/kvm/opcode.h b/arch/mips/kvm/opcode.h
deleted file mode 100644
index 03a6ae84c7df..
--- a/arch/mips/kvm/opcode.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
- * Authors: Sanjay Lal 
- */
-
-/* Define opcode values not defined in  */
-
-#ifndef __KVM_MIPS_OPCODE_H__
-#define __KVM_MIPS_OPCODE_H__
-
-/* COP0 Ops */
-#define mfmcz_op   0x0b/* 01011 */
-#define wrpgpr_op  0x0e/* 01110 */
-
-/* COP0 opcodes (only if COP0 and CO=1): */
-#define wait_op0x20/* 10 */
-
-#endif /* __KVM_MIPS_OPCODE_H__ */
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
index d836ed5b0bc7..ad988000563f 100644
--- a/arch/mips/kvm/trap_emul.c
+++ b/arch/mips/kvm/trap_emul.c
@@ -16,7 +16,6 @@
 
 #include 
 
-#include "opcode.h"
 #include "interrupt.h"
 
 static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva)
-- 
2.4.10

--
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


[PATCH 02/16] MIPS: KVM: Drop some unused definitions from kvm_host.h

2015-12-16 Thread James Hogan
Some definitions in the MIPS asm/kvm_host.h are completely unused, so
lets drop them.

MS_TO_NS is no longer used since commit e30492bbe95a ("MIPS: KVM:
Rewrite count/compare timer emulation"). The others don't appear ever to
have been used.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: kvm@vger.kernel.org
Cc: linux-m...@linux-mips.org
---
 arch/mips/include/asm/kvm_host.h | 5 -
 1 file changed, 5 deletions(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 6a313157db83..17782205c5db 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -92,11 +92,6 @@
 #define KVM_INVALID_INST   0xdeadbeef
 #define KVM_INVALID_ADDR   0xdeadbeef
 
-#define KVM_MALTA_GUEST_RTC_ADDR   0xb870UL
-
-#define GUEST_TICKS_PER_JIFFY  (4000/HZ)
-#define MS_TO_NS(x)(x * 1E6L)
-
 #define CAUSEB_DC  27
 #define CAUSEF_DC  (_ULCAST_(1) << 27)
 
-- 
2.4.10

--
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


[PATCH 00/16] MIPS: KVM: Misc trivial cleanups

2015-12-16 Thread James Hogan
This patchset contains a bunch of miscellaneous cleanups (which are
mostly trivial) for MIPS KVM & MIPS headers, such as:
- Style/whitespace fixes
- General cleanup and removal of dead code.
- Moving/refactoring of general MIPS definitions out of arch/mips/kvm/
  and into arch/mips/include/asm/ so they can be shared with the rest of
  arch/mips. Specifically COP0 register bits, exception codes, cache
  ops, & instruction opcodes.
- Add MAINTAINERS entry for MIPS KVM.

Due to the interaction with other arch/mips/ code, I think it makes
sense for these to go via the MIPS tree.

James Hogan (16):
  MIPS: KVM: Trivial whitespace and style fixes
  MIPS: KVM: Drop some unused definitions from kvm_host.h
  MIPS: Move definition of DC bit to mipsregs.h
  MIPS: KVM: Drop unused kvm_mips_host_tlb_inv_index()
  MIPS: KVM: Convert EXPORT_SYMBOL to _GPL
  MIPS: KVM: Refactor added offsetof()s
  MIPS: KVM: Make kvm_mips_{init,exit}() static
  MIPS: Move Cause.ExcCode trap codes to mipsregs.h
  MIPS: Update trap codes
  MIPS: Use EXCCODE_ constants with set_except_vector()
  MIPS: Break down cacheops.h definitions
  MIPS: KVM: Use cacheops.h definitions
  MIPS: Move KVM specific opcodes into asm/inst.h
  MIPS: KVM: Add missing newline to kvm_err()
  MIPS: KVM: Consistent use of uint*_t in MMIO handling
  MAINTAINERS: Add KVM for MIPS entry

 MAINTAINERS   |   8 +++
 arch/mips/Kconfig |   3 +-
 arch/mips/include/asm/cacheops.h  | 106 --
 arch/mips/include/asm/kvm_host.h  |  39 +
 arch/mips/include/asm/mipsregs.h  |  34 +++
 arch/mips/include/uapi/asm/inst.h |   3 +-
 arch/mips/kernel/cpu-bugs64.c |   8 +--
 arch/mips/kernel/traps.c  |  52 -
 arch/mips/kvm/callback.c  |   2 +-
 arch/mips/kvm/dyntrans.c  |  10 +---
 arch/mips/kvm/emulate.c   | 118 --
 arch/mips/kvm/interrupt.c |   8 +--
 arch/mips/kvm/locore.S|  12 ++--
 arch/mips/kvm/mips.c  |  38 ++--
 arch/mips/kvm/opcode.h|  22 ---
 arch/mips/kvm/tlb.c   |  77 +++--
 arch/mips/kvm/trap_emul.c |   1 -
 17 files changed, 245 insertions(+), 296 deletions(-)
 delete mode 100644 arch/mips/kvm/opcode.h

Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
-- 
2.4.10

--
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


[PATCH 06/16] MIPS: KVM: Refactor added offsetof()s

2015-12-16 Thread James Hogan
When calculating the offsets into the commpage for dynamically
translated mtc0/mfc0 guest instructions, multiple offsetof()s are added
together to find the offset of the specific register in the mips_coproc,
within the commpage.

Simplify each of these cases to a single offsetof() to find the offset
of the specific register within the commpage.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/kvm/dyntrans.c | 10 +++---
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/arch/mips/kvm/dyntrans.c b/arch/mips/kvm/dyntrans.c
index 521121bdebff..f1527a465c1b 100644
--- a/arch/mips/kvm/dyntrans.c
+++ b/arch/mips/kvm/dyntrans.c
@@ -86,10 +86,8 @@ int kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct 
kvm_vcpu *vcpu)
} else {
mfc0_inst = LW_TEMPLATE;
mfc0_inst |= ((rt & 0x1f) << 16);
-   mfc0_inst |=
-   offsetof(struct mips_coproc,
-reg[rd][sel]) + offsetof(struct kvm_mips_commpage,
- cop0);
+   mfc0_inst |= offsetof(struct kvm_mips_commpage,
+ cop0.reg[rd][sel]);
}
 
if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
@@ -123,9 +121,7 @@ int kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, 
struct kvm_vcpu *vcpu)
sel = inst & 0x7;
 
mtc0_inst |= ((rt & 0x1f) << 16);
-   mtc0_inst |=
-   offsetof(struct mips_coproc,
-reg[rd][sel]) + offsetof(struct kvm_mips_commpage, cop0);
+   mtc0_inst |= offsetof(struct kvm_mips_commpage, cop0.reg[rd][sel]);
 
if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) {
kseg0_opc =
-- 
2.4.10

--
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


[PATCH backport v3.12..v3.14 2/4] MIPS: KVM: Fix ASID restoration logic

2015-12-11 Thread James Hogan
commit 002374f371bd02df864cce1fe85d90dc5b292837 upstream.

ASID restoration on guest resume should determine the guest execution
mode based on the guest Status register rather than bit 30 of the guest
PC.

Fix the two places in locore.S that do this, loading the guest status
from the cop0 area. Note, this assembly is specific to the trap &
emulate implementation of KVM, so it doesn't need to check the
supervisor bit as that mode is not implemented in the guest.

Fixes: b680f70fc111 ("KVM/MIPS32: Entry point for trampolining to...")
Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Signed-off-by: Paolo Bonzini 
Signed-off-by: James Hogan 
---
 arch/mips/kvm/kvm_locore.S | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S
index 03a2db58b22d..ba5ce99c021d 100644
--- a/arch/mips/kvm/kvm_locore.S
+++ b/arch/mips/kvm/kvm_locore.S
@@ -159,9 +159,11 @@ FEXPORT(__kvm_mips_vcpu_run)
 
 FEXPORT(__kvm_mips_load_asid)
/* Set the ASID for the Guest Kernel */
-   INT_SLL t0, t0, 1   /* with kseg0 @ 0x4000, kernel */
-   /* addresses shift to 0x8000 */
-   bltzt0, 1f  /* If kernel */
+   PTR_L   t0, VCPU_COP0(k1)
+   LONG_L  t0, COP0_STATUS(t0)
+   andit0, KSU_USER | ST0_ERL | ST0_EXL
+   xorit0, KSU_USER
+   bnezt0, 1f  /* If kernel */
 INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID/* else user */
 1:
@@ -438,9 +440,11 @@ __kvm_mips_return_to_guest:
mtc0t0, CP0_EPC
 
/* Set the ASID for the Guest Kernel */
-   INT_SLL t0, t0, 1   /* with kseg0 @ 0x4000, kernel */
-   /* addresses shift to 0x8000 */
-   bltzt0, 1f  /* If kernel */
+   PTR_L   t0, VCPU_COP0(k1)
+   LONG_L  t0, COP0_STATUS(t0)
+   andit0, KSU_USER | ST0_ERL | ST0_EXL
+   xorit0, KSU_USER
+   bnezt0, 1f  /* If kernel */
 INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID/* else user */
 1:
-- 
2.4.10

--
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


[PATCH backport v3.10..v3.14 3/4] MIPS: KVM: Fix CACHE immediate offset sign extension

2015-12-11 Thread James Hogan
commit c5c2a3b998f1ff5a586f9d37e154070b8d550d17 upstream.

The immediate field of the CACHE instruction is signed, so ensure that
it gets sign extended by casting it to an int16_t rather than just
masking the low 16 bits.

Fixes: e685c689f3a8 ("KVM/MIPS32: Privileged instruction/target branch 
emulation.")
Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Signed-off-by: Paolo Bonzini 
Signed-off-by: James Hogan 
---
 arch/mips/kvm/kvm_mips_emul.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c
index c76f297b7149..33085819cd89 100644
--- a/arch/mips/kvm/kvm_mips_emul.c
+++ b/arch/mips/kvm/kvm_mips_emul.c
@@ -935,7 +935,7 @@ kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, 
uint32_t cause,
 
base = (inst >> 21) & 0x1f;
op_inst = (inst >> 16) & 0x1f;
-   offset = inst & 0x;
+   offset = (int16_t)inst;
cache = (inst >> 16) & 0x3;
op = (inst >> 18) & 0x7;
 
-- 
2.4.10

--
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


[PATCH backport v3.10..v3.14 4/4] MIPS: KVM: Uninit VCPU in vcpu_create error path

2015-12-11 Thread James Hogan
commit 585bb8f9a5e592f2ce7abbe5ed3112d5438d2754 upstream.

If either of the memory allocations in kvm_arch_vcpu_create() fail, the
vcpu which has been allocated and kvm_vcpu_init'd doesn't get uninit'd
in the error handling path. Add a call to kvm_vcpu_uninit() to fix this.

Fixes: 669e846e6c4e ("KVM/MIPS32: MIPS arch specific APIs for KVM")
Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Signed-off-by: Paolo Bonzini 
Signed-off-by: James Hogan 
---
 arch/mips/kvm/kvm_mips.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c
index 2cb24788a8a6..7e7de1f2b8ed 100644
--- a/arch/mips/kvm/kvm_mips.c
+++ b/arch/mips/kvm/kvm_mips.c
@@ -312,7 +312,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, 
unsigned int id)
 
if (!gebase) {
err = -ENOMEM;
-   goto out_free_cpu;
+   goto out_uninit_cpu;
}
kvm_info("Allocated %d bytes for KVM Exception Handlers @ %p\n",
 ALIGN(size, PAGE_SIZE), gebase);
@@ -372,6 +372,9 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, 
unsigned int id)
 out_free_gebase:
kfree(gebase);
 
+out_uninit_cpu:
+   kvm_vcpu_uninit(vcpu);
+
 out_free_cpu:
kfree(vcpu);
 
-- 
2.4.10

--
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


[PATCH backport v3.10 1/4] MIPS: KVM: Fix ASID restoration logic

2015-12-11 Thread James Hogan
commit 002374f371bd02df864cce1fe85d90dc5b292837 upstream.

ASID restoration on guest resume should determine the guest execution
mode based on the guest Status register rather than bit 30 of the guest
PC.

Fix the two places in locore.S that do this, loading the guest status
from the cop0 area. Note, this assembly is specific to the trap &
emulate implementation of KVM, so it doesn't need to check the
supervisor bit as that mode is not implemented in the guest.

Fixes: b680f70fc111 ("KVM/MIPS32: Entry point for trampolining to...")
Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Signed-off-by: Paolo Bonzini 
Signed-off-by: James Hogan 
---
 arch/mips/kvm/kvm_locore.S | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S
index 920b63210806..34c35f0e3290 100644
--- a/arch/mips/kvm/kvm_locore.S
+++ b/arch/mips/kvm/kvm_locore.S
@@ -156,9 +156,11 @@ FEXPORT(__kvm_mips_vcpu_run)
 
 FEXPORT(__kvm_mips_load_asid)
 /* Set the ASID for the Guest Kernel */
-sll t0, t0, 1   /* with kseg0 @ 0x4000, 
kernel */
-/* addresses shift to 
0x8000 */
-bltzt0, 1f  /* If kernel */
+PTR_L  t0, VCPU_COP0(k1)
+LONG_L t0, COP0_STATUS(t0)
+andi   t0, KSU_USER | ST0_ERL | ST0_EXL
+xori   t0, KSU_USER
+bnez   t0, 1f  /* If kernel */
addiu   t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
 addiu   t1, k1, VCPU_GUEST_USER_ASID/* else user */
 1:
@@ -442,9 +444,11 @@ __kvm_mips_return_to_guest:
mtc0t0, CP0_EPC
 
 /* Set the ASID for the Guest Kernel */
-sll t0, t0, 1   /* with kseg0 @ 0x4000, 
kernel */
-/* addresses shift to 
0x8000 */
-bltzt0, 1f  /* If kernel */
+PTR_L  t0, VCPU_COP0(k1)
+LONG_L t0, COP0_STATUS(t0)
+andi   t0, KSU_USER | ST0_ERL | ST0_EXL
+xori   t0, KSU_USER
+bnez   t0, 1f  /* If kernel */
addiu   t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
 addiu   t1, k1, VCPU_GUEST_USER_ASID/* else user */
 1:
-- 
2.4.10

--
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


Re: [PATCH 0/3] MIPS: KVM: Misc fixes

2015-11-11 Thread James Hogan
Hi Paolo,

On Wed, Nov 11, 2015 at 03:43:14PM +0100, Paolo Bonzini wrote:
> On 11/11/2015 15:21, James Hogan wrote:
> > A few misc MIPS KVM fixes for issues that have been around since the
> > code was merged in v3.10.
> > 
> > James Hogan (3):
> >   MIPS: KVM: Fix ASID restoration logic
> >   MIPS: KVM: Fix CACHE immediate offset sign extension
> >   MIPS: KVM: Uninit VCPU in vcpu_create error path
> > 
> >  arch/mips/kvm/emulate.c |  2 +-
> >  arch/mips/kvm/locore.S  | 16 ++--
> >  arch/mips/kvm/mips.c|  5 -
> >  3 files changed, 15 insertions(+), 8 deletions(-)
> > 
> > Cc: Ralf Baechle 
> > Cc: Paolo Bonzini 
> > Cc: Gleb Natapov 
> > Cc: linux-m...@linux-mips.org
> > Cc: kvm@vger.kernel.org
> > Cc: 
> > 
> 
> Thanks, these will have to wait after the end of the merge window.

Okay, no problem. As long as they can make v4.4.

For the record do you prefer not to receive patches during merge window?

Thanks
James


signature.asc
Description: Digital signature


[PATCH 2/3] MIPS: KVM: Fix CACHE immediate offset sign extension

2015-11-11 Thread James Hogan
The immediate field of the CACHE instruction is signed, so ensure that
it gets sign extended by casting it to an int16_t rather than just
masking the low 16 bits.

Fixes: e685c689f3a8 ("KVM/MIPS32: Privileged instruction/target branch 
emulation.")
Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc:  # 3.10.x-
---
 arch/mips/kvm/emulate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index d5fa3eaf39a1..41b1b090f56f 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1581,7 +1581,7 @@ enum emulation_result kvm_mips_emulate_cache(uint32_t 
inst, uint32_t *opc,
 
base = (inst >> 21) & 0x1f;
op_inst = (inst >> 16) & 0x1f;
-   offset = inst & 0x;
+   offset = (int16_t)inst;
cache = (inst >> 16) & 0x3;
op = (inst >> 18) & 0x7;
 
-- 
2.4.10

--
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


[PATCH 0/3] MIPS: KVM: Misc fixes

2015-11-11 Thread James Hogan
A few misc MIPS KVM fixes for issues that have been around since the
code was merged in v3.10.

James Hogan (3):
  MIPS: KVM: Fix ASID restoration logic
  MIPS: KVM: Fix CACHE immediate offset sign extension
  MIPS: KVM: Uninit VCPU in vcpu_create error path

 arch/mips/kvm/emulate.c |  2 +-
 arch/mips/kvm/locore.S  | 16 ++--
 arch/mips/kvm/mips.c|  5 -
 3 files changed, 15 insertions(+), 8 deletions(-)

Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: 
-- 
2.4.10

--
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


[PATCH 1/3] MIPS: KVM: Fix ASID restoration logic

2015-11-11 Thread James Hogan
ASID restoration on guest resume should determine the guest execution
mode based on the guest Status register rather than bit 30 of the guest
PC.

Fix the two places in locore.S that do this, loading the guest status
from the cop0 area. Note, this assembly is specific to the trap &
emulate implementation of KVM, so it doesn't need to check the
supervisor bit as that mode is not implemented in the guest.

Fixes: b680f70fc111 ("KVM/MIPS32: Entry point for trampolining to...")
Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc:  # 3.10.x-
---
 arch/mips/kvm/locore.S | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/mips/kvm/locore.S b/arch/mips/kvm/locore.S
index c567240386a0..d1ee95a7f7dd 100644
--- a/arch/mips/kvm/locore.S
+++ b/arch/mips/kvm/locore.S
@@ -165,9 +165,11 @@ FEXPORT(__kvm_mips_vcpu_run)
 
 FEXPORT(__kvm_mips_load_asid)
/* Set the ASID for the Guest Kernel */
-   INT_SLL t0, t0, 1   /* with kseg0 @ 0x4000, kernel */
-   /* addresses shift to 0x8000 */
-   bltzt0, 1f  /* If kernel */
+   PTR_L   t0, VCPU_COP0(k1)
+   LONG_L  t0, COP0_STATUS(t0)
+   andit0, KSU_USER | ST0_ERL | ST0_EXL
+   xorit0, KSU_USER
+   bnezt0, 1f  /* If kernel */
 INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID/* else user */
 1:
@@ -482,9 +484,11 @@ __kvm_mips_return_to_guest:
mtc0t0, CP0_EPC
 
/* Set the ASID for the Guest Kernel */
-   INT_SLL t0, t0, 1   /* with kseg0 @ 0x4000, kernel */
-   /* addresses shift to 0x8000 */
-   bltzt0, 1f  /* If kernel */
+   PTR_L   t0, VCPU_COP0(k1)
+   LONG_L  t0, COP0_STATUS(t0)
+   andit0, KSU_USER | ST0_ERL | ST0_EXL
+   xorit0, KSU_USER
+   bnezt0, 1f  /* If kernel */
 INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID  /* (BD)  */
INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID/* else user */
 1:
-- 
2.4.10

--
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


[PATCH 3/3] MIPS: KVM: Uninit VCPU in vcpu_create error path

2015-11-11 Thread James Hogan
If either of the memory allocations in kvm_arch_vcpu_create() fail, the
vcpu which has been allocated and kvm_vcpu_init'd doesn't get uninit'd
in the error handling path. Add a call to kvm_vcpu_uninit() to fix this.

Fixes: 669e846e6c4e ("KVM/MIPS32: MIPS arch specific APIs for KVM")
Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc:  # 3.10.x-
---
 arch/mips/kvm/mips.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 49ff3bfc007e..b9b803facdbf 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -279,7 +279,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, 
unsigned int id)
 
if (!gebase) {
err = -ENOMEM;
-   goto out_free_cpu;
+   goto out_uninit_cpu;
}
kvm_debug("Allocated %d bytes for KVM Exception Handlers @ %p\n",
  ALIGN(size, PAGE_SIZE), gebase);
@@ -343,6 +343,9 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, 
unsigned int id)
 out_free_gebase:
kfree(gebase);
 
+out_uninit_cpu:
+   kvm_vcpu_uninit(vcpu);
+
 out_free_cpu:
kfree(vcpu);
 
-- 
2.4.10

--
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


[PATCH] MIPS: KVM: Fix CP0_EBASE redefined build warning

2015-11-10 Thread James Hogan
The patch "MIPS: CPS: Early debug using an ns16550-compatible UART" in
linux-next causes a build warning in locore.S by adding an identical
definition of CP0_EBASE in asm/mipsregs.h.

arch/mips/kvm/locore.S:41:0: warning: "CP0_EBASE" redefined
 #define CP0_EBASE   $15,1
 ^
In file included from ./arch/mips/include/asm/msa.h:13:0,
 from ./arch/mips/include/asm/asmmacro.h:13,
 from arch/mips/kvm/locore.S:13:
./arch/mips/include/asm/mipsregs.h:62:0: note: this is the location of the 
previous definition
 #define CP0_EBASE $15, 1
 ^

Remove the definition in locore.S and move a few of the other similar
definitions in asm/mipsregs.h too. CP0_INTCTL, CP0_SRSCTL, & CP0_SRSMAP
are unused so they're just dropped instead. CP0_DDATA_LO is left where
it is as I have patches to eliminate its use in locore.S and it
otherwise is unlikely to need to be used from assembly code.

Fixes: "MIPS: CPS: Early debug using an ns16550-compatible UART"
Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paul Burton 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
Ralf: Please can you take this patch, as the thing it fixes is in the
mips-for-linux-next branch.
---
 arch/mips/include/asm/mipsregs.h | 3 +++
 arch/mips/kvm/locore.S   | 8 
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index e7c1e28438e0..e43aca183c99 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -50,6 +50,7 @@
 #define CP0_PAGEMASK $5
 #define CP0_WIRED $6
 #define CP0_INFO $7
+#define CP0_HWRENA $7, 0
 #define CP0_BADVADDR $8
 #define CP0_BADINSTR $8, 1
 #define CP0_COUNT $9
@@ -62,6 +63,8 @@
 #define CP0_EBASE $15, 1
 #define CP0_CMGCRBASE $15, 3
 #define CP0_CONFIG $16
+#define CP0_CONFIG3 $16, 3
+#define CP0_CONFIG5 $16, 5
 #define CP0_LLADDR $17
 #define CP0_WATCHLO $18
 #define CP0_WATCHHI $19
diff --git a/arch/mips/kvm/locore.S b/arch/mips/kvm/locore.S
index c567240386a0..7bab3a4e8f7d 100644
--- a/arch/mips/kvm/locore.S
+++ b/arch/mips/kvm/locore.S
@@ -36,14 +36,6 @@
 #define PT_HOST_USERLOCAL   PT_EPC
 
 #define CP0_DDATA_LO$28,3
-#define CP0_CONFIG3 $16,3
-#define CP0_CONFIG5 $16,5
-#define CP0_EBASE   $15,1
-
-#define CP0_INTCTL  $12,1
-#define CP0_SRSCTL  $12,2
-#define CP0_SRSMAP  $12,3
-#define CP0_HWRENA  $7,0
 
 /* Resume Flags */
 #define RESUME_FLAG_HOST(1<<1)  /* Resume host? */
-- 
2.4.10

--
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


Re: [PATCH v3 2/3] target-i386: calculate vcpu's TSC rate to be migrated

2015-11-02 Thread James Hogan
On Mon, Nov 02, 2015 at 05:26:42PM +0800, Haozhong Zhang wrote:
> The value of the migrated vcpu's TSC rate is determined as below.
>  1. If a TSC rate is specified by the cpu option 'tsc-freq', then this
> user-specified value will be used.
>  2. If neither a user-specified TSC rate nor a migrated TSC rate is
> present, we will use the TSC rate from KVM (returned by
> KVM_GET_TSC_KHZ).
>  3. Otherwise, we will use the migrated TSC rate.
> 
> Signed-off-by: Haozhong Zhang 
> ---
>  include/sysemu/kvm.h |  2 ++
>  kvm-all.c|  1 +
>  target-arm/kvm.c |  5 +
>  target-i386/kvm.c| 33 +
>  target-mips/kvm.c|  5 +
>  target-ppc/kvm.c |  5 +
>  target-s390x/kvm.c   |  5 +
>  7 files changed, 56 insertions(+)
> 
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index 461ef65..0ec8b98 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -328,6 +328,8 @@ int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry 
> *route,
>  
>  int kvm_arch_msi_data_to_gsi(uint32_t data);
>  
> +int kvm_arch_setup_tsc_khz(CPUState *cpu);
> +
>  int kvm_set_irq(KVMState *s, int irq, int level);
>  int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
>  
> diff --git a/kvm-all.c b/kvm-all.c
> index c442838..1ecaf04 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -1757,6 +1757,7 @@ static void do_kvm_cpu_synchronize_post_init(void *arg)
>  {
>  CPUState *cpu = arg;
>  
> +kvm_arch_setup_tsc_khz(cpu);

Sorry if this is a stupid question, but why aren't you doing this from
the i386 kvm_arch_put_registers when level == KVM_PUT_FULL_STATE, rather
than introducing x86 specifics to the generic KVM api?

Cheers
James

>  kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
>  cpu->kvm_vcpu_dirty = false;
>  }
> diff --git a/target-arm/kvm.c b/target-arm/kvm.c
> index 79ef4c6..a724f6d 100644
> --- a/target-arm/kvm.c
> +++ b/target-arm/kvm.c
> @@ -614,3 +614,8 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
>  {
>  return (data - 32) & 0x;
>  }
> +
> +int kvm_arch_setup_tsc_khz(CPUState *cs)
> +{
> +return 0;
> +}
> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index 64046cb..aae5e58 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -3034,3 +3034,36 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
>  {
>  abort();
>  }
> +
> +int kvm_arch_setup_tsc_khz(CPUState *cs)
> +{
> +X86CPU *cpu = X86_CPU(cs);
> +CPUX86State *env = &cpu->env;
> +int r;
> +
> +/*
> + * Prepare vcpu's TSC rate to be migrated.
> + *
> + * - If the user specifies the TSC rate by cpu option 'tsc-freq',
> + *   we will use the user-specified value.
> + *
> + * - If there is neither user-specified TSC rate nor migrated TSC
> + *   rate, we will ask KVM for the TSC rate by calling
> + *   KVM_GET_TSC_KHZ.
> + *
> + * - Otherwise, if there is a migrated TSC rate, we will use the
> + *   migrated value.
> + */
> +if (env->tsc_khz) {
> +env->tsc_khz_saved = env->tsc_khz;
> +} else if (!env->tsc_khz_saved) {
> +r = kvm_vcpu_ioctl(cs, KVM_GET_TSC_KHZ);
> +if (r < 0) {
> +fprintf(stderr, "KVM_GET_TSC_KHZ failed\n");
> +return r;
> +}
> +env->tsc_khz_saved = r;
> +}
> +
> +return 0;
> +}
> diff --git a/target-mips/kvm.c b/target-mips/kvm.c
> index 12d7db3..fb26d7e 100644
> --- a/target-mips/kvm.c
> +++ b/target-mips/kvm.c
> @@ -687,3 +687,8 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
>  {
>  abort();
>  }
> +
> +int kvm_arch_setup_tsc_khz(CPUState *cs)
> +{
> +return 0;
> +}
> diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
> index ac70f08..c429f0c 100644
> --- a/target-ppc/kvm.c
> +++ b/target-ppc/kvm.c
> @@ -2510,3 +2510,8 @@ int kvmppc_enable_hwrng(void)
>  
>  return kvmppc_enable_hcall(kvm_state, H_RANDOM);
>  }
> +
> +int kvm_arch_setup_tsc_khz(CPUState *cs)
> +{
> +return 0;
> +}
> diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
> index c3be180..db5d436 100644
> --- a/target-s390x/kvm.c
> +++ b/target-s390x/kvm.c
> @@ -2248,3 +2248,8 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
>  {
>  abort();
>  }
> +
> +int kvm_arch_setup_tsc_khz(CPUState *cs)
> +{
> +return 0;
> +}
> -- 
> 2.4.8
> 


signature.asc
Description: Digital signature


Re: [PATCH for 2.4 0/2] MIPS build fixes for v2.4

2015-07-09 Thread James Hogan
On 09/07/15 14:59, Peter Maydell wrote:
> On 9 July 2015 at 12:52, Leon Alrae  wrote:
>> On 09/07/2015 10:17, James Hogan wrote:
>>> These two patches fix build errors for the MIPS TCG backend and MIPS
>>> KVM.
>>>
>>> Please could they be applied for v2.4.
>>>
>>> James Hogan (2):
>>>   tcg/mips: Fix build error from merged memop+mmu_idx parameter
>>>   mips/kvm: Sync with newer MIPS KVM headers
>>>
>>>  target-mips/kvm.c | 15 ++-
>>>  tcg/mips/tcg-target.c |  4 ++--
>>>  2 files changed, 4 insertions(+), 15 deletions(-)
>>
>> Reviewed-by: Leon Alrae 
>>
>> Peter, since these are build fixes, could they be squeezed into rc0?
> 
> Applied to master, thanks.

Thanks guys!

James



signature.asc
Description: OpenPGP digital signature


[PATCH for 2.4 2/2] mips/kvm: Sync with newer MIPS KVM headers

2015-07-09 Thread James Hogan
The KVM_REG_MIPS_COUNT_* definitions are now included in
linux-headers/asm-mips/kvm.h since commit b061808d39fa ("linux-headers:
update linux headers to kvm/next"), therefore the duplicate definitions
in target-mips/kvm.c can now be dropped (the definitions were tweaked
slightly in commit 7a52ce8a1607 ("linux-headers: update") which
triggered the following build warnings turned errors):

target-mips/kvm.c:232:0: error: "KVM_REG_MIPS_COUNT_CTL" redefined [-Werror]
linux-headers/asm/kvm.h:129:0: note: this is the location of the previous 
definition
target-mips/kvm.c:236:0: error: "KVM_REG_MIPS_COUNT_RESUME" redefined [-Werror]
linux-headers/asm/kvm.h:141:0: note: this is the location of the previous 
definition
target-mips/kvm.c:239:0: error: "KVM_REG_MIPS_COUNT_HZ" redefined [-Werror]
linux-headers/asm/kvm.h:147:0: note: this is the location of the previous 
definition

Also update the MIPS_C0_{32,64} macros to utilise definitions more
recently added to the asm-mips/kvm.h header.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
Cc: kvm@vger.kernel.org
---
 target-mips/kvm.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 7d2293d93492..bd64a70bcda0 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -212,10 +212,10 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 }
 
 #define MIPS_CP0_32(_R, _S) \
-(KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x1 | (8 * (_R) + (_S)))
+(KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S)))
 
 #define MIPS_CP0_64(_R, _S) \
-(KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x1 | (8 * (_R) + (_S)))
+(KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
 
 #define KVM_REG_MIPS_CP0_INDEX  MIPS_CP0_32(0, 0)
 #define KVM_REG_MIPS_CP0_CONTEXTMIPS_CP0_64(4, 0)
@@ -232,17 +232,6 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
-/* CP0_Count control */
-#define KVM_REG_MIPS_COUNT_CTL  (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
- 0x2 | 0)
-#define KVM_REG_MIPS_COUNT_CTL_DC   0x0001  /* master disable */
-/* CP0_Count resume monotonic nanoseconds */
-#define KVM_REG_MIPS_COUNT_RESUME   (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
- 0x2 | 1)
-/* CP0_Count rate in Hz */
-#define KVM_REG_MIPS_COUNT_HZ   (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
- 0x2 | 2)
-
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
int32_t *addr)
 {
-- 
2.3.6

--
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


[PATCH for 2.4 0/2] MIPS build fixes for v2.4

2015-07-09 Thread James Hogan
These two patches fix build errors for the MIPS TCG backend and MIPS
KVM.

Please could they be applied for v2.4.

James Hogan (2):
  tcg/mips: Fix build error from merged memop+mmu_idx parameter
  mips/kvm: Sync with newer MIPS KVM headers

 target-mips/kvm.c | 15 ++-
 tcg/mips/tcg-target.c |  4 ++--
 2 files changed, 4 insertions(+), 15 deletions(-)

Cc: Aurelien Jarno 
Cc: Leon Alrae 
Cc: Richard Henderson 
Cc: Peter Maydell 
Cc: Paolo Bonzini 
Cc: kvm@vger.kernel.org
-- 
2.3.6

--
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


Re: [PATCH 0/2] mips/kvm: Fixes for big endian & MIPS64 hosts

2015-07-08 Thread James Hogan
Hi Paolo,

On 24/04/15 11:26, James Hogan wrote:
> A couple of small fixes for accessing 32-bit KVM registers on big
> endian, and to sign extend struct kvm_regs registers so as to work on
> MIPS64 hosts.
> 
> James Hogan (2):
>   mips/kvm: Fix Big endian 32-bit register access
>   mips/kvm: Sign extend registers written to KVM

Any chance of applying these in time for v2.4?

Thanks
James

> 
>  target-mips/kvm.c | 21 +++--
>  1 file changed, 7 insertions(+), 14 deletions(-)
> 
> Cc: Paolo Bonzini 
> Cc: Leon Alrae 
> Cc: Aurelien Jarno 
> Cc: kvm@vger.kernel.org
> Cc: qemu-sta...@nongnu.org
> 



signature.asc
Description: OpenPGP digital signature


[PATCH stable <3.17] MIPS: KVM: Do not sign extend on unsigned MMIO load

2015-07-08 Thread James Hogan
From: Nicholas Mc Guire 

commit ed9244e6c534612d2b5ae47feab2f55a0d4b4ced upstream.

Fix possible unintended sign extension in unsigned MMIO loads by casting
to uint16_t in the case of mmio_needed != 2.

Signed-off-by: Nicholas Mc Guire 
Reviewed-by: James Hogan 
Tested-by: James Hogan 
Cc: Gleb Natapov 
Cc: Paolo Bonzini 
Cc: kvm@vger.kernel.org
Cc: linux-m...@linux-mips.org
Cc: linux-ker...@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/9985/
Signed-off-by: Ralf Baechle 
Cc:  # v3.10+
Signed-off-by: James Hogan 
---
This is a trivial backport (i.e. git cherry-pick, git format-patch) for
stable branches before v3.17, due to the commit d7d5b05faf16 ("MIPS:
KVM: Rename files to remove the prefix "kvm_" and "kvm_mips_"") which
renamed a bunch of files including this one.
---
 arch/mips/kvm/kvm_mips_emul.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c
index e75ef8219caf..c76f297b7149 100644
--- a/arch/mips/kvm/kvm_mips_emul.c
+++ b/arch/mips/kvm/kvm_mips_emul.c
@@ -1626,7 +1626,7 @@ kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
if (vcpu->mmio_needed == 2)
*gpr = *(int16_t *) run->mmio.data;
else
-   *gpr = *(int16_t *) run->mmio.data;
+   *gpr = *(uint16_t *)run->mmio.data;
 
break;
case 1:
-- 
2.3.6

--
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


Re: [PATCH] MIPS: KVM: do not sign extend on unsigned MMIO load

2015-06-08 Thread James Hogan
Hi stable folk,

On 08/05/15 15:16, James Hogan wrote:
> On 07/05/15 13:47, Nicholas Mc Guire wrote:
>> Fix possible unintended sign extension in unsigned MMIO loads by casting
>> to uint16_t in the case of mmio_needed != 2.
>>
>> Signed-off-by: Nicholas Mc Guire 
> 
> Looks good to me. I wrote an MMIO test to reproduce the issue, and this
> fixes it.
> 
> Reviewed-by: James Hogan 
> Tested-by: James Hogan 
> 
> It looks suitable for stable too (3.10+).

This has reached mainline, commit ed9244e6c534612d2b5ae47feab2f55a0d4b4ced

Please could it be added to stable (3.10+).

Thanks
James


> 
> Cheers
> James
> 
>> ---
>>
>> Thanks to James Hogan  for the explaination of 
>> mmio_needed (there is not really any helpful comment in the code on this)
>> in this case (mmio_needed!=2) it should be unsigned.
>>
>> Patch was only compile tested msp71xx_defconfig + CONFIG_KVM=m
>>
>> Patch is against 4.1-rc2 (localversion-next is -next-20150506)
>>
>>  arch/mips/kvm/emulate.c |2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
>> index 6230f37..2f0fc60 100644
>> --- a/arch/mips/kvm/emulate.c
>> +++ b/arch/mips/kvm/emulate.c
>> @@ -2415,7 +2415,7 @@ enum emulation_result 
>> kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
>>  if (vcpu->mmio_needed == 2)
>>  *gpr = *(int16_t *) run->mmio.data;
>>  else
>> -*gpr = *(int16_t *) run->mmio.data;
>> +*gpr = *(uint16_t *)run->mmio.data;
>>  
>>  break;
>>  case 1:
>>
> 



signature.asc
Description: OpenPGP digital signature


[PATCH 2/2] mips/kvm: Sign extend registers written to KVM

2015-04-24 Thread James Hogan
In case we're running on a 64-bit host, be sure to sign extend the
general purpose registers and hi/lo/pc before writing them to KVM, so as
to take advantage of MIPS32/MIPS64 compatibility.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
Cc: kvm@vger.kernel.org
Cc: qemu-sta...@nongnu.org
---
 target-mips/kvm.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 1597bbeac17a..d5388ca27568 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -633,12 +633,12 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 
 /* Set the registers based on QEMU's view of things */
 for (i = 0; i < 32; i++) {
-regs.gpr[i] = env->active_tc.gpr[i];
+regs.gpr[i] = (int64_t)(target_long)env->active_tc.gpr[i];
 }
 
-regs.hi = env->active_tc.HI[0];
-regs.lo = env->active_tc.LO[0];
-regs.pc = env->active_tc.PC;
+regs.hi = (int64_t)(target_long)env->active_tc.HI[0];
+regs.lo = (int64_t)(target_long)env->active_tc.LO[0];
+regs.pc = (int64_t)(target_long)env->active_tc.PC;
 
 ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, ®s);
 
-- 
2.0.5

--
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


[PATCH 1/2] mips/kvm: Fix Big endian 32-bit register access

2015-04-24 Thread James Hogan
Fix access to 32-bit registers on big endian targets. The pointer passed
to the kernel must be for the actual 32-bit value, not a temporary
64-bit value, otherwise on big endian systems the kernel will only
interpret the upper half.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
Cc: kvm@vger.kernel.org
Cc: qemu-sta...@nongnu.org
---
 target-mips/kvm.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 4d1f7ead8142..1597bbeac17a 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -240,10 +240,9 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
int32_t *addr)
 {
-uint64_t val64 = *addr;
 struct kvm_one_reg cp0reg = {
 .id = reg_id,
-.addr = (uintptr_t)&val64
+.addr = (uintptr_t)addr
 };
 
 return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
@@ -275,18 +274,12 @@ static inline int kvm_mips_put_one_reg64(CPUState *cs, 
uint64_t reg_id,
 static inline int kvm_mips_get_one_reg(CPUState *cs, uint64_t reg_id,
int32_t *addr)
 {
-int ret;
-uint64_t val64 = 0;
 struct kvm_one_reg cp0reg = {
 .id = reg_id,
-.addr = (uintptr_t)&val64
+.addr = (uintptr_t)addr
 };
 
-ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
-if (ret >= 0) {
-*addr = val64;
-}
-return ret;
+return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
 }
 
 static inline int kvm_mips_get_one_ulreg(CPUState *cs, uint64 reg_id,
-- 
2.0.5

--
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


[PATCH 0/2] mips/kvm: Fixes for big endian & MIPS64 hosts

2015-04-24 Thread James Hogan
A couple of small fixes for accessing 32-bit KVM registers on big
endian, and to sign extend struct kvm_regs registers so as to work on
MIPS64 hosts.

James Hogan (2):
  mips/kvm: Fix Big endian 32-bit register access
  mips/kvm: Sign extend registers written to KVM

 target-mips/kvm.c | 21 +++--
 1 file changed, 7 insertions(+), 14 deletions(-)

Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
Cc: kvm@vger.kernel.org
Cc: qemu-sta...@nongnu.org
-- 
2.0.5

--
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


Re: [3.13.y-ckt stable] Patch "MIPS: Export FP functions used by lose_fpu(1) for KVM" has been added to staging queue

2015-03-31 Thread James Hogan
Hi Kamal,

On Tue, Mar 31, 2015 at 11:46:43AM -0700, Kamal Mostafa wrote:
> This is a note to let you know that I have just added a patch titled
> 
> MIPS: Export FP functions used by lose_fpu(1) for KVM
> 
> to the linux-3.13.y-queue branch of the 3.13.y-ckt extended stable tree 
> which can be found at:
> 
>  
> http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.13.y-queue
> 
> This patch is scheduled to be released in version 3.13.11-ckt18.
> 
> If you, or anyone else, feels it should not be added to this tree, please 
> reply to this email.
> 
> For more information about the 3.13.y-ckt tree, see
> https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
> 
> Thanks.
> -Kamal
> 
> --
> 
> From 7adee277d64254de602234e7e53691d729f5e50c Mon Sep 17 00:00:00 2001
> From: James Hogan 
> Date: Tue, 10 Feb 2015 10:02:59 +
> Subject: MIPS: Export FP functions used by lose_fpu(1) for KVM
> 
> commit 3ce465e04bfd8de9956d515d6e9587faac3375dc upstream.
> 
> Export the _save_fp asm function used by the lose_fpu(1) macro to GPL
> modules so that KVM can make use of it when it is built as a module.
> 
> This fixes the following build error when CONFIG_KVM=m due to commit
> f798217dfd03 ("KVM: MIPS: Don't leak FPU/DSP to guest"):
> 
> ERROR: "_save_fp" [arch/mips/kvm/kvm.ko] undefined!
> 
> Signed-off-by: James Hogan 
> Fixes: f798217dfd03 (KVM: MIPS: Don't leak FPU/DSP to guest)
> Cc: Paolo Bonzini 
> Cc: Ralf Baechle 
> Cc: Paul Burton 
> Cc: Gleb Natapov 
> Cc: kvm@vger.kernel.org
> Cc: linux-m...@linux-mips.org
> Patchwork: https://patchwork.linux-mips.org/patch/9260/
> Signed-off-by: Ralf Baechle 
> Signed-off-by: Kamal Mostafa 
> ---
>  arch/mips/kernel/mips_ksyms.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
> index 6e58e97..60adf79 100644
> --- a/arch/mips/kernel/mips_ksyms.c
> +++ b/arch/mips/kernel/mips_ksyms.c
> @@ -14,6 +14,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
> 
>  extern void *__bzero(void *__s, size_t __count);
>  extern long __strncpy_from_user_nocheck_asm(char *__to,
> @@ -26,6 +27,11 @@ extern long __strnlen_user_nocheck_asm(const char *s);
>  extern long __strnlen_user_asm(const char *s);
> 
>  /*
> + * Core architecture code
> + */
> +EXPORT_SYMBOL_GPL(_save_fp);

Before v3.16 this will cause a build error with cavium_octeon_defconfig.
I submitted an updated stable patch for v3.10, v3.12, and v3.14, which
should be suitable for v3.13 too. See:
https://marc.info/?l=linux-mips&m=142557178417268&w=2

Cheers
James

> +
> +/*
>   * String functions
>   */
>  EXPORT_SYMBOL(memset);
> --
> 1.9.1
> 


signature.asc
Description: Digital signature


[GIT PULL] MIPS KVM Guest FPU & SIMD (MSA) Support for 4.1

2015-03-30 Thread James Hogan
Hi Paolo, Marcelo,

Here is the MIPS guest FPU & SIMD (MSA) work. I've based this on
kvm/queue as of Friday, and it also pulls in some MIPS FP/MSA fixes from
a branch in Ralf's MIPS tree. Hope that's okay.

Please pull

Thanks
James

The following changes since commit b3a2a9076d3149781c8622d6a98a51045ff946e4:

  KVM: nVMX: Add support for rdtscp (2015-03-26 22:33:48 -0300)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jhogan/kvm-mips.git 
tags/kvm_mips_20150327

for you to fetch changes up to d952bd070f79b6dcbad52c03dbc41cbc8ba086c8:

  MIPS: KVM: Wire up MSA capability (2015-03-27 21:25:22 +)


MIPS KVM Guest FPU & SIMD (MSA) Support

Add guest FPU and MIPS SIMD Architecture (MSA) support to MIPS KVM, by
enabling the host FPU/MSA while in guest mode. This adds two new KVM
capabilities, KVM_CAP_MIPS_FPU & KVM_CAP_MIPS_MSA, and supports the 3 FP
register modes (FR=0, FR=1, FRE=1), and 128-bit MSA vector registers,
with lazy FPU/MSA context save and restore.

Some required MIPS FP/MSA fixes are merged in from a branch in the MIPS
tree first.

--------
James Hogan (24):
  MIPS: lose_fpu(): Disable FPU when MSA enabled
  Revert "MIPS: Don't assume 64-bit FP registers for context switch"
  MIPS: MSA: Fix big-endian FPR_IDX implementation
  Merge branch '4.1-fp' of 
git://git.linux-mips.org/pub/scm/ralf/upstream-sfr into kvm_mips_queue
  MIPS: KVM: Handle MSA Disabled exceptions from guest
  MIPS: Clear [MSA]FPE CSR.Cause after notify_die()
  MIPS: KVM: Handle TRAP exceptions from guest kernel
  MIPS: KVM: Implement PRid CP0 register access
  MIPS: KVM: Sort kvm_mips_get_reg() registers
  MIPS: KVM: Drop pr_info messages on init/exit
  MIPS: KVM: Clean up register definitions a little
  MIPS: KVM: Simplify default guest Config registers
  MIPS: KVM: Add Config4/5 and writing of Config registers
  MIPS: KVM: Add vcpu_get_regs/vcpu_set_regs callback
  MIPS: KVM: Add base guest FPU support
  MIPS: KVM: Emulate FPU bits in COP0 interface
  MIPS: KVM: Add FP exception handling
  MIPS: KVM: Expose FPU registers
  MIPS: KVM: Wire up FPU capability
  MIPS: KVM: Add base guest MSA support
  MIPS: KVM: Emulate MSA bits in COP0 interface
  MIPS: KVM: Add MSA exception handling
  MIPS: KVM: Expose MSA registers
  MIPS: KVM: Wire up MSA capability

Paul Burton (8):
  MIPS: Push .set mips64r* into the functions needing it
  MIPS: assume at as source/dest of MSA copy/insert instructions
  MIPS: remove MSA macro recursion
  MIPS: wrap cfcmsa & ctcmsa accesses for toolchains with MSA support
  MIPS: clear MSACSR cause bits when handling MSA FP exception
  MIPS: Ensure FCSR cause bits are clear after invoking FPU emulator
  MIPS: prevent FP context set via ptrace being discarded
  MIPS: disable FPU if the mode is unsupported

 Documentation/virtual/kvm/api.txt   |  54 +
 arch/mips/include/asm/asmmacro-32.h | 128 +-
 arch/mips/include/asm/asmmacro.h| 218 ++---
 arch/mips/include/asm/fpu.h |  20 +-
 arch/mips/include/asm/kdebug.h  |   3 +-
 arch/mips/include/asm/kvm_host.h| 125 +++---
 arch/mips/include/asm/processor.h   |   2 +-
 arch/mips/include/uapi/asm/kvm.h| 160 +++-
 arch/mips/kernel/asm-offsets.c  | 105 +++-
 arch/mips/kernel/genex.S|  15 +-
 arch/mips/kernel/ptrace.c   |  30 ++-
 arch/mips/kernel/r4k_fpu.S  |   2 +-
 arch/mips/kernel/traps.c|  35 ++-
 arch/mips/kvm/Makefile  |   8 +-
 arch/mips/kvm/emulate.c | 332 -
 arch/mips/kvm/fpu.S | 122 ++
 arch/mips/kvm/locore.S  |  38 +++
 arch/mips/kvm/mips.c| 472 +++-
 arch/mips/kvm/msa.S | 161 
 arch/mips/kvm/stats.c   |   4 +
 arch/mips/kvm/tlb.c |   6 +
 arch/mips/kvm/trap_emul.c   | 199 ++-
 include/uapi/linux/kvm.h|   2 +
 23 files changed, 1876 insertions(+), 365 deletions(-)
 create mode 100644 arch/mips/kvm/fpu.S
 create mode 100644 arch/mips/kvm/msa.S



signature.asc
Description: OpenPGP digital signature


[PATCH v2 15/20] MIPS: KVM: Wire up FPU capability

2015-03-26 Thread James Hogan
Now that the code is in place for KVM to support FPU in MIPS KVM guests,
wire up the new KVM_CAP_MIPS_FPU capability.

For backwards compatibility, the capability must be explicitly enabled
in order to detect or make use of the FPU from the guest.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Jonathan Corbet 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linux-...@vger.kernel.org
---
Changes in v2:
- Rebased on KVM queue (KVM_CAP_MIPS_FPU increased to 108 after
  KVM_CAP_S390_VECTOR_REGISTERS took 107).
- Just call kvm_vm_ioctl_check_extension() from
  kvm_vcpu_ioctl_enable_cap() rather than duplicating the extension
  presence condition (Paolo).
---
 Documentation/virtual/kvm/api.txt | 13 +
 arch/mips/kvm/mips.c  | 37 +
 include/uapi/linux/kvm.h  |  1 +
 3 files changed, 51 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index c666c375688e..c95134160843 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3208,6 +3208,19 @@ Parameters: none
 This capability enables the in-kernel irqchip for s390. Please refer to
 "4.24 KVM_CREATE_IRQCHIP" for details.
 
+6.9 KVM_CAP_MIPS_FPU
+
+Architectures: mips
+Target: vcpu
+Parameters: args[0] is reserved for future use (should be 0).
+
+This capability allows the use of the host Floating Point Unit by the guest. It
+allows the Config1.FP bit to be set to enable the FPU in the guest. Once this 
is
+done the KVM_REG_MIPS_FPR_* and KVM_REG_MIPS_FCR_* registers can be accessed
+(depending on the current guest FPU register mode), and the Status.FR,
+Config5.FRE bits are accessible via the KVM API and also from the guest,
+depending on them being supported by the FPU.
+
 7. Capabilities that can be enabled on VMs
 --
 
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 5e41afe15ae8..7f86cb73d05d 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -797,6 +797,30 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
return 0;
 }
 
+static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
+struct kvm_enable_cap *cap)
+{
+   int r = 0;
+
+   if (!kvm_vm_ioctl_check_extension(vcpu->kvm, cap->cap))
+   return -EINVAL;
+   if (cap->flags)
+   return -EINVAL;
+   if (cap->args[0])
+   return -EINVAL;
+
+   switch (cap->cap) {
+   case KVM_CAP_MIPS_FPU:
+   vcpu->arch.fpu_enabled = true;
+   break;
+   default:
+   r = -EINVAL;
+   break;
+   }
+
+   return r;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl,
 unsigned long arg)
 {
@@ -854,6 +878,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int 
ioctl,
r = kvm_vcpu_ioctl_interrupt(vcpu, &irq);
break;
}
+   case KVM_ENABLE_CAP: {
+   struct kvm_enable_cap cap;
+
+   r = -EFAULT;
+   if (copy_from_user(&cap, argp, sizeof(cap)))
+   goto out;
+   r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap);
+   break;
+   }
default:
r = -ENOIOCTLCMD;
}
@@ -962,11 +995,15 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long 
ext)
 
switch (ext) {
case KVM_CAP_ONE_REG:
+   case KVM_CAP_ENABLE_CAP:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
r = KVM_COALESCED_MMIO_PAGE_OFFSET;
break;
+   case KVM_CAP_MIPS_FPU:
+   r = !!cpu_has_fpu;
+   break;
default:
r = 0;
break;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 82634a492fe0..0670cf4337d6 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -761,6 +761,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_CHECK_EXTENSION_VM 105
 #define KVM_CAP_S390_USER_SIGP 106
 #define KVM_CAP_S390_VECTOR_REGISTERS 107
+#define KVM_CAP_MIPS_FPU 108
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.0.5

--
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


[PATCH v2 19/20] MIPS: KVM: Expose MSA registers

2015-03-26 Thread James Hogan
Add KVM register numbers for the MIPS SIMD Architecture (MSA) registers,
and implement access to them with the KVM_GET_ONE_REG / KVM_SET_ONE_REG
ioctls when the MSA capability is enabled (exposed in a later patch) and
present in the guest according to its Config3.MSAP bit.

The MSA vector registers use the same register numbers as the FPU
registers except with a different size (128bits). Since MSA depends on
Status.FR=1, these registers are inaccessible when Status.FR=0. These
registers are returned as a single native endian 128bit value, rather
than least significant half first with each 64-bit half native endian as
the kernel uses internally.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Jonathan Corbet 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linux-...@vger.kernel.org
---
Changes in v2:
- Add missing MSA vector and control register id bit patterns to API
  documentation.
---
 Documentation/virtual/kvm/api.txt | 12 +++-
 arch/mips/include/uapi/asm/kvm.h  | 12 ++--
 arch/mips/kvm/mips.c  | 65 +++
 3 files changed, 86 insertions(+), 3 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index c95134160843..e50cbb56272b 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1981,8 +1981,11 @@ registers, find a list below:
   MIPS  | KVM_REG_MIPS_COUNT_HZ | 64
   MIPS  | KVM_REG_MIPS_FPR_32(0..31)| 32
   MIPS  | KVM_REG_MIPS_FPR_64(0..31)| 64
+  MIPS  | KVM_REG_MIPS_VEC_128(0..31)   | 128
   MIPS  | KVM_REG_MIPS_FCR_IR   | 32
   MIPS  | KVM_REG_MIPS_FCR_CSR  | 32
+  MIPS  | KVM_REG_MIPS_MSA_IR   | 32
+  MIPS  | KVM_REG_MIPS_MSA_CSR  | 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
@@ -2040,14 +2043,21 @@ MIPS FPU registers (see KVM_REG_MIPS_FPR_{32,64}() 
above) have the following
 id bit patterns depending on the size of the register being accessed. They are
 always accessed according to the current guest FPU mode (Status.FR and
 Config5.FRE), i.e. as the guest would see them, and they become unpredictable
-if the guest FPU mode is changed:
+if the guest FPU mode is changed. MIPS SIMD Architecture (MSA) vector
+registers (see KVM_REG_MIPS_VEC_128() above) have similar patterns as they
+overlap the FPU registers:
   0x7020  0003 00 <0:3>  (32-bit FPU registers)
   0x7030  0003 00 <0:3>  (64-bit FPU registers)
+  0x7040  0003 00 <0:3>  (128-bit MSA vector registers)
 
 MIPS FPU control registers (see KVM_REG_MIPS_FCR_{IR,CSR} above) have the
 following id bit patterns:
   0x7020  0003 01 <0:3> 
 
+MIPS MSA control registers (see KVM_REG_MIPS_MSA_{IR,CSR} above) have the
+following id bit patterns:
+  0x7020  0003 02 <0:3> 
+
 
 4.69 KVM_GET_ONE_REG
 
diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h
index 401e6a6f8bb8..6985eb59b085 100644
--- a/arch/mips/include/uapi/asm/kvm.h
+++ b/arch/mips/include/uapi/asm/kvm.h
@@ -58,7 +58,7 @@ struct kvm_fpu {
  *
  * Register set = 2: KVM specific registers (see definitions below).
  *
- * Register set = 3: FPU registers (see definitions below).
+ * Register set = 3: FPU / MSA registers (see definitions below).
  *
  * Other sets registers may be added in the future.  Each set would
  * have its own identifier in bits[31..16].
@@ -148,7 +148,7 @@ struct kvm_fpu {
 
 
 /*
- * KVM_REG_MIPS_FPU - Floating Point registers.
+ * KVM_REG_MIPS_FPU - Floating Point and MIPS SIMD Architecture (MSA) 
registers.
  *
  *  bits[15..8]  - Register subset (see definitions below).
  *  bits[7..5]   - Must be zero.
@@ -157,12 +157,14 @@ struct kvm_fpu {
 
 #define KVM_REG_MIPS_FPR   (KVM_REG_MIPS_FPU | 0xULL)
 #define KVM_REG_MIPS_FCR   (KVM_REG_MIPS_FPU | 0x0100ULL)
+#define KVM_REG_MIPS_MSACR (KVM_REG_MIPS_FPU | 0x0200ULL)
 
 /*
  * KVM_REG_MIPS_FPR - Floating point / Vector registers.
  */
 #define KVM_REG_MIPS_FPR_32(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U32  | (n))
 #define KVM_REG_MIPS_FPR_64(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U64  | (n))
+#define KVM_REG_MIPS_VEC_128(n)(KVM_REG_MIPS_FPR | KVM_REG_SIZE_U128 | 
(n))
 
 /*
  * KVM_REG_MIPS_FCR - Floating point control registers.
@@ -170,6 +172,12 @@ struct kvm_fpu {
 #define KVM_REG_MIPS_FCR_IR(KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 |  0)
 #define KVM_REG_MIPS_FCR_CSR   (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 31)
 
+/*
+ * KVM_REG_MIPS_MSACR - MIPS SIMD Architecture (MSA) control registers.
+ */
+#define KVM_REG_MIPS_MSA_IR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 |  0)
+#define KVM_REG_MIPS_MSA_CSR(KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 |  1)
+
 
 /*
  * KVM MIPS specific structures and definitions
diff --git a/arch/m

[PATCH v2 20/20] MIPS: KVM: Wire up MSA capability

2015-03-26 Thread James Hogan
Now that the code is in place for KVM to support MIPS SIMD Architecutre
(MSA) in MIPS guests, wire up the new KVM_CAP_MIPS_MSA capability.

For backwards compatibility, the capability must be explicitly enabled
in order to detect or make use of MSA from the guest.

The capability is not supported if the hardware supports MSA vector
partitioning, since the extra support cannot be tested yet and it
extends the state that the userland program would have to save.

Signed-off-by: James Hogan 
Acked-by: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Jonathan Corbet 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linux-...@vger.kernel.org
---
Changes in v2:
- Rebased on KVM queue (KVM_CAP_MIPS_MSA increased to 109 after
  KVM_CAP_S390_VECTOR_REGISTERS took 107).
- Drop the MSA capability presence check from
  kvm_vcpu_ioctl_enable_cap() now that it already calls
  kvm_vm_ioctl_check_extension() (Paolo).
---
 Documentation/virtual/kvm/api.txt | 12 
 arch/mips/kvm/mips.c  | 18 ++
 include/uapi/linux/kvm.h  |  1 +
 3 files changed, 31 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index e50cbb56272b..b888db12ab21 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3231,6 +3231,18 @@ done the KVM_REG_MIPS_FPR_* and KVM_REG_MIPS_FCR_* 
registers can be accessed
 Config5.FRE bits are accessible via the KVM API and also from the guest,
 depending on them being supported by the FPU.
 
+6.10 KVM_CAP_MIPS_MSA
+
+Architectures: mips
+Target: vcpu
+Parameters: args[0] is reserved for future use (should be 0).
+
+This capability allows the use of the MIPS SIMD Architecture (MSA) by the 
guest.
+It allows the Config3.MSAP bit to be set to enable the use of MSA by the guest.
+Once this is done the KVM_REG_MIPS_VEC_* and KVM_REG_MIPS_MSA_* registers can 
be
+accessed, and the Config5.MSAEn bit is accessible via the KVM API and also from
+the guest.
+
 7. Capabilities that can be enabled on VMs
 --
 
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 35d3146895f1..bb68e8d520e8 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -880,6 +880,9 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
case KVM_CAP_MIPS_FPU:
vcpu->arch.fpu_enabled = true;
break;
+   case KVM_CAP_MIPS_MSA:
+   vcpu->arch.msa_enabled = true;
+   break;
default:
r = -EINVAL;
break;
@@ -1071,6 +1074,21 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long 
ext)
case KVM_CAP_MIPS_FPU:
r = !!cpu_has_fpu;
break;
+   case KVM_CAP_MIPS_MSA:
+   /*
+* We don't support MSA vector partitioning yet:
+* 1) It would require explicit support which can't be tested
+*yet due to lack of support in current hardware.
+* 2) It extends the state that would need to be saved/restored
+*by e.g. QEMU for migration.
+*
+* When vector partitioning hardware becomes available, support
+* could be added by requiring a flag when enabling
+* KVM_CAP_MIPS_MSA capability to indicate that userland knows
+* to save/restore the appropriate extra state.
+*/
+   r = cpu_has_msa && !(boot_cpu_data.msa_id & MSA_IR_WRPF);
+   break;
default:
r = 0;
break;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 0670cf4337d6..2263e749910b 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -762,6 +762,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_S390_USER_SIGP 106
 #define KVM_CAP_S390_VECTOR_REGISTERS 107
 #define KVM_CAP_MIPS_FPU 108
+#define KVM_CAP_MIPS_MSA 109
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.0.5

--
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


[PATCH v2 00/20] MIPS: KVM: Guest FPU & SIMD (MSA) support

2015-03-26 Thread James Hogan
This patchset primarily adds guest Floating Point Unit (FPU) and MIPS
SIMD Architecture (MSA) support to MIPS KVM, by enabling the host
FPU/MSA while in guest mode.

This patchset depends on Paul Burton's FP/MSA fixes patchset, which will
make it into 4.0. I've only included the 3 patches (15, 19, 20) that
have changed since v1, which can be found here:
http://thread.gmane.org/gmane.linux.kernel.api/8984

The corresponding QEMU patchset can be found here:
http://thread.gmane.org/gmane.comp.emulators.kvm.devel/134314

Assuming there are no further review comments I'll submit a pull request
once Ralf has applied the FP/MSA fixes for me to merge.

Changes in v2:
- Add missing MSA vector and control register id bit patterns to API
  documentation.
- Rebased on KVM queue (KVM_CAP_MIPS_FPU & KVM_CAP_MIPS_MSA increased to
  108 & 109 after KVM_CAP_S390_VECTOR_REGISTERS took 107).
- Just call kvm_vm_ioctl_check_extension() from
  kvm_vcpu_ioctl_enable_cap() rather than duplicating the extension
  presence conditions (Paolo).


Original description:
- Adds KVM_CAP_MIPS_FPU and KVM_CAP_MIPS_MSA capabilities which must be
  enabled to add FPU/MSA to the guest.
- Supports FR=0, FR=1, FRE=1 floating point register modes and 128-bit
  vector registers.
- Does not support UFR/UFE (guest user control of FR/FRE bits), or MSA
  vector partitioning.
- Context restore is lazy: done on first actual use.
- Context save is lazy: once restored, host FPU/MSA gets
  enabled/disabled when guest enables/disables it, with registers left
  loaded as long as possible.
- So the state that can be loaded at any one time is:
- No FPRs/vector state
- FR=0 FPRs (change of FR discards FP state)
- FR=1 FPRs
- Vector state (includes FR=1 FPRs)
- Vector state only (when guest CU1=0, FR=0)
- FCSR/MSACSR status registers are saved/restored around guest
  execution, since care must be taken to handle FP exceptions when
  writing these registers.

The patches are arranged roughly in groups:
- Patch 1 is a related minimal stable fix which can be applied in
  advance of the others (patch 18 fills it out a bit).
- Patch 2 is a generic MIPS change required to be able to restore
  FCSR/MSACSR registers with exceptions pending.
- Patches 3..10 add various misc KVM improvements and cleanups, most of
  which the later patches depend on.
- Patches 11..15 add the main guest FPU support.
- Patches 16..20 add the main guest MSA support (structured like 11.15).

James Hogan (20):
  MIPS: KVM: Handle MSA Disabled exceptions from guest

  MIPS: Clear [MSA]FPE CSR.Cause after notify_die()

  MIPS: KVM: Handle TRAP exceptions from guest kernel
  MIPS: KVM: Implement PRid CP0 register access
  MIPS: KVM: Sort kvm_mips_get_reg() registers
  MIPS: KVM: Drop pr_info messages on init/exit
  MIPS: KVM: Clean up register definitions a little
  MIPS: KVM: Simplify default guest Config registers
  MIPS: KVM: Add Config4/5 and writing of Config registers
  MIPS: KVM: Add vcpu_get_regs/vcpu_set_regs callback

  MIPS: KVM: Add base guest FPU support
  MIPS: KVM: Emulate FPU bits in COP0 interface
  MIPS: KVM: Add FP exception handling
  MIPS: KVM: Expose FPU registers
  MIPS: KVM: Wire up FPU capability

  MIPS: KVM: Add base guest MSA support
  MIPS: KVM: Emulate MSA bits in COP0 interface
  MIPS: KVM: Add MSA exception handling
  MIPS: KVM: Expose MSA registers
  MIPS: KVM: Wire up MSA capability

 Documentation/virtual/kvm/api.txt |  54 +
 arch/mips/include/asm/kdebug.h|   3 +-
 arch/mips/include/asm/kvm_host.h  | 125 +++---
 arch/mips/include/uapi/asm/kvm.h  | 160 -
 arch/mips/kernel/asm-offsets.c|  39 
 arch/mips/kernel/genex.S  |  14 +-
 arch/mips/kernel/traps.c  |  16 +-
 arch/mips/kvm/Makefile|   8 +-
 arch/mips/kvm/emulate.c   | 332 ++-
 arch/mips/kvm/fpu.S   | 122 ++
 arch/mips/kvm/locore.S|  38 +++
 arch/mips/kvm/mips.c  | 472 +-
 arch/mips/kvm/msa.S   | 161 +
 arch/mips/kvm/stats.c |   4 +
 arch/mips/kvm/tlb.c   |   6 +
 arch/mips/kvm/trap_emul.c | 199 +++-
 include/uapi/linux/kvm.h  |   2 +
 17 files changed, 1631 insertions(+), 124 deletions(-)
 create mode 100644 arch/mips/kvm/fpu.S
 create mode 100644 arch/mips/kvm/msa.S

Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Jonathan Corbet 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linux-...@vger.kernel.org
-- 
2.0.5

--
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


Re: [PATCH 20/20] MIPS: KVM: Wire up MSA capability

2015-03-26 Thread James Hogan
On 26/03/15 13:58, Paolo Bonzini wrote:
> 
> 
> On 11/03/2015 15:44, James Hogan wrote:
>> Now that the code is in place for KVM to support MIPS SIMD Architecutre
>> (MSA) in MIPS guests, wire up the new KVM_CAP_MIPS_MSA capability.
>>
>> For backwards compatibility, the capability must be explicitly enabled
>> in order to detect or make use of MSA from the guest.
>>
>> The capability is not supported if the hardware supports MSA vector
>> partitioning, since the extra support cannot be tested yet and it
>> extends the state that the userland program would have to save.
>>
>> Signed-off-by: James Hogan 
>> Cc: Paolo Bonzini 
>> Cc: Ralf Baechle 
>> Cc: Gleb Natapov 
>> Cc: Jonathan Corbet 
>> Cc: linux-m...@linux-mips.org
>> Cc: kvm@vger.kernel.org
>> Cc: linux-...@vger.kernel.org
>> Cc: linux-...@vger.kernel.org
>> Signed-off-by: James Hogan 
>> ---
>>  Documentation/virtual/kvm/api.txt | 12 
>>  arch/mips/kvm/mips.c  | 24 
>>  include/uapi/linux/kvm.h  |  1 +
>>  3 files changed, 37 insertions(+)
>>
>> diff --git a/Documentation/virtual/kvm/api.txt 
>> b/Documentation/virtual/kvm/api.txt
>> index 47ddf0475211..97dd9ee69ca8 100644
>> --- a/Documentation/virtual/kvm/api.txt
>> +++ b/Documentation/virtual/kvm/api.txt
>> @@ -3224,6 +3224,18 @@ done the KVM_REG_MIPS_FPR_* and KVM_REG_MIPS_FCR_* 
>> registers can be accessed
>>  Config5.FRE bits are accessible via the KVM API and also from the guest,
>>  depending on them being supported by the FPU.
>>  
>> +6.10 KVM_CAP_MIPS_MSA
>> +
>> +Architectures: mips
>> +Target: vcpu
>> +Parameters: args[0] is reserved for future use (should be 0).
>> +
>> +This capability allows the use of the MIPS SIMD Architecture (MSA) by the 
>> guest.
>> +It allows the Config3.MSAP bit to be set to enable the use of MSA by the 
>> guest.
>> +Once this is done the KVM_REG_MIPS_VEC_* and KVM_REG_MIPS_MSA_* registers 
>> can be
>> +accessed, and the Config5.MSAEn bit is accessible via the KVM API and also 
>> from
>> +the guest.
>> +
>>  7. Capabilities that can be enabled on VMs
>>  --
>>  
>> diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
>> index 9319c4360285..3b3530f493eb 100644
>> --- a/arch/mips/kvm/mips.c
>> +++ b/arch/mips/kvm/mips.c
>> @@ -880,6 +880,15 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu 
>> *vcpu,
>>  return -EINVAL;
>>  vcpu->arch.fpu_enabled = true;
>>  break;
>> +case KVM_CAP_MIPS_MSA:
>> +/*
>> + * MSA vector partitioning not supported,
>> + * see kvm_vm_ioctl_check_extension().
>> + */
>> +if (!cpu_has_msa || boot_cpu_data.msa_id & MSA_IR_WRPF)
>> +return -EINVAL;
> 
> Perhaps you can call kvm_vm_ioctl_check_extension directly, outside the
> switch (it's okay if it's called for a capability other than FPU and MSA)?

Yes, good idea. That works nicely.

> 
> Apart from this nit,
> 
> Acked-by: Paolo Bonzini 
> 
> Paolo

Thanks!
James

> 
>> +vcpu->arch.msa_enabled = true;
>> +break;
>>  default:
>>  r = -EINVAL;
>>  break;
>> @@ -1071,6 +1080,21 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, 
>> long ext)
>>  case KVM_CAP_MIPS_FPU:
>>  r = !!cpu_has_fpu;
>>  break;
>> +case KVM_CAP_MIPS_MSA:
>> +/*
>> + * We don't support MSA vector partitioning yet:
>> + * 1) It would require explicit support which can't be tested
>> + *yet due to lack of support in current hardware.
>> + * 2) It extends the state that would need to be saved/restored
>> + *by e.g. QEMU for migration.
>> + *
>> + * When vector partitioning hardware becomes available, support
>> + * could be added by requiring a flag when enabling
>> + * KVM_CAP_MIPS_MSA capability to indicate that userland knows
>> + * to save/restore the appropriate extra state.
>> + */
>> +r = cpu_has_msa && !(boot_cpu_data.msa_id & MSA_IR_WRPF);
>> +break;
>>  default:
>>  r = 0;
>>  break;
>> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
>> index 98f6e5c653ff..5f859888e3ad 100644
>> --- a/include/uapi/linux/kvm.h
>> +++ b/include/uapi/linux/kvm.h
>> @@ -761,6 +761,7 @@ struct kvm_ppc_smmu_info {
>>  #define KVM_CAP_CHECK_EXTENSION_VM 105
>>  #define KVM_CAP_S390_USER_SIGP 106
>>  #define KVM_CAP_MIPS_FPU 107
>> +#define KVM_CAP_MIPS_MSA 108
>>  
>>  #ifdef KVM_CAP_IRQ_ROUTING
>>  
>>



signature.asc
Description: OpenPGP digital signature


[PATCH v2 8/9] mips/kvm: Support FPU in MIPS KVM guests

2015-03-25 Thread James Hogan
Support the new KVM_CAP_MIPS_FPU capability, which allows the host's FPU
to be exposed to the KVM guest.

The capability is enabled if the guest core has an FPU according to its
Config1 register. Various config bits are now writeable so that KVM is
aware of the configuration (Config1.FP) and so that QEMU can
save/restore the guest modifiable bits (Config5.FRE, Config5.UFR,
Config5.UFE). The FCSR/FIR registers and the floating point registers
are now saved/restored (depending on the FR mode bit).

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
Changes in v2:
- Change (1 << x) to (1U << x) in important places to avoid compiler
  defined behaviour (Leon).
- Removed update of linux-headers/linux/kvm.h, see patch 1 (Paolo).
---
 target-mips/cpu.h |   2 +
 target-mips/kvm.c | 124 --
 2 files changed, 122 insertions(+), 4 deletions(-)

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index f9d2b4c5af80..68c8260da0e6 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -462,6 +462,8 @@ struct CPUMIPSState {
 #define CP0C5_CV 29
 #define CP0C5_EVA28
 #define CP0C5_MSAEn  27
+#define CP0C5_UFE9
+#define CP0C5_FRE8
 #define CP0C5_SBRI   6
 #define CP0C5_UFR2
 #define CP0C5_NFExists   0
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index e8a8858f0cfb..4920244c161a 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -29,6 +29,8 @@
 #define DPRINTF(fmt, ...) \
 do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0)
 
+static int kvm_mips_fpu_cap;
+
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
 };
@@ -45,16 +47,29 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 /* MIPS has 128 signals */
 kvm_set_sigmask_len(s, 16);
 
+kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU);
+
 DPRINTF("%s\n", __func__);
 return 0;
 }
 
 int kvm_arch_init_vcpu(CPUState *cs)
 {
+MIPSCPU *cpu = MIPS_CPU(cs);
+CPUMIPSState *env = &cpu->env;
 int ret = 0;
 
 qemu_add_vm_change_state_handler(kvm_mips_update_state, cs);
 
+if (kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) {
+ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_FPU, 0, 0);
+if (ret < 0) {
+/* mark unsupported so it gets disabled on reset */
+kvm_mips_fpu_cap = 0;
+ret = 0;
+}
+}
+
 DPRINTF("%s\n", __func__);
 return ret;
 }
@@ -63,8 +78,8 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu)
 {
 CPUMIPSState *env = &cpu->env;
 
-if (env->CP0_Config1 & (1 << CP0C1_FP)) {
-fprintf(stderr, "Warning: FPU not supported with KVM, disabling\n");
+if (!kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) {
+fprintf(stderr, "Warning: KVM does not support FPU, disabling\n");
 env->CP0_Config1 &= ~(1 << CP0C1_FP);
 }
 
@@ -363,11 +378,14 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, 
uint64 reg_id,
 }
 
 #define KVM_REG_MIPS_CP0_CONFIG_MASK(1U << CP0C0_M)
-#define KVM_REG_MIPS_CP0_CONFIG1_MASK   (1U << CP0C1_M)
+#define KVM_REG_MIPS_CP0_CONFIG1_MASK   ((1U << CP0C1_M) | \
+ (1U << CP0C1_FP))
 #define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1U << CP0C2_M)
 #define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1U << CP0C3_M)
 #define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1U << CP0C4_M)
-#define KVM_REG_MIPS_CP0_CONFIG5_MASK   0
+#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1U << CP0C5_UFE) | \
+ (1U << CP0C5_FRE) | \
+ (1U << CP0C5_UFR))
 
 static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
   int32_t *addr, int32_t mask)
@@ -529,6 +547,98 @@ static void kvm_mips_update_state(void *opaque, int 
running, RunState state)
 }
 }
 
+static int kvm_mips_put_fpu_registers(CPUState *cs, int level)
+{
+MIPSCPU *cpu = MIPS_CPU(cs);
+CPUMIPSState *env = &cpu->env;
+int err, ret = 0;
+unsigned int i;
+
+/* Only put FPU state if we're emulating a CPU with an FPU */
+if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+/* FPU Control Registers */
+if (level == KVM_PUT_FULL_STATE) {
+err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_IR,
+&env->active_fpu.fcr0);
+if (err < 0) {
+DPRINTF("%s: Failed to put FCR_IR (%d)\n", __func__, err);
+ret = err;
+}
+}
+err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_CSR,
+&env->active_fpu.f

[PATCH v2 6/9] mips/kvm: Support unsigned KVM registers

2015-03-25 Thread James Hogan
Add KVM register access functions for the uint32_t type. This is
required for FP and MSA control registers, which are represented as
unsigned 32-bit integers.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index ead8c5f73930..4e5c8ba3d10c 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -243,6 +243,18 @@ static inline int kvm_mips_put_one_reg(CPUState *cs, 
uint64_t reg_id,
 return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
 }
 
+static inline int kvm_mips_put_one_ureg(CPUState *cs, uint64_t reg_id,
+uint32_t *addr)
+{
+uint64_t val64 = *addr;
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)&val64
+};
+
+return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
+}
+
 static inline int kvm_mips_put_one_ulreg(CPUState *cs, uint64_t reg_id,
  target_ulong *addr)
 {
@@ -283,6 +295,23 @@ static inline int kvm_mips_get_one_reg(CPUState *cs, 
uint64_t reg_id,
 return ret;
 }
 
+static inline int kvm_mips_get_one_ureg(CPUState *cs, uint64_t reg_id,
+uint32_t *addr)
+{
+int ret;
+uint64_t val64 = 0;
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)&val64
+};
+
+ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
+if (ret >= 0) {
+*addr = val64;
+}
+return ret;
+}
+
 static inline int kvm_mips_get_one_ulreg(CPUState *cs, uint64 reg_id,
  target_ulong *addr)
 {
-- 
2.0.5

--
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


[PATCH v2 1/9] DONT APPLY: linux-headers: Update MIPS KVM headers

2015-03-25 Thread James Hogan
This patch updates the linux headers based solely on the changes in my
"MIPS: KVM: Guest FPU & SIMD (MSA) support" KVM patchset. It is provided
for reference since those changes haven't been merged yet. The stored
headers will need to be synced after my KVM patches are merged and
before the rest of this patchset is applied.

The individual KVM patches that make up this change are:
- "[PATCH 07/20] MIPS: KVM: Clean up register definitions a little"
  https://patchwork.kernel.org/patch/5986171/
- "[PATCH 14/20] MIPS: KVM: Expose FPU registers"
  https://patchwork.kernel.org/patch/5986211/
- "[PATCH 15/20] MIPS: KVM: Wire up FPU capability"
  https://patchwork.kernel.org/patch/5986201/
- "[PATCH 19/20] MIPS: KVM: Expose MSA registers"
  https://patchwork.kernel.org/patch/5986191/
- "[PATCH 20/20] MIPS: KVM: Wire up MSA capability"
  https://patchwork.kernel.org/patch/5986151/

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
Changes in v2:
- Removed most of patch 7 and updates to linux-headers/linux/kvm.h from
  patches 8 and 9, and put in this patch for reference (Paolo).
---
 linux-headers/asm-mips/kvm.h | 160 ++-
 linux-headers/linux/kvm.h|   2 +
 2 files changed, 101 insertions(+), 61 deletions(-)

diff --git a/linux-headers/asm-mips/kvm.h b/linux-headers/asm-mips/kvm.h
index 2c04b6d9ff85..6985eb59b085 100644
--- a/linux-headers/asm-mips/kvm.h
+++ b/linux-headers/asm-mips/kvm.h
@@ -36,77 +36,85 @@ struct kvm_regs {
 
 /*
  * for KVM_GET_FPU and KVM_SET_FPU
- *
- * If Status[FR] is zero (32-bit FPU), the upper 32-bits of the FPRs
- * are zero filled.
  */
 struct kvm_fpu {
-   __u64 fpr[32];
-   __u32 fir;
-   __u32 fccr;
-   __u32 fexr;
-   __u32 fenr;
-   __u32 fcsr;
-   __u32 pad;
 };
 
 
 /*
- * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access CP0
+ * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various
  * registers.  The id field is broken down as follows:
  *
- *  bits[2..0]   - Register 'sel' index.
- *  bits[7..3]   - Register 'rd'  index.
- *  bits[15..8]  - Must be zero.
- *  bits[31..16] - 1 -> CP0 registers.
- *  bits[51..32] - Must be zero.
  *  bits[63..52] - As per linux/kvm.h
+ *  bits[51..32] - Must be zero.
+ *  bits[31..16] - Register set.
+ *
+ * Register set = 0: GP registers from kvm_regs (see definitions below).
+ *
+ * Register set = 1: CP0 registers.
+ *  bits[15..8]  - Must be zero.
+ *  bits[7..3]   - Register 'rd'  index.
+ *  bits[2..0]   - Register 'sel' index.
+ *
+ * Register set = 2: KVM specific registers (see definitions below).
+ *
+ * Register set = 3: FPU / MSA registers (see definitions below).
  *
  * Other sets registers may be added in the future.  Each set would
  * have its own identifier in bits[31..16].
- *
- * The registers defined in struct kvm_regs are also accessible, the
- * id values for these are below.
  */
 
-#define KVM_REG_MIPS_R0 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0)
-#define KVM_REG_MIPS_R1 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 1)
-#define KVM_REG_MIPS_R2 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 2)
-#define KVM_REG_MIPS_R3 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 3)
-#define KVM_REG_MIPS_R4 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 4)
-#define KVM_REG_MIPS_R5 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 5)
-#define KVM_REG_MIPS_R6 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 6)
-#define KVM_REG_MIPS_R7 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 7)
-#define KVM_REG_MIPS_R8 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 8)
-#define KVM_REG_MIPS_R9 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 9)
-#define KVM_REG_MIPS_R10 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 10)
-#define KVM_REG_MIPS_R11 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 11)
-#define KVM_REG_MIPS_R12 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 12)
-#define KVM_REG_MIPS_R13 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 13)
-#define KVM_REG_MIPS_R14 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 14)
-#define KVM_REG_MIPS_R15 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 15)
-#define KVM_REG_MIPS_R16 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 16)
-#define KVM_REG_MIPS_R17 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 17)
-#define KVM_REG_MIPS_R18 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 18)
-#define KVM_REG_MIPS_R19 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 19)
-#define KVM_REG_MIPS_R20 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 20)
-#define KVM_REG_MIPS_R21 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 21)
-#define KVM_REG_MIPS_R22 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 22)
-#define KVM_REG_MIPS_R23 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 23)
-#define KVM_REG_MIPS_R24 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 24)
-#define KVM_REG_MIPS_R25 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 25)
-#define KVM_REG_MIPS_R26 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 26)
-#define KVM_REG_MIPS_R27 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 27)
-#define KVM_REG_MIPS_R28 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 28)
-#define KVM_REG_MIPS_R29 (KVM_REG_MIPS | KVM_REG_SIZE_U6

[PATCH v2 9/9] mips/kvm: Support MSA in MIPS KVM guests

2015-03-25 Thread James Hogan
Support the new KVM_CAP_MIPS_MSA capability, which allows MIPS SIMD
Architecture (MSA) to be exposed to the KVM guest.

The capability is enabled if the guest core has MSA according to its
Config3 register. Various config bits are now writeable so that KVM is
aware of the configuration (Config3.MSAP) and so that QEMU can
save/restore the guest modifiable bits (Config5.MSAEn). The MSACSR/MSAIR
registers and the MSA vector registers are now saved/restored. Since the
FP registers are a subset of the vector registers, they are omitted if
the guest has MSA.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
Changes in v2:
- Change (1 << x) to (1U << x) in important places to avoid compiler
  defined behaviour (Leon).
- Removed update of linux-headers/linux/kvm.h, see patch 1 (Paolo).
---
 target-mips/kvm.c | 127 +-
 1 file changed, 107 insertions(+), 20 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 4920244c161a..b9e7a97afca0 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -30,6 +30,7 @@
 do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0)
 
 static int kvm_mips_fpu_cap;
+static int kvm_mips_msa_cap;
 
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
@@ -48,6 +49,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 kvm_set_sigmask_len(s, 16);
 
 kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU);
+kvm_mips_msa_cap = kvm_check_extension(s, KVM_CAP_MIPS_MSA);
 
 DPRINTF("%s\n", __func__);
 return 0;
@@ -70,6 +72,15 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 }
 
+if (kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_MSA, 0, 0);
+if (ret < 0) {
+/* mark unsupported so it gets disabled on reset */
+kvm_mips_msa_cap = 0;
+ret = 0;
+}
+}
+
 DPRINTF("%s\n", __func__);
 return ret;
 }
@@ -82,6 +93,10 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu)
 fprintf(stderr, "Warning: KVM does not support FPU, disabling\n");
 env->CP0_Config1 &= ~(1 << CP0C1_FP);
 }
+if (!kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+fprintf(stderr, "Warning: KVM does not support MSA, disabling\n");
+env->CP0_Config3 &= ~(1 << CP0C3_MSAP);
+}
 
 DPRINTF("%s\n", __func__);
 }
@@ -381,9 +396,11 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, 
uint64 reg_id,
 #define KVM_REG_MIPS_CP0_CONFIG1_MASK   ((1U << CP0C1_M) | \
  (1U << CP0C1_FP))
 #define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1U << CP0C2_M)
-#define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1U << CP0C3_M)
+#define KVM_REG_MIPS_CP0_CONFIG3_MASK   ((1U << CP0C3_M) | \
+ (1U << CP0C3_MSAP))
 #define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1U << CP0C4_M)
-#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1U << CP0C5_UFE) | \
+#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1U << CP0C5_MSAEn) | \
+ (1U << CP0C5_UFE) | \
  (1U << CP0C5_FRE) | \
  (1U << CP0C5_UFR))
 
@@ -572,17 +589,53 @@ static int kvm_mips_put_fpu_registers(CPUState *cs, int 
level)
 ret = err;
 }
 
-/* Floating point registers */
+/*
+ * FPU register state is a subset of MSA vector state, so don't put FPU
+ * registers if we're emulating a CPU with MSA.
+ */
+if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
+/* Floating point registers */
+for (i = 0; i < 32; ++i) {
+if (env->CP0_Status & (1 << CP0St_FR)) {
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i),
+  &env->active_fpu.fpr[i].d);
+} else {
+err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FPR_32(i),
+&env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]);
+}
+if (err < 0) {
+DPRINTF("%s: Failed to put FPR%u (%d)\n", __func__, i, 
err);
+ret = err;
+}
+}
+}
+}
+
+/* Only put MSA state if we're emulating a CPU with MSA */
+if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+/* MSA Control Registers */
+if (level == KVM_PUT_FULL_STATE) {
+err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_IR,
+   &am

[PATCH v2 2/9] mips/kvm: Sync with newer MIPS KVM headers

2015-03-25 Thread James Hogan
The KVM_REG_MIPS_COUNT_* definitions are now included in
linux-headers/asm-mips/kvm.h since commit b061808d39fa ("linux-headers:
update linux headers to kvm/next"), therefore the duplicate definitions
in target-mips/kvm.c can now be dropped.

The MIPS_C0_{32,64} macros are also updated to utilise definitions more
recently added to the asm-mips/kvm.h header.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
Changes in v2:
- Add the changes to MIPS_CP0_{32,64} macros from v1 patch 7, since the
  rest of that patch is now unnecessary and the change is along the same
  lines as this patch.
- (not added Leon's Reviewed-by due to above non-reviewed change).
---
 target-mips/kvm.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 4d1f7ead8142..bbdaccc9d729 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -206,10 +206,10 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 }
 
 #define MIPS_CP0_32(_R, _S) \
-(KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x1 | (8 * (_R) + (_S)))
+(KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S)))
 
 #define MIPS_CP0_64(_R, _S) \
-(KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x1 | (8 * (_R) + (_S)))
+(KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
 
 #define KVM_REG_MIPS_CP0_INDEX  MIPS_CP0_32(0, 0)
 #define KVM_REG_MIPS_CP0_CONTEXTMIPS_CP0_64(4, 0)
@@ -226,17 +226,6 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
-/* CP0_Count control */
-#define KVM_REG_MIPS_COUNT_CTL  (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
- 0x2 | 0)
-#define KVM_REG_MIPS_COUNT_CTL_DC   0x0001  /* master disable */
-/* CP0_Count resume monotonic nanoseconds */
-#define KVM_REG_MIPS_COUNT_RESUME   (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
- 0x2 | 1)
-/* CP0_Count rate in Hz */
-#define KVM_REG_MIPS_COUNT_HZ   (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
- 0x2 | 2)
-
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
int32_t *addr)
 {
-- 
2.0.5

--
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


[PATCH v2 5/9] mips/kvm: Implement Config CP0 registers

2015-03-25 Thread James Hogan
Implement saving and restoring to KVM state of the Config CP0 registers
(namely Config, Config1, Config2, Config3, Config4, and Config5). These
control the features available to a guest, and a few of the fields will
soon be writeable by a guest so QEMU needs to know about them so as not
to clobber them on migration/savevm.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
Changes in v2:
- Fix line wrapping of kvm_mips_get_one_reg() calls from Config4 and
  Config5 (Leon).
- Change (1 << x) to (1U << x) in important places to avoid compiler
  defined behaviour (Leon).
---
 target-mips/kvm.c | 106 ++
 1 file changed, 106 insertions(+)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index d41facfca0d5..ead8c5f73930 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -223,6 +223,12 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
+#define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
+#define KVM_REG_MIPS_CP0_CONFIG1MIPS_CP0_32(16, 1)
+#define KVM_REG_MIPS_CP0_CONFIG2MIPS_CP0_32(16, 2)
+#define KVM_REG_MIPS_CP0_CONFIG3MIPS_CP0_32(16, 3)
+#define KVM_REG_MIPS_CP0_CONFIG4MIPS_CP0_32(16, 4)
+#define KVM_REG_MIPS_CP0_CONFIG5MIPS_CP0_32(16, 5)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
@@ -305,6 +311,34 @@ static inline int kvm_mips_get_one_reg64(CPUState *cs, 
uint64 reg_id,
 return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
 }
 
+#define KVM_REG_MIPS_CP0_CONFIG_MASK(1U << CP0C0_M)
+#define KVM_REG_MIPS_CP0_CONFIG1_MASK   (1U << CP0C1_M)
+#define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1U << CP0C2_M)
+#define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1U << CP0C3_M)
+#define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1U << CP0C4_M)
+#define KVM_REG_MIPS_CP0_CONFIG5_MASK   0
+
+static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
+  int32_t *addr, int32_t mask)
+{
+int err;
+int32_t tmp, change;
+
+err = kvm_mips_get_one_reg(cs, reg_id, &tmp);
+if (err < 0) {
+return err;
+}
+
+/* only change bits in mask */
+change = (*addr ^ tmp) & mask;
+if (!change) {
+return 0;
+}
+
+tmp = tmp ^ change;
+return kvm_mips_put_one_reg(cs, reg_id, &tmp);
+}
+
 /*
  * We freeze the KVM timer when either the VM clock is stopped or the state is
  * saved (the state is dirty).
@@ -527,6 +561,48 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int 
level)
 DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
 ret = err;
 }
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG,
+  &env->CP0_Config0,
+  KVM_REG_MIPS_CP0_CONFIG_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1,
+  &env->CP0_Config1,
+  KVM_REG_MIPS_CP0_CONFIG1_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG1 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2,
+  &env->CP0_Config2,
+  KVM_REG_MIPS_CP0_CONFIG2_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG2 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3,
+  &env->CP0_Config3,
+  KVM_REG_MIPS_CP0_CONFIG3_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG3 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG4,
+  &env->CP0_Config4,
+  KVM_REG_MIPS_CP0_CONFIG4_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG4 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG5,
+  &env->CP0_Config5,
+  KVM_REG_MIPS_CP0_CONFIG5_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG5 (%d)\n", __func__, err);
+ret = err;
+}
 err = kvm_mips_put_one_ulreg(cs, KVM_

[PATCH v2 3/9] mips/kvm: Remove a couple of noisy DPRINTFs

2015-03-25 Thread James Hogan
The DPRINTFs in cpu_mips_io_interrupts_pending() and kvm_arch_pre_run()
are particularly noisy during normal execution, and also not
particularly helpful. Remove them so that more important debug messages
can be more easily seen.

Signed-off-by: James Hogan 
Reviewed-by: Leon Alrae 
Cc: Paolo Bonzini 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index bbdaccc9d729..1722a6a40598 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -87,7 +87,6 @@ static inline int cpu_mips_io_interrupts_pending(MIPSCPU *cpu)
 {
 CPUMIPSState *env = &cpu->env;
 
-DPRINTF("%s: %#x\n", __func__, env->CP0_Cause & (1 << (2 + CP0Ca_IP)));
 return env->CP0_Cause & (0x1 << (2 + CP0Ca_IP));
 }
 
@@ -112,7 +111,6 @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
 
 void kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
 {
-DPRINTF("%s\n", __func__);
 }
 
 int kvm_arch_process_async_events(CPUState *cs)
-- 
2.0.5

--
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


[PATCH v2 4/9] mips/kvm: Implement PRid CP0 register

2015-03-25 Thread James Hogan
Implement saving and restoring to KVM state of the Processor ID (PRid)
CP0 register. This allows QEMU to control the PRid exposed to the guest
instead of using the default set by KVM.

Signed-off-by: James Hogan 
Reviewed-by: Leon Alrae 
Cc: Paolo Bonzini 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 1722a6a40598..d41facfca0d5 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -222,6 +222,7 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0)
 #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
+#define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
@@ -521,6 +522,11 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int 
level)
 DPRINTF("%s: Failed to put CP0_EPC (%d)\n", __func__, err);
 ret = err;
 }
+err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid);
+if (err < 0) {
+DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
+ret = err;
+}
 err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
  &env->CP0_ErrorEPC);
 if (err < 0) {
@@ -607,6 +613,11 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
 DPRINTF("%s: Failed to get CP0_EPC (%d)\n", __func__, err);
 ret = err;
 }
+err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid);
+if (err < 0) {
+DPRINTF("%s: Failed to get CP0_PRID (%d)\n", __func__, err);
+ret = err;
+}
 err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
  &env->CP0_ErrorEPC);
 if (err < 0) {
-- 
2.0.5

--
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


[PATCH v2 7/9] mips/kvm: Support signed 64-bit KVM registers

2015-03-25 Thread James Hogan
Rename kvm_mips_{get,put}_one_reg64() to kvm_mips_{get,put}_one_ureg64()
since they take an int64_t pointer, and add separate signed 64-bit
accessors. These will be used for double precision floating point
registers.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 40 +++-
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 4e5c8ba3d10c..e8a8858f0cfb 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -268,7 +268,18 @@ static inline int kvm_mips_put_one_ulreg(CPUState *cs, 
uint64_t reg_id,
 }
 
 static inline int kvm_mips_put_one_reg64(CPUState *cs, uint64_t reg_id,
- uint64_t *addr)
+ int64_t *addr)
+{
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)addr
+};
+
+return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
+}
+
+static inline int kvm_mips_put_one_ureg64(CPUState *cs, uint64_t reg_id,
+  uint64_t *addr)
 {
 struct kvm_one_reg cp0reg = {
 .id = reg_id,
@@ -330,7 +341,18 @@ static inline int kvm_mips_get_one_ulreg(CPUState *cs, 
uint64 reg_id,
 }
 
 static inline int kvm_mips_get_one_reg64(CPUState *cs, uint64 reg_id,
- uint64_t *addr)
+ int64_t *addr)
+{
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)addr
+};
+
+return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
+}
+
+static inline int kvm_mips_get_one_ureg64(CPUState *cs, uint64 reg_id,
+  uint64_t *addr)
 {
 struct kvm_one_reg cp0reg = {
 .id = reg_id,
@@ -385,13 +407,13 @@ static int kvm_mips_save_count(CPUState *cs)
 int err, ret = 0;
 
 /* freeze KVM timer */
-err = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err);
 ret = err;
 } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
 count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
-err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
 ret = err;
@@ -427,14 +449,14 @@ static int kvm_mips_restore_count(CPUState *cs)
 int err_dc, err, ret = 0;
 
 /* check the timer is frozen */
-err_dc = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err_dc = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err_dc < 0) {
 DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err_dc);
 ret = err_dc;
 } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
 /* freeze timer (sets COUNT_RESUME for us) */
 count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
-err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
 ret = err;
@@ -458,7 +480,7 @@ static int kvm_mips_restore_count(CPUState *cs)
 /* resume KVM timer */
 if (err_dc >= 0) {
 count_ctl &= ~KVM_REG_MIPS_COUNT_CTL_DC;
-err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to set COUNT_CTL.DC=0 (%d)\n", __func__, err);
 ret = err;
@@ -491,8 +513,8 @@ static void kvm_mips_update_state(void *opaque, int 
running, RunState state)
 } else {
 /* Set clock restore time to now */
 count_resume = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-ret = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_RESUME,
- &count_resume);
+ret = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_RESUME,
+  &count_resume);
 if (ret < 0) {
 fprintf(stderr, "Failed setting COUNT_RESUME\n");
 return;
-- 
2.0.5

--
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


[PATCH v2 0/9] mips/kvm: Support FPU & SIMD (MSA) in MIPS KVM guests

2015-03-25 Thread James Hogan
Review on v1 has gone quiet, so here's v2 which addresses the feedback
received for v1. Thanks to all who have taken the time to review it so
far.

This patchset primarily adds support for FPU and MIPS SIMD Architecture
(MSA) in MIPS KVM guests to QEMU. It depends on the KVM patchset which I
recently submitted to add the corresponding hypervisor support to KVM
("[PATCH 00/20] MIPS: KVM: Guest FPU & SIMD (MSA) support").

All comments welcome.

Changes in v2:
- Moved most of patch 7 and updates to linux-headers/linux/kvm.h from
  patches 8 and 9 into a new patch 1, which is purely for reference
  (Paolo).
- Add the changes to MIPS_CP0_{32,64} macros from v1 patch 7 to patch 2,
  since the rest of that patch is now unnecessary and the change is
  along the same lines as patch 2 (not added Leon's Reviewed-by to this
  patch due to that non-reviewed change).
- Fix line wrapping of kvm_mips_get_one_reg() calls from Config4 and
  Config5 in patch 5 (Leon).
- Change (1 << x) to (1U << x) in important places in patch 5, 8 & 9 to
  avoid compiler defined behaviour (Leon).

James Hogan (9):
  DONT APPLY: linux-headers: Update MIPS KVM headers
  mips/kvm: Sync with newer MIPS KVM headers
  mips/kvm: Remove a couple of noisy DPRINTFs
  mips/kvm: Implement PRid CP0 register
  mips/kvm: Implement Config CP0 registers
  mips/kvm: Support unsigned KVM registers
  mips/kvm: Support signed 64-bit KVM registers
  mips/kvm: Support FPU in MIPS KVM guests
  mips/kvm: Support MSA in MIPS KVM guests

 linux-headers/asm-mips/kvm.h | 160 ++---
 linux-headers/linux/kvm.h|   2 +
 target-mips/cpu.h|   2 +
 target-mips/kvm.c| 410 ---
 4 files changed, 487 insertions(+), 87 deletions(-)

-- 
2.0.5

--
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


Re: [PATCH 8/9] mips/kvm: Support FPU in MIPS KVM guests

2015-03-12 Thread James Hogan
On 12/03/15 16:44, Paolo Bonzini wrote:
> 
> 
> On 11/03/2015 16:22, James Hogan wrote:
>> diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
>> index 12045a11c036..410eb158f564 100644
>> --- a/linux-headers/linux/kvm.h
>> +++ b/linux-headers/linux/kvm.h
>> @@ -761,6 +761,7 @@ struct kvm_ppc_smmu_info {
>>  #define KVM_CAP_PPC_FIXUP_HCALL 103
>>  #define KVM_CAP_PPC_ENABLE_HCALL 104
>>  #define KVM_CAP_CHECK_EXTENSION_VM 105
>> +#define KVM_CAP_MIPS_FPU 107
>>  
> 
> Changes to linux-headers/linux/kvm.h should go in through a complete
> sync of the kernel headers.  The good thing is that then the series
> becomes 100% MIPS-specific. :)

Right. I'll maybe move all those changes in a preliminary "don't apply
me" patch for reference (there are some other duplicated definitions in
kvm.c too, similar to what patch 1 cleans up) and assume that one way or
another a sync will happen between the KVM changes being merged and the
QEMU patchset being applied.

Cheers
James



signature.asc
Description: OpenPGP digital signature


Re: [PATCH 4/9] mips/kvm: Implement Config CP0 registers

2015-03-12 Thread James Hogan
On 12/03/15 16:41, Leon Alrae wrote:
> On 11/03/2015 15:22, James Hogan wrote:
>> Implement saving and restoring to KVM state of the Config CP0 registers
>> (namely Config, Config1, Config2, Config3, Config4, and Config5). These
>> control the features available to a guest, and a few of the fields will
>> soon be writeable by a guest so QEMU needs to know about them so as not
>> to clobber them on migration/savevm.
>>
>> Signed-off-by: James Hogan 
>> Cc: Paolo Bonzini 
>> Cc: Leon Alrae 
>> Cc: Aurelien Jarno 
>> ---
>>  target-mips/kvm.c | 108 
>> ++
>>  1 file changed, 108 insertions(+)
>>
>> diff --git a/target-mips/kvm.c b/target-mips/kvm.c
>> index 730c67e247d8..b8813a2722a3 100644
>> --- a/target-mips/kvm.c
>> +++ b/target-mips/kvm.c
>> @@ -223,6 +223,12 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, 
>> int level)
>>  #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
>>  #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
>>  #define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
>> +#define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
>> +#define KVM_REG_MIPS_CP0_CONFIG1MIPS_CP0_32(16, 1)
>> +#define KVM_REG_MIPS_CP0_CONFIG2MIPS_CP0_32(16, 2)
>> +#define KVM_REG_MIPS_CP0_CONFIG3MIPS_CP0_32(16, 3)
>> +#define KVM_REG_MIPS_CP0_CONFIG4MIPS_CP0_32(16, 4)
>> +#define KVM_REG_MIPS_CP0_CONFIG5MIPS_CP0_32(16, 5)
>>  #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
>>  
>>  static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
>> @@ -305,6 +311,34 @@ static inline int kvm_mips_get_one_reg64(CPUState *cs, 
>> uint64 reg_id,
>>  return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
>>  }
>>  
>> +#define KVM_REG_MIPS_CP0_CONFIG_MASK(1 << CP0C0_M)
>> +#define KVM_REG_MIPS_CP0_CONFIG1_MASK   (1 << CP0C1_M)
>> +#define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1 << CP0C2_M)
>> +#define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1 << CP0C3_M)
>> +#define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1 << CP0C4_M)
> 
> CP0Cx_M is 31, thus without "U" suffix 1 is left shifted into sign bit
> which is undefined behaviour.

Well spotted, I'll fix that.

> 
>> +#define KVM_REG_MIPS_CP0_CONFIG5_MASK   0
>> +
>> +static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
>> +  int32_t *addr, int32_t mask)
>> +{
>> +int err;
>> +int32_t tmp, change;
>> +
>> +err = kvm_mips_get_one_reg(cs, reg_id, &tmp);
>> +if (err < 0) {
>> +return err;
>> +}
>> +
>> +/* only change bits in mask */
>> +change = (*addr ^ tmp) & mask;
>> +if (!change) {
>> +return 0;
>> +}
>> +
>> +tmp = tmp ^ change;
>> +return kvm_mips_put_one_reg(cs, reg_id, &tmp);
>> +}
>> +
>>  /*
>>   * We freeze the KVM timer when either the VM clock is stopped or the state 
>> is
>>   * saved (the state is dirty).
>> @@ -527,6 +561,48 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int 
>> level)
>>  DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
>>  ret = err;
>>  }
>> +err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG,
>> +  &env->CP0_Config0,
>> +  KVM_REG_MIPS_CP0_CONFIG_MASK);
>> +if (err < 0) {
>> +DPRINTF("%s: Failed to change CP0_CONFIG (%d)\n", __func__, err);
>> +ret = err;
>> +}
>> +err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1,
>> +  &env->CP0_Config1,
>> +  KVM_REG_MIPS_CP0_CONFIG1_MASK);
>> +if (err < 0) {
>> +DPRINTF("%s: Failed to change CP0_CONFIG1 (%d)\n", __func__, err);
>> +ret = err;
>> +}
>> +err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2,
>> +  &env->CP0_Config2,
>> +  KVM_REG_MIPS_CP0_CONFIG2_MASK);
>> +if (err < 0) {
>> +DPRINTF("%s: Failed to change CP0_CONFIG2 (%d)\n", __func__, err);
>> +ret = err;
>> +}
>> +err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3,
>> +  &env->CP0_Confi

[PATCH 9/9] mips/kvm: Support MSA in MIPS KVM guests

2015-03-12 Thread James Hogan
Support the new KVM_CAP_MIPS_MSA capability, which allows MIPS SIMD
Architecture (MSA) to be exposed to the KVM guest.

The capability is enabled if the guest core has MSA according to its
Config3 register. Various config bits are now writeable so that KVM is
aware of the configuration (Config3.MSAP) and so that QEMU can
save/restore the guest modifiable bits (Config5.MSAEn). The MSACSR/MSAIR
registers and the MSA vector registers are now saved/restored. Since the
FP registers are a subset of the vector registers, they are omitted if
the guest has MSA.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 linux-headers/linux/kvm.h |   1 +
 target-mips/kvm.c | 127 ++
 2 files changed, 108 insertions(+), 20 deletions(-)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 410eb158f564..0b2519332ac7 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -762,6 +762,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_PPC_ENABLE_HCALL 104
 #define KVM_CAP_CHECK_EXTENSION_VM 105
 #define KVM_CAP_MIPS_FPU 107
+#define KVM_CAP_MIPS_MSA 108
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index c0191a525171..a66e5eb44937 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -30,6 +30,7 @@
 do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0)
 
 static int kvm_mips_fpu_cap;
+static int kvm_mips_msa_cap;
 
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
@@ -48,6 +49,7 @@ int kvm_arch_init(KVMState *s)
 kvm_set_sigmask_len(s, 16);
 
 kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU);
+kvm_mips_msa_cap = kvm_check_extension(s, KVM_CAP_MIPS_MSA);
 
 DPRINTF("%s\n", __func__);
 return 0;
@@ -70,6 +72,15 @@ int kvm_arch_init_vcpu(CPUState *cs)
 }
 }
 
+if (kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_MSA, 0, 0);
+if (ret < 0) {
+/* mark unsupported so it gets disabled on reset */
+kvm_mips_msa_cap = 0;
+ret = 0;
+}
+}
+
 DPRINTF("%s\n", __func__);
 return ret;
 }
@@ -82,6 +93,10 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu)
 fprintf(stderr, "Warning: KVM does not support FPU, disabling\n");
 env->CP0_Config1 &= ~(1 << CP0C1_FP);
 }
+if (!kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
+fprintf(stderr, "Warning: KVM does not support MSA, disabling\n");
+env->CP0_Config3 &= ~(1 << CP0C3_MSAP);
+}
 
 DPRINTF("%s\n", __func__);
 }
@@ -404,9 +419,11 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, 
uint64 reg_id,
 #define KVM_REG_MIPS_CP0_CONFIG1_MASK   ((1 << CP0C1_M) | \
  (1 << CP0C1_FP))
 #define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1 << CP0C2_M)
-#define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1 << CP0C3_M)
+#define KVM_REG_MIPS_CP0_CONFIG3_MASK   ((1 << CP0C3_M) | \
+ (1 << CP0C3_MSAP))
 #define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1 << CP0C4_M)
-#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1 << CP0C5_UFE) | \
+#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1 << CP0C5_MSAEn) | \
+ (1 << CP0C5_UFE) | \
  (1 << CP0C5_FRE) | \
  (1 << CP0C5_UFR))
 
@@ -595,17 +612,53 @@ static int kvm_mips_put_fpu_registers(CPUState *cs, int 
level)
 ret = err;
 }
 
-/* Floating point registers */
+/*
+ * FPU register state is a subset of MSA vector state, so don't put FPU
+ * registers if we're emulating a CPU with MSA.
+ */
+if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
+/* Floating point registers */
+for (i = 0; i < 32; ++i) {
+if (env->CP0_Status & (1 << CP0St_FR)) {
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i),
+  &env->active_fpu.fpr[i].d);
+} else {
+err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FPR_32(i),
+&env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]);
+}
+if (err < 0) {
+DPRINTF("%s: Failed to put FPR%u (%d)\n", __func__, i, 
err);
+ret = err;
+}
+}
+}
+}
+
+/* Only put MSA state if we're emulating a CPU with MSA */
+if (env->CP0_Config3 & (1 << CP0C3_MSA

[PATCH 1/9] mips/kvm: Drop KVM_REG_MIPS_COUNT_* definitions

2015-03-12 Thread James Hogan
The KVM_REG_MIPS_COUNT_* definitions are now included in
linux-headers/asm-mips/kvm.h since commit b061808d39fa ("linux-headers:
update linux headers to kvm/next"), therefore the duplicate definitions
in target-mips/kvm.c can now be dropped.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 11 ---
 1 file changed, 11 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index b68191c88e87..49e71b3791b7 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -226,17 +226,6 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
-/* CP0_Count control */
-#define KVM_REG_MIPS_COUNT_CTL  (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
- 0x2 | 0)
-#define KVM_REG_MIPS_COUNT_CTL_DC   0x0001  /* master disable */
-/* CP0_Count resume monotonic nanoseconds */
-#define KVM_REG_MIPS_COUNT_RESUME   (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
- 0x2 | 1)
-/* CP0_Count rate in Hz */
-#define KVM_REG_MIPS_COUNT_HZ   (KVM_REG_MIPS | KVM_REG_SIZE_U64 | \
- 0x2 | 2)
-
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
int32_t *addr)
 {
-- 
2.0.5

--
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


[PATCH 2/9] mips/kvm: Remove a couple of noisy DPRINTFs

2015-03-12 Thread James Hogan
The DPRINTFs in cpu_mips_io_interrupts_pending() and kvm_arch_pre_run()
are particularly noisy during normal execution, and also not
particularly helpful. Remove them so that more important debug messages
can be more easily seen.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 49e71b3791b7..2ec7a6588568 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -87,7 +87,6 @@ static inline int cpu_mips_io_interrupts_pending(MIPSCPU *cpu)
 {
 CPUMIPSState *env = &cpu->env;
 
-DPRINTF("%s: %#x\n", __func__, env->CP0_Cause & (1 << (2 + CP0Ca_IP)));
 return env->CP0_Cause & (0x1 << (2 + CP0Ca_IP));
 }
 
@@ -112,7 +111,6 @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
 
 void kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
 {
-DPRINTF("%s\n", __func__);
 }
 
 int kvm_arch_process_async_events(CPUState *cs)
-- 
2.0.5

--
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


[PATCH 5/9] mips/kvm: Support unsigned KVM registers

2015-03-12 Thread James Hogan
Add KVM register access functions for the uint32_t type. This is
required for FP and MSA control registers, which are represented as
unsigned 32-bit integers.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index b8813a2722a3..f4ee22f3e998 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -243,6 +243,18 @@ static inline int kvm_mips_put_one_reg(CPUState *cs, 
uint64_t reg_id,
 return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
 }
 
+static inline int kvm_mips_put_one_ureg(CPUState *cs, uint64_t reg_id,
+uint32_t *addr)
+{
+uint64_t val64 = *addr;
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)&val64
+};
+
+return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
+}
+
 static inline int kvm_mips_put_one_ulreg(CPUState *cs, uint64_t reg_id,
  target_ulong *addr)
 {
@@ -283,6 +295,23 @@ static inline int kvm_mips_get_one_reg(CPUState *cs, 
uint64_t reg_id,
 return ret;
 }
 
+static inline int kvm_mips_get_one_ureg(CPUState *cs, uint64_t reg_id,
+uint32_t *addr)
+{
+int ret;
+uint64_t val64 = 0;
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)&val64
+};
+
+ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
+if (ret >= 0) {
+*addr = val64;
+}
+return ret;
+}
+
 static inline int kvm_mips_get_one_ulreg(CPUState *cs, uint64 reg_id,
  target_ulong *addr)
 {
-- 
2.0.5

--
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


[PATCH 6/9] mips/kvm: Support signed 64-bit KVM registers

2015-03-12 Thread James Hogan
Rename kvm_mips_{get,put}_one_reg64() to kvm_mips_{get,put}_one_ureg64()
since they take an int64_t pointer, and add separate signed 64-bit
accessors. These will be used for double precision floating point
registers.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 40 +++-
 1 file changed, 31 insertions(+), 9 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index f4ee22f3e998..6abd391f2cd5 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -268,7 +268,18 @@ static inline int kvm_mips_put_one_ulreg(CPUState *cs, 
uint64_t reg_id,
 }
 
 static inline int kvm_mips_put_one_reg64(CPUState *cs, uint64_t reg_id,
- uint64_t *addr)
+ int64_t *addr)
+{
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)addr
+};
+
+return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
+}
+
+static inline int kvm_mips_put_one_ureg64(CPUState *cs, uint64_t reg_id,
+  uint64_t *addr)
 {
 struct kvm_one_reg cp0reg = {
 .id = reg_id,
@@ -330,7 +341,18 @@ static inline int kvm_mips_get_one_ulreg(CPUState *cs, 
uint64 reg_id,
 }
 
 static inline int kvm_mips_get_one_reg64(CPUState *cs, uint64 reg_id,
- uint64_t *addr)
+ int64_t *addr)
+{
+struct kvm_one_reg cp0reg = {
+.id = reg_id,
+.addr = (uintptr_t)addr
+};
+
+return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
+}
+
+static inline int kvm_mips_get_one_ureg64(CPUState *cs, uint64 reg_id,
+  uint64_t *addr)
 {
 struct kvm_one_reg cp0reg = {
 .id = reg_id,
@@ -385,13 +407,13 @@ static int kvm_mips_save_count(CPUState *cs)
 int err, ret = 0;
 
 /* freeze KVM timer */
-err = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err);
 ret = err;
 } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
 count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
-err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
 ret = err;
@@ -427,14 +449,14 @@ static int kvm_mips_restore_count(CPUState *cs)
 int err_dc, err, ret = 0;
 
 /* check the timer is frozen */
-err_dc = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err_dc = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err_dc < 0) {
 DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err_dc);
 ret = err_dc;
 } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
 /* freeze timer (sets COUNT_RESUME for us) */
 count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
-err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
 ret = err;
@@ -458,7 +480,7 @@ static int kvm_mips_restore_count(CPUState *cs)
 /* resume KVM timer */
 if (err_dc >= 0) {
 count_ctl &= ~KVM_REG_MIPS_COUNT_CTL_DC;
-err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
+err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
 if (err < 0) {
 DPRINTF("%s: Failed to set COUNT_CTL.DC=0 (%d)\n", __func__, err);
 ret = err;
@@ -491,8 +513,8 @@ static void kvm_mips_update_state(void *opaque, int 
running, RunState state)
 } else {
 /* Set clock restore time to now */
 count_resume = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
-ret = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_COUNT_RESUME,
- &count_resume);
+ret = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_RESUME,
+  &count_resume);
 if (ret < 0) {
 fprintf(stderr, "Failed setting COUNT_RESUME\n");
 return;
-- 
2.0.5

--
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


[PATCH 12/20] MIPS: KVM: Emulate FPU bits in COP0 interface

2015-03-12 Thread James Hogan
Emulate FPU related parts of COP0 interface so that the guest will be
able to enable/disable the following once the FPU capability has been
wired up:
- The FPU (Status.CU1)
- 64-bit FP register mode (Status.FR)
- Hybrid FP register mode (Config5.FRE)

Changing Status.CU1 has no immediate effect if the FPU state isn't live,
as the FPU state is restored lazily on first use. After that, changes
take place immediately in the host Status.CU1, so that the guest can
start getting coprocessor unusable exceptions right away for guest FPU
operations if it is disabled. The FPU state is saved lazily too, as the
FPU may get re-enabled in the near future anyway.

Any change to Status.FR causes the FPU state to be discarded and FPU
disabled, as the register state is architecturally UNPREDICTABLE after
such a change. This should also ensure that the FPU state is fully
initialised (with stale state, but that's fine) when it is next used in
the new FP mode.

Any change to the Config5.FRE bit is immediately updated in the host
state so that the guest can get the relevant exceptions right away for
single-precision FPU operations.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/kvm/emulate.c | 111 +++-
 1 file changed, 100 insertions(+), 11 deletions(-)

diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 91d5b0e370b4..3511bb20fe0e 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -893,8 +893,13 @@ enum emulation_result kvm_mips_emul_tlbp(struct kvm_vcpu 
*vcpu)
  */
 unsigned int kvm_mips_config1_wrmask(struct kvm_vcpu *vcpu)
 {
-   /* Read-only */
-   return 0;
+   unsigned int mask = 0;
+
+   /* Permit FPU to be present if FPU is supported */
+   if (kvm_mips_guest_can_have_fpu(&vcpu->arch))
+   mask |= MIPS_CONF1_FP;
+
+   return mask;
 }
 
 /**
@@ -932,8 +937,19 @@ unsigned int kvm_mips_config4_wrmask(struct kvm_vcpu *vcpu)
  */
 unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu)
 {
-   /* Read-only */
-   return 0;
+   unsigned int mask = 0;
+
+   /*
+* Permit guest FPU mode changes if FPU is enabled and the relevant
+* feature exists according to FIR register.
+*/
+   if (kvm_mips_guest_has_fpu(&vcpu->arch)) {
+   if (cpu_has_fre)
+   mask |= MIPS_CONF5_FRE;
+   /* We don't support UFR or UFE */
+   }
+
+   return mask;
 }
 
 enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc,
@@ -1073,18 +1089,91 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t 
inst, uint32_t *opc,
kvm_mips_write_compare(vcpu,
   vcpu->arch.gprs[rt]);
} else if ((rd == MIPS_CP0_STATUS) && (sel == 0)) {
-   kvm_write_c0_guest_status(cop0,
- vcpu->arch.gprs[rt]);
+   unsigned int old_val, val, change;
+
+   old_val = kvm_read_c0_guest_status(cop0);
+   val = vcpu->arch.gprs[rt];
+   change = val ^ old_val;
+
+   /* Make sure that the NMI bit is never set */
+   val &= ~ST0_NMI;
+
/*
-* Make sure that CU1 and NMI bits are
-* never set
+* Don't allow CU1 or FR to be set unless FPU
+* capability enabled and exists in guest
+* configuration.
 */
-   kvm_clear_c0_guest_status(cop0,
- (ST0_CU1 | ST0_NMI));
+   if (!kvm_mips_guest_has_fpu(&vcpu->arch))
+   val &= ~(ST0_CU1 | ST0_FR);
+
+   /*
+* Also don't allow FR to be set if host doesn't
+* support it.
+*/
+   if (!(current_cpu_data.fpu_id & MIPS_FPIR_F64))
+   val &= ~ST0_FR;
+
+
+   /* Handle changes in FPU mode */
+   preempt_disable();
+
+   /*
+* FPU and Vector register state is made
+* UNPREDICTABLE by a change of FR, so don't
+* even bother saving it

[PATCH 10/20] MIPS: KVM: Add vcpu_get_regs/vcpu_set_regs callback

2015-03-12 Thread James Hogan
Add a vcpu_get_regs() and vcpu_set_regs() callbacks for loading and
restoring context which may be in hardware registers. This may include
floating point and MIPS SIMD Architecture (MSA) state which may be
accessed directly by the guest (but restored lazily by the hypervisor),
and also dedicated guest registers as provided by the VZ ASE.

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h |  2 ++
 arch/mips/kvm/tlb.c  |  6 ++
 arch/mips/kvm/trap_emul.c| 12 
 3 files changed, 20 insertions(+)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 3f58ee1ebfab..fb79d67de192 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -585,6 +585,8 @@ struct kvm_mips_callbacks {
   const struct kvm_one_reg *reg, s64 *v);
int (*set_one_reg)(struct kvm_vcpu *vcpu,
   const struct kvm_one_reg *reg, s64 v);
+   int (*vcpu_get_regs)(struct kvm_vcpu *vcpu);
+   int (*vcpu_set_regs)(struct kvm_vcpu *vcpu);
 };
 extern struct kvm_mips_callbacks *kvm_mips_callbacks;
 int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks);
diff --git a/arch/mips/kvm/tlb.c b/arch/mips/kvm/tlb.c
index bbcd82242059..caa0b13fa37e 100644
--- a/arch/mips/kvm/tlb.c
+++ b/arch/mips/kvm/tlb.c
@@ -732,6 +732,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
}
}
 
+   /* restore guest state to registers */
+   kvm_mips_callbacks->vcpu_set_regs(vcpu);
+
local_irq_restore(flags);
 
 }
@@ -750,6 +753,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
vcpu->arch.preempt_entryhi = read_c0_entryhi();
vcpu->arch.last_sched_cpu = cpu;
 
+   /* save guest state in registers */
+   kvm_mips_callbacks->vcpu_get_regs(vcpu);
+
if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) &
 ASID_VERSION_MASK)) {
kvm_debug("%s: Dropping MMU Context:  %#lx\n", __func__,
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
index 8e0968428a78..0d2729d202f4 100644
--- a/arch/mips/kvm/trap_emul.c
+++ b/arch/mips/kvm/trap_emul.c
@@ -552,6 +552,16 @@ static int kvm_trap_emul_set_one_reg(struct kvm_vcpu *vcpu,
return ret;
 }
 
+static int kvm_trap_emul_vcpu_get_regs(struct kvm_vcpu *vcpu)
+{
+   return 0;
+}
+
+static int kvm_trap_emul_vcpu_set_regs(struct kvm_vcpu *vcpu)
+{
+   return 0;
+}
+
 static struct kvm_mips_callbacks kvm_trap_emul_callbacks = {
/* exit handlers */
.handle_cop_unusable = kvm_trap_emul_handle_cop_unusable,
@@ -578,6 +588,8 @@ static struct kvm_mips_callbacks kvm_trap_emul_callbacks = {
.irq_clear = kvm_mips_irq_clear_cb,
.get_one_reg = kvm_trap_emul_get_one_reg,
.set_one_reg = kvm_trap_emul_set_one_reg,
+   .vcpu_get_regs = kvm_trap_emul_vcpu_get_regs,
+   .vcpu_set_regs = kvm_trap_emul_vcpu_set_regs,
 };
 
 int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks)
-- 
2.0.5

--
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


[PATCH 19/20] MIPS: KVM: Expose MSA registers

2015-03-12 Thread James Hogan
Add KVM register numbers for the MIPS SIMD Architecture (MSA) registers,
and implement access to them with the KVM_GET_ONE_REG / KVM_SET_ONE_REG
ioctls when the MSA capability is enabled (exposed in a later patch) and
present in the guest according to its Config3.MSAP bit.

The MSA vector registers use the same register numbers as the FPU
registers except with a different size (128bits). Since MSA depends on
Status.FR=1, these registers are inaccessible when Status.FR=0. These
registers are returned as a single native endian 128bit value, rather
than least significant half first with each 64-bit half native endian as
the kernel uses internally.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Jonathan Corbet 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linux-...@vger.kernel.org
---
 Documentation/virtual/kvm/api.txt |  3 ++
 arch/mips/include/uapi/asm/kvm.h  | 12 ++--
 arch/mips/kvm/mips.c  | 65 +++
 3 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 44623688d566..47ddf0475211 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1981,8 +1981,11 @@ registers, find a list below:
   MIPS  | KVM_REG_MIPS_COUNT_HZ | 64
   MIPS  | KVM_REG_MIPS_FPR_32(0..31)| 32
   MIPS  | KVM_REG_MIPS_FPR_64(0..31)| 64
+  MIPS  | KVM_REG_MIPS_VEC_128(0..31)   | 128
   MIPS  | KVM_REG_MIPS_FCR_IR   | 32
   MIPS  | KVM_REG_MIPS_FCR_CSR  | 32
+  MIPS  | KVM_REG_MIPS_MSA_IR   | 32
+  MIPS  | KVM_REG_MIPS_MSA_CSR  | 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h
index 401e6a6f8bb8..6985eb59b085 100644
--- a/arch/mips/include/uapi/asm/kvm.h
+++ b/arch/mips/include/uapi/asm/kvm.h
@@ -58,7 +58,7 @@ struct kvm_fpu {
  *
  * Register set = 2: KVM specific registers (see definitions below).
  *
- * Register set = 3: FPU registers (see definitions below).
+ * Register set = 3: FPU / MSA registers (see definitions below).
  *
  * Other sets registers may be added in the future.  Each set would
  * have its own identifier in bits[31..16].
@@ -148,7 +148,7 @@ struct kvm_fpu {
 
 
 /*
- * KVM_REG_MIPS_FPU - Floating Point registers.
+ * KVM_REG_MIPS_FPU - Floating Point and MIPS SIMD Architecture (MSA) 
registers.
  *
  *  bits[15..8]  - Register subset (see definitions below).
  *  bits[7..5]   - Must be zero.
@@ -157,12 +157,14 @@ struct kvm_fpu {
 
 #define KVM_REG_MIPS_FPR   (KVM_REG_MIPS_FPU | 0xULL)
 #define KVM_REG_MIPS_FCR   (KVM_REG_MIPS_FPU | 0x0100ULL)
+#define KVM_REG_MIPS_MSACR (KVM_REG_MIPS_FPU | 0x0200ULL)
 
 /*
  * KVM_REG_MIPS_FPR - Floating point / Vector registers.
  */
 #define KVM_REG_MIPS_FPR_32(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U32  | (n))
 #define KVM_REG_MIPS_FPR_64(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U64  | (n))
+#define KVM_REG_MIPS_VEC_128(n)(KVM_REG_MIPS_FPR | KVM_REG_SIZE_U128 | 
(n))
 
 /*
  * KVM_REG_MIPS_FCR - Floating point control registers.
@@ -170,6 +172,12 @@ struct kvm_fpu {
 #define KVM_REG_MIPS_FCR_IR(KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 |  0)
 #define KVM_REG_MIPS_FCR_CSR   (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 31)
 
+/*
+ * KVM_REG_MIPS_MSACR - MIPS SIMD Architecture (MSA) control registers.
+ */
+#define KVM_REG_MIPS_MSA_IR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 |  0)
+#define KVM_REG_MIPS_MSA_CSR(KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 |  1)
+
 
 /*
  * KVM MIPS specific structures and definitions
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index a44a37475156..9319c4360285 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -531,6 +531,7 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
struct mips_fpu_struct *fpu = &vcpu->arch.fpu;
int ret;
s64 v;
+   s64 vs[2];
unsigned int idx;
 
switch (reg->id) {
@@ -579,6 +580,35 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
v = fpu->fcr31;
break;
 
+   /* MIPS SIMD Architecture (MSA) registers */
+   case KVM_REG_MIPS_VEC_128(0) ... KVM_REG_MIPS_VEC_128(31):
+   if (!kvm_mips_guest_has_msa(&vcpu->arch))
+   return -EINVAL;
+   /* Can't access MSA registers in FR=0 mode */
+   if (!(kvm_read_c0_guest_status(cop0) & ST0_FR))
+   return -EINVAL;
+   idx = reg->id - KVM_REG_MIPS_VEC_128(0);
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+   /* least significant byte first */
+   vs[0] = get_fpr64(&fpu->fpr[idx], 0);
+   vs[1]

[PATCH 18/20] MIPS: KVM: Add MSA exception handling

2015-03-12 Thread James Hogan
Add guest exception handling for MIPS SIMD Architecture (MSA) floating
point exceptions and MSA disabled exceptions.

MSA floating point exceptions from the guest need passing to the guest
kernel, so for these a guest MSAFPE is emulated.

MSA disabled exceptions are normally handled by passing a reserved
instruction exception to the guest (because no guest MSA was supported),
but the hypervisor can now handle them if the guest has MSA by passing
an MSA disabled exception to the guest, or if the guest has MSA enabled
by transparently restoring the guest MSA context and enabling MSA and
the FPU.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h | 16 +
 arch/mips/kvm/emulate.c  | 71 
 arch/mips/kvm/mips.c | 10 ++
 arch/mips/kvm/stats.c|  2 ++
 arch/mips/kvm/trap_emul.c| 43 ++--
 5 files changed, 140 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 1dc0dca15cbd..4c25823563fe 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -123,7 +123,9 @@ struct kvm_vcpu_stat {
u32 resvd_inst_exits;
u32 break_inst_exits;
u32 trap_inst_exits;
+   u32 msa_fpe_exits;
u32 fpe_exits;
+   u32 msa_disabled_exits;
u32 flush_dcache_exits;
u32 halt_successful_poll;
u32 halt_wakeup;
@@ -144,7 +146,9 @@ enum kvm_mips_exit_types {
RESVD_INST_EXITS,
BREAK_INST_EXITS,
TRAP_INST_EXITS,
+   MSA_FPE_EXITS,
FPE_EXITS,
+   MSA_DISABLED_EXITS,
FLUSH_DCACHE_EXITS,
MAX_KVM_MIPS_EXIT_TYPES
 };
@@ -305,6 +309,7 @@ enum mips_mmu_types {
  */
 #define T_TRAP 13  /* Trap instruction */
 #define T_VCEI 14  /* Virtual coherency exception */
+#define T_MSAFPE   14  /* MSA floating point exception */
 #define T_FPE  15  /* Floating point exception */
 #define T_MSADIS   21  /* MSA disabled exception */
 #define T_WATCH23  /* Watch address reference */
@@ -601,6 +606,7 @@ struct kvm_mips_callbacks {
int (*handle_res_inst)(struct kvm_vcpu *vcpu);
int (*handle_break)(struct kvm_vcpu *vcpu);
int (*handle_trap)(struct kvm_vcpu *vcpu);
+   int (*handle_msa_fpe)(struct kvm_vcpu *vcpu);
int (*handle_fpe)(struct kvm_vcpu *vcpu);
int (*handle_msa_disabled)(struct kvm_vcpu *vcpu);
int (*vm_init)(struct kvm *kvm);
@@ -756,11 +762,21 @@ extern enum emulation_result 
kvm_mips_emulate_trap_exc(unsigned long cause,
   struct kvm_run *run,
   struct kvm_vcpu *vcpu);
 
+extern enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause,
+uint32_t *opc,
+struct kvm_run *run,
+struct kvm_vcpu *vcpu);
+
 extern enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause,
  uint32_t *opc,
  struct kvm_run *run,
  struct kvm_vcpu *vcpu);
 
+extern enum emulation_result kvm_mips_emulate_msadis_exc(unsigned long cause,
+uint32_t *opc,
+struct kvm_run *run,
+struct kvm_vcpu *vcpu);
+
 extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
 struct kvm_run *run);
 
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 07f554c72cb8..6230f376a44e 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -2179,6 +2179,41 @@ enum emulation_result kvm_mips_emulate_trap_exc(unsigned 
long cause,
return er;
 }
 
+enum emulation_result kvm_mips_emulate_msafpe_exc(unsigned long cause,
+ uint32_t *opc,
+ struct kvm_run *run,
+ struct kvm_vcpu *vcpu)
+{
+   struct mips_coproc *cop0 = vcpu->arch.cop0;
+   struct kvm_vcpu_arch *arch = &vcpu->arch;
+   enum emulation_result er = EMULATE_DONE;
+
+   if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
+   /* save old pc */
+   kvm_write_c0_guest_epc(cop0, arch->pc);
+   kvm_se

[PATCH 06/20] MIPS: KVM: Drop pr_info messages on init/exit

2015-03-12 Thread James Hogan
The information messages when the KVM module is loaded and unloaded are
a bit pointless and out of line with other architectures, so lets drop
them.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/kvm/mips.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index b909c0046f08..0aab83d894ba 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -1191,7 +1191,6 @@ int __init kvm_mips_init(void)
kvm_mips_release_pfn_clean = kvm_release_pfn_clean;
kvm_mips_is_error_pfn = is_error_pfn;
 
-   pr_info("KVM/MIPS Initialized\n");
return 0;
 }
 
@@ -1202,8 +1201,6 @@ void __exit kvm_mips_exit(void)
kvm_mips_gfn_to_pfn = NULL;
kvm_mips_release_pfn_clean = NULL;
kvm_mips_is_error_pfn = NULL;
-
-   pr_info("KVM/MIPS unloaded\n");
 }
 
 module_init(kvm_mips_init);
-- 
2.0.5

--
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


[PATCH 20/20] MIPS: KVM: Wire up MSA capability

2015-03-12 Thread James Hogan
Now that the code is in place for KVM to support MIPS SIMD Architecutre
(MSA) in MIPS guests, wire up the new KVM_CAP_MIPS_MSA capability.

For backwards compatibility, the capability must be explicitly enabled
in order to detect or make use of MSA from the guest.

The capability is not supported if the hardware supports MSA vector
partitioning, since the extra support cannot be tested yet and it
extends the state that the userland program would have to save.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Jonathan Corbet 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: James Hogan 
---
 Documentation/virtual/kvm/api.txt | 12 
 arch/mips/kvm/mips.c  | 24 
 include/uapi/linux/kvm.h  |  1 +
 3 files changed, 37 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 47ddf0475211..97dd9ee69ca8 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3224,6 +3224,18 @@ done the KVM_REG_MIPS_FPR_* and KVM_REG_MIPS_FCR_* 
registers can be accessed
 Config5.FRE bits are accessible via the KVM API and also from the guest,
 depending on them being supported by the FPU.
 
+6.10 KVM_CAP_MIPS_MSA
+
+Architectures: mips
+Target: vcpu
+Parameters: args[0] is reserved for future use (should be 0).
+
+This capability allows the use of the MIPS SIMD Architecture (MSA) by the 
guest.
+It allows the Config3.MSAP bit to be set to enable the use of MSA by the guest.
+Once this is done the KVM_REG_MIPS_VEC_* and KVM_REG_MIPS_MSA_* registers can 
be
+accessed, and the Config5.MSAEn bit is accessible via the KVM API and also from
+the guest.
+
 7. Capabilities that can be enabled on VMs
 --
 
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 9319c4360285..3b3530f493eb 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -880,6 +880,15 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
return -EINVAL;
vcpu->arch.fpu_enabled = true;
break;
+   case KVM_CAP_MIPS_MSA:
+   /*
+* MSA vector partitioning not supported,
+* see kvm_vm_ioctl_check_extension().
+*/
+   if (!cpu_has_msa || boot_cpu_data.msa_id & MSA_IR_WRPF)
+   return -EINVAL;
+   vcpu->arch.msa_enabled = true;
+   break;
default:
r = -EINVAL;
break;
@@ -1071,6 +1080,21 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long 
ext)
case KVM_CAP_MIPS_FPU:
r = !!cpu_has_fpu;
break;
+   case KVM_CAP_MIPS_MSA:
+   /*
+* We don't support MSA vector partitioning yet:
+* 1) It would require explicit support which can't be tested
+*yet due to lack of support in current hardware.
+* 2) It extends the state that would need to be saved/restored
+*by e.g. QEMU for migration.
+*
+* When vector partitioning hardware becomes available, support
+* could be added by requiring a flag when enabling
+* KVM_CAP_MIPS_MSA capability to indicate that userland knows
+* to save/restore the appropriate extra state.
+*/
+   r = cpu_has_msa && !(boot_cpu_data.msa_id & MSA_IR_WRPF);
+   break;
default:
r = 0;
break;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 98f6e5c653ff..5f859888e3ad 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -761,6 +761,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_CHECK_EXTENSION_VM 105
 #define KVM_CAP_S390_USER_SIGP 106
 #define KVM_CAP_MIPS_FPU 107
+#define KVM_CAP_MIPS_MSA 108
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.0.5

--
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


[PATCH 09/20] MIPS: KVM: Add Config4/5 and writing of Config registers

2015-03-12 Thread James Hogan
Add Config4 and Config5 co-processor 0 registers, and add capability to
write the Config1, Config3, Config4, and Config5 registers using the KVM
API.

Only supported bits can be written, to minimise the chances of the guest
being given a configuration from e.g. QEMU that is inconsistent with
that being emulated, and as such the handling is in trap_emul.c as it
may need to be different for VZ. Currently the only modification
permitted is to make Config4 and Config5 exist via the M bits, but other
bits will be added for FPU and MSA support in future patches.

Care should be taken by userland not to change bits without fully
handling the possible extra state that may then exist and which the
guest may begin to use and depend on.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 Documentation/virtual/kvm/api.txt |  2 ++
 arch/mips/include/asm/kvm_host.h  | 13 ++
 arch/mips/kvm/emulate.c   | 52 +++
 arch/mips/kvm/mips.c  | 14 +++
 arch/mips/kvm/trap_emul.c | 49 ++--
 5 files changed, 128 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 22dfaa31ed86..1e59515b6d1f 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1972,6 +1972,8 @@ registers, find a list below:
   MIPS  | KVM_REG_MIPS_CP0_CONFIG1  | 32
   MIPS  | KVM_REG_MIPS_CP0_CONFIG2  | 32
   MIPS  | KVM_REG_MIPS_CP0_CONFIG3  | 32
+  MIPS  | KVM_REG_MIPS_CP0_CONFIG4  | 32
+  MIPS  | KVM_REG_MIPS_CP0_CONFIG5  | 32
   MIPS  | KVM_REG_MIPS_CP0_CONFIG7  | 32
   MIPS  | KVM_REG_MIPS_CP0_ERROREPC | 64
   MIPS  | KVM_REG_MIPS_COUNT_CTL| 64
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 6996447fd2a7..3f58ee1ebfab 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -48,6 +48,8 @@
 #define KVM_REG_MIPS_CP0_CONFIG1   MIPS_CP0_32(16, 1)
 #define KVM_REG_MIPS_CP0_CONFIG2   MIPS_CP0_32(16, 2)
 #define KVM_REG_MIPS_CP0_CONFIG3   MIPS_CP0_32(16, 3)
+#define KVM_REG_MIPS_CP0_CONFIG4   MIPS_CP0_32(16, 4)
+#define KVM_REG_MIPS_CP0_CONFIG5   MIPS_CP0_32(16, 5)
 #define KVM_REG_MIPS_CP0_CONFIG7   MIPS_CP0_32(16, 7)
 #define KVM_REG_MIPS_CP0_XCONTEXT  MIPS_CP0_64(20, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC  MIPS_CP0_64(30, 0)
@@ -209,6 +211,8 @@ struct mips_coproc {
 #define MIPS_CP0_CONFIG1_SEL   1
 #define MIPS_CP0_CONFIG2_SEL   2
 #define MIPS_CP0_CONFIG3_SEL   3
+#define MIPS_CP0_CONFIG4_SEL   4
+#define MIPS_CP0_CONFIG5_SEL   5
 
 /* Config0 register bits */
 #define CP0C0_M31
@@ -461,11 +465,15 @@ struct kvm_vcpu_arch {
 #define kvm_read_c0_guest_config1(cop0)
(cop0->reg[MIPS_CP0_CONFIG][1])
 #define kvm_read_c0_guest_config2(cop0)
(cop0->reg[MIPS_CP0_CONFIG][2])
 #define kvm_read_c0_guest_config3(cop0)
(cop0->reg[MIPS_CP0_CONFIG][3])
+#define kvm_read_c0_guest_config4(cop0)
(cop0->reg[MIPS_CP0_CONFIG][4])
+#define kvm_read_c0_guest_config5(cop0)
(cop0->reg[MIPS_CP0_CONFIG][5])
 #define kvm_read_c0_guest_config7(cop0)
(cop0->reg[MIPS_CP0_CONFIG][7])
 #define kvm_write_c0_guest_config(cop0, val)   (cop0->reg[MIPS_CP0_CONFIG][0] 
= (val))
 #define kvm_write_c0_guest_config1(cop0, val)  (cop0->reg[MIPS_CP0_CONFIG][1] 
= (val))
 #define kvm_write_c0_guest_config2(cop0, val)  (cop0->reg[MIPS_CP0_CONFIG][2] 
= (val))
 #define kvm_write_c0_guest_config3(cop0, val)  (cop0->reg[MIPS_CP0_CONFIG][3] 
= (val))
+#define kvm_write_c0_guest_config4(cop0, val)  (cop0->reg[MIPS_CP0_CONFIG][4] 
= (val))
+#define kvm_write_c0_guest_config5(cop0, val)  (cop0->reg[MIPS_CP0_CONFIG][5] 
= (val))
 #define kvm_write_c0_guest_config7(cop0, val)  (cop0->reg[MIPS_CP0_CONFIG][7] 
= (val))
 #define kvm_read_c0_guest_errorepc(cop0)   
(cop0->reg[MIPS_CP0_ERROR_PC][0])
 #define kvm_write_c0_guest_errorepc(cop0, val) 
(cop0->reg[MIPS_CP0_ERROR_PC][0] = (val))
@@ -735,6 +743,11 @@ enum emulation_result kvm_mips_emulate_load(uint32_t inst,
struct kvm_run *run,
struct kvm_vcpu *vcpu);
 
+unsigned int kvm_mips_config1_wrmask(struct kvm_vcpu *vcpu);
+unsigned int kvm_mips_config3_wrmask(struct kvm_vcpu *vcpu);
+unsigned int kvm_mips_config4_wrmask(struct kvm_vcpu *vcpu);
+unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu);
+
 /* Dynamic binary translation */
 extern int kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc,
  struct kvm_vcpu *vcpu);
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 33e132dc7de8..91d5b0e370b4 100644
--- 

[PATCH 04/20] MIPS: KVM: Implement PRid CP0 register access

2015-03-12 Thread James Hogan
Implement access to the guest Processor Identification CP0 register
using the KVM_GET_ONE_REG and KVM_SET_ONE_REG ioctls. This allows the
owning process to modify and read back the value that is exposed to the
guest in this register.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 Documentation/virtual/kvm/api.txt | 1 +
 arch/mips/include/asm/kvm_host.h  | 1 +
 arch/mips/kvm/mips.c  | 7 +++
 3 files changed, 9 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index b112efc816f1..22dfaa31ed86 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1967,6 +1967,7 @@ registers, find a list below:
   MIPS  | KVM_REG_MIPS_CP0_STATUS   | 32
   MIPS  | KVM_REG_MIPS_CP0_CAUSE| 32
   MIPS  | KVM_REG_MIPS_CP0_EPC  | 64
+  MIPS  | KVM_REG_MIPS_CP0_PRID | 32
   MIPS  | KVM_REG_MIPS_CP0_CONFIG   | 32
   MIPS  | KVM_REG_MIPS_CP0_CONFIG1  | 32
   MIPS  | KVM_REG_MIPS_CP0_CONFIG2  | 32
diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 8fc3ba2872f0..26d91b0f3c3c 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -42,6 +42,7 @@
 #define KVM_REG_MIPS_CP0_STATUSMIPS_CP0_32(12, 0)
 #define KVM_REG_MIPS_CP0_CAUSE MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPC   MIPS_CP0_64(14, 0)
+#define KVM_REG_MIPS_CP0_PRID  MIPS_CP0_32(15, 0)
 #define KVM_REG_MIPS_CP0_EBASE MIPS_CP0_64(15, 1)
 #define KVM_REG_MIPS_CP0_CONFIGMIPS_CP0_32(16, 0)
 #define KVM_REG_MIPS_CP0_CONFIG1   MIPS_CP0_32(16, 1)
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 399b5517ecb8..fd620cc8a44c 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -505,6 +505,7 @@ static u64 kvm_mips_get_one_regs[] = {
KVM_REG_MIPS_CP0_STATUS,
KVM_REG_MIPS_CP0_CAUSE,
KVM_REG_MIPS_CP0_EPC,
+   KVM_REG_MIPS_CP0_PRID,
KVM_REG_MIPS_CP0_CONFIG,
KVM_REG_MIPS_CP0_CONFIG1,
KVM_REG_MIPS_CP0_CONFIG2,
@@ -574,6 +575,9 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
case KVM_REG_MIPS_CP0_EPC:
v = (long)kvm_read_c0_guest_epc(cop0);
break;
+   case KVM_REG_MIPS_CP0_PRID:
+   v = (long)kvm_read_c0_guest_prid(cop0);
+   break;
case KVM_REG_MIPS_CP0_ERROREPC:
v = (long)kvm_read_c0_guest_errorepc(cop0);
break;
@@ -687,6 +691,9 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
case KVM_REG_MIPS_CP0_EPC:
kvm_write_c0_guest_epc(cop0, v);
break;
+   case KVM_REG_MIPS_CP0_PRID:
+   kvm_write_c0_guest_prid(cop0, v);
+   break;
case KVM_REG_MIPS_CP0_ERROREPC:
kvm_write_c0_guest_errorepc(cop0, v);
break;
-- 
2.0.5

--
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


[PATCH 15/20] MIPS: KVM: Wire up FPU capability

2015-03-12 Thread James Hogan
Now that the code is in place for KVM to support FPU in MIPS KVM guests,
wire up the new KVM_CAP_MIPS_FPU capability.

For backwards compatibility, the capability must be explicitly enabled
in order to detect or make use of the FPU from the guest.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Jonathan Corbet 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linux-...@vger.kernel.org
---
 Documentation/virtual/kvm/api.txt | 13 +
 arch/mips/kvm/mips.c  | 37 +
 include/uapi/linux/kvm.h  |  1 +
 3 files changed, 51 insertions(+)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 8ba55b9c903e..44623688d566 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3208,6 +3208,19 @@ Parameters: none
 This capability enables the in-kernel irqchip for s390. Please refer to
 "4.24 KVM_CREATE_IRQCHIP" for details.
 
+6.9 KVM_CAP_MIPS_FPU
+
+Architectures: mips
+Target: vcpu
+Parameters: args[0] is reserved for future use (should be 0).
+
+This capability allows the use of the host Floating Point Unit by the guest. It
+allows the Config1.FP bit to be set to enable the FPU in the guest. Once this 
is
+done the KVM_REG_MIPS_FPR_* and KVM_REG_MIPS_FCR_* registers can be accessed
+(depending on the current guest FPU register mode), and the Status.FR,
+Config5.FRE bits are accessible via the KVM API and also from the guest,
+depending on them being supported by the FPU.
+
 7. Capabilities that can be enabled on VMs
 --
 
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index 5e41afe15ae8..6cdb2a1cd8ec 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -797,6 +797,30 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
return 0;
 }
 
+static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
+struct kvm_enable_cap *cap)
+{
+   int r = 0;
+
+   if (cap->flags)
+   return -EINVAL;
+   if (cap->args[0])
+   return -EINVAL;
+
+   switch (cap->cap) {
+   case KVM_CAP_MIPS_FPU:
+   if (!cpu_has_fpu)
+   return -EINVAL;
+   vcpu->arch.fpu_enabled = true;
+   break;
+   default:
+   r = -EINVAL;
+   break;
+   }
+
+   return r;
+}
+
 long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int ioctl,
 unsigned long arg)
 {
@@ -854,6 +878,15 @@ long kvm_arch_vcpu_ioctl(struct file *filp, unsigned int 
ioctl,
r = kvm_vcpu_ioctl_interrupt(vcpu, &irq);
break;
}
+   case KVM_ENABLE_CAP: {
+   struct kvm_enable_cap cap;
+
+   r = -EFAULT;
+   if (copy_from_user(&cap, argp, sizeof(cap)))
+   goto out;
+   r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap);
+   break;
+   }
default:
r = -ENOIOCTLCMD;
}
@@ -962,11 +995,15 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long 
ext)
 
switch (ext) {
case KVM_CAP_ONE_REG:
+   case KVM_CAP_ENABLE_CAP:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
r = KVM_COALESCED_MMIO_PAGE_OFFSET;
break;
+   case KVM_CAP_MIPS_FPU:
+   r = !!cpu_has_fpu;
+   break;
default:
r = 0;
break;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 805570650062..98f6e5c653ff 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -760,6 +760,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_PPC_ENABLE_HCALL 104
 #define KVM_CAP_CHECK_EXTENSION_VM 105
 #define KVM_CAP_S390_USER_SIGP 106
+#define KVM_CAP_MIPS_FPU 107
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.0.5

--
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


[PATCH 03/20] MIPS: KVM: Handle TRAP exceptions from guest kernel

2015-03-12 Thread James Hogan
Trap instructions are used by Linux to implement BUG_ON(), however KVM
doesn't pass trap exceptions on to the guest if they occur in guest
kernel mode, instead triggering an internal error "Exception Code: 13,
not yet handled". The guest kernel then doesn't get a chance to print
the usual BUG message and stack trace.

Implement handling of the trap exception so that it gets passed to the
guest and the user is left with a more useful log message.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: kvm@vger.kernel.org
Cc: linux-m...@linux-mips.org
---
 arch/mips/include/asm/kvm_host.h |  8 
 arch/mips/kvm/emulate.c  | 36 
 arch/mips/kvm/mips.c |  7 +++
 arch/mips/kvm/stats.c|  1 +
 arch/mips/kvm/trap_emul.c| 19 +++
 5 files changed, 71 insertions(+)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index f722b0528c25..8fc3ba2872f0 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -119,6 +119,7 @@ struct kvm_vcpu_stat {
u32 syscall_exits;
u32 resvd_inst_exits;
u32 break_inst_exits;
+   u32 trap_inst_exits;
u32 flush_dcache_exits;
u32 halt_successful_poll;
u32 halt_wakeup;
@@ -138,6 +139,7 @@ enum kvm_mips_exit_types {
SYSCALL_EXITS,
RESVD_INST_EXITS,
BREAK_INST_EXITS,
+   TRAP_INST_EXITS,
FLUSH_DCACHE_EXITS,
MAX_KVM_MIPS_EXIT_TYPES
 };
@@ -579,6 +581,7 @@ struct kvm_mips_callbacks {
int (*handle_syscall)(struct kvm_vcpu *vcpu);
int (*handle_res_inst)(struct kvm_vcpu *vcpu);
int (*handle_break)(struct kvm_vcpu *vcpu);
+   int (*handle_trap)(struct kvm_vcpu *vcpu);
int (*handle_msa_disabled)(struct kvm_vcpu *vcpu);
int (*vm_init)(struct kvm *kvm);
int (*vcpu_init)(struct kvm_vcpu *vcpu);
@@ -713,6 +716,11 @@ extern enum emulation_result 
kvm_mips_emulate_bp_exc(unsigned long cause,
 struct kvm_run *run,
 struct kvm_vcpu *vcpu);
 
+extern enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause,
+  uint32_t *opc,
+  struct kvm_run *run,
+  struct kvm_vcpu *vcpu);
+
 extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
 struct kvm_run *run);
 
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 838d3a6a5b7d..33e132dc7de8 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -1970,6 +1970,41 @@ enum emulation_result kvm_mips_emulate_bp_exc(unsigned 
long cause,
return er;
 }
 
+enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause,
+   uint32_t *opc,
+   struct kvm_run *run,
+   struct kvm_vcpu *vcpu)
+{
+   struct mips_coproc *cop0 = vcpu->arch.cop0;
+   struct kvm_vcpu_arch *arch = &vcpu->arch;
+   enum emulation_result er = EMULATE_DONE;
+
+   if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
+   /* save old pc */
+   kvm_write_c0_guest_epc(cop0, arch->pc);
+   kvm_set_c0_guest_status(cop0, ST0_EXL);
+
+   if (cause & CAUSEF_BD)
+   kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
+   else
+   kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);
+
+   kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc);
+
+   kvm_change_c0_guest_cause(cop0, (0xff),
+ (T_TRAP << CAUSEB_EXCCODE));
+
+   /* Set PC to the exception entry point */
+   arch->pc = KVM_GUEST_KSEG0 + 0x180;
+
+   } else {
+   kvm_err("Trying to deliver TRAP when EXL is already set\n");
+   er = EMULATE_FAIL;
+   }
+
+   return er;
+}
+
 /* ll/sc, rdhwr, sync emulation */
 
 #define OPCODE 0xfc00
@@ -2176,6 +2211,7 @@ enum emulation_result kvm_mips_check_privilege(unsigned 
long cause,
case T_SYSCALL:
case T_BREAK:
case T_RES_INST:
+   case T_TRAP:
case T_MSADIS:
break;
 
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index f5e7ddab02f7..399b5517ecb8 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -48,6 +48,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "syscall",  VCPU_STAT(syscall_exits),  KVM_

[PATCH 13/20] MIPS: KVM: Add FP exception handling

2015-03-12 Thread James Hogan
Add guest exception handling for floating point exceptions and
coprocessor 1 unusable exceptions.

Floating point exceptions from the guest need passing to the guest
kernel, so for these a guest FPE is emulated.

Also, coprocessor 1 unusable exceptions are normally passed straight
through to the guest (because no guest FPU was supported), but the
hypervisor can now handle them if the guest has its FPU enabled by
restoring the guest FPU context and enabling the FPU.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h |  8 
 arch/mips/kvm/emulate.c  | 36 
 arch/mips/kvm/mips.c |  7 +++
 arch/mips/kvm/stats.c|  1 +
 arch/mips/kvm/trap_emul.c| 39 ---
 5 files changed, 88 insertions(+), 3 deletions(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 866edf330e53..fb264d8695e4 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -123,6 +123,7 @@ struct kvm_vcpu_stat {
u32 resvd_inst_exits;
u32 break_inst_exits;
u32 trap_inst_exits;
+   u32 fpe_exits;
u32 flush_dcache_exits;
u32 halt_successful_poll;
u32 halt_wakeup;
@@ -143,6 +144,7 @@ enum kvm_mips_exit_types {
RESVD_INST_EXITS,
BREAK_INST_EXITS,
TRAP_INST_EXITS,
+   FPE_EXITS,
FLUSH_DCACHE_EXITS,
MAX_KVM_MIPS_EXIT_TYPES
 };
@@ -585,6 +587,7 @@ struct kvm_mips_callbacks {
int (*handle_res_inst)(struct kvm_vcpu *vcpu);
int (*handle_break)(struct kvm_vcpu *vcpu);
int (*handle_trap)(struct kvm_vcpu *vcpu);
+   int (*handle_fpe)(struct kvm_vcpu *vcpu);
int (*handle_msa_disabled)(struct kvm_vcpu *vcpu);
int (*vm_init)(struct kvm *kvm);
int (*vcpu_init)(struct kvm_vcpu *vcpu);
@@ -734,6 +737,11 @@ extern enum emulation_result 
kvm_mips_emulate_trap_exc(unsigned long cause,
   struct kvm_run *run,
   struct kvm_vcpu *vcpu);
 
+extern enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause,
+ uint32_t *opc,
+ struct kvm_run *run,
+ struct kvm_vcpu *vcpu);
+
 extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
 struct kvm_run *run);
 
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index 3511bb20fe0e..fbf169fb63df 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -2146,6 +2146,41 @@ enum emulation_result kvm_mips_emulate_trap_exc(unsigned 
long cause,
return er;
 }
 
+enum emulation_result kvm_mips_emulate_fpe_exc(unsigned long cause,
+  uint32_t *opc,
+  struct kvm_run *run,
+  struct kvm_vcpu *vcpu)
+{
+   struct mips_coproc *cop0 = vcpu->arch.cop0;
+   struct kvm_vcpu_arch *arch = &vcpu->arch;
+   enum emulation_result er = EMULATE_DONE;
+
+   if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
+   /* save old pc */
+   kvm_write_c0_guest_epc(cop0, arch->pc);
+   kvm_set_c0_guest_status(cop0, ST0_EXL);
+
+   if (cause & CAUSEF_BD)
+   kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
+   else
+   kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);
+
+   kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc);
+
+   kvm_change_c0_guest_cause(cop0, (0xff),
+ (T_FPE << CAUSEB_EXCCODE));
+
+   /* Set PC to the exception entry point */
+   arch->pc = KVM_GUEST_KSEG0 + 0x180;
+
+   } else {
+   kvm_err("Trying to deliver FPE when EXL is already set\n");
+   er = EMULATE_FAIL;
+   }
+
+   return er;
+}
+
 /* ll/sc, rdhwr, sync emulation */
 
 #define OPCODE 0xfc00
@@ -2353,6 +2388,7 @@ enum emulation_result kvm_mips_check_privilege(unsigned 
long cause,
case T_BREAK:
case T_RES_INST:
case T_TRAP:
+   case T_FPE:
case T_MSADIS:
break;
 
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index b26a48d81467..dd0833833bea 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -50,6 +50,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "resvd_inst",   VCPU_S

[PATCH 17/20] MIPS: KVM: Emulate MSA bits in COP0 interface

2015-03-12 Thread James Hogan
Emulate MSA related parts of COP0 interface so that the guest will be
able to enable/disable MSA (Config5.MSAEn) once the MSA capability has
been wired up.

As with the FPU (Status.CU1) setting Config5.MSAEn has no immediate
effect if the MSA state isn't live, as MSA state is restored lazily on
first use. Changes after the MSA state has been restored take immediate
effect, so that the guest can start getting MSA disabled exceptions
right away for guest MSA operations. The MSA state is saved lazily too,
as MSA may get re-enabled in the near future anyway.

A special case is also added for when Status.CU1 is set while FR=0 and
the MSA state is live. In this case we are at risk of getting reserved
instruction exceptions if we try and save the MSA state, so we lose the
MSA state sooner while MSA is still usable.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/kvm/emulate.c | 37 +++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index fbf169fb63df..07f554c72cb8 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -912,7 +912,13 @@ unsigned int kvm_mips_config1_wrmask(struct kvm_vcpu *vcpu)
 unsigned int kvm_mips_config3_wrmask(struct kvm_vcpu *vcpu)
 {
/* Config4 is optional */
-   return MIPS_CONF_M;
+   unsigned int mask = MIPS_CONF_M;
+
+   /* Permit MSA to be present if MSA is supported */
+   if (kvm_mips_guest_can_have_msa(&vcpu->arch))
+   mask |= MIPS_CONF3_MSA;
+
+   return mask;
 }
 
 /**
@@ -939,6 +945,10 @@ unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu)
 {
unsigned int mask = 0;
 
+   /* Permit MSAEn changes if MSA supported and enabled */
+   if (kvm_mips_guest_has_msa(&vcpu->arch))
+   mask |= MIPS_CONF5_MSAEN;
+
/*
 * Permit guest FPU mode changes if FPU is enabled and the relevant
 * feature exists according to FIR register.
@@ -1126,6 +1136,18 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t 
inst, uint32_t *opc,
kvm_drop_fpu(vcpu);
 
/*
+* If MSA state is already live, it is undefined
+* how it interacts with FR=0 FPU state, and we
+* don't want to hit reserved instruction
+* exceptions trying to save the MSA state later
+* when CU=1 && FR=1, so play it safe and save
+* it first.
+*/
+   if (change & ST0_CU1 && !(val & ST0_FR) &&
+   vcpu->arch.fpu_inuse & KVM_MIPS_FPU_MSA)
+   kvm_lose_fpu(vcpu);
+
+   /*
 * Propagate CU1 (FPU enable) changes
 * immediately if the FPU context is already
 * loaded. When disabling we leave the context
@@ -1160,7 +1182,7 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, 
uint32_t *opc,
val = old_val ^ change;
 
 
-   /* Handle changes in FPU modes */
+   /* Handle changes in FPU/MSA modes */
preempt_disable();
 
/*
@@ -1171,6 +1193,17 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t 
inst, uint32_t *opc,
vcpu->arch.fpu_inuse & KVM_MIPS_FPU_FPU)
change_c0_config5(MIPS_CONF5_FRE, val);
 
+   /*
+* Propagate MSAEn changes immediately if the
+* MSA context is already loaded. When disabling
+* we leave the context loaded so it can be
+* quickly enabled again in the near future.
+*/
+   if (change & MIPS_CONF5_MSAEN &&
+   vcpu->arch.fpu_inuse & KVM_MIPS_FPU_MSA)
+   change_c0_config5(MIPS_CONF5_MSAEN,
+ val);
+
preempt_enable();
 
kvm_write_c0_guest_config5(cop0, val);
-- 
2.0.5

--
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


[PATCH 4/9] mips/kvm: Implement Config CP0 registers

2015-03-11 Thread James Hogan
Implement saving and restoring to KVM state of the Config CP0 registers
(namely Config, Config1, Config2, Config3, Config4, and Config5). These
control the features available to a guest, and a few of the fields will
soon be writeable by a guest so QEMU needs to know about them so as not
to clobber them on migration/savevm.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 108 ++
 1 file changed, 108 insertions(+)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 730c67e247d8..b8813a2722a3 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -223,6 +223,12 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
 #define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
+#define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
+#define KVM_REG_MIPS_CP0_CONFIG1MIPS_CP0_32(16, 1)
+#define KVM_REG_MIPS_CP0_CONFIG2MIPS_CP0_32(16, 2)
+#define KVM_REG_MIPS_CP0_CONFIG3MIPS_CP0_32(16, 3)
+#define KVM_REG_MIPS_CP0_CONFIG4MIPS_CP0_32(16, 4)
+#define KVM_REG_MIPS_CP0_CONFIG5MIPS_CP0_32(16, 5)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
@@ -305,6 +311,34 @@ static inline int kvm_mips_get_one_reg64(CPUState *cs, 
uint64 reg_id,
 return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
 }
 
+#define KVM_REG_MIPS_CP0_CONFIG_MASK(1 << CP0C0_M)
+#define KVM_REG_MIPS_CP0_CONFIG1_MASK   (1 << CP0C1_M)
+#define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1 << CP0C2_M)
+#define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1 << CP0C3_M)
+#define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1 << CP0C4_M)
+#define KVM_REG_MIPS_CP0_CONFIG5_MASK   0
+
+static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
+  int32_t *addr, int32_t mask)
+{
+int err;
+int32_t tmp, change;
+
+err = kvm_mips_get_one_reg(cs, reg_id, &tmp);
+if (err < 0) {
+return err;
+}
+
+/* only change bits in mask */
+change = (*addr ^ tmp) & mask;
+if (!change) {
+return 0;
+}
+
+tmp = tmp ^ change;
+return kvm_mips_put_one_reg(cs, reg_id, &tmp);
+}
+
 /*
  * We freeze the KVM timer when either the VM clock is stopped or the state is
  * saved (the state is dirty).
@@ -527,6 +561,48 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int 
level)
 DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
 ret = err;
 }
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG,
+  &env->CP0_Config0,
+  KVM_REG_MIPS_CP0_CONFIG_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1,
+  &env->CP0_Config1,
+  KVM_REG_MIPS_CP0_CONFIG1_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG1 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2,
+  &env->CP0_Config2,
+  KVM_REG_MIPS_CP0_CONFIG2_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG2 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3,
+  &env->CP0_Config3,
+  KVM_REG_MIPS_CP0_CONFIG3_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG3 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG4,
+  &env->CP0_Config4,
+  KVM_REG_MIPS_CP0_CONFIG4_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG4 (%d)\n", __func__, err);
+ret = err;
+}
+err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG5,
+  &env->CP0_Config5,
+  KVM_REG_MIPS_CP0_CONFIG5_MASK);
+if (err < 0) {
+DPRINTF("%s: Failed to change CP0_CONFIG5 (%d)\n", __func__, err);
+ret = err;
+}
 err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
  &env->CP0_ErrorEPC);
 if (err < 0) {
@@ -618,6 +694,38 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
 DPRINTF("%s: Failed to get CP0

[PATCH 8/9] mips/kvm: Support FPU in MIPS KVM guests

2015-03-11 Thread James Hogan
Support the new KVM_CAP_MIPS_FPU capability, which allows the host's FPU
to be exposed to the KVM guest.

The capability is enabled if the guest core has an FPU according to its
Config1 register. Various config bits are now writeable so that KVM is
aware of the configuration (Config1.FP) and so that QEMU can
save/restore the guest modifiable bits (Config5.FRE, Config5.UFR,
Config5.UFE). The FCSR/FIR registers and the floating point registers
are now saved/restored (depending on the FR mode bit).

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 linux-headers/linux/kvm.h |   1 +
 target-mips/cpu.h |   2 +
 target-mips/kvm.c | 124 --
 3 files changed, 123 insertions(+), 4 deletions(-)

diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 12045a11c036..410eb158f564 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -761,6 +761,7 @@ struct kvm_ppc_smmu_info {
 #define KVM_CAP_PPC_FIXUP_HCALL 103
 #define KVM_CAP_PPC_ENABLE_HCALL 104
 #define KVM_CAP_CHECK_EXTENSION_VM 105
+#define KVM_CAP_MIPS_FPU 107
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 5ea61bceea42..07c1e0146ec9 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -462,6 +462,8 @@ struct CPUMIPSState {
 #define CP0C5_CV 29
 #define CP0C5_EVA28
 #define CP0C5_MSAEn  27
+#define CP0C5_UFE9
+#define CP0C5_FRE8
 #define CP0C5_SBRI   6
 #define CP0C5_UFR2
 #define CP0C5_NFExists   0
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 7f72d6fb511f..c0191a525171 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -29,6 +29,8 @@
 #define DPRINTF(fmt, ...) \
 do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0)
 
+static int kvm_mips_fpu_cap;
+
 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 KVM_CAP_LAST_INFO
 };
@@ -45,16 +47,29 @@ int kvm_arch_init(KVMState *s)
 /* MIPS has 128 signals */
 kvm_set_sigmask_len(s, 16);
 
+kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU);
+
 DPRINTF("%s\n", __func__);
 return 0;
 }
 
 int kvm_arch_init_vcpu(CPUState *cs)
 {
+MIPSCPU *cpu = MIPS_CPU(cs);
+CPUMIPSState *env = &cpu->env;
 int ret = 0;
 
 qemu_add_vm_change_state_handler(kvm_mips_update_state, cs);
 
+if (kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) {
+ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_FPU, 0, 0);
+if (ret < 0) {
+/* mark unsupported so it gets disabled on reset */
+kvm_mips_fpu_cap = 0;
+ret = 0;
+}
+}
+
 DPRINTF("%s\n", __func__);
 return ret;
 }
@@ -63,8 +78,8 @@ void kvm_mips_reset_vcpu(MIPSCPU *cpu)
 {
 CPUMIPSState *env = &cpu->env;
 
-if (env->CP0_Config1 & (1 << CP0C1_FP)) {
-fprintf(stderr, "Warning: FPU not supported with KVM, disabling\n");
+if (!kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) {
+fprintf(stderr, "Warning: KVM does not support FPU, disabling\n");
 env->CP0_Config1 &= ~(1 << CP0C1_FP);
 }
 
@@ -386,11 +401,14 @@ static inline int kvm_mips_get_one_ureg64(CPUState *cs, 
uint64 reg_id,
 }
 
 #define KVM_REG_MIPS_CP0_CONFIG_MASK(1 << CP0C0_M)
-#define KVM_REG_MIPS_CP0_CONFIG1_MASK   (1 << CP0C1_M)
+#define KVM_REG_MIPS_CP0_CONFIG1_MASK   ((1 << CP0C1_M) | \
+ (1 << CP0C1_FP))
 #define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1 << CP0C2_M)
 #define KVM_REG_MIPS_CP0_CONFIG3_MASK   (1 << CP0C3_M)
 #define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1 << CP0C4_M)
-#define KVM_REG_MIPS_CP0_CONFIG5_MASK   0
+#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1 << CP0C5_UFE) | \
+ (1 << CP0C5_FRE) | \
+ (1 << CP0C5_UFR))
 
 static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
   int32_t *addr, int32_t mask)
@@ -552,6 +570,98 @@ static void kvm_mips_update_state(void *opaque, int 
running, RunState state)
 }
 }
 
+static int kvm_mips_put_fpu_registers(CPUState *cs, int level)
+{
+MIPSCPU *cpu = MIPS_CPU(cs);
+CPUMIPSState *env = &cpu->env;
+int err, ret = 0;
+unsigned int i;
+
+/* Only put FPU state if we're emulating a CPU with an FPU */
+if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+/* FPU Control Registers */
+if (level == KVM_PUT_FULL_STATE) {
+err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_IR,
+&env->active_fpu.fcr0);
+if (err < 0) {
+DPRINTF("%s: Failed to put F

[PATCH 7/9] mips/kvm: Add FP & MSA register definitions

2015-03-11 Thread James Hogan
Add the new floating point and MIPS SIMD Architecture (MSA) KVM register
definitions to kvm.c.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 27 +--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 6abd391f2cd5..7f72d6fb511f 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -203,11 +203,16 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 return 0;
 }
 
+#define KVM_REG_MIPS_GP (KVM_REG_MIPS | 0xULL)
+#define KVM_REG_MIPS_CP0(KVM_REG_MIPS | 0x0001ULL)
+#define KVM_REG_MIPS_KVM(KVM_REG_MIPS | 0x0002ULL)
+#define KVM_REG_MIPS_FPU(KVM_REG_MIPS | 0x0003ULL)
+
 #define MIPS_CP0_32(_R, _S) \
-(KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x1 | (8 * (_R) + (_S)))
+(KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S)))
 
 #define MIPS_CP0_64(_R, _S) \
-(KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x1 | (8 * (_R) + (_S)))
+(KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
 
 #define KVM_REG_MIPS_CP0_INDEX  MIPS_CP0_32(0, 0)
 #define KVM_REG_MIPS_CP0_CONTEXTMIPS_CP0_64(4, 0)
@@ -231,6 +236,24 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_CONFIG5MIPS_CP0_32(16, 5)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
+/* Floating Point and MIPS SIMD Architecture (MSA) registers. */
+#define KVM_REG_MIPS_FPR(KVM_REG_MIPS_FPU | 0xULL)
+#define KVM_REG_MIPS_FCR(KVM_REG_MIPS_FPU | 0x0100ULL)
+#define KVM_REG_MIPS_MSACR  (KVM_REG_MIPS_FPU | 0x0200ULL)
+
+/* Floating point / Vector registers.  */
+#define KVM_REG_MIPS_FPR_32(n)  (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U32  | (n))
+#define KVM_REG_MIPS_FPR_64(n)  (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U64  | (n))
+#define KVM_REG_MIPS_VEC_128(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U128 | (n))
+
+/* Floating point control registers. */
+#define KVM_REG_MIPS_FCR_IR (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 |  0)
+#define KVM_REG_MIPS_FCR_CSR(KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 31)
+
+/* MIPS SIMD Architecture (MSA) control registers. */
+#define KVM_REG_MIPS_MSA_IR  (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 |  0)
+#define KVM_REG_MIPS_MSA_CSR (KVM_REG_MIPS_MSACR | KVM_REG_SIZE_U32 |  1)
+
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
int32_t *addr)
 {
-- 
2.0.5

--
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


[PATCH 3/9] mips/kvm: Implement PRid CP0 register

2015-03-11 Thread James Hogan
Implement saving and restoring to KVM state of the Processor ID (PRid)
CP0 register. This allows QEMU to control the PRid exposed to the guest
instead of using the default set by KVM.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
---
 target-mips/kvm.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index 2ec7a6588568..730c67e247d8 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -222,6 +222,7 @@ int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int 
level)
 #define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0)
 #define KVM_REG_MIPS_CP0_CAUSE  MIPS_CP0_32(13, 0)
 #define KVM_REG_MIPS_CP0_EPCMIPS_CP0_64(14, 0)
+#define KVM_REG_MIPS_CP0_PRID   MIPS_CP0_32(15, 0)
 #define KVM_REG_MIPS_CP0_ERROREPC   MIPS_CP0_64(30, 0)
 
 static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
@@ -521,6 +522,11 @@ static int kvm_mips_put_cp0_registers(CPUState *cs, int 
level)
 DPRINTF("%s: Failed to put CP0_EPC (%d)\n", __func__, err);
 ret = err;
 }
+err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid);
+if (err < 0) {
+DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
+ret = err;
+}
 err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
  &env->CP0_ErrorEPC);
 if (err < 0) {
@@ -607,6 +613,11 @@ static int kvm_mips_get_cp0_registers(CPUState *cs)
 DPRINTF("%s: Failed to get CP0_EPC (%d)\n", __func__, err);
 ret = err;
 }
+err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid);
+if (err < 0) {
+DPRINTF("%s: Failed to get CP0_PRID (%d)\n", __func__, err);
+ret = err;
+}
 err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
  &env->CP0_ErrorEPC);
 if (err < 0) {
-- 
2.0.5

--
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


[PATCH 0/9] mips/kvm: Support FPU & SIMD (MSA) in MIPS KVM guests

2015-03-11 Thread James Hogan
This patchset primarily adds support for FPU and MIPS SIMD Architecture
(MSA) in MIPS KVM guests to QEMU. It depends on the KVM patchset which I
recently submitted to add the corresponding hypervisor support to KVM
("[PATCH 00/20] MIPS: KVM: Guest FPU & SIMD (MSA) support").

All comments welcome.

James Hogan (9):
  mips/kvm: Drop KVM_REG_MIPS_COUNT_* definitions
  mips/kvm: Remove a couple of noisy DPRINTFs
  mips/kvm: Implement PRid CP0 register
  mips/kvm: Implement Config CP0 registers
  mips/kvm: Support unsigned KVM registers
  mips/kvm: Support signed 64-bit KVM registers
  mips/kvm: Add FP & MSA register definitions
  mips/kvm: Support FPU in MIPS KVM guests
  mips/kvm: Support MSA in MIPS KVM guests

 linux-headers/linux/kvm.h |   2 +
 target-mips/cpu.h |   2 +
 target-mips/kvm.c | 433 +++---
 3 files changed, 412 insertions(+), 25 deletions(-)

Cc: Paolo Bonzini 
Cc: Leon Alrae 
Cc: Aurelien Jarno 
-- 
2.0.5

--
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


[PATCH 01/20] MIPS: KVM: Handle MSA Disabled exceptions from guest

2015-03-11 Thread James Hogan
Guest user mode can generate a guest MSA Disabled exception on an MSA
capable core by simply trying to execute an MSA instruction. Since this
exception is unknown to KVM it will be passed on to the guest kernel.
However guest Linux kernels prior to v3.15 do not set up an exception
handler for the MSA Disabled exception as they don't support any MSA
capable cores. This results in a guest OS panic.

Since an older processor ID may be being emulated, and MSA support is
not advertised to the guest, the correct behaviour is to generate a
Reserved Instruction exception in the guest kernel so it can send the
guest process an illegal instruction signal (SIGILL), as would happen
with a non-MSA-capable core.

Fix this as minimally as reasonably possible by preventing
kvm_mips_check_privilege() from relaying MSA Disabled exceptions from
guest user mode to the guest kernel, and handling the MSA Disabled
exception by emulating a Reserved Instruction exception in the guest,
via a new handle_msa_disabled() KVM callback.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc:  # v3.15+
---
 arch/mips/include/asm/kvm_host.h |  2 ++
 arch/mips/kvm/emulate.c  |  1 +
 arch/mips/kvm/mips.c |  4 
 arch/mips/kvm/trap_emul.c| 28 
 4 files changed, 35 insertions(+)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index ac4fc716062b..f722b0528c25 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -322,6 +322,7 @@ enum mips_mmu_types {
 #define T_TRAP 13  /* Trap instruction */
 #define T_VCEI 14  /* Virtual coherency exception */
 #define T_FPE  15  /* Floating point exception */
+#define T_MSADIS   21  /* MSA disabled exception */
 #define T_WATCH23  /* Watch address reference */
 #define T_VCED 31  /* Virtual coherency data */
 
@@ -578,6 +579,7 @@ struct kvm_mips_callbacks {
int (*handle_syscall)(struct kvm_vcpu *vcpu);
int (*handle_res_inst)(struct kvm_vcpu *vcpu);
int (*handle_break)(struct kvm_vcpu *vcpu);
+   int (*handle_msa_disabled)(struct kvm_vcpu *vcpu);
int (*vm_init)(struct kvm *kvm);
int (*vcpu_init)(struct kvm_vcpu *vcpu);
int (*vcpu_setup)(struct kvm_vcpu *vcpu);
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
index fb3e8dfd1ff6..838d3a6a5b7d 100644
--- a/arch/mips/kvm/emulate.c
+++ b/arch/mips/kvm/emulate.c
@@ -2176,6 +2176,7 @@ enum emulation_result kvm_mips_check_privilege(unsigned 
long cause,
case T_SYSCALL:
case T_BREAK:
case T_RES_INST:
+   case T_MSADIS:
break;
 
case T_COP_UNUSABLE:
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index c9eccf5df912..f5e7ddab02f7 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -1119,6 +1119,10 @@ int kvm_mips_handle_exit(struct kvm_run *run, struct 
kvm_vcpu *vcpu)
ret = kvm_mips_callbacks->handle_break(vcpu);
break;
 
+   case T_MSADIS:
+   ret = kvm_mips_callbacks->handle_msa_disabled(vcpu);
+   break;
+
default:
kvm_err("Exception Code: %d, not yet handled, @ PC: %p, inst: 
0x%08x  BadVaddr: %#lx Status: %#lx\n",
exccode, opc, kvm_get_inst(opc, vcpu), badvaddr,
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
index fd7257b70e65..4372cc86650c 100644
--- a/arch/mips/kvm/trap_emul.c
+++ b/arch/mips/kvm/trap_emul.c
@@ -330,6 +330,33 @@ static int kvm_trap_emul_handle_break(struct kvm_vcpu 
*vcpu)
return ret;
 }
 
+static int kvm_trap_emul_handle_msa_disabled(struct kvm_vcpu *vcpu)
+{
+   struct kvm_run *run = vcpu->run;
+   uint32_t __user *opc = (uint32_t __user *) vcpu->arch.pc;
+   unsigned long cause = vcpu->arch.host_cp0_cause;
+   enum emulation_result er = EMULATE_DONE;
+   int ret = RESUME_GUEST;
+
+   /* No MSA supported in guest, guest reserved instruction exception */
+   er = kvm_mips_emulate_ri_exc(cause, opc, run, vcpu);
+
+   switch (er) {
+   case EMULATE_DONE:
+   ret = RESUME_GUEST;
+   break;
+
+   case EMULATE_FAIL:
+   run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
+   ret = RESUME_HOST;
+   break;
+
+   default:
+   BUG();
+   }
+   return ret;
+}
+
 static int kvm_trap_emul_vm_init(struct kvm *kvm)
 {
return 0;
@@ -470,6 +497,7 @@ static struct kvm_mips_callbacks kvm_trap_emul_callbacks = {
.handle_syscall = kvm_trap_emul_handle_syscall,
.handle_res_inst = kvm_trap_emul_handle_res_inst,
.handle_b

[PATCH 11/20] MIPS: KVM: Add base guest FPU support

2015-03-11 Thread James Hogan
Add base code for supporting FPU in MIPS KVM guests. The FPU cannot yet
be enabled in the guest, we're just laying the groundwork.

Whether the guest's FPU context is loaded is stored in a bit in the
fpu_inuse vcpu member. This allows the FPU to be disabled when the guest
disables it, but keeping the FPU context loaded so it doesn't have to be
reloaded if the guest re-enables it.

An fpu_enabled vcpu member stores whether userland has enabled the FPU
capability (which will be wired up in a later patch).

New assembly code is added for saving and restoring the FPU context, and
for saving/clearing and restoring FCSR (which can itself cause an FP
exception depending on the value). The FCSR is restored before returning
to the guest if the FPU is already enabled, and a die notifier is
registered to catch the possible FP exception and step over the ctc1
instruction.

The helper function kvm_lose_fpu() is added to save FPU context and
disable the FPU, which is used when saving hardware state before a
context switch or KVM exit (the vcpu_get_regs() callback).

The helper function kvm_own_fpu() is added to enable the FPU and restore
the FPU context if it isn't already loaded, which will be used in a
later patch when the guest attempts to use the FPU for the first time
and triggers a co-processor unusable exception.

The helper function kvm_drop_fpu() is added to discard the FPU context
and disable the FPU, which will be used in a later patch when the FPU
state will become architecturally UNPREDICTABLE (change of FR mode) to
force a reload of [stale] context in the new FR mode.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h |  27 +
 arch/mips/kernel/asm-offsets.c   |  38 
 arch/mips/kvm/Makefile   |   2 +-
 arch/mips/kvm/fpu.S  | 122 +
 arch/mips/kvm/locore.S   |  17 ++
 arch/mips/kvm/mips.c | 126 +++
 arch/mips/kvm/trap_emul.c|   2 +
 7 files changed, 333 insertions(+), 1 deletion(-)
 create mode 100644 arch/mips/kvm/fpu.S

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index fb79d67de192..866edf330e53 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -357,6 +357,8 @@ struct kvm_mips_tlb {
long tlb_lo1;
 };
 
+#define KVM_MIPS_FPU_FPU   0x1
+
 #define KVM_MIPS_GUEST_TLB_SIZE64
 struct kvm_vcpu_arch {
void *host_ebase, *guest_ebase;
@@ -378,6 +380,8 @@ struct kvm_vcpu_arch {
 
/* FPU State */
struct mips_fpu_struct fpu;
+   /* Which FPU state is loaded (KVM_MIPS_FPU_*) */
+   unsigned int fpu_inuse;
 
/* COP0 State */
struct mips_coproc *cop0;
@@ -424,6 +428,8 @@ struct kvm_vcpu_arch {
 
/* WAIT executed */
int wait;
+
+   u8 fpu_enabled;
 };
 
 
@@ -554,6 +560,19 @@ static inline void 
_kvm_atomic_change_c0_guest_reg(unsigned long *reg,
kvm_set_c0_guest_ebase(cop0, ((val) & (change)));   \
 }
 
+/* Helpers */
+
+static inline bool kvm_mips_guest_can_have_fpu(struct kvm_vcpu_arch *vcpu)
+{
+   return (!__builtin_constant_p(cpu_has_fpu) || cpu_has_fpu) &&
+   vcpu->fpu_enabled;
+}
+
+static inline bool kvm_mips_guest_has_fpu(struct kvm_vcpu_arch *vcpu)
+{
+   return kvm_mips_guest_can_have_fpu(vcpu) &&
+   kvm_read_c0_guest_config1(vcpu->cop0) & MIPS_CONF1_FP;
+}
 
 struct kvm_mips_callbacks {
int (*handle_cop_unusable)(struct kvm_vcpu *vcpu);
@@ -597,6 +616,14 @@ int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu);
 /* Trampoline ASM routine to start running in "Guest" context */
 extern int __kvm_mips_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu);
 
+/* FPU context management */
+void __kvm_save_fpu(struct kvm_vcpu_arch *vcpu);
+void __kvm_restore_fpu(struct kvm_vcpu_arch *vcpu);
+void __kvm_restore_fcsr(struct kvm_vcpu_arch *vcpu);
+void kvm_own_fpu(struct kvm_vcpu *vcpu);
+void kvm_drop_fpu(struct kvm_vcpu *vcpu);
+void kvm_lose_fpu(struct kvm_vcpu *vcpu);
+
 /* TLB handling */
 uint32_t kvm_get_kernel_asid(struct kvm_vcpu *vcpu);
 
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 3ee1565c5be3..a12bcf920073 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -404,6 +404,44 @@ void output_kvm_defines(void)
OFFSET(VCPU_LO, kvm_vcpu_arch, lo);
OFFSET(VCPU_HI, kvm_vcpu_arch, hi);
OFFSET(VCPU_PC, kvm_vcpu_arch, pc);
+   BLANK();
+
+   OFFSET(VCPU_FPR0, kvm_vcpu_arch, fpu.fpr[0]);
+   OFFSET(VCPU_FPR1, kvm_vcpu_arch, fpu.fpr[1]);
+   OFFSET(VCPU_FPR2, kvm_vcpu_arch, fpu.fpr[2]);
+   OFFSET(VCPU_FPR3, kvm_vcpu_arch, fpu.fpr[3]);
+   

[PATCH 08/20] MIPS: KVM: Simplify default guest Config registers

2015-03-11 Thread James Hogan
Various semi-used definitions exist in kvm_host.h for the default guest
config registers. Remove them and use the appropriate values directly
when initialising the Config registers.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h | 25 -
 arch/mips/kvm/trap_emul.c| 15 +--
 2 files changed, 9 insertions(+), 31 deletions(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 1bd392d3a35b..6996447fd2a7 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -265,31 +265,6 @@ struct mips_coproc {
 #define CP0C3_SM   1
 #define CP0C3_TL   0
 
-/* Have config1, Cacheable, noncoherent, write-back, write allocate*/
-#define MIPS_CONFIG0   \
-  ((1 << CP0C0_M) | (0x3 << CP0C0_K0))
-
-/* Have config2, no coprocessor2 attached, no MDMX support attached,
-   no performance counters, watch registers present,
-   no code compression, EJTAG present, no FPU, no watch registers */
-#define MIPS_CONFIG1   \
-((1 << CP0C1_M) |  \
- (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) | \
- (0 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) | \
- (0 << CP0C1_FP))
-
-/* Have config3, no tertiary/secondary caches implemented */
-#define MIPS_CONFIG2   \
-((1 << CP0C2_M))
-
-/* No config4, no DSP ASE, no large physaddr (PABITS),
-   no external interrupt controller, no vectored interrupts,
-   no 1kb pages, no SmartMIPS ASE, no trace logic */
-#define MIPS_CONFIG3   \
-((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) |   \
- (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) | \
- (0 << CP0C3_SM) | (0 << CP0C3_TL))
-
 /* MMU types, the first four entries have the same layout as the
CP0C0_MT field.  */
 enum mips_mmu_types {
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
index dc019950e243..bffba002d1a4 100644
--- a/arch/mips/kvm/trap_emul.c
+++ b/arch/mips/kvm/trap_emul.c
@@ -396,8 +396,9 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu)
 * guest will come up as expected, for now we simulate a MIPS 24kc
 */
kvm_write_c0_guest_prid(cop0, 0x00019300);
-   kvm_write_c0_guest_config(cop0,
- MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
+   /* Have config1, Cacheable, noncoherent, write-back, write allocate */
+   kvm_write_c0_guest_config(cop0, MIPS_CONF_M | (0x3 << CP0C0_K0) |
+ (0x1 << CP0C0_AR) |
  (MMU_TYPE_R4000 << CP0C0_MT));
 
/* Read the cache characteristics from the host Config1 Register */
@@ -413,10 +414,12 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu)
  (1 << CP0C1_WR) | (1 << CP0C1_CA));
kvm_write_c0_guest_config1(cop0, config1);
 
-   kvm_write_c0_guest_config2(cop0, MIPS_CONFIG2);
-   /* MIPS_CONFIG2 | (read_c0_config2() & 0xfff) */
-   kvm_write_c0_guest_config3(cop0, MIPS_CONFIG3 | (0 << CP0C3_VInt) |
-(1 << CP0C3_ULRI));
+   /* Have config3, no tertiary/secondary caches implemented */
+   kvm_write_c0_guest_config2(cop0, MIPS_CONF_M);
+   /* MIPS_CONF_M | (read_c0_config2() & 0xfff) */
+
+   /* No config4, UserLocal */
+   kvm_write_c0_guest_config3(cop0, MIPS_CONF3_ULRI);
 
/* Set Wait IE/IXMT Ignore in Config7, IAR, AR */
kvm_write_c0_guest_config7(cop0, (MIPS_CONF7_WII) | (1 << 10));
-- 
2.0.5

--
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


[PATCH 07/20] MIPS: KVM: Clean up register definitions a little

2015-03-11 Thread James Hogan
Clean up KVM_GET_ONE_REG / KVM_SET_ONE_REG register definitions for
MIPS, to prepare for adding a new group for FPU & MSA vector registers.

Definitions are added for common bits in each group of registers, e.g.
KVM_REG_MIPS_CP0 = KVM_REG_MIPS | 0x1, for the coprocessor 0
registers.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h |   4 +-
 arch/mips/include/uapi/asm/kvm.h | 115 ++-
 2 files changed, 66 insertions(+), 53 deletions(-)

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index 26d91b0f3c3c..1bd392d3a35b 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -21,10 +21,10 @@
 
 /* MIPS KVM register ids */
 #define MIPS_CP0_32(_R, _S)\
-   (KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x1 | (8 * (_R) + (_S)))
+   (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S)))
 
 #define MIPS_CP0_64(_R, _S)\
-   (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x1 | (8 * (_R) + (_S)))
+   (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))
 
 #define KVM_REG_MIPS_CP0_INDEX MIPS_CP0_32(0, 0)
 #define KVM_REG_MIPS_CP0_ENTRYLO0  MIPS_CP0_64(2, 0)
diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h
index 2c04b6d9ff85..75d6d8557e57 100644
--- a/arch/mips/include/uapi/asm/kvm.h
+++ b/arch/mips/include/uapi/asm/kvm.h
@@ -52,61 +52,76 @@ struct kvm_fpu {
 
 
 /*
- * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access CP0
+ * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various
  * registers.  The id field is broken down as follows:
  *
- *  bits[2..0]   - Register 'sel' index.
- *  bits[7..3]   - Register 'rd'  index.
- *  bits[15..8]  - Must be zero.
- *  bits[31..16] - 1 -> CP0 registers.
- *  bits[51..32] - Must be zero.
  *  bits[63..52] - As per linux/kvm.h
+ *  bits[51..32] - Must be zero.
+ *  bits[31..16] - Register set.
+ *
+ * Register set = 0: GP registers from kvm_regs (see definitions below).
+ *
+ * Register set = 1: CP0 registers.
+ *  bits[15..8]  - Must be zero.
+ *  bits[7..3]   - Register 'rd'  index.
+ *  bits[2..0]   - Register 'sel' index.
+ *
+ * Register set = 2: KVM specific registers (see definitions below).
  *
  * Other sets registers may be added in the future.  Each set would
  * have its own identifier in bits[31..16].
- *
- * The registers defined in struct kvm_regs are also accessible, the
- * id values for these are below.
  */
 
-#define KVM_REG_MIPS_R0 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0)
-#define KVM_REG_MIPS_R1 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 1)
-#define KVM_REG_MIPS_R2 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 2)
-#define KVM_REG_MIPS_R3 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 3)
-#define KVM_REG_MIPS_R4 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 4)
-#define KVM_REG_MIPS_R5 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 5)
-#define KVM_REG_MIPS_R6 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 6)
-#define KVM_REG_MIPS_R7 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 7)
-#define KVM_REG_MIPS_R8 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 8)
-#define KVM_REG_MIPS_R9 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 9)
-#define KVM_REG_MIPS_R10 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 10)
-#define KVM_REG_MIPS_R11 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 11)
-#define KVM_REG_MIPS_R12 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 12)
-#define KVM_REG_MIPS_R13 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 13)
-#define KVM_REG_MIPS_R14 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 14)
-#define KVM_REG_MIPS_R15 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 15)
-#define KVM_REG_MIPS_R16 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 16)
-#define KVM_REG_MIPS_R17 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 17)
-#define KVM_REG_MIPS_R18 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 18)
-#define KVM_REG_MIPS_R19 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 19)
-#define KVM_REG_MIPS_R20 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 20)
-#define KVM_REG_MIPS_R21 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 21)
-#define KVM_REG_MIPS_R22 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 22)
-#define KVM_REG_MIPS_R23 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 23)
-#define KVM_REG_MIPS_R24 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 24)
-#define KVM_REG_MIPS_R25 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 25)
-#define KVM_REG_MIPS_R26 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 26)
-#define KVM_REG_MIPS_R27 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 27)
-#define KVM_REG_MIPS_R28 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 28)
-#define KVM_REG_MIPS_R29 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 29)
-#define KVM_REG_MIPS_R30 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 30)
-#define KVM_REG_MIPS_R31 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 31)
+#define KVM_REG_MIPS_GP(KVM_REG_MIPS | 0xULL)
+#define KVM_REG_MIPS_CP0   (KVM_REG_MIPS | 0x0001ULL)
+#define KVM_REG_MIPS_KVM   (KVM_REG_MIPS | 0x

[PATCH 14/20] MIPS: KVM: Expose FPU registers

2015-03-11 Thread James Hogan
Add KVM register numbers for the MIPS FPU registers, and implement
access to them with the KVM_GET_ONE_REG / KVM_SET_ONE_REG ioctls when
the FPU capability is enabled (exposed in a later patch) and present in
the guest according to its Config1.FP bit.

The registers are accessible in the current mode of the guest, with each
sized access showing what the guest would see with an equivalent access,
and like the architecture they may become UNPREDICTABLE if the FR mode
is changed. When FR=0, odd doubles are inaccessible as they do not exist
in that mode.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Jonathan Corbet 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linux-...@vger.kernel.org
---
 Documentation/virtual/kvm/api.txt | 16 +
 arch/mips/include/uapi/asm/kvm.h  | 37 ++--
 arch/mips/kvm/mips.c  | 72 ++-
 3 files changed, 114 insertions(+), 11 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 1e59515b6d1f..8ba55b9c903e 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1979,6 +1979,10 @@ registers, find a list below:
   MIPS  | KVM_REG_MIPS_COUNT_CTL| 64
   MIPS  | KVM_REG_MIPS_COUNT_RESUME | 64
   MIPS  | KVM_REG_MIPS_COUNT_HZ | 64
+  MIPS  | KVM_REG_MIPS_FPR_32(0..31)| 32
+  MIPS  | KVM_REG_MIPS_FPR_64(0..31)| 64
+  MIPS  | KVM_REG_MIPS_FCR_IR   | 32
+  MIPS  | KVM_REG_MIPS_FCR_CSR  | 32
 
 ARM registers are mapped using the lower 32 bits.  The upper 16 of that
 is the register group type, or coprocessor number:
@@ -2032,6 +2036,18 @@ patterns depending on whether they're 32-bit or 64-bit 
registers:
 MIPS KVM control registers (see above) have the following id bit patterns:
   0x7030  0002 
 
+MIPS FPU registers (see KVM_REG_MIPS_FPR_{32,64}() above) have the following
+id bit patterns depending on the size of the register being accessed. They are
+always accessed according to the current guest FPU mode (Status.FR and
+Config5.FRE), i.e. as the guest would see them, and they become unpredictable
+if the guest FPU mode is changed:
+  0x7020  0003 00 <0:3>  (32-bit FPU registers)
+  0x7030  0003 00 <0:3>  (64-bit FPU registers)
+
+MIPS FPU control registers (see KVM_REG_MIPS_FCR_{IR,CSR} above) have the
+following id bit patterns:
+  0x7020  0003 01 <0:3> 
+
 
 4.69 KVM_GET_ONE_REG
 
diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h
index 75d6d8557e57..401e6a6f8bb8 100644
--- a/arch/mips/include/uapi/asm/kvm.h
+++ b/arch/mips/include/uapi/asm/kvm.h
@@ -36,18 +36,8 @@ struct kvm_regs {
 
 /*
  * for KVM_GET_FPU and KVM_SET_FPU
- *
- * If Status[FR] is zero (32-bit FPU), the upper 32-bits of the FPRs
- * are zero filled.
  */
 struct kvm_fpu {
-   __u64 fpr[32];
-   __u32 fir;
-   __u32 fccr;
-   __u32 fexr;
-   __u32 fenr;
-   __u32 fcsr;
-   __u32 pad;
 };
 
 
@@ -68,6 +58,8 @@ struct kvm_fpu {
  *
  * Register set = 2: KVM specific registers (see definitions below).
  *
+ * Register set = 3: FPU registers (see definitions below).
+ *
  * Other sets registers may be added in the future.  Each set would
  * have its own identifier in bits[31..16].
  */
@@ -75,6 +67,7 @@ struct kvm_fpu {
 #define KVM_REG_MIPS_GP(KVM_REG_MIPS | 0xULL)
 #define KVM_REG_MIPS_CP0   (KVM_REG_MIPS | 0x0001ULL)
 #define KVM_REG_MIPS_KVM   (KVM_REG_MIPS | 0x0002ULL)
+#define KVM_REG_MIPS_FPU   (KVM_REG_MIPS | 0x0003ULL)
 
 
 /*
@@ -155,6 +148,30 @@ struct kvm_fpu {
 
 
 /*
+ * KVM_REG_MIPS_FPU - Floating Point registers.
+ *
+ *  bits[15..8]  - Register subset (see definitions below).
+ *  bits[7..5]   - Must be zero.
+ *  bits[4..0]   - Register number within register subset.
+ */
+
+#define KVM_REG_MIPS_FPR   (KVM_REG_MIPS_FPU | 0xULL)
+#define KVM_REG_MIPS_FCR   (KVM_REG_MIPS_FPU | 0x0100ULL)
+
+/*
+ * KVM_REG_MIPS_FPR - Floating point / Vector registers.
+ */
+#define KVM_REG_MIPS_FPR_32(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U32  | (n))
+#define KVM_REG_MIPS_FPR_64(n) (KVM_REG_MIPS_FPR | KVM_REG_SIZE_U64  | (n))
+
+/*
+ * KVM_REG_MIPS_FCR - Floating point control registers.
+ */
+#define KVM_REG_MIPS_FCR_IR(KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 |  0)
+#define KVM_REG_MIPS_FCR_CSR   (KVM_REG_MIPS_FCR | KVM_REG_SIZE_U32 | 31)
+
+
+/*
  * KVM MIPS specific structures and definitions
  *
  */
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index dd0833833bea..5e41afe15ae8 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -526,10 +526,13 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
const struct kvm_one_reg *reg)
 {
struct mips_coproc *cop0 = vcpu->

[PATCH 05/20] MIPS: KVM: Sort kvm_mips_get_reg() registers

2015-03-11 Thread James Hogan
Sort the registers in the kvm_mips_get_reg() switch by register number,
which puts ERROREPC after the CONFIG registers.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/kvm/mips.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
index fd620cc8a44c..b909c0046f08 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
@@ -578,9 +578,6 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
case KVM_REG_MIPS_CP0_PRID:
v = (long)kvm_read_c0_guest_prid(cop0);
break;
-   case KVM_REG_MIPS_CP0_ERROREPC:
-   v = (long)kvm_read_c0_guest_errorepc(cop0);
-   break;
case KVM_REG_MIPS_CP0_CONFIG:
v = (long)kvm_read_c0_guest_config(cop0);
break;
@@ -596,6 +593,9 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
case KVM_REG_MIPS_CP0_CONFIG7:
v = (long)kvm_read_c0_guest_config7(cop0);
break;
+   case KVM_REG_MIPS_CP0_ERROREPC:
+   v = (long)kvm_read_c0_guest_errorepc(cop0);
+   break;
/* registers to be handled specially */
case KVM_REG_MIPS_CP0_COUNT:
case KVM_REG_MIPS_COUNT_CTL:
-- 
2.0.5

--
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


[PATCH 16/20] MIPS: KVM: Add base guest MSA support

2015-03-11 Thread James Hogan
Add base code for supporting the MIPS SIMD Architecture (MSA) in MIPS
KVM guests. MSA cannot yet be enabled in the guest, we're just laying
the groundwork.

As with the FPU, whether the guest's MSA context is loaded is stored in
another bit in the fpu_inuse vcpu member. This allows MSA to be disabled
when the guest disables it, but keeping the MSA context loaded so it
doesn't have to be reloaded if the guest re-enables it.

New assembly code is added for saving and restoring the MSA context,
restoring only the upper half of the MSA context (for if the FPU context
is already loaded) and for saving/clearing and restoring MSACSR (which
can itself cause an MSA FP exception depending on the value). The MSACSR
is restored before returning to the guest if MSA is already enabled, and
the existing FP exception die notifier is extended to catch the possible
MSA FP exception and step over the ctcmsa instruction.

The helper function kvm_own_msa() is added to enable MSA and restore
the MSA context if it isn't already loaded, which will be used in a
later patch when the guest attempts to use MSA for the first time and
triggers an MSA disabled exception.

The existing FPU helpers are extended to handle MSA. kvm_lose_fpu()
saves the full MSA context if it is loaded (which includes the FPU
context) and both kvm_lose_fpu() and kvm_drop_fpu() disable MSA.

kvm_own_fpu() also needs to lose any MSA context if FR=0, since there
would be a risk of getting reserved instruction exceptions if CU1 is
enabled and we later try and save the MSA context. We shouldn't usually
hit this case since it will be handled when emulating CU1 changes,
however there's nothing to stop the guest modifying the Status register
directly via the comm page, which will cause this case to get hit.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kvm_host.h |  21 -
 arch/mips/kernel/asm-offsets.c   |   1 +
 arch/mips/kvm/Makefile   |   6 +-
 arch/mips/kvm/locore.S   |  21 +
 arch/mips/kvm/mips.c | 132 
 arch/mips/kvm/msa.S  | 161 +++
 6 files changed, 323 insertions(+), 19 deletions(-)
 create mode 100644 arch/mips/kvm/msa.S

diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
index fb264d8695e4..1dc0dca15cbd 100644
--- a/arch/mips/include/asm/kvm_host.h
+++ b/arch/mips/include/asm/kvm_host.h
@@ -360,6 +360,7 @@ struct kvm_mips_tlb {
 };
 
 #define KVM_MIPS_FPU_FPU   0x1
+#define KVM_MIPS_FPU_MSA   0x2
 
 #define KVM_MIPS_GUEST_TLB_SIZE64
 struct kvm_vcpu_arch {
@@ -432,6 +433,7 @@ struct kvm_vcpu_arch {
int wait;
 
u8 fpu_enabled;
+   u8 msa_enabled;
 };
 
 
@@ -576,6 +578,18 @@ static inline bool kvm_mips_guest_has_fpu(struct 
kvm_vcpu_arch *vcpu)
kvm_read_c0_guest_config1(vcpu->cop0) & MIPS_CONF1_FP;
 }
 
+static inline bool kvm_mips_guest_can_have_msa(struct kvm_vcpu_arch *vcpu)
+{
+   return (!__builtin_constant_p(cpu_has_msa) || cpu_has_msa) &&
+   vcpu->msa_enabled;
+}
+
+static inline bool kvm_mips_guest_has_msa(struct kvm_vcpu_arch *vcpu)
+{
+   return kvm_mips_guest_can_have_msa(vcpu) &&
+   kvm_read_c0_guest_config3(vcpu->cop0) & MIPS_CONF3_MSA;
+}
+
 struct kvm_mips_callbacks {
int (*handle_cop_unusable)(struct kvm_vcpu *vcpu);
int (*handle_tlb_mod)(struct kvm_vcpu *vcpu);
@@ -619,11 +633,16 @@ int kvm_arch_vcpu_dump_regs(struct kvm_vcpu *vcpu);
 /* Trampoline ASM routine to start running in "Guest" context */
 extern int __kvm_mips_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu);
 
-/* FPU context management */
+/* FPU/MSA context management */
 void __kvm_save_fpu(struct kvm_vcpu_arch *vcpu);
 void __kvm_restore_fpu(struct kvm_vcpu_arch *vcpu);
 void __kvm_restore_fcsr(struct kvm_vcpu_arch *vcpu);
+void __kvm_save_msa(struct kvm_vcpu_arch *vcpu);
+void __kvm_restore_msa(struct kvm_vcpu_arch *vcpu);
+void __kvm_restore_msa_upper(struct kvm_vcpu_arch *vcpu);
+void __kvm_restore_msacsr(struct kvm_vcpu_arch *vcpu);
 void kvm_own_fpu(struct kvm_vcpu *vcpu);
+void kvm_own_msa(struct kvm_vcpu *vcpu);
 void kvm_drop_fpu(struct kvm_vcpu *vcpu);
 void kvm_lose_fpu(struct kvm_vcpu *vcpu);
 
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index a12bcf920073..e59fd7cfac9e 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -440,6 +440,7 @@ void output_kvm_defines(void)
OFFSET(VCPU_FPR31, kvm_vcpu_arch, fpu.fpr[31]);
 
OFFSET(VCPU_FCR31, kvm_vcpu_arch, fpu.fcr31);
+   OFFSET(VCPU_MSA_CSR, kvm_vcpu_arch, fpu.msacsr);
BLANK();
 
OFFSET(VCPU_COP0, kvm_vcpu_arch, cop0);
diff --git a/arch/mips/kvm/Makefile b/arch/mips

[PATCH 00/20] MIPS: KVM: Guest FPU & SIMD (MSA) support

2015-03-11 Thread James Hogan
This patchset primarily adds guest Floating Point Unit (FPU) and MIPS
SIMD Architecture (MSA) support to MIPS KVM, by enabling the host
FPU/MSA while in guest mode.

This patchset depends on Paul Burton's FP/MSA fixes patchset, which will
hopefully make it into 4.0. I'd like to get this into 4.1, so all review
comments welcome. Corresponding QEMU patches will follow soon.

- Adds KVM_CAP_MIPS_FPU and KVM_CAP_MIPS_MSA capabilities which must be
  enabled to add FPU/MSA to the guest.
- Supports FR=0, FR=1, FRE=1 floating point register modes and 128-bit
  vector registers.
- Does not support UFR/UFE (guest user control of FR/FRE bits), or MSA
  vector partitioning.
- Context restore is lazy: done on first actual use.
- Context save is lazy: once restored, host FPU/MSA gets
  enabled/disabled when guest enables/disables it, with registers left
  loaded as long as possible.
- So the state that can be loaded at any one time is:
- No FPRs/vector state
- FR=0 FPRs (change of FR discards FP state)
- FR=1 FPRs
- Vector state (includes FR=1 FPRs)
- Vector state only (when guest CU1=0, FR=0)
- FCSR/MSACSR status registers are saved/restored around guest
  execution, since care must be taken to handle FP exceptions when
  writing these registers.

The patches are arranged roughly in groups:
- Patch 1 is a related minimal stable fix which can be applied in
  advance of the others (patch 18 fills it out a bit).
- Patch 2 is a generic MIPS change required to be able to restore
  FCSR/MSACSR registers with exceptions pending.
- Patches 3..10 add various misc KVM improvements and cleanups, most of
  which the later patches depend on.
- Patches 11..15 add the main guest FPU support.
- Patches 16..20 add the main guest MSA support (structured like 11.15).

James Hogan (20):
  MIPS: KVM: Handle MSA Disabled exceptions from guest

  MIPS: Clear [MSA]FPE CSR.Cause after notify_die()

  MIPS: KVM: Handle TRAP exceptions from guest kernel
  MIPS: KVM: Implement PRid CP0 register access
  MIPS: KVM: Sort kvm_mips_get_reg() registers
  MIPS: KVM: Drop pr_info messages on init/exit
  MIPS: KVM: Clean up register definitions a little
  MIPS: KVM: Simplify default guest Config registers
  MIPS: KVM: Add Config4/5 and writing of Config registers
  MIPS: KVM: Add vcpu_get_regs/vcpu_set_regs callback

  MIPS: KVM: Add base guest FPU support
  MIPS: KVM: Emulate FPU bits in COP0 interface
  MIPS: KVM: Add FP exception handling
  MIPS: KVM: Expose FPU registers
  MIPS: KVM: Wire up FPU capability

  MIPS: KVM: Add base guest MSA support
  MIPS: KVM: Emulate MSA bits in COP0 interface
  MIPS: KVM: Add MSA exception handling
  MIPS: KVM: Expose MSA registers
  MIPS: KVM: Wire up MSA capability

 Documentation/virtual/kvm/api.txt |  47 
 arch/mips/include/asm/kdebug.h|   3 +-
 arch/mips/include/asm/kvm_host.h  | 125 +++---
 arch/mips/include/uapi/asm/kvm.h  | 160 -
 arch/mips/kernel/asm-offsets.c|  39 
 arch/mips/kernel/genex.S  |  14 +-
 arch/mips/kernel/traps.c  |  16 +-
 arch/mips/kvm/Makefile|   8 +-
 arch/mips/kvm/emulate.c   | 332 +-
 arch/mips/kvm/fpu.S   | 122 ++
 arch/mips/kvm/locore.S|  38 +++
 arch/mips/kvm/mips.c  | 478 +-
 arch/mips/kvm/msa.S   | 161 +
 arch/mips/kvm/stats.c |   4 +
 arch/mips/kvm/tlb.c   |   6 +
 arch/mips/kvm/trap_emul.c | 199 +++-
 include/uapi/linux/kvm.h  |   2 +
 17 files changed, 1630 insertions(+), 124 deletions(-)
 create mode 100644 arch/mips/kvm/fpu.S
 create mode 100644 arch/mips/kvm/msa.S

Cc: Paolo Bonzini 
Cc: Paul Burton 
Cc: Ralf Baechle 
Cc: Gleb Natapov 
Cc: Jonathan Corbet 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
Cc: linux-...@vger.kernel.org
Cc: linux-...@vger.kernel.org
-- 
2.0.5

--
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


[PATCH 02/20] MIPS: Clear [MSA]FPE CSR.Cause after notify_die()

2015-03-11 Thread James Hogan
When handling floating point exceptions (FPEs) and MSA FPEs the Cause
bits of the appropriate control and status register (FCSR for FPEs and
MSACSR for MSA FPEs) are read and cleared before enabling interrupts,
presumably so that it doesn't have to go through the pain of restoring
those bits if the process is pre-empted, since writing those bits would
cause another immediate exception while still in the kernel.

The bits aren't normally ever restored again, since userland never
expects to see them set.

However for virtualisation it is necessary for the kernel to be able to
restore these Cause bits, as the guest may have been interrupted in an
FP exception handler but before it could read the Cause bits. This can
be done by registering a die notifier, to get notified of the exception
when such a value is restored, and if the PC was at the instruction
which is used to restore the guest state, the handler can step over it
and continue execution. The Cause bits can then remain set without
causing further exceptions.

For this to work safely a few changes are made:
- __build_clear_fpe and __build_clear_msa_fpe no longer clear the Cause
  bits, and now return from exception level with interrupts disabled
  instead of enabled.
- do_fpe() now clears the Cause bits and enables interrupts after
  notify_die() is called, so that the notifier can chose to return from
  exception without this happening.
- do_msa_fpe() acts similarly, but now actually makes use of the second
  argument (msacsr) and calls notify_die() with the new DIE_MSAFP,
  allowing die notifiers to be informed of MSA FPEs too.

Signed-off-by: James Hogan 
Cc: Ralf Baechle 
Cc: Paul Burton 
Cc: Paolo Bonzini 
Cc: Gleb Natapov 
Cc: linux-m...@linux-mips.org
Cc: kvm@vger.kernel.org
---
 arch/mips/include/asm/kdebug.h |  3 ++-
 arch/mips/kernel/genex.S   | 14 --
 arch/mips/kernel/traps.c   | 16 +++-
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/arch/mips/include/asm/kdebug.h b/arch/mips/include/asm/kdebug.h
index 6a9af5fcb5d7..cba22ab7ad4d 100644
--- a/arch/mips/include/asm/kdebug.h
+++ b/arch/mips/include/asm/kdebug.h
@@ -10,7 +10,8 @@ enum die_val {
DIE_RI,
DIE_PAGE_FAULT,
DIE_BREAK,
-   DIE_SSTEPBP
+   DIE_SSTEPBP,
+   DIE_MSAFP
 };
 
 #endif /* _ASM_MIPS_KDEBUG_H */
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 86e22422d08c..af42e7003f12 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -360,21 +360,15 @@ NESTED(nmi_handler, PT_SIZE, sp)
.setmips1
SET_HARDFLOAT
cfc1a1, fcr31
-   li  a2, ~(0x3f << 12)
-   and a2, a1
-   ctc1a2, fcr31
.setpop
-   TRACE_IRQS_ON
-   STI
+   CLI
+   TRACE_IRQS_OFF
.endm
 
.macro  __build_clear_msa_fpe
_cfcmsa a1, MSA_CSR
-   li  a2, ~(0x3f << 12)
-   and a1, a1, a2
-   _ctcmsa MSA_CSR, a1
-   TRACE_IRQS_ON
-   STI
+   CLI
+   TRACE_IRQS_OFF
.endm
 
.macro  __build_clear_ade
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 8943ebe4d154..5b4d711f878d 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -788,6 +788,11 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long 
fcr31)
if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs),
   SIGFPE) == NOTIFY_STOP)
goto out;
+
+   /* Clear FCSR.Cause before enabling interrupts */
+   write_32bit_cp1_register(CP1_STATUS, fcr31 & ~FPU_CSR_ALL_X);
+   local_irq_enable();
+
die_if_kernel("FP exception in kernel code", regs);
 
if (fcr31 & FPU_CSR_UNI_X) {
@@ -1393,13 +1398,22 @@ out:
exception_exit(prev_state);
 }
 
-asmlinkage void do_msa_fpe(struct pt_regs *regs)
+asmlinkage void do_msa_fpe(struct pt_regs *regs, unsigned int msacsr)
 {
enum ctx_state prev_state;
 
prev_state = exception_enter();
+   if (notify_die(DIE_MSAFP, "MSA FP exception", regs, 0,
+  regs_to_trapnr(regs), SIGFPE) == NOTIFY_STOP)
+   goto out;
+
+   /* Clear MSACSR.Cause before enabling interrupts */
+   write_msa_csr(msacsr & ~MSA_CSR_CAUSEF);
+   local_irq_enable();
+
die_if_kernel("do_msa_fpe invoked from kernel context!", regs);
force_sig(SIGFPE, current);
+out:
exception_exit(prev_state);
 }
 
-- 
2.0.5

--
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


[PATCH stable 3.10, 3.12, 3.14] MIPS: Export FP functions used by lose_fpu(1) for KVM

2015-03-05 Thread James Hogan
[ Upstream commit 3ce465e04bfd8de9956d515d6e9587faac3375dc ]

Export the _save_fp asm function used by the lose_fpu(1) macro to GPL
modules so that KVM can make use of it when it is built as a module.

This fixes the following build error when CONFIG_KVM=m due to commit
f798217dfd03 ("KVM: MIPS: Don't leak FPU/DSP to guest"):

ERROR: "_save_fp" [arch/mips/kvm/kvm.ko] undefined!

Signed-off-by: James Hogan 
Fixes: f798217dfd03 (KVM: MIPS: Don't leak FPU/DSP to guest)
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Paul Burton 
Cc: Gleb Natapov 
Cc: kvm@vger.kernel.org
Cc: linux-m...@linux-mips.org
Cc:  # 3.10...3.15
Patchwork: https://patchwork.linux-mips.org/patch/9260/
Signed-off-by: Ralf Baechle 
[james.ho...@imgtec.com: Only export when CPU_R4K_FPU=y prior to v3.16,
 so as not to break the Octeon build which excludes FPU support. KVM
 depends on MIPS32r2 anyway.]
Signed-off-by: James Hogan 
---
Appologies for the previous cavium_octeon_defconfig link breakage.
Octeon has the symbol since 3.16, but not before. This backport should
do the trick for stable 3.10, 3.12, and 3.14. Build tested with
cavium_octeon_defconfig and malta_kvm_defconfig on those stable
branches.
---
 arch/mips/kernel/mips_ksyms.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 6e58e97fcd39..cedeb5686eb5 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 
 extern void *__bzero(void *__s, size_t __count);
 extern long __strncpy_from_user_nocheck_asm(char *__to,
@@ -26,6 +27,13 @@ extern long __strnlen_user_nocheck_asm(const char *s);
 extern long __strnlen_user_asm(const char *s);
 
 /*
+ * Core architecture code
+ */
+#ifdef CONFIG_CPU_R4K_FPU
+EXPORT_SYMBOL_GPL(_save_fp);
+#endif
+
+/*
  * String functions
  */
 EXPORT_SYMBOL(memset);
-- 
2.0.5

--
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


Re: [PATCH 3.14 58/73] KVM: MIPS: Dont leak FPU/DSP to guest

2015-03-04 Thread James Hogan
Hi Greg,

On Tue, Mar 03, 2015 at 10:13:26PM -0800, Greg Kroah-Hartman wrote:
> 3.14-stable review patch.  If anyone has any objections, please let me know.
> 
> --
> 
> From: James Hogan 
> 
> commit f798217dfd038af981a18bbe4bc57027a08bb182 upstream.
> 
> The FPU and DSP are enabled via the CP0 Status CU1 and MX bits by
> kvm_mips_set_c0_status() on a guest exit, presumably in case there is
> active state that needs saving if pre-emption occurs. However neither of
> these bits are cleared again when returning to the guest.
> 
> This effectively gives the guest access to the FPU/DSP hardware after
> the first guest exit even though it is not aware of its presence,
> allowing FP instructions in guest user code to intermittently actually
> execute instead of trapping into the guest OS for emulation. It will
> then read & manipulate the hardware FP registers which technically
> belong to the user process (e.g. QEMU), or are stale from another user
> process. It can also crash the guest OS by causing an FP exception, for
> which a guest exception handler won't have been registered.
> 
> First lets save and disable the FPU (and MSA) state with lose_fpu(1)
> before entering the guest. This simplifies the problem, especially for
> when guest FPU/MSA support is added in the future, and prevents FR=1 FPU
> state being live when the FR bit gets cleared for the guest, which
> according to the architecture causes the contents of the FPU and vector
> registers to become UNPREDICTABLE.
> 
> We can then safely remove the enabling of the FPU in
> kvm_mips_set_c0_status(), since there should never be any active FPU or
> MSA state to save at pre-emption, which should plug the FPU leak.
> 
> DSP state is always live rather than being lazily restored, so for that
> it is simpler to just clear the MX bit again when re-entering the guest.
> 
> Signed-off-by: James Hogan 
> Cc: Paolo Bonzini 
> Cc: Ralf Baechle 
> Cc: Sanjay Lal 
> Cc: Gleb Natapov 
> Cc: kvm@vger.kernel.org
> Cc: linux-m...@linux-mips.org
> Cc:  # v3.10+: 044f0f03eca0: MIPS: KVM: Deliver guest 
> interrupts

The original 3.10 and 3.12/3.14 backports had this added:
Cc:  # v3.10+: 3ce465e04bfd: MIPS: Export FP functions 
used by lose_fpu(1) for KVM 
Which I can't see included in the v3.10 stable queue or branch. It fixes
a build error with MIPS malta_kvm_defconfig (MIPS=y, KVM=m) after this
patch is applied.

Same applies to the 3.14 queue too I think.

Cheers
James

> Cc:  # v3.10+
> Signed-off-by: Paolo Bonzini 
> Signed-off-by: James Hogan 
> Signed-off-by: Greg Kroah-Hartman 
> ---
> This should apply to stable trees 3.12 and 3.14, but not 3.10. The files
> had been renamed since v3.14 so it cherry-picked cleanly but the patch
> didn't apply cleanly. I've also added a reference to the "MIPS: Export
> FP functions used by lose_fpu(1) for KVM" commit which is itself marked
> for stable, but is needed to avoid a build failure when KVM=m.
> ---
>  arch/mips/kvm/kvm_locore.S |2 +-
>  arch/mips/kvm/kvm_mips.c   |6 +++---
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> --- a/arch/mips/kvm/kvm_locore.S
> +++ b/arch/mips/kvm/kvm_locore.S
> @@ -428,7 +428,7 @@ __kvm_mips_return_to_guest:
>   /* Setup status register for running guest in UM */
>   .setat
>   or  v1, v1, (ST0_EXL | KSU_USER | ST0_IE)
> - and v1, v1, ~ST0_CU0
> + and v1, v1, ~(ST0_CU0 | ST0_MX)
>   .setnoat
>   mtc0v1, CP0_STATUS
>   ehb
> --- a/arch/mips/kvm/kvm_mips.c
> +++ b/arch/mips/kvm/kvm_mips.c
> @@ -15,6 +15,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -418,6 +419,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
>   vcpu->mmio_needed = 0;
>   }
>  
> + lose_fpu(1);
> +
>   local_irq_disable();
>   /* Check if we have any exceptions/interrupts pending */
>   kvm_mips_deliver_interrupts(vcpu,
> @@ -1021,9 +1024,6 @@ void kvm_mips_set_c0_status(void)
>  {
>   uint32_t status = read_c0_status();
>  
> - if (cpu_has_fpu)
> - status |= (ST0_CU1);
> -
>   if (cpu_has_dsp)
>   status |= (ST0_MX);
>  
> 
> 


signature.asc
Description: Digital signature


[PATCH stable 3.10] KVM: MIPS: Don't leak FPU/DSP to guest

2015-03-02 Thread James Hogan
[ Upstream commit f798217dfd038af981a18bbe4bc57027a08bb182 ]

The FPU and DSP are enabled via the CP0 Status CU1 and MX bits by
kvm_mips_set_c0_status() on a guest exit, presumably in case there is
active state that needs saving if pre-emption occurs. However neither of
these bits are cleared again when returning to the guest.

This effectively gives the guest access to the FPU/DSP hardware after
the first guest exit even though it is not aware of its presence,
allowing FP instructions in guest user code to intermittently actually
execute instead of trapping into the guest OS for emulation. It will
then read & manipulate the hardware FP registers which technically
belong to the user process (e.g. QEMU), or are stale from another user
process. It can also crash the guest OS by causing an FP exception, for
which a guest exception handler won't have been registered.

First lets save and disable the FPU (and MSA) state with lose_fpu(1)
before entering the guest. This simplifies the problem, especially for
when guest FPU/MSA support is added in the future, and prevents FR=1 FPU
state being live when the FR bit gets cleared for the guest, which
according to the architecture causes the contents of the FPU and vector
registers to become UNPREDICTABLE.

We can then safely remove the enabling of the FPU in
kvm_mips_set_c0_status(), since there should never be any active FPU or
MSA state to save at pre-emption, which should plug the FPU leak.

DSP state is always live rather than being lazily restored, so for that
it is simpler to just clear the MX bit again when re-entering the guest.

Signed-off-by: James Hogan 
Cc: Paolo Bonzini 
Cc: Ralf Baechle 
Cc: Sanjay Lal 
Cc: Gleb Natapov 
Cc: kvm@vger.kernel.org
Cc: linux-m...@linux-mips.org
Cc:  # v3.10+: 044f0f03eca0: MIPS: KVM: Deliver guest 
interrupts
Cc:  # v3.10+: 3ce465e04bfd: MIPS: Export FP functions 
used by lose_fpu(1) for KVM
Cc:  # v3.10+
Signed-off-by: Paolo Bonzini 
Signed-off-by: James Hogan 
---
This should apply to stable tree 3.10. In addition to the files being
renamed since v3.14, kvm_locore.S was reformatted slightly between v3.10
and v3.12. I've also added a reference to the "MIPS: Export FP functions
used by lose_fpu(1) for KVM" commit which is itself marked for stable,
but is needed to avoid a build failure when KVM=m.
---
 arch/mips/kvm/kvm_locore.S | 2 +-
 arch/mips/kvm/kvm_mips.c   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S
index dca2aa665993..920b63210806 100644
--- a/arch/mips/kvm/kvm_locore.S
+++ b/arch/mips/kvm/kvm_locore.S
@@ -431,7 +431,7 @@ __kvm_mips_return_to_guest:
 /* Setup status register for running guest in UM */
 .set at
 or v1, v1, (ST0_EXL | KSU_USER | ST0_IE)
-and v1, v1, ~ST0_CU0
+and v1, v1, ~(ST0_CU0 | ST0_MX)
 .set noat
 mtc0v1, CP0_STATUS
 ehb
diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c
index f957a8ac979b..843ec38fec7b 100644
--- a/arch/mips/kvm/kvm_mips.c
+++ b/arch/mips/kvm/kvm_mips.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -413,6 +414,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
vcpu->mmio_needed = 0;
}
 
+   lose_fpu(1);
+
local_irq_disable();
/* Check if we have any exceptions/interrupts pending */
kvm_mips_deliver_interrupts(vcpu,
@@ -1017,9 +1020,6 @@ void kvm_mips_set_c0_status(void)
 {
uint32_t status = read_c0_status();
 
-   if (cpu_has_fpu)
-   status |= (ST0_CU1);
-
if (cpu_has_dsp)
status |= (ST0_MX);
 
-- 
2.0.5

--
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


  1   2   3   >