* [PATCH 00/20] MIPS: KVM: Guest FPU & SIMD (MSA) support @ 2015-03-11 14:44 James Hogan 2015-03-11 14:44 ` [PATCH 14/20] MIPS: KVM: Expose FPU registers James Hogan ` (2 more replies) 0 siblings, 3 replies; 8+ messages in thread From: James Hogan @ 2015-03-11 14:44 UTC (permalink / raw) To: Paolo Bonzini, kvm-u79uwXL29TY76Z2rM5mHXA, linux-mips-6z/3iImG2C8G8FEW9MqTrA Cc: James Hogan, Paul Burton, Ralf Baechle, Gleb Natapov, Jonathan Corbet, linux-api-u79uwXL29TY76Z2rM5mHXA, linux-doc-u79uwXL29TY76Z2rM5mHXA 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 <pbonzini-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> Cc: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org> Cc: Ralf Baechle <ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org> Cc: Gleb Natapov <gleb-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> Cc: Jonathan Corbet <corbet-T1hC0tSOHrs@public.gmane.org> Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org Cc: kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org -- 2.0.5 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 14/20] MIPS: KVM: Expose FPU registers 2015-03-11 14:44 [PATCH 00/20] MIPS: KVM: Guest FPU & SIMD (MSA) support James Hogan @ 2015-03-11 14:44 ` James Hogan 2015-03-26 13:55 ` Paolo Bonzini [not found] ` <1426085096-12932-1-git-send-email-james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org> 2015-03-11 14:44 ` [PATCH 20/20] MIPS: KVM: Wire up MSA capability James Hogan 2 siblings, 1 reply; 8+ messages in thread From: James Hogan @ 2015-03-11 14:44 UTC (permalink / raw) To: Paolo Bonzini, kvm, linux-mips Cc: James Hogan, Paul Burton, Ralf Baechle, Gleb Natapov, Jonathan Corbet, linux-api, linux-doc 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 <james.hogan@imgtec.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Paul Burton <paul.burton@imgtec.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Gleb Natapov <gleb@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Cc: linux-api@vger.kernel.org Cc: linux-doc@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 0000 0002 <reg:16> +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 0000 0003 00 <0:3> <reg:5> (32-bit FPU registers) + 0x7030 0000 0003 00 <0:3> <reg:5> (64-bit FPU registers) + +MIPS FPU control registers (see KVM_REG_MIPS_FCR_{IR,CSR} above) have the +following id bit patterns: + 0x7020 0000 0003 01 <0:3> <reg:5> + 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 | 0x0000000000000000ULL) #define KVM_REG_MIPS_CP0 (KVM_REG_MIPS | 0x0000000000010000ULL) #define KVM_REG_MIPS_KVM (KVM_REG_MIPS | 0x0000000000020000ULL) +#define KVM_REG_MIPS_FPU (KVM_REG_MIPS | 0x0000000000030000ULL) /* @@ -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 | 0x0000000000000000ULL) +#define KVM_REG_MIPS_FCR (KVM_REG_MIPS_FPU | 0x0000000000000100ULL) + +/* + * 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->arch.cop0; + struct mips_fpu_struct *fpu = &vcpu->arch.fpu; int ret; s64 v; + unsigned int idx; switch (reg->id) { + /* General purpose registers */ case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31: v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0]; break; @@ -543,6 +546,38 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, v = (long)vcpu->arch.pc; break; + /* Floating point registers */ + case KVM_REG_MIPS_FPR_32(0) ... KVM_REG_MIPS_FPR_32(31): + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) + return -EINVAL; + idx = reg->id - KVM_REG_MIPS_FPR_32(0); + /* Odd singles in top of even double when FR=0 */ + if (kvm_read_c0_guest_status(cop0) & ST0_FR) + v = get_fpr32(&fpu->fpr[idx], 0); + else + v = get_fpr32(&fpu->fpr[idx & ~1], idx & 1); + break; + case KVM_REG_MIPS_FPR_64(0) ... KVM_REG_MIPS_FPR_64(31): + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) + return -EINVAL; + idx = reg->id - KVM_REG_MIPS_FPR_64(0); + /* Can't access odd doubles in FR=0 mode */ + if (idx & 1 && !(kvm_read_c0_guest_status(cop0) & ST0_FR)) + return -EINVAL; + v = get_fpr64(&fpu->fpr[idx], 0); + break; + case KVM_REG_MIPS_FCR_IR: + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) + return -EINVAL; + v = boot_cpu_data.fpu_id; + break; + case KVM_REG_MIPS_FCR_CSR: + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) + return -EINVAL; + v = fpu->fcr31; + break; + + /* Co-processor 0 registers */ case KVM_REG_MIPS_CP0_INDEX: v = (long)kvm_read_c0_guest_index(cop0); break; @@ -636,7 +671,9 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { struct mips_coproc *cop0 = vcpu->arch.cop0; - u64 v; + struct mips_fpu_struct *fpu = &vcpu->arch.fpu; + s64 v; + unsigned int idx; if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) { u64 __user *uaddr64 = (u64 __user *)(long)reg->addr; @@ -655,6 +692,7 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, } switch (reg->id) { + /* General purpose registers */ case KVM_REG_MIPS_R0: /* Silently ignore requests to set $0 */ break; @@ -671,6 +709,38 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, vcpu->arch.pc = v; break; + /* Floating point registers */ + case KVM_REG_MIPS_FPR_32(0) ... KVM_REG_MIPS_FPR_32(31): + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) + return -EINVAL; + idx = reg->id - KVM_REG_MIPS_FPR_32(0); + /* Odd singles in top of even double when FR=0 */ + if (kvm_read_c0_guest_status(cop0) & ST0_FR) + set_fpr32(&fpu->fpr[idx], 0, v); + else + set_fpr32(&fpu->fpr[idx & ~1], idx & 1, v); + break; + case KVM_REG_MIPS_FPR_64(0) ... KVM_REG_MIPS_FPR_64(31): + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) + return -EINVAL; + idx = reg->id - KVM_REG_MIPS_FPR_64(0); + /* Can't access odd doubles in FR=0 mode */ + if (idx & 1 && !(kvm_read_c0_guest_status(cop0) & ST0_FR)) + return -EINVAL; + set_fpr64(&fpu->fpr[idx], 0, v); + break; + case KVM_REG_MIPS_FCR_IR: + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) + return -EINVAL; + /* Read-only */ + break; + case KVM_REG_MIPS_FCR_CSR: + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) + return -EINVAL; + fpu->fcr31 = v; + break; + + /* Co-processor 0 registers */ case KVM_REG_MIPS_CP0_INDEX: kvm_write_c0_guest_index(cop0, v); break; -- 2.0.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 14/20] MIPS: KVM: Expose FPU registers 2015-03-11 14:44 ` [PATCH 14/20] MIPS: KVM: Expose FPU registers James Hogan @ 2015-03-26 13:55 ` Paolo Bonzini 0 siblings, 0 replies; 8+ messages in thread From: Paolo Bonzini @ 2015-03-26 13:55 UTC (permalink / raw) To: James Hogan, kvm, linux-mips Cc: Paul Burton, Ralf Baechle, Gleb Natapov, Jonathan Corbet, linux-api, linux-doc On 11/03/2015 15:44, James Hogan wrote: > 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 <james.hogan@imgtec.com> > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Paul Burton <paul.burton@imgtec.com> > Cc: Ralf Baechle <ralf@linux-mips.org> > Cc: Gleb Natapov <gleb@kernel.org> > Cc: Jonathan Corbet <corbet@lwn.net> > Cc: linux-mips@linux-mips.org > Cc: kvm@vger.kernel.org > Cc: linux-api@vger.kernel.org > Cc: linux-doc@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 0000 0002 <reg:16> > > +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 0000 0003 00 <0:3> <reg:5> (32-bit FPU registers) > + 0x7030 0000 0003 00 <0:3> <reg:5> (64-bit FPU registers) > + > +MIPS FPU control registers (see KVM_REG_MIPS_FCR_{IR,CSR} above) have the > +following id bit patterns: > + 0x7020 0000 0003 01 <0:3> <reg:5> > + > > 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 | 0x0000000000000000ULL) > #define KVM_REG_MIPS_CP0 (KVM_REG_MIPS | 0x0000000000010000ULL) > #define KVM_REG_MIPS_KVM (KVM_REG_MIPS | 0x0000000000020000ULL) > +#define KVM_REG_MIPS_FPU (KVM_REG_MIPS | 0x0000000000030000ULL) > > > /* > @@ -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 | 0x0000000000000000ULL) > +#define KVM_REG_MIPS_FCR (KVM_REG_MIPS_FPU | 0x0000000000000100ULL) > + > +/* > + * 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->arch.cop0; > + struct mips_fpu_struct *fpu = &vcpu->arch.fpu; > int ret; > s64 v; > + unsigned int idx; > > switch (reg->id) { > + /* General purpose registers */ > case KVM_REG_MIPS_R0 ... KVM_REG_MIPS_R31: > v = (long)vcpu->arch.gprs[reg->id - KVM_REG_MIPS_R0]; > break; > @@ -543,6 +546,38 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, > v = (long)vcpu->arch.pc; > break; > > + /* Floating point registers */ > + case KVM_REG_MIPS_FPR_32(0) ... KVM_REG_MIPS_FPR_32(31): > + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) > + return -EINVAL; > + idx = reg->id - KVM_REG_MIPS_FPR_32(0); > + /* Odd singles in top of even double when FR=0 */ > + if (kvm_read_c0_guest_status(cop0) & ST0_FR) > + v = get_fpr32(&fpu->fpr[idx], 0); > + else > + v = get_fpr32(&fpu->fpr[idx & ~1], idx & 1); > + break; > + case KVM_REG_MIPS_FPR_64(0) ... KVM_REG_MIPS_FPR_64(31): > + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) > + return -EINVAL; > + idx = reg->id - KVM_REG_MIPS_FPR_64(0); > + /* Can't access odd doubles in FR=0 mode */ > + if (idx & 1 && !(kvm_read_c0_guest_status(cop0) & ST0_FR)) > + return -EINVAL; > + v = get_fpr64(&fpu->fpr[idx], 0); > + break; > + case KVM_REG_MIPS_FCR_IR: > + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) > + return -EINVAL; > + v = boot_cpu_data.fpu_id; > + break; > + case KVM_REG_MIPS_FCR_CSR: > + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) > + return -EINVAL; > + v = fpu->fcr31; > + break; > + > + /* Co-processor 0 registers */ > case KVM_REG_MIPS_CP0_INDEX: > v = (long)kvm_read_c0_guest_index(cop0); > break; > @@ -636,7 +671,9 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, > const struct kvm_one_reg *reg) > { > struct mips_coproc *cop0 = vcpu->arch.cop0; > - u64 v; > + struct mips_fpu_struct *fpu = &vcpu->arch.fpu; > + s64 v; > + unsigned int idx; > > if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) { > u64 __user *uaddr64 = (u64 __user *)(long)reg->addr; > @@ -655,6 +692,7 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, > } > > switch (reg->id) { > + /* General purpose registers */ > case KVM_REG_MIPS_R0: > /* Silently ignore requests to set $0 */ > break; > @@ -671,6 +709,38 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, > vcpu->arch.pc = v; > break; > > + /* Floating point registers */ > + case KVM_REG_MIPS_FPR_32(0) ... KVM_REG_MIPS_FPR_32(31): > + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) > + return -EINVAL; > + idx = reg->id - KVM_REG_MIPS_FPR_32(0); > + /* Odd singles in top of even double when FR=0 */ > + if (kvm_read_c0_guest_status(cop0) & ST0_FR) > + set_fpr32(&fpu->fpr[idx], 0, v); > + else > + set_fpr32(&fpu->fpr[idx & ~1], idx & 1, v); > + break; > + case KVM_REG_MIPS_FPR_64(0) ... KVM_REG_MIPS_FPR_64(31): > + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) > + return -EINVAL; > + idx = reg->id - KVM_REG_MIPS_FPR_64(0); > + /* Can't access odd doubles in FR=0 mode */ > + if (idx & 1 && !(kvm_read_c0_guest_status(cop0) & ST0_FR)) > + return -EINVAL; > + set_fpr64(&fpu->fpr[idx], 0, v); > + break; > + case KVM_REG_MIPS_FCR_IR: > + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) > + return -EINVAL; > + /* Read-only */ > + break; > + case KVM_REG_MIPS_FCR_CSR: > + if (!kvm_mips_guest_has_fpu(&vcpu->arch)) > + return -EINVAL; > + fpu->fcr31 = v; > + break; > + > + /* Co-processor 0 registers */ > case KVM_REG_MIPS_CP0_INDEX: > kvm_write_c0_guest_index(cop0, v); > break; > Acked-by: Paolo Bonzini <pbonzini@redhat.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <1426085096-12932-1-git-send-email-james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org>]
* [PATCH 15/20] MIPS: KVM: Wire up FPU capability [not found] ` <1426085096-12932-1-git-send-email-james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org> @ 2015-03-11 14:44 ` James Hogan 2015-03-11 14:44 ` [PATCH 19/20] MIPS: KVM: Expose MSA registers James Hogan 1 sibling, 0 replies; 8+ messages in thread From: James Hogan @ 2015-03-11 14:44 UTC (permalink / raw) To: Paolo Bonzini, kvm-u79uwXL29TY76Z2rM5mHXA, linux-mips-6z/3iImG2C8G8FEW9MqTrA Cc: James Hogan, Ralf Baechle, Gleb Natapov, Jonathan Corbet, linux-api-u79uwXL29TY76Z2rM5mHXA, linux-doc-u79uwXL29TY76Z2rM5mHXA 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 <james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org> Cc: Paolo Bonzini <pbonzini-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> Cc: Ralf Baechle <ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org> Cc: Gleb Natapov <gleb-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> Cc: Jonathan Corbet <corbet-T1hC0tSOHrs@public.gmane.org> Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org Cc: kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.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 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 19/20] MIPS: KVM: Expose MSA registers [not found] ` <1426085096-12932-1-git-send-email-james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org> 2015-03-11 14:44 ` [PATCH 15/20] MIPS: KVM: Wire up FPU capability James Hogan @ 2015-03-11 14:44 ` James Hogan 1 sibling, 0 replies; 8+ messages in thread From: James Hogan @ 2015-03-11 14:44 UTC (permalink / raw) To: Paolo Bonzini, kvm-u79uwXL29TY76Z2rM5mHXA, linux-mips-6z/3iImG2C8G8FEW9MqTrA Cc: James Hogan, Paul Burton, Ralf Baechle, Gleb Natapov, Jonathan Corbet, linux-api-u79uwXL29TY76Z2rM5mHXA, linux-doc-u79uwXL29TY76Z2rM5mHXA 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 <james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org> Cc: Paolo Bonzini <pbonzini-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> Cc: Paul Burton <paul.burton-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org> Cc: Ralf Baechle <ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org> Cc: Gleb Natapov <gleb-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> Cc: Jonathan Corbet <corbet-T1hC0tSOHrs@public.gmane.org> Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org Cc: kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.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 | 0x0000000000000000ULL) #define KVM_REG_MIPS_FCR (KVM_REG_MIPS_FPU | 0x0000000000000100ULL) +#define KVM_REG_MIPS_MSACR (KVM_REG_MIPS_FPU | 0x0000000000000200ULL) /* * 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] = get_fpr64(&fpu->fpr[idx], 1); +#else + /* most significant byte first */ + vs[0] = get_fpr64(&fpu->fpr[idx], 1); + vs[1] = get_fpr64(&fpu->fpr[idx], 0); +#endif + break; + case KVM_REG_MIPS_MSA_IR: + if (!kvm_mips_guest_has_msa(&vcpu->arch)) + return -EINVAL; + v = boot_cpu_data.msa_id; + break; + case KVM_REG_MIPS_MSA_CSR: + if (!kvm_mips_guest_has_msa(&vcpu->arch)) + return -EINVAL; + v = fpu->msacsr; + break; + /* Co-processor 0 registers */ case KVM_REG_MIPS_CP0_INDEX: v = (long)kvm_read_c0_guest_index(cop0); @@ -664,6 +694,10 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu, u32 v32 = (u32)v; return put_user(v32, uaddr32); + } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) { + void __user *uaddr = (void __user *)(long)reg->addr; + + return copy_to_user(uaddr, vs, 16); } else { return -EINVAL; } @@ -675,6 +709,7 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, struct mips_coproc *cop0 = vcpu->arch.cop0; struct mips_fpu_struct *fpu = &vcpu->arch.fpu; s64 v; + s64 vs[2]; unsigned int idx; if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) { @@ -689,6 +724,10 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, if (get_user(v32, uaddr32) != 0) return -EFAULT; v = (s64)v32; + } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) { + void __user *uaddr = (void __user *)(long)reg->addr; + + return copy_from_user(vs, uaddr, 16); } else { return -EINVAL; } @@ -742,6 +781,32 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu, fpu->fcr31 = v; 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; + idx = reg->id - KVM_REG_MIPS_VEC_128(0); +#ifdef CONFIG_CPU_LITTLE_ENDIAN + /* least significant byte first */ + set_fpr64(&fpu->fpr[idx], 0, vs[0]); + set_fpr64(&fpu->fpr[idx], 1, vs[1]); +#else + /* most significant byte first */ + set_fpr64(&fpu->fpr[idx], 1, vs[0]); + set_fpr64(&fpu->fpr[idx], 0, vs[1]); +#endif + break; + case KVM_REG_MIPS_MSA_IR: + if (!kvm_mips_guest_has_msa(&vcpu->arch)) + return -EINVAL; + /* Read-only */ + break; + case KVM_REG_MIPS_MSA_CSR: + if (!kvm_mips_guest_has_msa(&vcpu->arch)) + return -EINVAL; + fpu->msacsr = v; + break; + /* Co-processor 0 registers */ case KVM_REG_MIPS_CP0_INDEX: kvm_write_c0_guest_index(cop0, v); -- 2.0.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 20/20] MIPS: KVM: Wire up MSA capability 2015-03-11 14:44 [PATCH 00/20] MIPS: KVM: Guest FPU & SIMD (MSA) support James Hogan 2015-03-11 14:44 ` [PATCH 14/20] MIPS: KVM: Expose FPU registers James Hogan [not found] ` <1426085096-12932-1-git-send-email-james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org> @ 2015-03-11 14:44 ` James Hogan 2015-03-26 13:58 ` Paolo Bonzini 2 siblings, 1 reply; 8+ messages in thread From: James Hogan @ 2015-03-11 14:44 UTC (permalink / raw) To: Paolo Bonzini, kvm, linux-mips Cc: James Hogan, Ralf Baechle, Gleb Natapov, Jonathan Corbet, linux-api, linux-doc 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 <james.hogan@imgtec.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Gleb Natapov <gleb@kernel.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Cc: linux-api@vger.kernel.org Cc: linux-doc@vger.kernel.org Signed-off-by: James Hogan <james.hogan@imgtec.com> --- 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 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 20/20] MIPS: KVM: Wire up MSA capability 2015-03-11 14:44 ` [PATCH 20/20] MIPS: KVM: Wire up MSA capability James Hogan @ 2015-03-26 13:58 ` Paolo Bonzini 2015-03-26 14:52 ` James Hogan 0 siblings, 1 reply; 8+ messages in thread From: Paolo Bonzini @ 2015-03-26 13:58 UTC (permalink / raw) To: James Hogan, kvm, linux-mips Cc: Ralf Baechle, Gleb Natapov, Jonathan Corbet, linux-api, linux-doc 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 <james.hogan@imgtec.com> > Cc: Paolo Bonzini <pbonzini@redhat.com> > Cc: Ralf Baechle <ralf@linux-mips.org> > Cc: Gleb Natapov <gleb@kernel.org> > Cc: Jonathan Corbet <corbet@lwn.net> > Cc: linux-mips@linux-mips.org > Cc: kvm@vger.kernel.org > Cc: linux-api@vger.kernel.org > Cc: linux-doc@vger.kernel.org > Signed-off-by: James Hogan <james.hogan@imgtec.com> > --- > 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)? Apart from this nit, Acked-by: Paolo Bonzini <pbonzini@redhat.com> Paolo > + 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 > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 20/20] MIPS: KVM: Wire up MSA capability 2015-03-26 13:58 ` Paolo Bonzini @ 2015-03-26 14:52 ` James Hogan 0 siblings, 0 replies; 8+ messages in thread From: James Hogan @ 2015-03-26 14:52 UTC (permalink / raw) To: Paolo Bonzini, kvm, linux-mips Cc: Ralf Baechle, Gleb Natapov, Jonathan Corbet, linux-api, linux-doc [-- Attachment #1: Type: text/plain, Size: 4602 bytes --] 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 <james.hogan@imgtec.com> >> Cc: Paolo Bonzini <pbonzini@redhat.com> >> Cc: Ralf Baechle <ralf@linux-mips.org> >> Cc: Gleb Natapov <gleb@kernel.org> >> Cc: Jonathan Corbet <corbet@lwn.net> >> Cc: linux-mips@linux-mips.org >> Cc: kvm@vger.kernel.org >> Cc: linux-api@vger.kernel.org >> Cc: linux-doc@vger.kernel.org >> Signed-off-by: James Hogan <james.hogan@imgtec.com> >> --- >> 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 <pbonzini@redhat.com> > > 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 >> >> [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-03-26 14:52 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-03-11 14:44 [PATCH 00/20] MIPS: KVM: Guest FPU & SIMD (MSA) support James Hogan 2015-03-11 14:44 ` [PATCH 14/20] MIPS: KVM: Expose FPU registers James Hogan 2015-03-26 13:55 ` Paolo Bonzini [not found] ` <1426085096-12932-1-git-send-email-james.hogan-1AXoQHu6uovQT0dZR+AlfA@public.gmane.org> 2015-03-11 14:44 ` [PATCH 15/20] MIPS: KVM: Wire up FPU capability James Hogan 2015-03-11 14:44 ` [PATCH 19/20] MIPS: KVM: Expose MSA registers James Hogan 2015-03-11 14:44 ` [PATCH 20/20] MIPS: KVM: Wire up MSA capability James Hogan 2015-03-26 13:58 ` Paolo Bonzini 2015-03-26 14:52 ` James Hogan
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).