Re: [Qemu-devel] [PATCH v5 10/12] hw/mips: malta: Add KVM support
On Jun 19, 2014, at 9:27 AM, Aurelien Jarno aurel...@aurel32.net wrote: On Tue, Jun 17, 2014 at 11:10:35PM +0100, James Hogan wrote: In KVM mode the bootrom is loaded and executed from the last 1MB of DRAM. What is the reason for that? I am not opposed to that, but if it is really needed, it means that loading a bootloader into the flash area (for example YAMON) won't work and that this should be forbidden to the user. In trap and emulate mode, both the kernel and userland run in user mode on the processor. Virtual addresses = 0x8000 are only accessible in kernel mode, and the default flash area (VA: 0xbfc0/PA: 0x1fc0) falls in this range. We therefore decided to relocate the bootloader to the last 1MB of RAM. This area is excluded from the RAM ranges supplied to the kernel, so it should not be accessible to the user. Regards Sanjay signature.asc Description: Message signed with OpenPGP using GPGMail
Re: [PATCH 00/31] KVM/MIPS: Implement hardware virtualization via the MIPS-VZ extensions.
On Jun 9, 2013, at 4:23 PM, David Daney wrote: On 06/09/2013 12:31 AM, Gleb Natapov wrote: On Fri, Jun 07, 2013 at 04:15:00PM -0700, David Daney wrote: I should also add that I will shortly send patches for the kvm tool required to drive this VM as well as a small set of patches that create a para-virtualized MIPS/Linux guest kernel. The idea is that because there is no standard SMP linux system, we create a standard para-virtualized system that uses a handful of hypercalls, but mostly just uses virtio devices. It has no emulated real hardware (no 8250 UART, no emulated legacy anything...) Virtualization is useful for running legacy code. Why dismiss support for non pv guests so easily? Just because we create standard PV system devices, doesn't preclude emulating real hardware. In fact Sanjay Lal's work includes QEMU support for doing just this for a MIPS malta board. I just wanted a very simple system I could implement with the kvm tool in a couple of days, so that is what I initially did. The problem is that almost nobody has real malta boards, they are really only of interest because QEMU implements a virtual malta board. Personally, I see the most interesting us cases of MIPS KVM being a deployment platform for new services, so legacy support is not so important to me. That doesn't mean that other people wouldn't want some sort of legacy support. The problem with 'legacy' on MIPS is that there are hundreds of legacies to choose from (Old SGI and DEC hardware, various network hardware from many different vendors, etc.). Which would you choose? How different MIPS SMP systems are? o Old SGI heavy metal (several different system architectures). o Cavium OCTEON SMP SoCs. o Broadcom (several flavors) SoCs o Loongson Come to think of it, Emulating SGI hardware might be an interesting case. There may be old IRIX systems and applications that could be running low on real hardware. Some of those systems take up a whole room and draw a lot of power. They might run faster and at much lower power consumption on a modern 48-Way SMP SoC based system. What about running non pv UP systems? See above. I think this is what Sanjay Lal is doing. The KVM implementation from MIPS (currently in mainline) supports UP systems in trap and emulate mode. The patch set I posted earlier adding VZ support also supports SMP. We leverage the Malta board emulation in QEMU to offer full non-PV virtualization: UP system: Malta board with a MIPS 24K processor SMP system: Malta board with a 1074K CMP processor cluster with a GIC. When it comes to PV/non-PV support, I see the two implementations as complementary. If people want full legacy system emulation without any kernel modifications, then they can run the full QEMU/KVM stack, while people interested in pure PV solutions can run the lkvm version. Regards Sanjay -- 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/31] KVM/MIPS: Implement hardware virtualization via the MIPS-VZ extensions.
On Jun 7, 2013, at 4:03 PM, David Daney wrote: From: David Daney david.da...@cavium.com These patches take a somewhat different approach to MIPS virtualization via the MIPS-VZ extensions than the patches previously sent by Sanjay Lal. Several facts about the code: o Currently probably only usable on the OCTEON III CPU model, as some MIPS-VZ implementation-defined behaviors were assumed to have the OCTEON III behavior. I've only briefly gone over the patches, but I was wondering if the Cavium implementation has support for GuestIDs, which are optional in the VZ-ASE? Regards Sanjay -- 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 10/18] KVM/MIPS32-VZ: Add API for VZ-ASE Capability
On May 30, 2013, at 10:07 AM, David Daney wrote: On 05/28/2013 09:34 AM, Paolo Bonzini wrote: Il 19/05/2013 07:47, Sanjay Lal ha scritto: - Add API to allow clients (QEMU etc.) to check whether the H/W supports the MIPS VZ-ASE. Why does this matter to userspace? Do the userspace have some way to detect if the kernel is unmodified or minimally-modified? There are (will be) two types of VM presented by MIPS KVM: 1) That provided by the initial patch where a faux-MIPS is emulated and all kernel code must be in the USEG address space. 2) Real MIPS, addressing works as per the architecture specification. Presumably the user-space client would like to know which of these are supported, as well as be able to select the desired model. I don't know the best way to do this, but I agree that KVM_CAP_MIPS_VZ_ASE is probably not the best name for it. My idea was to have the arg of the KVM_CREATE_VM ioctl specify the desired style David Daney Hi Paolo, just wanted to add to David's comments. KVM/MIPS currently supports the two modes David mentioned, based on a kernel config option. KVM_CAP_MIPS_VZ_ASE is used by QEMU to make sure that the kvm module currently loaded supports the H/W virtualization. Its a bit cumbersome on MIPS, because you really can't fall back to trap and emulate, since the guest kernel for trap and emulate has a user mode link address. I am open to other ways of doing this. Regards Sanjay -- 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 06/18] KVM/MIPS32-VZ: VZ-ASE related callbacks to handle guest exceptions that trap to the Root context.
On May 28, 2013, at 8:04 AM, Paolo Bonzini wrote: Il 19/05/2013 07:47, Sanjay Lal ha scritto: +static int kvm_vz_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) +{ +struct mips_coproc *cop0 = vcpu-arch.cop0; + +/* some registers are not restored + * random, count: read-only + * userlocal: not implemented in qemu + * config6 : not implemented in processor variant + * compare, cause : defer to kvm_vz_restore_guest_timer_int + */ + +kvm_write_c0_guest_index(cop0, regs-cp0reg[MIPS_CP0_TLB_INDEX][0]); +kvm_write_c0_guest_entrylo0(cop0, regs-cp0reg[MIPS_CP0_TLB_LO0][0]); +kvm_write_c0_guest_entrylo1(cop0, regs-cp0reg[MIPS_CP0_TLB_LO1][0]); +kvm_write_c0_guest_context(cop0, regs-cp0reg[MIPS_CP0_TLB_CONTEXT][0]); +kvm_write_c0_guest_pagemask(cop0, +regs-cp0reg[MIPS_CP0_TLB_PG_MASK][0]); +kvm_write_c0_guest_pagegrain(cop0, + regs-cp0reg[MIPS_CP0_TLB_PG_MASK][1]); +kvm_write_c0_guest_wired(cop0, regs-cp0reg[MIPS_CP0_TLB_WIRED][0]); +kvm_write_c0_guest_hwrena(cop0, regs-cp0reg[MIPS_CP0_HWRENA][0]); +kvm_write_c0_guest_badvaddr(cop0, regs-cp0reg[MIPS_CP0_BAD_VADDR][0]); +/* skip kvm_write_c0_guest_count */ +kvm_write_c0_guest_entryhi(cop0, regs-cp0reg[MIPS_CP0_TLB_HI][0]); +/* defer kvm_write_c0_guest_compare */ +kvm_write_c0_guest_status(cop0, regs-cp0reg[MIPS_CP0_STATUS][0]); +kvm_write_c0_guest_intctl(cop0, regs-cp0reg[MIPS_CP0_STATUS][1]); +/* defer kvm_write_c0_guest_cause */ +kvm_write_c0_guest_epc(cop0, regs-cp0reg[MIPS_CP0_EXC_PC][0]); +kvm_write_c0_guest_prid(cop0, regs-cp0reg[MIPS_CP0_PRID][0]); +kvm_write_c0_guest_ebase(cop0, regs-cp0reg[MIPS_CP0_PRID][1]); + +/* only restore implemented config registers */ +kvm_write_c0_guest_config(cop0, regs-cp0reg[MIPS_CP0_CONFIG][0]); + +if ((regs-cp0reg[MIPS_CP0_CONFIG][0] MIPS_CONF_M) +cpu_vz_has_config1) +kvm_write_c0_guest_config1(cop0, +regs-cp0reg[MIPS_CP0_CONFIG][1]); + +if ((regs-cp0reg[MIPS_CP0_CONFIG][1] MIPS_CONF_M) +cpu_vz_has_config2) +kvm_write_c0_guest_config2(cop0, +regs-cp0reg[MIPS_CP0_CONFIG][2]); + +if ((regs-cp0reg[MIPS_CP0_CONFIG][2] MIPS_CONF_M) +cpu_vz_has_config3) +kvm_write_c0_guest_config3(cop0, +regs-cp0reg[MIPS_CP0_CONFIG][3]); + +if ((regs-cp0reg[MIPS_CP0_CONFIG][3] MIPS_CONF_M) +cpu_vz_has_config4) +kvm_write_c0_guest_config4(cop0, +regs-cp0reg[MIPS_CP0_CONFIG][4]); + +if ((regs-cp0reg[MIPS_CP0_CONFIG][4] MIPS_CONF_M) +cpu_vz_has_config5) +kvm_write_c0_guest_config5(cop0, +regs-cp0reg[MIPS_CP0_CONFIG][5]); + +if (cpu_vz_has_config6) +kvm_write_c0_guest_config6(cop0, +regs-cp0reg[MIPS_CP0_CONFIG][6]); +if (cpu_vz_has_config7) +kvm_write_c0_guest_config7(cop0, +regs-cp0reg[MIPS_CP0_CONFIG][7]); + +kvm_write_c0_guest_errorepc(cop0, regs-cp0reg[MIPS_CP0_ERROR_PC][0]); + +/* call after setting MIPS_CP0_CAUSE to avoid having it overwritten + * this will set guest compare and cause.TI if necessary + */ +kvm_vz_restore_guest_timer_int(vcpu, regs); + +return 0; +} All this is now obsolete after David's patches (reusing kvm_regs looked a bit strange in fact). Paolo These patched were against 3.10-rc2, now that David's patches have been accepted, I'll migrate to the new ABI for v2 of the patch set. Regards Sanjay -- 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 06/18] KVM/MIPS32-VZ: VZ-ASE related callbacks to handle guest exceptions that trap to the Root context.
On May 28, 2013, at 9:14 AM, Paolo Bonzini wrote: Il 19/05/2013 07:47, Sanjay Lal ha scritto: +#endif +local_irq_save(flags); +if (kvm_mips_handle_vz_root_tlb_fault(badvaddr, vcpu) 0) { +run-exit_reason = KVM_EXIT_INTERNAL_ERROR; +er = EMULATE_FAIL; +} +local_irq_restore(flags); +} This is introduced much later. Please make sure that, with CONFIG_KVM_MIPS_VZ, every patch builds. Paolo Again, I think this has to do with the fact that the patches were against 3.10-rc2, will rebase for v2. Regards Sanjay -- 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 06/18] KVM/MIPS32-VZ: VZ-ASE related callbacks to handle guest exceptions that trap to the Root context.
On May 30, 2013, at 1:11 PM, Paolo Bonzini wrote: Il 30/05/2013 20:35, Sanjay Lal ha scritto: +#endif +local_irq_save(flags); +if (kvm_mips_handle_vz_root_tlb_fault(badvaddr, vcpu) 0) { +run-exit_reason = KVM_EXIT_INTERNAL_ERROR; +er = EMULATE_FAIL; +} +local_irq_restore(flags); +} This is introduced much later. Please make sure that, with CONFIG_KVM_MIPS_VZ, every patch builds. Paolo Again, I think this has to do with the fact that the patches were against 3.10-rc2, will rebase for v2. No, this is a simple patch ordering problem. kvm_mips_handle_vz_root_tlb_fault is added in patch 11 only. Paolo Ah I see what you mean. Will fix the ordering in v2. Thanks Sanjay -- 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 v4 0/6] mips/kvm: Fix ABI for compatibility with 64-bit guests.
On May 22, 2013, at 5:54 AM, Gleb Natapov wrote: On Tue, May 21, 2013 at 01:54:49PM -0700, David Daney wrote: From: David Daney david.da...@cavium.com The initial patch set implementing MIPS KVM does not handle 64-bit guests or use of the FPU. This patch set corrects these ABI issues, and does some very minor clean up. Sanjay, is this looks good to you. What userspace MIPS is using for machine emulation? Is there corresponding patches to the userspace? Gleb, I'll post some comments on the patches later in the day. We use QEMu for the machine emulation. I am in the process of integrating with the new ABI, and will post the QEMU patches shortly. Regards Sanjay -- 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 v4 5/6] mips/kvm: Fix ABI by moving manipulation of CP0 registers to KVM_{G,S}ET_ONE_REG
On May 21, 2013, at 1:54 PM, David Daney wrote: From: David Daney david.da...@cavium.com Because not all 256 CP0 registers are ever implemented, we need a different method of manipulating them. Use the KVM_SET_ONE_REG/KVM_GET_ONE_REG mechanism. Code related to implementing KVM_SET_ONE_REG/KVM_GET_ONE_REG is consolidated in to kvm_trap_emul.c, now unused code and definitions are removed. Signed-off-by: David Daney david.da...@cavium.com --- arch/mips/include/asm/kvm.h | 91 +-- arch/mips/include/asm/kvm_host.h | 4 - arch/mips/kvm/kvm_mips.c | 90 +-- arch/mips/kvm/kvm_trap_emul.c| 338 ++- 4 files changed, 383 insertions(+), 140 deletions(-) diff --git a/arch/mips/include/asm/kvm.h b/arch/mips/include/asm/kvm.h index d145ead..3f424f5 100644 --- a/arch/mips/include/asm/kvm.h +++ b/arch/mips/include/asm/kvm.h @@ -13,10 +13,11 @@ #include linux/types.h -#define __KVM_MIPS - -#define N_MIPS_COPROC_REGS 32 -#define N_MIPS_COPROC_SEL8 +/* + * KVM MIPS specific structures and definitions. + * + * Some parts derived from the x86 version of this file. + */ /* * for KVM_GET_REGS and KVM_SET_REGS @@ -31,12 +32,6 @@ struct kvm_regs { __u64 hi; __u64 lo; __u64 pc; - - __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; -}; - -/* for KVM_GET_SREGS and KVM_SET_SREGS */ -struct kvm_sregs { }; /* @@ -55,21 +50,89 @@ struct kvm_fpu { __u32 pad; }; + +/* + * For MIPS, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access CP0 + * 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[63..16] - 1 - CP0 registers. + * + * Other sets registers may be added in the future. Each set would + * have its own identifier in bits[63..16]. + * + * The addr field of struct kvm_one_reg must point to an aligned + * 64-bit wide location. For registers that are narrower than + * 64-bits, the value is stored in the low order bits of the location, + * and sign extended to 64-bits. + * + * The registers defined in struct kvm_regs are also accessible, the + * id values for these are below. + */ + +#define KVM_REG_MIPS_R0 0 +#define KVM_REG_MIPS_R1 1 +#define KVM_REG_MIPS_R2 2 +#define KVM_REG_MIPS_R3 3 +#define KVM_REG_MIPS_R4 4 +#define KVM_REG_MIPS_R5 5 +#define KVM_REG_MIPS_R6 6 +#define KVM_REG_MIPS_R7 7 +#define KVM_REG_MIPS_R8 8 +#define KVM_REG_MIPS_R9 9 +#define KVM_REG_MIPS_R10 10 +#define KVM_REG_MIPS_R11 11 +#define KVM_REG_MIPS_R12 12 +#define KVM_REG_MIPS_R13 13 +#define KVM_REG_MIPS_R14 14 +#define KVM_REG_MIPS_R15 15 +#define KVM_REG_MIPS_R16 16 +#define KVM_REG_MIPS_R17 17 +#define KVM_REG_MIPS_R18 18 +#define KVM_REG_MIPS_R19 19 +#define KVM_REG_MIPS_R20 20 +#define KVM_REG_MIPS_R21 21 +#define KVM_REG_MIPS_R22 22 +#define KVM_REG_MIPS_R23 23 +#define KVM_REG_MIPS_R24 24 +#define KVM_REG_MIPS_R25 25 +#define KVM_REG_MIPS_R26 26 +#define KVM_REG_MIPS_R27 27 +#define KVM_REG_MIPS_R28 28 +#define KVM_REG_MIPS_R29 29 +#define KVM_REG_MIPS_R30 30 +#define KVM_REG_MIPS_R31 31 + +#define KVM_REG_MIPS_HI 32 +#define KVM_REG_MIPS_LO 33 +#define KVM_REG_MIPS_PC 34 + +/* + * KVM MIPS specific structures and definitions + * + */ struct kvm_debug_exit_arch { + __u64 epc; }; /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { }; +/* definition of registers in kvm_run */ +struct kvm_sync_regs { +}; + +/* dummy definition */ +struct kvm_sregs { +}; + struct kvm_mips_interrupt { /* in */ __u32 cpu; __u32 irq; }; -/* definition of registers in kvm_run */ -struct kvm_sync_regs { -}; - #endif /* __LINUX_KVM_MIPS_H */ diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 143875c..4d6fa0b 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -496,10 +496,6 @@ struct kvm_mips_callbacks { uint32_t cause); int (*irq_clear) (struct kvm_vcpu *vcpu, unsigned int priority, uint32_t cause); - int (*vcpu_ioctl_get_regs) (struct kvm_vcpu *vcpu, - struct kvm_regs *regs); - int (*vcpu_ioctl_set_regs) (struct kvm_vcpu *vcpu, - struct kvm_regs *regs); }; 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/kvm_mips.c b/arch/mips/kvm/kvm_mips.c index 71a1fc1..bc879bd 100644 --- a/arch/mips/kvm/kvm_mips.c +++ b/arch/mips/kvm/kvm_mips.c @@ -51,16 +51,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { {NULL} }; -static int kvm_mips_reset_vcpu(struct kvm_vcpu *vcpu) -{ - int i; - for_each_possible_cpu(i) {
Re: [PATCH v5 0/6] mips/kvm: Fix ABI for compatibility with 64-bit guests.
On May 22, 2013, at 11:43 AM, David Daney wrote: From: David Daney david.da...@cavium.com The initial patch set implementing MIPS KVM does not handle 64-bit guests or use of the FPU. This patch set corrects these ABI issues, and does some very minor clean up. Changes from v4: No code change, just keep more of the code in kvm_mips.c rather than kvm_trap_emul.c Changes from v3: Use KVM_SET_ONE_REG instead of KVM_SET_MSRS. Added ENOIOCTLCMD patch. Changes from v2: Split into five parts, no code change. David Daney (6): mips/kvm: Fix ABI for use of FPU. mips/kvm: Fix ABI for use of 64-bit registers. mips/kvm: Fix name of gpr field in struct kvm_regs. mips/kvm: Use ARRAY_SIZE() instead of hardcoded constants in kvm_arch_vcpu_ioctl_{s,g}et_regs mips/kvm: Fix ABI by moving manipulation of CP0 registers to KVM_{G,S}ET_ONE_REG mips/kvm: Use ENOIOCTLCMD to indicate unimplemented ioctls. arch/mips/include/asm/kvm.h | 137 +++ arch/mips/include/asm/kvm_host.h | 4 - arch/mips/kvm/kvm_mips.c | 278 --- arch/mips/kvm/kvm_trap_emul.c| 50 --- 4 files changed, 367 insertions(+), 102 deletions(-) -- 1.7.11.7 Acked-by: Sanjay Lal sanj...@kymasys.com Regards Sanjay -- 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 2/4] KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock()
On May 21, 2013, at 1:00 AM, Gleb Natapov wrote: On Sun, May 19, 2013 at 10:36:32AM -0400, Sanjay Lal wrote: On May 19, 2013, at 8:52 AM, Gleb Natapov wrote: On Sat, May 18, 2013 at 06:54:24AM -0700, Sanjay Lal wrote: - As suggested by Gleb, wrap calls to gfn_to_pfn() with srcu_read_lock/unlock(). Memory slots should be acccessed from a SRCU read section. - kvm_mips_map_page() now returns an error code to it's callers, instead of calling panic() if it cannot find a mapping for a particular gfn. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_tlb.c | 36 +++- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c index 89511a9..ab2e9b0 100644 --- a/arch/mips/kvm/kvm_tlb.c +++ b/arch/mips/kvm/kvm_tlb.c @@ -16,7 +16,10 @@ #include linux/mm.h #include linux/delay.h #include linux/module.h +#include linux/bootmem.h You haven't answered it when I asked it on v2: Is this include still needed now when export of min_low_pfn is not longer here? Sorry about that, juggling too many patches, bootmem.h is no longer needed in kvm_tlb.c. Actually, I thought I had removed it before posting v3. Should I expect new version, or can I just drop this include from the patch and apply? Please drop the include. Regards Sanjay -- 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/18] KVM/MIPS32: Support for the new Virtualization ASE (VZ-ASE)
On May 20, 2013, at 8:50 AM, David Daney wrote: On 05/18/2013 10:47 PM, Sanjay Lal wrote: The following patch set adds support for the recently announced virtualization extensions for the MIPS32 architecture and allows running unmodified kernels in Guest Mode. For more info please refer to : MIPS Document #: MD00846 Volume IV-i: Virtualization Module of the MIPS32 Architecture which can be accessed @: http://www.mips.com/auth/MD00846-2B-VZMIPS32-AFP-01.03.pdf The patch is agains Linux-3.10-rc1. KVM/MIPS now supports 2 modes of operation: (1) VZ mode: Unmodified kernels running in Guest Mode. The processor now provides an almost complete COP0 context in Guest mode. This greatly reduces VM exits. Two questions: 1) How are you handling not clobbering the Guest K0/K1 registers when a Root exception occurs? It is not obvious to me from inspecting the code. 2) What environment are you using to test this stuff? David Daney (1) Newer versions of the MIPS architecture define scratch registers for just this purpose, but since we have to support standard MIPS32R2 processors, we use the DDataLo Register (CP0 Register 28, Select 3) as a scratch register to save k0 and save k1 @ a known offset from EBASE. (2) Platforms that we've tested on: KVM Trap Emulate - Malta Board with FPGA based 34K - Sigma Designs TangoX board with a 24K based 8654 SoC. - Malta Board with 74K @ 1GHz - QEMU (as of 1.4.90) - Imperas M*SDK MIPS32 simulator KVM MIPS/VZ - Imperas M*SDK MIPS32 simulator + MIPS/VZ model. Regards Sanjay -- 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/18] KVM/MIPS32: Support for the new Virtualization ASE (VZ-ASE)
On May 20, 2013, at 10:29 AM, David Daney wrote: On 05/20/2013 09:58 AM, Sanjay Lal wrote: On May 20, 2013, at 8:50 AM, David Daney wrote: On 05/18/2013 10:47 PM, Sanjay Lal wrote: The following patch set adds support for the recently announced virtualization extensions for the MIPS32 architecture and allows running unmodified kernels in Guest Mode. For more info please refer to : MIPS Document #: MD00846 Volume IV-i: Virtualization Module of the MIPS32 Architecture which can be accessed @: http://www.mips.com/auth/MD00846-2B-VZMIPS32-AFP-01.03.pdf The patch is agains Linux-3.10-rc1. KVM/MIPS now supports 2 modes of operation: (1) VZ mode: Unmodified kernels running in Guest Mode. The processor now provides an almost complete COP0 context in Guest mode. This greatly reduces VM exits. Two questions: 1) How are you handling not clobbering the Guest K0/K1 registers when a Root exception occurs? It is not obvious to me from inspecting the code. 2) What environment are you using to test this stuff? David Daney (1) Newer versions of the MIPS architecture define scratch registers for just this purpose, but since we have to support standard MIPS32R2 processors, we use the DDataLo Register (CP0 Register 28, Select 3) as a scratch register to save k0 and save k1 @ a known offset from EBASE. Right, I understand that. But I am looking at arch/mips/mm/tlbex.c, and I don't see the code that does that for TLBRefill exceptions. Where is it done for interrupts? I would expect code in arch/mips/kernel/genex.S and/or stackframe.h would handle this. But I don't see where it is. Am I missing something? David Daney arch/mips/kvm/kvm_locore.S -- 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 2/4] KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock()
On May 19, 2013, at 8:52 AM, Gleb Natapov wrote: On Sat, May 18, 2013 at 06:54:24AM -0700, Sanjay Lal wrote: - As suggested by Gleb, wrap calls to gfn_to_pfn() with srcu_read_lock/unlock(). Memory slots should be acccessed from a SRCU read section. - kvm_mips_map_page() now returns an error code to it's callers, instead of calling panic() if it cannot find a mapping for a particular gfn. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_tlb.c | 36 +++- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c index 89511a9..ab2e9b0 100644 --- a/arch/mips/kvm/kvm_tlb.c +++ b/arch/mips/kvm/kvm_tlb.c @@ -16,7 +16,10 @@ #include linux/mm.h #include linux/delay.h #include linux/module.h +#include linux/bootmem.h You haven't answered it when I asked it on v2: Is this include still needed now when export of min_low_pfn is not longer here? Sorry about that, juggling too many patches, bootmem.h is no longer needed in kvm_tlb.c. Actually, I thought I had removed it before posting v3. Regards Sanjay -- 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 v3 0/4] KVM/MIPS32: Fixes for Linux 3.10
The following patch set fixes a few issues with KVM/MIPS32 in Linux 3.10. Changes from v2: - Drop KVM-MIPS32-Fix-up-KVM-breakage-caused-by-d532f3d2671 as the offending commit has been reverted and will be submitted upstream via the linux-mips tree. - Integrate with the new 64 bit compatible KVM/MIPS ABI defined by David Daney @ Cavium. -- Sanjay Lal (4): KVM/MIPS32: Move include/asm/kvm.h = include/uapi/asm/kvm.h since it is a user visible API. KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock() KVM/MIPS32: Export min_low_pfn. KVM/MIPS32: Bring in patch from David Daney with new 64 bit compatible ABI. arch/mips/include/asm/kvm.h | 55 --- arch/mips/include/asm/kvm_host.h | 9 +- arch/mips/include/uapi/asm/kvm.h | 113 ++ arch/mips/kernel/mips_ksyms.c| 6 + arch/mips/kvm/kvm_mips.c | 102 +--- arch/mips/kvm/kvm_mips_emul.c| 22 +-- arch/mips/kvm/kvm_tlb.c | 55 --- arch/mips/kvm/kvm_trap_emul.c| 330 ++- 8 files changed, 471 insertions(+), 221 deletions(-) delete mode 100644 arch/mips/include/asm/kvm.h create mode 100644 arch/mips/include/uapi/asm/kvm.h -- 1.7.11.3 -- 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/4] KVM/MIPS32: Move include/asm/kvm.h = include/uapi/asm/kvm.h since it is a user visible API.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/kvm.h | 55 arch/mips/include/uapi/asm/kvm.h | 55 2 files changed, 55 insertions(+), 55 deletions(-) delete mode 100644 arch/mips/include/asm/kvm.h create mode 100644 arch/mips/include/uapi/asm/kvm.h diff --git a/arch/mips/include/asm/kvm.h b/arch/mips/include/asm/kvm.h deleted file mode 100644 index 85789ea..000 --- a/arch/mips/include/asm/kvm.h +++ /dev/null @@ -1,55 +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 sanj...@kymasys.com -*/ - -#ifndef __LINUX_KVM_MIPS_H -#define __LINUX_KVM_MIPS_H - -#include linux/types.h - -#define __KVM_MIPS - -#define N_MIPS_COPROC_REGS 32 -#define N_MIPS_COPROC_SEL 8 - -/* for KVM_GET_REGS and KVM_SET_REGS */ -struct kvm_regs { - __u32 gprs[32]; - __u32 hi; - __u32 lo; - __u32 pc; - - __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; -}; - -/* for KVM_GET_SREGS and KVM_SET_SREGS */ -struct kvm_sregs { -}; - -/* for KVM_GET_FPU and KVM_SET_FPU */ -struct kvm_fpu { -}; - -struct kvm_debug_exit_arch { -}; - -/* for KVM_SET_GUEST_DEBUG */ -struct kvm_guest_debug_arch { -}; - -struct kvm_mips_interrupt { - /* in */ - __u32 cpu; - __u32 irq; -}; - -/* definition of registers in kvm_run */ -struct kvm_sync_regs { -}; - -#endif /* __LINUX_KVM_MIPS_H */ diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h new file mode 100644 index 000..85789ea --- /dev/null +++ b/arch/mips/include/uapi/asm/kvm.h @@ -0,0 +1,55 @@ +/* +* 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 sanj...@kymasys.com +*/ + +#ifndef __LINUX_KVM_MIPS_H +#define __LINUX_KVM_MIPS_H + +#include linux/types.h + +#define __KVM_MIPS + +#define N_MIPS_COPROC_REGS 32 +#define N_MIPS_COPROC_SEL 8 + +/* for KVM_GET_REGS and KVM_SET_REGS */ +struct kvm_regs { + __u32 gprs[32]; + __u32 hi; + __u32 lo; + __u32 pc; + + __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; +}; + +/* for KVM_GET_SREGS and KVM_SET_SREGS */ +struct kvm_sregs { +}; + +/* for KVM_GET_FPU and KVM_SET_FPU */ +struct kvm_fpu { +}; + +struct kvm_debug_exit_arch { +}; + +/* for KVM_SET_GUEST_DEBUG */ +struct kvm_guest_debug_arch { +}; + +struct kvm_mips_interrupt { + /* in */ + __u32 cpu; + __u32 irq; +}; + +/* definition of registers in kvm_run */ +struct kvm_sync_regs { +}; + +#endif /* __LINUX_KVM_MIPS_H */ -- 1.7.11.3 -- 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/4] KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock()
- As suggested by Gleb, wrap calls to gfn_to_pfn() with srcu_read_lock/unlock(). Memory slots should be acccessed from a SRCU read section. - kvm_mips_map_page() now returns an error code to it's callers, instead of calling panic() if it cannot find a mapping for a particular gfn. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_tlb.c | 36 +++- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c index 89511a9..ab2e9b0 100644 --- a/arch/mips/kvm/kvm_tlb.c +++ b/arch/mips/kvm/kvm_tlb.c @@ -16,7 +16,10 @@ #include linux/mm.h #include linux/delay.h #include linux/module.h +#include linux/bootmem.h #include linux/kvm_host.h +#include linux/srcu.h + #include asm/cpu.h #include asm/bootinfo.h @@ -169,21 +172,27 @@ void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu) } } -static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) +static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) { + int srcu_idx, err = 0; pfn_t pfn; if (kvm-arch.guest_pmap[gfn] != KVM_INVALID_PAGE) - return; + return 0; +srcu_idx = srcu_read_lock(kvm-srcu); pfn = kvm_mips_gfn_to_pfn(kvm, gfn); if (kvm_mips_is_error_pfn(pfn)) { - panic(Couldn't get pfn for gfn %# PRIx64 !\n, gfn); + kvm_err(Couldn't get pfn for gfn %# PRIx64 !\n, gfn); + err = -EFAULT; + goto out; } kvm-arch.guest_pmap[gfn] = pfn; - return; +out: + srcu_read_unlock(kvm-srcu, srcu_idx); + return err; } /* Translate guest KSEG0 addresses to Host PA */ @@ -207,7 +216,10 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu, gva); return KVM_INVALID_PAGE; } - kvm_mips_map_page(vcpu-kvm, gfn); + + if (kvm_mips_map_page(vcpu-kvm, gfn) 0) + return KVM_INVALID_ADDR; + return (kvm-arch.guest_pmap[gfn] PAGE_SHIFT) + offset; } @@ -310,8 +322,11 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr, even = !(gfn 0x1); vaddr = badvaddr (PAGE_MASK 1); - kvm_mips_map_page(vcpu-kvm, gfn); - kvm_mips_map_page(vcpu-kvm, gfn ^ 0x1); + if (kvm_mips_map_page(vcpu-kvm, gfn) 0) + return -1; + + if (kvm_mips_map_page(vcpu-kvm, gfn ^ 0x1) 0) + return -1; if (even) { pfn0 = kvm-arch.guest_pmap[gfn]; @@ -389,8 +404,11 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, pfn0 = 0; pfn1 = 0; } else { - kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo0) PAGE_SHIFT); - kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo1) PAGE_SHIFT); + if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo0) PAGE_SHIFT) 0) + return -1; + + if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo1) PAGE_SHIFT) 0) + return -1; pfn0 = kvm-arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb-tlb_lo0) PAGE_SHIFT]; pfn1 = kvm-arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb-tlb_lo1) PAGE_SHIFT]; -- 1.7.11.3 -- 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/4] KVM/MIPS32: Export min_low_pfn.
The KVM module uses the standard MIPS cache management routines, which use min_low_pfn. This creates and indirect dependency, requiring min_low_pfn to be exported. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kernel/mips_ksyms.c | 6 ++ arch/mips/kvm/kvm_tlb.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 6e58e97..0299472 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c @@ -14,6 +14,7 @@ #include linux/mm.h #include asm/uaccess.h #include asm/ftrace.h +#include linux/bootmem.h extern void *__bzero(void *__s, size_t __count); extern long __strncpy_from_user_nocheck_asm(char *__to, @@ -60,3 +61,8 @@ EXPORT_SYMBOL(invalid_pte_table); /* _mcount is defined in arch/mips/kernel/mcount.S */ EXPORT_SYMBOL(_mcount); #endif + +/* The KVM module uses the standard MIPS cache functions which use + * min_low_pfn, requiring it to be exported. + */ +EXPORT_SYMBOL(min_low_pfn); diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c index ab2e9b0..87d845e 100644 --- a/arch/mips/kvm/kvm_tlb.c +++ b/arch/mips/kvm/kvm_tlb.c @@ -16,7 +16,6 @@ #include linux/mm.h #include linux/delay.h #include linux/module.h -#include linux/bootmem.h #include linux/kvm_host.h #include linux/srcu.h -- 1.7.11.3 -- 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/4] KVM/MIPS32: Bring in patch from David Daney with new 64 bit compatible ABI.
From: David Daney david.da...@cavium.com There are several parts to this: o All registers are 64-bits wide, 32-bit guests use the least significant portion of the register storage fields. o FPU register formats are defined. o CP0 Registers are manipulated via the KVM_GET_MSRS/KVM_SET_MSRS mechanism. The vcpu_ioctl_get_regs and vcpu_ioctl_set_regs function pointers become unused so they were removed. Some IOCTL functions were moved to kvm_trap_emul because the implementations are only for that flavor of KVM host. In the future, if hardware based virtualization is added, they can be hidden behind function pointers as appropriate. Signed-off-by: David Daney david.da...@cavium.com Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/kvm_host.h | 4 - arch/mips/include/uapi/asm/kvm.h | 106 ++--- arch/mips/kvm/kvm_mips.c | 102 +--- arch/mips/kvm/kvm_trap_emul.c| 330 ++- 4 files changed, 382 insertions(+), 160 deletions(-) diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index e68781e..e3d49ec 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -496,10 +496,6 @@ struct kvm_mips_callbacks { uint32_t cause); int (*irq_clear) (struct kvm_vcpu *vcpu, unsigned int priority, uint32_t cause); - int (*vcpu_ioctl_get_regs) (struct kvm_vcpu *vcpu, - struct kvm_regs *regs); - int (*vcpu_ioctl_set_regs) (struct kvm_vcpu *vcpu, - struct kvm_regs *regs); }; extern struct kvm_mips_callbacks *kvm_mips_callbacks; int kvm_mips_emulation_init(struct kvm_mips_callbacks **install_callbacks); diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h index 85789ea..83c44d8 100644 --- a/arch/mips/include/uapi/asm/kvm.h +++ b/arch/mips/include/uapi/asm/kvm.h @@ -1,55 +1,113 @@ /* -* 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 sanj...@kymasys.com -*/ + * 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. + * Copyright (C) 2013 Cavium, Inc. + * Authors: Sanjay Lal sanj...@kymasys.com + */ #ifndef __LINUX_KVM_MIPS_H #define __LINUX_KVM_MIPS_H #include linux/types.h -#define __KVM_MIPS - -#define N_MIPS_COPROC_REGS 32 -#define N_MIPS_COPROC_SEL 8 +/* + * KVM MIPS specific structures and definitions. + * + * Some parts derived from the x86 version of this file. + */ /* for KVM_GET_REGS and KVM_SET_REGS */ +/* + * If Config[AT] is zero (32-bit CPU), the register contents are + * stored in the lower 32-bits of the struct kvm_regs fields and sign + * extended to 64-bits. + */ struct kvm_regs { - __u32 gprs[32]; - __u32 hi; - __u32 lo; - __u32 pc; + /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ + __u64 gpr[32]; + __u64 hi, lo; + __u64 pc; +}; - __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; +/* 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 KVM_GET_SREGS and KVM_SET_SREGS */ -struct kvm_sregs { + +/* + * For MIPS, we use the same APIs as x86, where 'msr' corresponds to a + * CP0 register. The index 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] - 0 - CP0 registers. + * + * Other sets registers may be added in the future. Each set would + * have its own identifier in bits[31..16]. + * + * For MSRs that are narrower than 64-bits, the value is stored in the + * low order bits of the data field, and sign extended to 64-bits. + */ +#define KVM_MIPS_MSR_CP0 0 +struct kvm_msr_entry { + __u32 index; + __u32 reserved; + __u64 data; }; -/* for KVM_GET_FPU and KVM_SET_FPU */ -struct kvm_fpu { +/* for KVM_GET_MSRS and KVM_SET_MSRS */ +struct kvm_msrs { + __u32 nmsrs; /* number of msrs in entries */ + __u32 pad; + + struct kvm_msr_entry entries[0]; }; +/* for KVM_GET_MSR_INDEX_LIST */ +struct kvm_msr_list { + __u32 nmsrs; /* number of msrs in entries */ + __u32 indices[0]; +}; + +/* + * KVM MIPS specific structures and definitions + * + */ struct kvm_debug_exit_arch { + __u64 epc
[PATCH 00/18] KVM/MIPS32: Support for the new Virtualization ASE (VZ-ASE)
The following patch set adds support for the recently announced virtualization extensions for the MIPS32 architecture and allows running unmodified kernels in Guest Mode. For more info please refer to : MIPS Document #: MD00846 Volume IV-i: Virtualization Module of the MIPS32 Architecture which can be accessed @: http://www.mips.com/auth/MD00846-2B-VZMIPS32-AFP-01.03.pdf The patch is agains Linux-3.10-rc1. KVM/MIPS now supports 2 modes of operation: (1) VZ mode: Unmodified kernels running in Guest Mode. The processor now provides an almost complete COP0 context in Guest mode. This greatly reduces VM exits. (2) Trap and Emulate: Runs minimally modified guest kernels in UM and uses binary patching to minimize the number of traps and improve performance. This is used for processors that do not support the VZ-ASE. -- Sanjay Lal (18): Revert MIPS: microMIPS: Support dynamic ASID sizing. Revert MIPS: Allow ASID size to be determined at boot time. KVM/MIPS32: Export min_low_pfn. KVM/MIPS32-VZ: MIPS VZ-ASE related register defines and helper macros. KVM/MIPS32-VZ: VZ-ASE assembler wrapper functions to set GuestIDs KVM/MIPS32-VZ: VZ-ASE related callbacks to handle guest exceptions that trap to the Root context. KVM/MIPS32: VZ-ASE related CPU feature flags and options. KVM/MIPS32-VZ: Entry point for trampolining to the guest and trap handlers. KVM/MIPS32-VZ: Add support for CONFIG_KVM_MIPS_VZ option KVM/MIPS32-VZ: Add API for VZ-ASE Capability KVM/MIPS32-VZ: VZ: Handle Guest TLB faults that are handled in Root context KVM/MIPS32-VZ: VM Exit Stats, add VZ exit reasons. KVM/MIPS32-VZ: Top level handler for Guest faults KVM/MIPS32-VZ: Guest exception batching support. KVM/MIPS32: Add dummy trap handler to catch unexpected exceptions and dump out useful info KVM/MIPS32-VZ: Add VZ-ASE support to KVM/MIPS data structures. KVM/MIPS32: Revert to older method for accessing ASID parameters KVM/MIPS32-VZ: Dump out additional info about VZ features as part of /proc/cpuinfo arch/mips/include/asm/cpu-features.h | 36 ++ arch/mips/include/asm/cpu-info.h | 21 + arch/mips/include/asm/cpu.h |5 + arch/mips/include/asm/kvm_host.h | 244 ++-- arch/mips/include/asm/mipsvzregs.h | 494 +++ arch/mips/include/asm/mmu_context.h | 95 ++- arch/mips/kernel/genex.S |2 +- arch/mips/kernel/mips_ksyms.c|6 + arch/mips/kernel/proc.c | 11 + arch/mips/kernel/smtc.c | 10 +- arch/mips/kernel/traps.c |6 +- arch/mips/kvm/Kconfig| 14 +- arch/mips/kvm/Makefile | 14 +- arch/mips/kvm/kvm_locore.S | 1088 ++ arch/mips/kvm/kvm_mips.c | 73 ++- arch/mips/kvm/kvm_mips_dyntrans.c| 24 +- arch/mips/kvm/kvm_mips_emul.c| 236 arch/mips/kvm/kvm_mips_int.h |5 + arch/mips/kvm/kvm_mips_stats.c | 17 +- arch/mips/kvm/kvm_tlb.c | 444 +++--- arch/mips/kvm/kvm_trap_emul.c| 68 ++- arch/mips/kvm/kvm_vz.c | 786 arch/mips/kvm/kvm_vz_locore.S| 74 +++ arch/mips/lib/dump_tlb.c |5 +- arch/mips/lib/r3k_dump_tlb.c |7 +- arch/mips/mm/tlb-r3k.c | 20 +- arch/mips/mm/tlb-r4k.c |2 +- arch/mips/mm/tlb-r8k.c |2 +- arch/mips/mm/tlbex.c | 82 +-- include/uapi/linux/kvm.h |1 + 30 files changed, 2906 insertions(+), 986 deletions(-) create mode 100644 arch/mips/include/asm/mipsvzregs.h create mode 100644 arch/mips/kvm/kvm_vz.c create mode 100644 arch/mips/kvm/kvm_vz_locore.S -- 1.7.11.3 -- 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/18] Revert MIPS: Allow ASID size to be determined at boot time.
This reverts commit d532f3d26716a39dfd4b88d687bd344fbe77e390. Conflicts: arch/mips/mm/tlbex.c Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/mmu_context.h | 95 ++--- arch/mips/kernel/genex.S| 2 +- arch/mips/kernel/smtc.c | 10 ++-- arch/mips/kernel/traps.c| 6 +-- arch/mips/lib/dump_tlb.c| 5 +- arch/mips/lib/r3k_dump_tlb.c| 7 ++- arch/mips/mm/tlb-r3k.c | 20 arch/mips/mm/tlb-r4k.c | 2 +- arch/mips/mm/tlb-r8k.c | 2 +- arch/mips/mm/tlbex.c| 52 +--- 10 files changed, 62 insertions(+), 139 deletions(-) diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 1554721..8201160 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h @@ -67,68 +67,45 @@ extern unsigned long pgd_current[]; TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) #endif #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) -#define ASID_INC(asid) \ -({ \ - unsigned long __asid = asid;\ - __asm__(1:\taddiu\t%0,1\t\t\t\t# patched\n\t \ - .section\t__asid_inc,\a\\n\t\ - .word\t1b\n\t \ - .previous \ - :=r (__asid) \ - :0 (__asid)); \ - __asid; \ -}) -#define ASID_MASK(asid)\ -({ \ - unsigned long __asid = asid;\ - __asm__(1:\tandi\t%0,%1,0xfc0\t\t\t# patched\n\t \ - .section\t__asid_mask,\a\\n\t \ - .word\t1b\n\t \ - .previous \ - :=r (__asid) \ - :r (__asid)); \ - __asid; \ -}) -#define ASID_VERSION_MASK \ -({ \ - unsigned long __asid; \ - __asm__(1:\taddiu\t%0,$0,0xff00\t\t\t\t# patched\n\t \ - .section\t__asid_version_mask,\a\\n\t \ - .word\t1b\n\t \ - .previous \ - :=r (__asid));\ - __asid; \ -}) -#define ASID_FIRST_VERSION \ -({ \ - unsigned long __asid = asid;\ - __asm__(1:\tli\t%0,0x100\t\t\t\t# patched\n\t \ - .section\t__asid_first_version,\a\\n\t \ - .word\t1b\n\t \ - .previous \ - :=r (__asid));\ - __asid; \ -}) - -#define ASID_FIRST_VERSION_R3000 0x1000 -#define ASID_FIRST_VERSION_R4000 0x100 -#define ASID_FIRST_VERSION_R8000 0x1000 -#define ASID_FIRST_VERSION_RM9000 0x1000 +#define ASID_INC 0x40 +#define ASID_MASK 0xfc0 + +#elif defined(CONFIG_CPU_R8000) + +#define ASID_INC 0x10 +#define ASID_MASK 0xff0 + +#elif defined(CONFIG_MIPS_MT_SMTC) + +#define ASID_INC 0x1 +extern unsigned long smtc_asid_mask; +#define ASID_MASK (smtc_asid_mask) +#define HW_ASID_MASK 0xff +/* End SMTC/34K debug hack */ +#else /* FIXME: not correct for R6000 */ + +#define ASID_INC 0x1 +#define ASID_MASK 0xff -#ifdef CONFIG_MIPS_MT_SMTC -#define SMTC_HW_ASID_MASK 0xff -extern unsigned int smtc_asid_mask; #endif #define cpu_context(cpu, mm) ((mm)-context.asid[cpu]) -#define cpu_asid(cpu, mm) ASID_MASK(cpu_context((cpu), (mm))) +#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) ASID_MASK) #define asid_cache(cpu)(cpu_data[cpu].asid_cache) static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { } +/* + * All unused by hardware upper bits will be considered + * as a software asid extension. + */ +#define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) +#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1
[PATCH 01/18] Revert MIPS: microMIPS: Support dynamic ASID sizing.
This reverts commit f6b06d9361a008afb93b97fb3683a6e92d69d0f4. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/mm/tlbex.c | 34 ++ 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 4d46d37..2ad41e9 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -309,32 +309,13 @@ static int check_for_high_segbits __cpuinitdata; static void __cpuinit insn_fixup(unsigned int **start, unsigned int **stop, unsigned int i_const) { - unsigned int **p; + unsigned int **p, *ip; for (p = start; p stop; p++) { -#ifndef CONFIG_CPU_MICROMIPS - unsigned int *ip; - ip = *p; *ip = (*ip 0x) | i_const; -#else - unsigned short *ip; - - ip = ((unsigned short *)((unsigned int)*p - 1)); - if ((*ip 0xf000) == 0x4000) { - *ip = 0xfff1; - *ip |= (i_const 1); - } else if ((*ip 0xf000) == 0x6000) { - *ip = 0xfff1; - *ip |= ((i_const 2) 1); - } else { - ip++; - *ip = i_const; - } -#endif - local_flush_icache_range((unsigned long)ip, -(unsigned long)ip + sizeof(*ip)); } + local_flush_icache_range((unsigned long)*p, (unsigned long)((*p) + 1)); } #define asid_insn_fixup(section, const) \ @@ -354,14 +335,6 @@ static void __cpuinit setup_asid(unsigned int inc, unsigned int mask, extern asmlinkage void handle_ri_rdhwr_vivt(void); unsigned long *vivt_exc; -#ifdef CONFIG_CPU_MICROMIPS - /* -* Worst case optimised microMIPS addiu instructions support -* only a 3-bit immediate value. -*/ - if(inc 7) - panic(Invalid ASID increment value!); -#endif asid_insn_fixup(__asid_inc, inc); asid_insn_fixup(__asid_mask, mask); asid_insn_fixup(__asid_version_mask, version_mask); @@ -369,9 +342,6 @@ static void __cpuinit setup_asid(unsigned int inc, unsigned int mask, /* Patch up the 'handle_ri_rdhwr_vivt' handler. */ vivt_exc = (unsigned long *) handle_ri_rdhwr_vivt; -#ifdef CONFIG_CPU_MICROMIPS - vivt_exc = (unsigned long *)((unsigned long) vivt_exc - 1); -#endif vivt_exc++; *vivt_exc = (*vivt_exc ~mask) | mask; -- 1.7.11.3 -- 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/18] KVM/MIPS32-VZ: VZ-ASE assembler wrapper functions to set GuestIDs
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_vz_locore.S | 74 +++ 1 file changed, 74 insertions(+) create mode 100644 arch/mips/kvm/kvm_vz_locore.S diff --git a/arch/mips/kvm/kvm_vz_locore.S b/arch/mips/kvm/kvm_vz_locore.S new file mode 100644 index 000..6d037d7 --- /dev/null +++ b/arch/mips/kvm/kvm_vz_locore.S @@ -0,0 +1,74 @@ +/* + * 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. + * + * KVM/MIPS: Assembler support for hardware virtualization extensions + * + * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. + * Authors: Yann Le Du l...@kymasys.com + */ + +#include asm/asm.h +#include asm/asmmacro.h +#include asm/regdef.h +#include asm/mipsregs.h +#include asm/asm-offsets.h +#include asm/mipsvzregs.h + +#define MIPSX(name)mips32_ ## name + +/* + * This routine sets GuestCtl1.RID to GUESTCTL1_VZ_ROOT_GUESTID + * Inputs: none + */ +LEAF(MIPSX(ClearGuestRID)) + .setpush + .setmips32r2 + .setnoreorder + mfc0t0, CP0_GUESTCTL1 + addiu t1, zero, GUESTCTL1_VZ_ROOT_GUESTID + ins t0, t1, GUESTCTL1_RID_SHIFT, GUESTCTL1_RID_WIDTH + mtc0t0, CP0_GUESTCTL1 # Set GuestCtl1.RID = GUESTCTL1_VZ_ROOT_GUESTID + ehb + j ra + nop # BD Slot + .setpop +END(MIPSX(ClearGuestRID)) + + +/* + * This routine sets GuestCtl1.RID to a new value + * Inputs: a0 = new GuestRID value (right aligned) + */ +LEAF(MIPSX(SetGuestRID)) + .setpush + .setmips32r2 + .setnoreorder + mfc0t0, CP0_GUESTCTL1 + ins t0, a0, GUESTCTL1_RID_SHIFT, GUESTCTL1_RID_WIDTH + mtc0t0, CP0_GUESTCTL1 # Set GuestCtl1.RID + ehb + j ra + nop # BD Slot + .setpop +END(MIPSX(SetGuestRID)) + + + /* +* This routine sets GuestCtl1.RID to GuestCtl1.ID +* Inputs: none +*/ +LEAF(MIPSX(SetGuestRIDtoGuestID)) + .setpush + .setmips32r2 + .setnoreorder + mfc0t0, CP0_GUESTCTL1 # Get current GuestID + ext t1, t0, GUESTCTL1_ID_SHIFT, GUESTCTL1_ID_WIDTH + ins t0, t1, GUESTCTL1_RID_SHIFT, GUESTCTL1_RID_WIDTH + mtc0t0, CP0_GUESTCTL1 # Set GuestCtl1.RID = GuestCtl1.ID + ehb + j ra + nop # BD Slot + .setpop +END(MIPSX(SetGuestRIDtoGuestID)) -- 1.7.11.3 -- 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/18] KVM/MIPS32: Export min_low_pfn.
The KVM module uses the standard MIPS cache management routines, which use min_low_pfn. This creates and indirect dependency, requiring min_low_pfn to be exported. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- 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..0299472 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c @@ -14,6 +14,7 @@ #include linux/mm.h #include asm/uaccess.h #include asm/ftrace.h +#include linux/bootmem.h extern void *__bzero(void *__s, size_t __count); extern long __strncpy_from_user_nocheck_asm(char *__to, @@ -60,3 +61,8 @@ EXPORT_SYMBOL(invalid_pte_table); /* _mcount is defined in arch/mips/kernel/mcount.S */ EXPORT_SYMBOL(_mcount); #endif + +/* The KVM module uses the standard MIPS cache functions which use + * min_low_pfn, requiring it to be exported. + */ +EXPORT_SYMBOL(min_low_pfn); -- 1.7.11.3 -- 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/18] KVM/MIPS32-VZ: MIPS VZ-ASE related register defines and helper macros.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/mipsvzregs.h | 494 + 1 file changed, 494 insertions(+) create mode 100644 arch/mips/include/asm/mipsvzregs.h diff --git a/arch/mips/include/asm/mipsvzregs.h b/arch/mips/include/asm/mipsvzregs.h new file mode 100644 index 000..84b94b4 --- /dev/null +++ b/arch/mips/include/asm/mipsvzregs.h @@ -0,0 +1,494 @@ +/* +* 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. +* +* MIPS VZ-ASE related register defines and helper macros +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Yann Le Du l...@kymasys.com +*/ + + +/* + * VZ regs definitions, follows on from mipsregs.h + */ + +#ifndef _ASM_MIPSVZREGS_H +#define _ASM_MIPSVZREGS_H + +#include asm/mipsregs.h +#include asm/war.h + +#ifndef __ASSEMBLY__ + +/* + * C macros + */ + +#define read_c0_guestctl0()__read_32bit_c0_register($12, 6) +#define write_c0_guestctl0(val) __write_32bit_c0_register($12, 6, val) +#define read_c0_guestctl1()__read_32bit_c0_register($10, 4) +#define write_c0_guestctl1(val)__write_32bit_c0_register($10, 4, val) +#define read_c0_guestctl2()__read_32bit_c0_register($10, 5) +#define write_c0_guestctl2(val)__write_32bit_c0_register($10, 5, val) +#define read_c0_gtoffset() __read_32bit_c0_register($12, 7) +#define write_c0_gtoffset(val) __write_32bit_c0_register($12, 7, val) + +__BUILD_SET_C0(guestctl1) +__BUILD_SET_C0(guestctl2) + +#else /* Assembly */ +/* + * Macros for use in assembly language code + */ + +#define CP0_GUESTCTL0 $12,6 +#define CP0_GUESTCTL1 $10,4 +#define CP0_GTOFFSET $12,7 + +#endif + +/* GuestCtl0 fields */ +#define GUESTCTL0_GM_SHIFT 31 +#define GUESTCTL0_GM (_ULCAST_(1) GUESTCTL0_GM_SHIFT) +#define GUESTCTL0_CP0_SHIFT28 +#define GUESTCTL0_CP0 (_ULCAST_(1) GUESTCTL0_CP0_SHIFT) +#define GUESTCTL0_AT_SHIFT 26 +#define GUESTCTL0_AT (_ULCAST_(0x3) GUESTCTL0_AT_SHIFT) +#define GUESTCTL0_AT3 (_ULCAST_(3) GUESTCTL0_AT_SHIFT) +#define GUESTCTL0_AT1 (_ULCAST_(1) GUESTCTL0_AT_SHIFT) +#define GUESTCTL0_GT_SHIFT 25 +#define GUESTCTL0_GT (_ULCAST_(1) GUESTCTL0_GT_SHIFT) +#define GUESTCTL0_CG_SHIFT 24 +#define GUESTCTL0_CG (_ULCAST_(1) GUESTCTL0_CG_SHIFT) +#define GUESTCTL0_CF_SHIFT 23 +#define GUESTCTL0_CF (_ULCAST_(1) GUESTCTL0_CF_SHIFT) +#define GUESTCTL0_G1_SHIFT 22 +#define GUESTCTL0_G1 (_ULCAST_(1) GUESTCTL0_G1_SHIFT) +#define GUESTCTL0_RAD_SHIFT9 +#define GUESTCTL0_RAD (_ULCAST_(1) GUESTCTL0_RAD_SHIFT) +#define GUESTCTL0_DRG_SHIFT8 +#define GUESTCTL0_DRG (_ULCAST_(1) GUESTCTL0_DRG_SHIFT) +#define GUESTCTL0_G2_SHIFT 7 +#define GUESTCTL0_G2 (_ULCAST_(1) GUESTCTL0_G2_SHIFT) + +/* GuestCtl0.GExcCode Hypervisor exception cause code */ +#define GUESTCTL0_GEXC_SHIFT 2 +#define GUESTCTL0_GEXC (_ULCAST_(0x1f) GUESTCTL0_GEXC_SHIFT) +#define GUESTCTL0_GEXC_GPSI0 /* Guest Privileged Sensitive Instruction */ +#define GUESTCTL0_GEXC_GSFC1 /* Guest Software Field Change */ +#define GUESTCTL0_GEXC_HC 2 /* Hypercall */ +#define GUESTCTL0_GEXC_GRR 3 /* Guest Reserved Instruction Redirect */ +#define GUESTCTL0_GEXC_GVA 8 /* Guest Virtual Address available */ +#define GUESTCTL0_GEXC_GHFC9 /* Guest Hardware Field Change */ +#define GUESTCTL0_GEXC_GPA 10 /* Guest Physical Address available */ + +/* GuestCtl1 fields */ +#define GUESTCTL1_ID_SHIFT 0 +#define GUESTCTL1_ID_WIDTH 8 +#define GUESTCTL1_ID (_ULCAST_(0xff) GUESTCTL1_ID_SHIFT) +#define GUESTCTL1_RID_SHIFT16 +#define GUESTCTL1_RID_WIDTH8 +#define GUESTCTL1_RID (_ULCAST_(0xff) GUESTCTL1_RID_SHIFT) + +/* VZ GuestID reserved for root context */ +#define GUESTCTL1_VZ_ROOT_GUESTID 0x00 + +/* entryhi fields */ +#define ENTRYHI_EHINV_SHIFT10 +#define ENTRYHI_EHINV (_ULCAST_(1) ENTRYHI_EHINV_SHIFT) + +#ifndef __ASSEMBLY__ + +#define mfgc0(rd,sel) \ +({ \ +unsigned long __res; \ + \ + __asm__ __volatile__( \ + .setpush\n \ + .setmips32r2\n \ + .setnoat\n \ + # mfgc0 $1, $ #rd , #sel \n \ + .word 0x4060 | (116) | ( #rd 11) | #sel \n \ + move%0, $1 \n
[PATCH 07/18] KVM/MIPS32: VZ-ASE related CPU feature flags and options.
- GuestIDs and Virtual IRQs are optional - New TLBINV instruction is also optional Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/cpu-features.h | 36 arch/mips/include/asm/cpu-info.h | 21 + arch/mips/include/asm/cpu.h | 5 + 3 files changed, 62 insertions(+) diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index e5ec8fc..11c8fb8 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -83,6 +83,17 @@ #ifndef kernel_uses_llsc #define kernel_uses_llsc cpu_has_llsc #endif +#ifdef CONFIG_KVM_MIPS_VZ +#ifndef cpu_has_vzguestid +#define cpu_has_vzguestid (cpu_data[0].options MIPS_CPU_VZGUESTID) +#endif +#ifndef cpu_has_vzvirtirq +#define cpu_has_vzvirtirq (cpu_data[0].options MIPS_CPU_VZVIRTIRQ) +#endif +#ifndef cpu_has_tlbinv +#define cpu_has_tlbinv (cpu_data[0].options MIPS_CPU_TLBINV) +#endif +#endif /* CONFIG_KVM_MIPS_VZ */ #ifndef cpu_has_mips16 #define cpu_has_mips16 (cpu_data[0].ases MIPS_ASE_MIPS16) #endif @@ -198,6 +209,31 @@ #define cpu_has_mipsmt (cpu_data[0].ases MIPS_ASE_MIPSMT) #endif +#ifndef cpu_has_vz +#ifdef CONFIG_KVM_MIPS_VZ +#define cpu_has_vz (cpu_data[0].ases MIPS_ASE_VZ) +#else +#define cpu_has_vz (0) +#endif +#define cpu_vz_config0 (cpu_data[0].vz.config0) +#define cpu_vz_config1 (cpu_data[0].vz.config1) +#define cpu_vz_config2 (cpu_data[0].vz.config2) +#define cpu_vz_config3 (cpu_data[0].vz.config3) +#define cpu_vz_config4 (cpu_data[0].vz.config4) +#define cpu_vz_config5 (cpu_data[0].vz.config5) +#define cpu_vz_config6 (cpu_data[0].vz.config6) +#define cpu_vz_config7 (cpu_data[0].vz.config7) + +#define cpu_vz_has_tlb (cpu_data[0].vz.options MIPS_CPU_TLB) +#define cpu_vz_has_config1 (cpu_data[0].vz.config0 MIPS_CONF_M) +#define cpu_vz_has_config2 (cpu_data[0].vz.config1 MIPS_CONF_M) +#define cpu_vz_has_config3 (cpu_data[0].vz.config2 MIPS_CONF_M) +#define cpu_vz_has_config4 (cpu_data[0].vz.config3 MIPS_CONF_M) +#define cpu_vz_has_config5 (cpu_data[0].vz.config4 MIPS_CONF_M) +#define cpu_vz_has_config6 (0) +#define cpu_vz_has_config7 (1) +#endif + #ifndef cpu_has_userlocal #define cpu_has_userlocal (cpu_data[0].options MIPS_CPU_ULRI) #endif diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index 41401d8..70d104c 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -28,6 +28,24 @@ struct cache_desc { unsigned char flags;/* Flags describing cache properties */ }; +#ifdef CONFIG_KVM_MIPS_VZ +/* + * initial VZ ASE configuration + */ +struct vzase_info { + unsigned long options; + int tlbsize; + unsigned long config0; + unsigned long config1; + unsigned long config2; + unsigned long config3; + unsigned long config4; + unsigned long config5; + unsigned long config6; + unsigned long config7; +}; +#endif + /* * Flag definitions */ @@ -79,6 +97,9 @@ struct cpuinfo_mips { #define NUM_WATCH_REGS 4 u16 watch_reg_masks[NUM_WATCH_REGS]; unsigned intkscratch_mask; /* Usable KScratch mask. */ +#ifdef CONFIG_KVM_MIPS_VZ + struct vzase_info vz; +#endif } __attribute__((aligned(SMP_CACHE_BYTES))); extern struct cpuinfo_mips cpu_data[]; diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index dd86ab2..6836320 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -325,6 +325,11 @@ enum cpu_type_enum { #define MIPS_CPU_PCI 0x0040 /* CPU has Perf Ctr Int indicator */ #define MIPS_CPU_RIXI 0x0080 /* CPU has TLB Read/eXec Inhibit */ #define MIPS_CPU_MICROMIPS 0x0100 /* CPU has microMIPS capability */ +#ifdef CONFIG_KVM_MIPS_VZ +#define MIPS_CPU_VZGUESTID 0x0200 /* CPU uses VZ ASE GuestID feature */ +#define MIPS_CPU_VZVIRTIRQ 0x0400 /* CPU has VZ ASE virtual interrupt feature */ +#define MIPS_CPU_TLBINV0x0800 /* CPU has TLB invalidate instruction */ +#endif /* * CPU ASE encodings -- 1.7.11.3 -- 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/18] KVM/MIPS32-VZ: Top level handler for Guest faults
- Add VZ specific VM Exit reasons to the traces. - Add top level handler for Guest Exit exceptions. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips.c | 73 +++- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c index e0dad02..cad9112 100644 --- a/arch/mips/kvm/kvm_mips.c +++ b/arch/mips/kvm/kvm_mips.c @@ -18,6 +18,9 @@ #include asm/page.h #include asm/cacheflush.h #include asm/mmu_context.h +#ifdef CONFIG_KVM_MIPS_VZ +#include asm/mipsvzregs.h +#endif #include linux/kvm_host.h @@ -47,6 +50,21 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { resvd_inst, VCPU_STAT(resvd_inst_exits) }, { break_inst, VCPU_STAT(break_inst_exits) }, { flush_dcache, VCPU_STAT(flush_dcache_exits) }, +#ifdef CONFIG_KVM_MIPS_VZ + { hypervisor_gpsi, VCPU_STAT(hypervisor_gpsi_exits) }, + { hypervisor_gpsi_cp0, VCPU_STAT(hypervisor_gpsi_cp0_exits) }, + { hypervisor_gpsi_cache, VCPU_STAT(hypervisor_gpsi_cache_exits) }, + { hypervisor_gsfc, VCPU_STAT(hypervisor_gsfc_exits) }, + { hypervisor_gsfc_cp0_status, VCPU_STAT(hypervisor_gsfc_cp0_status_exits) }, + { hypervisor_gsfc_cp0_cause, VCPU_STAT(hypervisor_gsfc_cp0_cause_exits) }, + { hypervisor_gsfc_cp0_intctl, VCPU_STAT(hypervisor_gsfc_cp0_intctl_exits) }, + { hypervisor_hc, VCPU_STAT(hypervisor_hc_exits) }, + { hypervisor_grr, VCPU_STAT(hypervisor_grr_exits) }, + { hypervisor_gva, VCPU_STAT(hypervisor_gva_exits) }, + { hypervisor_ghfc, VCPU_STAT(hypervisor_ghfc_exits) }, + { hypervisor_gpa, VCPU_STAT(hypervisor_gpa_exits) }, + { hypervisor_resv, VCPU_STAT(hypervisor_resv_exits) }, +#endif { halt_wakeup, VCPU_STAT(halt_wakeup) }, {NULL} }; @@ -57,6 +75,9 @@ static int kvm_mips_reset_vcpu(struct kvm_vcpu *vcpu) for_each_possible_cpu(i) { vcpu-arch.guest_kernel_asid[i] = 0; vcpu-arch.guest_user_asid[i] = 0; +#ifdef CONFIG_KVM_MIPS_VZ + vcpu-arch.vzguestid[i] = 0; +#endif } return 0; } @@ -106,7 +127,7 @@ void kvm_arch_check_processor_compat(void *rtn) static void kvm_mips_init_tlbs(struct kvm *kvm) { - unsigned long wired; + ulong wired; /* Add a wired entry to the TLB, it is used to map the commpage to the Guest kernel */ wired = read_c0_wired(); @@ -209,19 +230,19 @@ int kvm_arch_create_memslot(struct kvm_memory_slot *slot, unsigned long npages) } int kvm_arch_prepare_memory_region(struct kvm *kvm, -struct kvm_memory_slot *memslot, -struct kvm_userspace_memory_region *mem, -enum kvm_mr_change change) + struct kvm_memory_slot *memslot, + struct kvm_userspace_memory_region *mem, + enum kvm_mr_change change) { return 0; } void kvm_arch_commit_memory_region(struct kvm *kvm, -struct kvm_userspace_memory_region *mem, -const struct kvm_memory_slot *old, -enum kvm_mr_change change) + struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old, + enum kvm_mr_change change) { - unsigned long npages = 0; + ulong npages = 0; int i, err = 0; kvm_debug(%s: kvm: %p slot: %d, GPA: %llx, size: %llx, QVA: %llx\n, @@ -236,7 +257,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, if (npages) { kvm-arch.guest_pmap_npages = npages; kvm-arch.guest_pmap = - kzalloc(npages * sizeof(unsigned long), GFP_KERNEL); + kzalloc(npages * sizeof(ulong), GFP_KERNEL); if (!kvm-arch.guest_pmap) { kvm_err(Failed to allocate guest PMAP); @@ -345,7 +366,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) mips32_GuestExceptionEnd - mips32_GuestException); /* Invalidate the icache for these ranges */ - mips32_SyncICache((unsigned long) gebase, ALIGN(size, PAGE_SIZE)); + mips32_SyncICache((ulong) gebase, ALIGN(size, PAGE_SIZE)); /* Allocate comm page for guest kernel, a TLB will be reserved for mapping GVA @ 0x8000 to this page */ vcpu-arch.kseg0_commpage = kzalloc(PAGE_SIZE 1, GFP_KERNEL); @@ -376,6 +397,12 @@ out: return ERR_PTR(err); } +int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) +{ + return 0; +} + + void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) { hrtimer_cancel(vcpu-arch.comparecount_timer); @@ -527,7
[PATCH 06/18] KVM/MIPS32-VZ: VZ-ASE related callbacks to handle guest exceptions that trap to the Root context.
The VZ-ASE provices the Guest with its own COP0 context, so the types of exceptions that will trap to the root a lot fewer than in the trap and emulate case. - Root level TLB miss handlers that map GPAs to RPAs. - Guest Exits Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_vz.c | 786 + 1 file changed, 786 insertions(+) create mode 100644 arch/mips/kvm/kvm_vz.c diff --git a/arch/mips/kvm/kvm_vz.c b/arch/mips/kvm/kvm_vz.c new file mode 100644 index 000..e85a497 --- /dev/null +++ b/arch/mips/kvm/kvm_vz.c @@ -0,0 +1,786 @@ +/* +* 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. +* +* KVM/MIPS: Support for hardware virtualization extensions +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Yann Le Du l...@kymasys.com +*/ + +#include linux/errno.h +#include linux/err.h +#include linux/module.h +#include linux/vmalloc.h +#include asm/cacheflush.h +#include asm/mipsvzregs.h +#include asm/inst.h + +#include linux/kvm_host.h + +#include kvm_mips_opcode.h +#include kvm_mips_int.h + +#include trace.h + +static gpa_t kvm_vz_gva_to_gpa_cb(gva_t gva) +{ + /* VZ guest has already converted gva to gpa */ + return gva; +} + +void kvm_vz_queue_irq(struct kvm_vcpu *vcpu, uint32_t priority) +{ + set_bit(priority, vcpu-arch.pending_exceptions); + clear_bit(priority, vcpu-arch.pending_exceptions_clr); +} + +void kvm_vz_dequeue_irq(struct kvm_vcpu *vcpu, uint32_t priority) +{ + clear_bit(priority, vcpu-arch.pending_exceptions); + set_bit(priority, vcpu-arch.pending_exceptions_clr); +} + +void kvm_vz_queue_timer_int_cb(struct kvm_vcpu *vcpu) +{ + /* timer expiry is asynchronous to vcpu execution therefore defer guest +* cp0 accesses */ + kvm_vz_queue_irq(vcpu, MIPS_EXC_INT_TIMER); +} + +void kvm_vz_dequeue_timer_int_cb(struct kvm_vcpu *vcpu) +{ + /* timer expiry is asynchronous to vcpu execution therefore defer guest +* cp0 accesses */ + kvm_vz_dequeue_irq(vcpu, MIPS_EXC_INT_TIMER); +} + +void +kvm_vz_queue_io_int_cb(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq) +{ + int intr = (int)irq-irq; + + /* interrupts are asynchronous to vcpu execution therefore defer guest +* cp0 accesses */ + switch (intr) { + case 2: + kvm_vz_queue_irq(vcpu, MIPS_EXC_INT_IO); + break; + + case 3: + kvm_vz_queue_irq(vcpu, MIPS_EXC_INT_IPI_1); + break; + + case 4: + kvm_vz_queue_irq(vcpu, MIPS_EXC_INT_IPI_2); + break; + + default: + break; + } + +} + +void +kvm_vz_dequeue_io_int_cb(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq) +{ + int intr = (int)irq-irq; + + /* interrupts are asynchronous to vcpu execution therefore defer guest +* cp0 accesses */ + switch (intr) { + case -2: + kvm_vz_dequeue_irq(vcpu, MIPS_EXC_INT_IO); + break; + + case -3: + kvm_vz_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_1); + break; + + case -4: + kvm_vz_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_2); + break; + + default: + break; + } + +} + +static uint32_t kvm_vz_priority_to_irq[MIPS_EXC_MAX] = { + [MIPS_EXC_INT_TIMER] = C_TI, + [MIPS_EXC_INT_IO]= C_IRQ0, + [MIPS_EXC_INT_IPI_1] = C_IRQ1, + [MIPS_EXC_INT_IPI_2] = C_IRQ2, +}; + +static int +kvm_vz_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority, + uint32_t cause) +{ + uint32_t irq = (priority MIPS_EXC_MAX) ? + kvm_vz_priority_to_irq[priority] : 0; + + switch (priority) { + case MIPS_EXC_INT_TIMER: + kvm_set_c0_guest_cause(vcpu-arch.cop0, irq); + break; + + case MIPS_EXC_INT_IO: + case MIPS_EXC_INT_IPI_1: + case MIPS_EXC_INT_IPI_2: + if (cpu_has_vzvirtirq) + set_c0_guestctl2(irq); + else + kvm_set_c0_guest_cause(vcpu-arch.cop0, irq); + break; + + default: + break; + } + + clear_bit(priority, vcpu-arch.pending_exceptions); + return 1; +} + +static int +kvm_vz_irq_clear_cb(struct kvm_vcpu *vcpu, unsigned int priority, + uint32_t cause) +{ + uint32_t irq = (priority MIPS_EXC_MAX) ? + kvm_vz_priority_to_irq[priority] : 0; + + switch (priority) { + case MIPS_EXC_INT_TIMER: + /* Call to kvm_write_c0_guest_compare clears Cause.TI in +* kvm_mips_emulate_CP0. Explicitly clear irq associated with +* Cause.IP[IPTI] if GuestCtl2 virtual interrupt register
[PATCH 08/18] KVM/MIPS32-VZ: Entry point for trampolining to the guest and trap handlers.
- Add support for the MIPS VZ-ASE - Whitespace fixes Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_locore.S | 1088 +++- 1 file changed, 573 insertions(+), 515 deletions(-) diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S index dca2aa6..936171f 100644 --- a/arch/mips/kvm/kvm_locore.S +++ b/arch/mips/kvm/kvm_locore.S @@ -1,13 +1,13 @@ /* -* 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. -* -* Main entry point for the guest, exception handling. -* -* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. -* Authors: Sanjay Lal sanj...@kymasys.com -*/ + * 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. + * + * Main entry point for the guest, exception handling. + * + * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. + * Authors: Sanjay Lal sanj...@kymasys.com + */ #include asm/asm.h #include asm/asmmacro.h @@ -16,39 +16,40 @@ #include asm/stackframe.h #include asm/asm-offsets.h +#ifdef CONFIG_KVM_MIPS_VZ +#include asm/mipsvzregs.h +#endif -#define _C_LABEL(x) x -#define MIPSX(name) mips32_ ## name -#define CALLFRAME_SIZ 32 +#define _C_LABEL(x)x +#define MIPSX(name)mips32_ ## name +#define CALLFRAME_SIZ 32 /* * VECTOR * exception vector entrypoint */ -#define VECTOR(x, regmask) \ -.ent_C_LABEL(x),0; \ -EXPORT(x); +#define VECTOR(x, regmask) \ + .ent_C_LABEL(x),0; \ + EXPORT(x); -#define VECTOR_END(x) \ -EXPORT(x); +#define VECTOR_END(x) \ + EXPORT(x); /* Overload, Danger Will Robinson!! */ -#define PT_HOST_ASIDPT_BVADDR -#define PT_HOST_USERLOCAL PT_EPC +#define PT_HOST_USERLOCAL PT_EPC -#define CP0_DDATA_LO$28,3 -#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 +#define CP0_DDATA_LO $28,3 +#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(11) /* Resume host? */ +#define RESUME_FLAG_HOST (11) /* Resume host? */ -#define RESUME_GUEST0 -#define RESUME_HOST RESUME_FLAG_HOST +#define RESUME_GUEST 0 +#define RESUME_HOSTRESUME_FLAG_HOST /* * __kvm_mips_vcpu_run: entry point to the guest @@ -57,172 +58,188 @@ */ FEXPORT(__kvm_mips_vcpu_run) -.setpush -.setnoreorder -.setnoat - -/* k0/k1 not being used in host kernel context */ - addiu k1,sp, -PT_SIZE -LONG_S $0, PT_R0(k1) -LONG_S $1, PT_R1(k1) -LONG_S $2, PT_R2(k1) -LONG_S $3, PT_R3(k1) - -LONG_S $4, PT_R4(k1) -LONG_S $5, PT_R5(k1) -LONG_S $6, PT_R6(k1) -LONG_S $7, PT_R7(k1) - -LONG_S $8, PT_R8(k1) -LONG_S $9, PT_R9(k1) -LONG_S $10, PT_R10(k1) -LONG_S $11, PT_R11(k1) -LONG_S $12, PT_R12(k1) -LONG_S $13, PT_R13(k1) -LONG_S $14, PT_R14(k1) -LONG_S $15, PT_R15(k1) -LONG_S $16, PT_R16(k1) -LONG_S $17, PT_R17(k1) - -LONG_S $18, PT_R18(k1) -LONG_S $19, PT_R19(k1) -LONG_S $20, PT_R20(k1) -LONG_S $21, PT_R21(k1) -LONG_S $22, PT_R22(k1) -LONG_S $23, PT_R23(k1) -LONG_S $24, PT_R24(k1) -LONG_S $25, PT_R25(k1) + .setpush + .setnoreorder + .setnoat + + /* k0/k1 not being used in host kernel context */ + addiu k1,sp, -PT_SIZE + LONG_S $0, PT_R0(k1) + LONG_S $1, PT_R1(k1) + LONG_S $2, PT_R2(k1) + LONG_S $3, PT_R3(k1) + LONG_S $4, PT_R4(k1) + LONG_S $5, PT_R5(k1) + LONG_S $6, PT_R6(k1) + LONG_S $7, PT_R7(k1) + LONG_S $8, PT_R8(k1) + LONG_S $9, PT_R9(k1) + LONG_S $10, PT_R10(k1) + LONG_S $11, PT_R11(k1) + LONG_S $12, PT_R12(k1) + LONG_S $13, PT_R13(k1) + LONG_S $14, PT_R14(k1) + LONG_S $15, PT_R15(k1) + LONG_S $16, PT_R16(k1) + LONG_S $17, PT_R17(k1) + LONG_S $18, PT_R18(k1) + LONG_S $19, PT_R19(k1) + LONG_S $20, PT_R20(k1) + LONG_S $21, PT_R21(k1) + LONG_S $22, PT_R22(k1) + LONG_S $23, PT_R23(k1) + LONG_S $24, PT_R24(k1
[PATCH 17/18] KVM/MIPS32: Revert to older method for accessing ASID parameters
- Now that commit d532f3d26 has been reverted in the MIPS tree, revert back to the older method of using the ASID_MASK. - Trivial cleanup: s/unsigned long/long Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips_dyntrans.c | 24 ++-- arch/mips/kvm/kvm_mips_emul.c | 236 ++ 2 files changed, 147 insertions(+), 113 deletions(-) diff --git a/arch/mips/kvm/kvm_mips_dyntrans.c b/arch/mips/kvm/kvm_mips_dyntrans.c index 96528e2..c657b37 100644 --- a/arch/mips/kvm/kvm_mips_dyntrans.c +++ b/arch/mips/kvm/kvm_mips_dyntrans.c @@ -32,13 +32,13 @@ kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu) { int result = 0; - unsigned long kseg0_opc; + ulong kseg0_opc; uint32_t synci_inst = 0x0; /* Replace the CACHE instruction, with a NOP */ kseg0_opc = CKSEG0ADDR(kvm_mips_translate_guest_kseg0_to_hpa - (vcpu, (unsigned long) opc)); + (vcpu, (ulong) opc)); memcpy((void *)kseg0_opc, (void *)synci_inst, sizeof(uint32_t)); mips32_SyncICache(kseg0_opc, 32); @@ -54,7 +54,7 @@ kvm_mips_trans_cache_va(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu) { int result = 0; - unsigned long kseg0_opc; + ulong kseg0_opc; uint32_t synci_inst = SYNCI_TEMPLATE, base, offset; base = (inst 21) 0x1f; @@ -64,7 +64,7 @@ kvm_mips_trans_cache_va(uint32_t inst, uint32_t *opc, kseg0_opc = CKSEG0ADDR(kvm_mips_translate_guest_kseg0_to_hpa - (vcpu, (unsigned long) opc)); + (vcpu, (ulong) opc)); memcpy((void *)kseg0_opc, (void *)synci_inst, sizeof(uint32_t)); mips32_SyncICache(kseg0_opc, 32); @@ -76,7 +76,7 @@ kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu) { int32_t rt, rd, sel; uint32_t mfc0_inst; - unsigned long kseg0_opc, flags; + ulong kseg0_opc, flags; rt = (inst 16) 0x1f; rd = (inst 11) 0x1f; @@ -97,13 +97,13 @@ kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu) if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) { kseg0_opc = CKSEG0ADDR(kvm_mips_translate_guest_kseg0_to_hpa - (vcpu, (unsigned long) opc)); + (vcpu, (ulong) opc)); memcpy((void *)kseg0_opc, (void *)mfc0_inst, sizeof(uint32_t)); mips32_SyncICache(kseg0_opc, 32); - } else if (KVM_GUEST_KSEGX((unsigned long) opc) == KVM_GUEST_KSEG23) { + } else if (KVM_GUEST_KSEGX((ulong) opc) == KVM_GUEST_KSEG23) { local_irq_save(flags); memcpy((void *)opc, (void *)mfc0_inst, sizeof(uint32_t)); - mips32_SyncICache((unsigned long) opc, 32); + mips32_SyncICache((ulong) opc, 32); local_irq_restore(flags); } else { kvm_err(%s: Invalid address: %p\n, __func__, opc); @@ -118,7 +118,7 @@ kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu) { int32_t rt, rd, sel; uint32_t mtc0_inst = SW_TEMPLATE; - unsigned long kseg0_opc, flags; + ulong kseg0_opc, flags; rt = (inst 16) 0x1f; rd = (inst 11) 0x1f; @@ -132,13 +132,13 @@ kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu) if (KVM_GUEST_KSEGX(opc) == KVM_GUEST_KSEG0) { kseg0_opc = CKSEG0ADDR(kvm_mips_translate_guest_kseg0_to_hpa - (vcpu, (unsigned long) opc)); + (vcpu, (ulong) opc)); memcpy((void *)kseg0_opc, (void *)mtc0_inst, sizeof(uint32_t)); mips32_SyncICache(kseg0_opc, 32); - } else if (KVM_GUEST_KSEGX((unsigned long) opc) == KVM_GUEST_KSEG23) { + } else if (KVM_GUEST_KSEGX((ulong) opc) == KVM_GUEST_KSEG23) { local_irq_save(flags); memcpy((void *)opc, (void *)mtc0_inst, sizeof(uint32_t)); - mips32_SyncICache((unsigned long) opc, 32); + mips32_SyncICache((ulong) opc, 32); local_irq_restore(flags); } else { kvm_err(%s: Invalid address: %p\n, __func__, opc); diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c index 2b2bac9..d9fb542 100644 --- a/arch/mips/kvm/kvm_mips_emul.c +++ b/arch/mips/kvm/kvm_mips_emul.c @@ -34,12 +34,13 @@ #include trace.h +static int debug __maybe_unused; + /* * Compute the return address and do emulate branch simulation, if required. * This function should be called only in branch delay slot active. */ -unsigned long kvm_compute_return_epc(struct kvm_vcpu *vcpu, - unsigned long instpc) +u_long kvm_compute_return_epc(struct kvm_vcpu *vcpu, u_long
[PATCH 09/18] KVM/MIPS32-VZ: Add support for CONFIG_KVM_MIPS_VZ option
- Add config option for KVM/MIPS with VZ support. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/Kconfig | 14 +- arch/mips/kvm/Makefile | 14 +- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/arch/mips/kvm/Kconfig b/arch/mips/kvm/Kconfig index 2c15590..963657f 100644 --- a/arch/mips/kvm/Kconfig +++ b/arch/mips/kvm/Kconfig @@ -25,9 +25,21 @@ config KVM Support for hosting Guest kernels. Currently supported on MIPS32 processors. +config KVM_MIPS_VZ + bool KVM support using the MIPS Virtualization ASE + depends on KVM + ---help--- + Support running unmodified guest kernels in virtual machines using + the MIPS virtualization ASE. If this option is not selected + then KVM will default to using trap and emulate to virtualize + guests, which will not be as optimal as using the VZ ASE. + + If unsure, say N. + config KVM_MIPS_DYN_TRANS bool KVM/MIPS: Dynamic binary translation to reduce traps - depends on KVM + depends on KVM !KVM_MIPS_VZ + default y ---help--- When running in Trap Emulate mode patch privileged instructions to reduce the number of traps. diff --git a/arch/mips/kvm/Makefile b/arch/mips/kvm/Makefile index 78d87bb..cc64bb4 100644 --- a/arch/mips/kvm/Makefile +++ b/arch/mips/kvm/Makefile @@ -5,9 +5,13 @@ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) EXTRA_CFLAGS += -Ivirt/kvm -Iarch/mips/kvm -kvm-objs := $(common-objs) kvm_mips.o kvm_mips_emul.o kvm_locore.o \ - kvm_mips_int.o kvm_mips_stats.o kvm_mips_commpage.o \ - kvm_mips_dyntrans.o kvm_trap_emul.o +kvm-objs := $(common-objs) kvm_mips.o kvm_mips_emul.o kvm_locore.o kvm_mips_int.o \ +kvm_mips_stats.o kvm_mips_commpage.o kvm_mips_dyntrans.o -obj-$(CONFIG_KVM) += kvm.o -obj-y += kvm_cb.o kvm_tlb.o +ifdef CONFIG_KVM_MIPS_VZ +kvm-objs += kvm_vz.o +else +kvm-objs += kvm_trap_emul.o +endif +obj-$(CONFIG_KVM) += kvm.o +obj-y += kvm_tlb.o kvm_cb.o kvm_vz_locore.o -- 1.7.11.3 -- 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 10/18] KVM/MIPS32-VZ: Add API for VZ-ASE Capability
- Add API to allow clients (QEMU etc.) to check whether the H/W supports the MIPS VZ-ASE. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- include/uapi/linux/kvm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index a5c86fc..5889e976 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -666,6 +666,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_IRQ_MPIC 90 #define KVM_CAP_PPC_RTAS 91 #define KVM_CAP_IRQ_XICS 92 +#define KVM_CAP_MIPS_VZ_ASE 93 #ifdef KVM_CAP_IRQ_ROUTING -- 1.7.11.3 -- 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/18] KVM/MIPS32-VZ: VZ: Handle Guest TLB faults that are handled in Root context
- Guest physical addresses need to be mapped by the Root TLB. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_tlb.c | 444 +++- 1 file changed, 359 insertions(+), 85 deletions(-) diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c index 89511a9..5b1a221 100644 --- a/arch/mips/kvm/kvm_tlb.c +++ b/arch/mips/kvm/kvm_tlb.c @@ -17,12 +17,16 @@ #include linux/delay.h #include linux/module.h #include linux/kvm_host.h +#include linux/srcu.h #include asm/cpu.h #include asm/bootinfo.h #include asm/mmu_context.h #include asm/pgtable.h #include asm/cacheflush.h +#ifdef CONFIG_KVM_MIPS_VZ +#include asm/mipsvzregs.h +#endif #undef CONFIG_MIPS_MT #include asm/r4kcache.h @@ -33,8 +37,12 @@ #define PRIx64 llx +#ifdef CONFIG_KVM_MIPS_VZ /* Use VZ EntryHi.EHINV to invalidate TLB entries */ +#define UNIQUE_ENTRYHI(idx) (ENTRYHI_EHINV | (CKSEG0 + ((idx) (PAGE_SHIFT + 1 +#else #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) (PAGE_SHIFT + 1))) +#endif atomic_t kvm_mips_instance; EXPORT_SYMBOL(kvm_mips_instance); @@ -51,13 +59,13 @@ EXPORT_SYMBOL(kvm_mips_is_error_pfn); uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu) { - return ASID_MASK(vcpu-arch.guest_kernel_asid[smp_processor_id()]); + return vcpu-arch.guest_kernel_asid[smp_processor_id()] ASID_MASK; } uint32_t kvm_mips_get_user_asid(struct kvm_vcpu *vcpu) { - return ASID_MASK(vcpu-arch.guest_user_asid[smp_processor_id()]); + return vcpu-arch.guest_user_asid[smp_processor_id()] ASID_MASK; } inline uint32_t kvm_mips_get_commpage_asid (struct kvm_vcpu *vcpu) @@ -72,11 +80,11 @@ inline uint32_t kvm_mips_get_commpage_asid (struct kvm_vcpu *vcpu) void kvm_mips_dump_host_tlbs(void) { - unsigned long old_entryhi; - unsigned long old_pagemask; struct kvm_mips_tlb tlb; - unsigned long flags; int i; + ulong flags; + unsigned long old_entryhi; + unsigned long old_pagemask; local_irq_save(flags); @@ -84,7 +92,7 @@ void kvm_mips_dump_host_tlbs(void) old_pagemask = read_c0_pagemask(); printk(HOST TLBs:\n); - printk(ASID: %#lx\n, ASID_MASK(read_c0_entryhi())); + printk(ASID: %#lx\n, read_c0_entryhi() ASID_MASK); for (i = 0; i current_cpu_data.tlbsize; i++) { write_c0_index(i); @@ -97,10 +105,23 @@ void kvm_mips_dump_host_tlbs(void) tlb.tlb_lo0 = read_c0_entrylo0(); tlb.tlb_lo1 = read_c0_entrylo1(); tlb.tlb_mask = read_c0_pagemask(); +#ifdef CONFIG_KVM_MIPS_VZ + tlb.guestctl1 = 0; + if (cpu_has_vzguestid) { + tlb.guestctl1 = read_c0_guestctl1(); + /* clear GuestRID after tlb_read in case it was changed */ + mips32_ClearGuestRID(); + } +#endif printk(TLB%c%3d Hi 0x%08lx , (tlb.tlb_lo0 | tlb.tlb_lo1) MIPS3_PG_V ? ' ' : '*', i, tlb.tlb_hi); +#ifdef CONFIG_KVM_MIPS_VZ + if (cpu_has_vzguestid) { + printk(GuestCtl1 0x%08x , tlb.guestctl1); + } +#endif printk(Lo0=0x%09 PRIx64 %c%c attr %lx , (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo0), (tlb.tlb_lo0 MIPS3_PG_D) ? 'D' : ' ', @@ -120,9 +141,9 @@ void kvm_mips_dump_host_tlbs(void) void kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu) { - struct mips_coproc *cop0 = vcpu-arch.cop0; - struct kvm_mips_tlb tlb; int i; + struct kvm_mips_tlb tlb; + struct mips_coproc *cop0 = vcpu-arch.cop0; printk(Guest TLBs:\n); printk(Guest EntryHi: %#lx\n, kvm_read_c0_guest_entryhi(cop0)); @@ -156,6 +177,11 @@ void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu) printk(TLB%c%3d Hi 0x%08lx , (tlb.tlb_lo0 | tlb.tlb_lo1) MIPS3_PG_V ? ' ' : '*', i, tlb.tlb_hi); +#ifdef CONFIG_KVM_MIPS_VZ + if (cpu_has_vzguestid) { + printk(GuestCtl1 0x%08x , tlb.guestctl1); + } +#endif printk(Lo0=0x%09 PRIx64 %c%c attr %lx , (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo0), (tlb.tlb_lo0 MIPS3_PG_D) ? 'D' : ' ', @@ -169,26 +195,31 @@ void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu) } } -static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) +static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) { + int srcu_idx, err = 0; pfn_t pfn; if (kvm-arch.guest_pmap[gfn] != KVM_INVALID_PAGE) - return; + return 0; +srcu_idx = srcu_read_lock(kvm-srcu); pfn = kvm_mips_gfn_to_pfn(kvm, gfn); if (kvm_mips_is_error_pfn(pfn)) { - panic(Couldn't get pfn for gfn
[PATCH 12/18] KVM/MIPS32-VZ: VM Exit Stats, add VZ exit reasons.
- Additional VZ related exit reasons, used in the trace logs. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips_stats.c | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/mips/kvm/kvm_mips_stats.c b/arch/mips/kvm/kvm_mips_stats.c index 075904b..c0d0c0f 100644 --- a/arch/mips/kvm/kvm_mips_stats.c +++ b/arch/mips/kvm/kvm_mips_stats.c @@ -3,7 +3,7 @@ * License. See the file COPYING in the main directory of this archive * for more details. * -* KVM/MIPS: COP0 access histogram +* KVM/MIPS: VM Exit stats, COP0 access histogram * * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Authors: Sanjay Lal sanj...@kymasys.com @@ -26,6 +26,21 @@ char *kvm_mips_exit_types_str[MAX_KVM_MIPS_EXIT_TYPES] = { Reserved Inst, Break Inst, D-Cache Flushes, +#ifdef CONFIG_KVM_MIPS_VZ + Hypervisor GPSI, + Hypervisor GPSI [CP0], + Hypervisor GPSI [CACHE], + Hypervisor GSFC, + Hypervisor GSFC [STATUS], + Hypervisor GSFC [CAUSE], + Hypervisor GSFC [INTCTL], + Hypervisor HC, + Hypervisor GRR, + Hypervisor GVA, + Hypervisor GHFC, + Hypervisor GPA, + Hypervisor RESV, +#endif }; char *kvm_cop0_str[N_MIPS_COPROC_REGS] = { -- 1.7.11.3 -- 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/18] KVM/MIPS32-VZ: Guest exception batching support.
- In Trap Emulate the hypervisor maintains exception priority in order to comply with the priorities defined by the architecture. - In VZ mode, we just set all the pending exception bits, and let the processor deliver them to the guest in the expected priority order. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips_int.h | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/mips/kvm/kvm_mips_int.h b/arch/mips/kvm/kvm_mips_int.h index 20da7d2..7eac28e 100644 --- a/arch/mips/kvm/kvm_mips_int.h +++ b/arch/mips/kvm/kvm_mips_int.h @@ -29,8 +29,13 @@ #define C_TI(_ULCAST_(1) 30) +#ifdef CONFIG_KVM_MIPS_VZ +#define KVM_MIPS_IRQ_DELIVER_ALL_AT_ONCE (1) +#define KVM_MIPS_IRQ_CLEAR_ALL_AT_ONCE (1) +#else #define KVM_MIPS_IRQ_DELIVER_ALL_AT_ONCE (0) #define KVM_MIPS_IRQ_CLEAR_ALL_AT_ONCE (0) +#endif void kvm_mips_queue_irq(struct kvm_vcpu *vcpu, uint32_t priority); void kvm_mips_dequeue_irq(struct kvm_vcpu *vcpu, uint32_t priority); -- 1.7.11.3 -- 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/18] KVM/MIPS32: Add dummy trap handler to catch unexpected exceptions and dump out useful info
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_trap_emul.c | 68 --- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/arch/mips/kvm/kvm_trap_emul.c b/arch/mips/kvm/kvm_trap_emul.c index 466aeef..19b32a1 100644 --- a/arch/mips/kvm/kvm_trap_emul.c +++ b/arch/mips/kvm/kvm_trap_emul.c @@ -27,7 +27,7 @@ static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva) if ((kseg == CKSEG0) || (kseg == CKSEG1)) gpa = CPHYSADDR(gva); else { - printk(%s: cannot find GPA for GVA: %#lx\n, __func__, gva); + kvm_err(%s: cannot find GPA for GVA: %#lx\n, __func__, gva); kvm_mips_dump_host_tlbs(); gpa = KVM_INVALID_ADDR; } @@ -39,12 +39,29 @@ static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva) return gpa; } +#ifdef CONFIG_KVM_MIPS_VZ +static int kvm_trap_emul_no_handler(struct kvm_vcpu *vcpu) +{ + uint32_t *opc = (uint32_t *) vcpu-arch.pc; + ulong cause = vcpu-arch.host_cp0_cause; + uint32_t exccode = (cause CAUSEB_EXCCODE) 0x1f; + ulong badvaddr = vcpu-arch.host_cp0_badvaddr; + + printk + (Exception Code: %d, not handled, @ PC: %p, inst: 0x%08x BadVaddr: %#lx Status: %#lx\n, +exccode, opc, kvm_get_inst(opc, vcpu), badvaddr, +kvm_read_c0_guest_status(vcpu-arch.cop0)); + kvm_arch_vcpu_dump_regs(vcpu); + vcpu-run-exit_reason = KVM_EXIT_INTERNAL_ERROR; + return RESUME_HOST; +} +#endif static int kvm_trap_emul_handle_cop_unusable(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; + uint32_t *opc = (uint32_t *) vcpu-arch.pc; + ulong cause = vcpu-arch.host_cp0_cause; enum emulation_result er = EMULATE_DONE; int ret = RESUME_GUEST; @@ -77,9 +94,9 @@ static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu) static int kvm_trap_emul_handle_tlb_mod(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu-run; - uint32_t __user *opc = (uint32_t __user *) vcpu-arch.pc; - unsigned long badvaddr = vcpu-arch.host_cp0_badvaddr; - unsigned long cause = vcpu-arch.host_cp0_cause; + uint32_t *opc = (uint32_t *) vcpu-arch.pc; + ulong cause = vcpu-arch.host_cp0_cause; + ulong badvaddr = vcpu-arch.host_cp0_badvaddr; enum emulation_result er = EMULATE_DONE; int ret = RESUME_GUEST; @@ -124,9 +141,9 @@ static int kvm_trap_emul_handle_tlb_mod(struct kvm_vcpu *vcpu) static int kvm_trap_emul_handle_tlb_st_miss(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu-run; - uint32_t __user *opc = (uint32_t __user *) vcpu-arch.pc; - unsigned long badvaddr = vcpu-arch.host_cp0_badvaddr; - unsigned long cause = vcpu-arch.host_cp0_cause; + uint32_t *opc = (uint32_t *) vcpu-arch.pc; + ulong cause = vcpu-arch.host_cp0_cause; + ulong badvaddr = vcpu-arch.host_cp0_badvaddr; enum emulation_result er = EMULATE_DONE; int ret = RESUME_GUEST; @@ -174,9 +191,9 @@ static int kvm_trap_emul_handle_tlb_st_miss(struct kvm_vcpu *vcpu) static int kvm_trap_emul_handle_tlb_ld_miss(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu-run; - uint32_t __user *opc = (uint32_t __user *) vcpu-arch.pc; - unsigned long badvaddr = vcpu-arch.host_cp0_badvaddr; - unsigned long cause = vcpu-arch.host_cp0_cause; + uint32_t *opc = (uint32_t *) vcpu-arch.pc; + ulong cause = vcpu-arch.host_cp0_cause; + ulong badvaddr = vcpu-arch.host_cp0_badvaddr; enum emulation_result er = EMULATE_DONE; int ret = RESUME_GUEST; @@ -228,9 +245,9 @@ static int kvm_trap_emul_handle_tlb_ld_miss(struct kvm_vcpu *vcpu) static int kvm_trap_emul_handle_addr_err_st(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu-run; - uint32_t __user *opc = (uint32_t __user *) vcpu-arch.pc; - unsigned long badvaddr = vcpu-arch.host_cp0_badvaddr; - unsigned long cause = vcpu-arch.host_cp0_cause; + uint32_t *opc = (uint32_t *) vcpu-arch.pc; + ulong cause = vcpu-arch.host_cp0_cause; + ulong badvaddr = vcpu-arch.host_cp0_badvaddr; enum emulation_result er = EMULATE_DONE; int ret = RESUME_GUEST; @@ -261,9 +278,9 @@ static int kvm_trap_emul_handle_addr_err_st(struct kvm_vcpu *vcpu) static int kvm_trap_emul_handle_addr_err_ld(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu-run; - uint32_t __user *opc = (uint32_t __user *) vcpu-arch.pc; - unsigned long badvaddr = vcpu-arch.host_cp0_badvaddr; - unsigned long cause = vcpu-arch.host_cp0_cause; + uint32_t *opc = (uint32_t *) vcpu-arch.pc; + ulong cause = vcpu-arch.host_cp0_cause; + ulong badvaddr = vcpu-arch.host_cp0_badvaddr; enum emulation_result er
[PATCH 16/18] KVM/MIPS32-VZ: Add VZ-ASE support to KVM/MIPS data structures.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/kvm_host.h | 244 ++- 1 file changed, 191 insertions(+), 53 deletions(-) diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index e68781e..c92e297 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -19,21 +19,28 @@ #include linux/threads.h #include linux/spinlock.h +#ifdef CONFIG_KVM_MIPS_VZ +#include asm/mipsvzregs.h +#endif -#define KVM_MAX_VCPUS 1 -#define KVM_USER_MEM_SLOTS 8 +#define KVM_MAX_VCPUS 8 +#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 /* Don't support huge pages */ -#define KVM_HPAGE_GFN_SHIFT(x) 0 +#define KVM_HPAGE_GFN_SHIFT(x) 0 /* We don't currently support large pages. */ #define KVM_NR_PAGE_SIZES 1 -#define KVM_PAGES_PER_HPAGE(x) 1 +#define KVM_PAGES_PER_HPAGE(x) 1 +#ifdef CONFIG_KVM_MIPS_VZ +#define KVM_VZROOTID (GUESTCTL1_VZ_ROOT_GUESTID) +#define KVM_VZGUESTID_MASK (GUESTCTL1_ID) +#endif /* Special address that contains the comm page, used for reducing # of traps */ @@ -42,11 +49,20 @@ #define KVM_GUEST_KERNEL_MODE(vcpu) ((kvm_read_c0_guest_status(vcpu-arch.cop0) (ST0_EXL | ST0_ERL)) || \ ((kvm_read_c0_guest_status(vcpu-arch.cop0) KSU_USER) == 0)) +#ifdef CONFIG_KVM_MIPS_VZ +#define KVM_GUEST_KUSEG 0xUL +#define KVM_GUEST_KSEG0 0x8000UL +#define KVM_GUEST_KSEG1 0xa000UL +#define KVM_GUEST_KSEG230xc000UL +#define KVM_GUEST_KSEGX(a) ((_ACAST32_(a)) 0xe000) +#define KVM_GUEST_CPHYSADDR(a) ((_ACAST32_(a)) 0x1fff) +#else #define KVM_GUEST_KUSEG 0xUL #define KVM_GUEST_KSEG0 0x4000UL #define KVM_GUEST_KSEG230x6000UL #define KVM_GUEST_KSEGX(a) ((_ACAST32_(a)) 0x6000) #define KVM_GUEST_CPHYSADDR(a) ((_ACAST32_(a)) 0x1fff) +#endif #define KVM_GUEST_CKSEG0ADDR(a)(KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG0) #define KVM_GUEST_CKSEG1ADDR(a)(KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG1) @@ -100,6 +116,21 @@ struct kvm_vcpu_stat { u32 resvd_inst_exits; u32 break_inst_exits; u32 flush_dcache_exits; +#ifdef CONFIG_KVM_MIPS_VZ + u32 hypervisor_gpsi_exits; + u32 hypervisor_gpsi_cp0_exits; + u32 hypervisor_gpsi_cache_exits; + u32 hypervisor_gsfc_exits; + u32 hypervisor_gsfc_cp0_status_exits; + u32 hypervisor_gsfc_cp0_cause_exits; + u32 hypervisor_gsfc_cp0_intctl_exits; + u32 hypervisor_hc_exits; + u32 hypervisor_grr_exits; + u32 hypervisor_gva_exits; + u32 hypervisor_ghfc_exits; + u32 hypervisor_gpa_exits; + u32 hypervisor_resv_exits; +#endif u32 halt_wakeup; }; @@ -118,6 +149,21 @@ enum kvm_mips_exit_types { RESVD_INST_EXITS, BREAK_INST_EXITS, FLUSH_DCACHE_EXITS, +#ifdef CONFIG_KVM_MIPS_VZ + HYPERVISOR_GPSI_EXITS, + HYPERVISOR_GPSI_CP0_EXITS, + HYPERVISOR_GPSI_CACHE_EXITS, + HYPERVISOR_GSFC_EXITS, + HYPERVISOR_GSFC_CP0_STATUS_EXITS, + HYPERVISOR_GSFC_CP0_CAUSE_EXITS, + HYPERVISOR_GSFC_CP0_INTCTL_EXITS, + HYPERVISOR_HC_EXITS, + HYPERVISOR_GRR_EXITS, + HYPERVISOR_GVA_EXITS, + HYPERVISOR_GHFC_EXITS, + HYPERVISOR_GPA_EXITS, + HYPERVISOR_RESV_EXITS, +#endif MAX_KVM_MIPS_EXIT_TYPES }; @@ -126,8 +172,8 @@ struct kvm_arch_memory_slot { struct kvm_arch { /* Guest GVA-HPA page table */ - unsigned long *guest_pmap; - unsigned long guest_pmap_npages; + ulong *guest_pmap; + ulong guest_pmap_npages; /* Wired host TLB used for the commpage */ int commpage_tlb; @@ -137,9 +183,9 @@ struct kvm_arch { #define N_MIPS_COPROC_SEL 8 struct mips_coproc { - unsigned long reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; + ulong reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; #ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS - unsigned long stat[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; + ulong stat[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; #endif }; @@ -294,6 +340,9 @@ enum mips_mmu_types { #define T_RES_INST 10 /* Reserved instruction exception */ #define T_COP_UNUSABLE 11 /* Coprocessor unusable */ #define T_OVFLOW12 /* Arithmetic overflow */ +#ifdef CONFIG_KVM_MIPS_VZ +#define T_GUEST_EXIT27 /* Guest Exit (VZ ASE) */ +#endif /* * Trap definitions added for r4000 port. @@ -336,7 +385,7 @@ enum emulation_result { #define VPN2_MASK 0xe000 #define TLB_IS_GLOBAL(x)(((x).tlb_lo0 MIPS3_PG_G) ((x).tlb_lo1 MIPS3_PG_G)) #define TLB_VPN2(x) ((x
[PATCH 18/18] KVM/MIPS32-VZ: Dump out additional info about VZ features as part of /proc/cpuinfo
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kernel/proc.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index a3e4614..308e042 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -99,6 +99,17 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (cpu_has_vz) seq_printf(m, %s, vz); seq_printf(m, \n); +#ifdef CONFIG_KVM_MIPS_VZ + if (cpu_has_vz) { + seq_printf(m, vz guestid\t\t: %s\n, + cpu_has_vzguestid ? yes : no); + seq_printf(m, vz virt irq\t\t: %s\n, + cpu_has_vzvirtirq ? yes : no); + } + seq_printf(m, tlbinv instructions\t: %s\n, + cpu_has_tlbinv ? yes : no); +#endif + if (cpu_has_mmips) { seq_printf(m, micromips kernel\t: %s\n, (read_c0_config3() MIPS_CONF3_ISA_OE) ? yes : no); -- 1.7.11.3 -- 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] KVM/MIPS32: Export min_low_pfn.
The KVM module uses the standard MIPS cache management routines, which use min_low_pfn. This creates and indirect dependency, requiring min_low_pfn to be exported. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- 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..0299472 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c @@ -14,6 +14,7 @@ #include linux/mm.h #include asm/uaccess.h #include asm/ftrace.h +#include linux/bootmem.h extern void *__bzero(void *__s, size_t __count); extern long __strncpy_from_user_nocheck_asm(char *__to, @@ -60,3 +61,8 @@ EXPORT_SYMBOL(invalid_pte_table); /* _mcount is defined in arch/mips/kernel/mcount.S */ EXPORT_SYMBOL(_mcount); #endif + +/* The KVM module uses the standard MIPS cache functions which use + * min_low_pfn, requiring it to be exported. + */ +EXPORT_SYMBOL(min_low_pfn); -- 1.7.11.3 -- 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/3] KVM/MIPS32: Fixes for Linux 3.10
The following patch set fixes a few issues with KVM/MIPS32 in Linux 3.10. -- Sanjay Lal (3): KVM/MIPS32: Move include/asm/kvm.h = include/uapi/asm/kvm.h since it is a user visible API. KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock() KVM/MIPS32: Fix up KVM breakage caused by d532f3d26716a39dfd4b88d687bd344fbe77e390 which allows ASID mask and increment to be determined @ runtime. arch/mips/include/asm/kvm.h | 55 --- arch/mips/include/asm/kvm_host.h | 5 arch/mips/include/uapi/asm/kvm.h | 55 +++ arch/mips/kvm/kvm_mips_emul.c| 22 arch/mips/kvm/kvm_tlb.c | 56 ++-- 5 files changed, 108 insertions(+), 85 deletions(-) delete mode 100644 arch/mips/include/asm/kvm.h create mode 100644 arch/mips/include/uapi/asm/kvm.h -- 1.7.11.3 -- 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] KVM/MIPS32: Move include/asm/kvm.h = include/uapi/asm/kvm.h since it is a user visible API.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/kvm.h | 55 arch/mips/include/uapi/asm/kvm.h | 55 2 files changed, 55 insertions(+), 55 deletions(-) delete mode 100644 arch/mips/include/asm/kvm.h create mode 100644 arch/mips/include/uapi/asm/kvm.h diff --git a/arch/mips/include/asm/kvm.h b/arch/mips/include/asm/kvm.h deleted file mode 100644 index 85789ea..000 --- a/arch/mips/include/asm/kvm.h +++ /dev/null @@ -1,55 +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 sanj...@kymasys.com -*/ - -#ifndef __LINUX_KVM_MIPS_H -#define __LINUX_KVM_MIPS_H - -#include linux/types.h - -#define __KVM_MIPS - -#define N_MIPS_COPROC_REGS 32 -#define N_MIPS_COPROC_SEL 8 - -/* for KVM_GET_REGS and KVM_SET_REGS */ -struct kvm_regs { - __u32 gprs[32]; - __u32 hi; - __u32 lo; - __u32 pc; - - __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; -}; - -/* for KVM_GET_SREGS and KVM_SET_SREGS */ -struct kvm_sregs { -}; - -/* for KVM_GET_FPU and KVM_SET_FPU */ -struct kvm_fpu { -}; - -struct kvm_debug_exit_arch { -}; - -/* for KVM_SET_GUEST_DEBUG */ -struct kvm_guest_debug_arch { -}; - -struct kvm_mips_interrupt { - /* in */ - __u32 cpu; - __u32 irq; -}; - -/* definition of registers in kvm_run */ -struct kvm_sync_regs { -}; - -#endif /* __LINUX_KVM_MIPS_H */ diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h new file mode 100644 index 000..85789ea --- /dev/null +++ b/arch/mips/include/uapi/asm/kvm.h @@ -0,0 +1,55 @@ +/* +* 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 sanj...@kymasys.com +*/ + +#ifndef __LINUX_KVM_MIPS_H +#define __LINUX_KVM_MIPS_H + +#include linux/types.h + +#define __KVM_MIPS + +#define N_MIPS_COPROC_REGS 32 +#define N_MIPS_COPROC_SEL 8 + +/* for KVM_GET_REGS and KVM_SET_REGS */ +struct kvm_regs { + __u32 gprs[32]; + __u32 hi; + __u32 lo; + __u32 pc; + + __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; +}; + +/* for KVM_GET_SREGS and KVM_SET_SREGS */ +struct kvm_sregs { +}; + +/* for KVM_GET_FPU and KVM_SET_FPU */ +struct kvm_fpu { +}; + +struct kvm_debug_exit_arch { +}; + +/* for KVM_SET_GUEST_DEBUG */ +struct kvm_guest_debug_arch { +}; + +struct kvm_mips_interrupt { + /* in */ + __u32 cpu; + __u32 irq; +}; + +/* definition of registers in kvm_run */ +struct kvm_sync_regs { +}; + +#endif /* __LINUX_KVM_MIPS_H */ -- 1.7.11.3 -- 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/3] KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock()
- As suggested by Gleb, wrap calls to gfn_to_pfn() with srcu_read_lock/unlock(). Memory slots should be acccessed from a SRCU read section. - kvm_mips_map_page() now returns an error code to it's callers, instead of calling panic() if it cannot find a mapping for a particular gfn. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_tlb.c | 36 +++- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c index 89511a9..ab2e9b0 100644 --- a/arch/mips/kvm/kvm_tlb.c +++ b/arch/mips/kvm/kvm_tlb.c @@ -16,7 +16,10 @@ #include linux/mm.h #include linux/delay.h #include linux/module.h +#include linux/bootmem.h #include linux/kvm_host.h +#include linux/srcu.h + #include asm/cpu.h #include asm/bootinfo.h @@ -169,21 +172,27 @@ void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu) } } -static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) +static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) { + int srcu_idx, err = 0; pfn_t pfn; if (kvm-arch.guest_pmap[gfn] != KVM_INVALID_PAGE) - return; + return 0; +srcu_idx = srcu_read_lock(kvm-srcu); pfn = kvm_mips_gfn_to_pfn(kvm, gfn); if (kvm_mips_is_error_pfn(pfn)) { - panic(Couldn't get pfn for gfn %# PRIx64 !\n, gfn); + kvm_err(Couldn't get pfn for gfn %# PRIx64 !\n, gfn); + err = -EFAULT; + goto out; } kvm-arch.guest_pmap[gfn] = pfn; - return; +out: + srcu_read_unlock(kvm-srcu, srcu_idx); + return err; } /* Translate guest KSEG0 addresses to Host PA */ @@ -207,7 +216,10 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu, gva); return KVM_INVALID_PAGE; } - kvm_mips_map_page(vcpu-kvm, gfn); + + if (kvm_mips_map_page(vcpu-kvm, gfn) 0) + return KVM_INVALID_ADDR; + return (kvm-arch.guest_pmap[gfn] PAGE_SHIFT) + offset; } @@ -310,8 +322,11 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr, even = !(gfn 0x1); vaddr = badvaddr (PAGE_MASK 1); - kvm_mips_map_page(vcpu-kvm, gfn); - kvm_mips_map_page(vcpu-kvm, gfn ^ 0x1); + if (kvm_mips_map_page(vcpu-kvm, gfn) 0) + return -1; + + if (kvm_mips_map_page(vcpu-kvm, gfn ^ 0x1) 0) + return -1; if (even) { pfn0 = kvm-arch.guest_pmap[gfn]; @@ -389,8 +404,11 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, pfn0 = 0; pfn1 = 0; } else { - kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo0) PAGE_SHIFT); - kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo1) PAGE_SHIFT); + if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo0) PAGE_SHIFT) 0) + return -1; + + if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo1) PAGE_SHIFT) 0) + return -1; pfn0 = kvm-arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb-tlb_lo0) PAGE_SHIFT]; pfn1 = kvm-arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb-tlb_lo1) PAGE_SHIFT]; -- 1.7.11.3 -- 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] KVM/MIPS32: Fix up KVM breakage caused by d532f3d26716a39dfd4b88d687bd344fbe77e390 which allows ASID mask and increment to be determined @ runtime.
The ASID paramters have default values which are then patched @ runtime as part of the TLB initialization. The fixup does not work since KVM is a kernel module and we end up with the default mask of 0xfc0 instead of the standard ASID mask of 0xff for MIPS32R2 processors. I've posted the issue on the MIPS mailing list and until a solution is found, For now define KVM_ASID_MASK as 0xFF to fix this issue up for Linux 3.10. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/kvm_host.h | 5 + arch/mips/kvm/kvm_mips_emul.c| 22 +++--- arch/mips/kvm/kvm_tlb.c | 20 ++-- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index e68781e..747c193 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -71,6 +71,11 @@ #define CAUSEB_DC 27 #define CAUSEF_DC (_ULCAST_(1)27) +/* KVM supports MIPS32R2 and beyond, so ASID_MASK is always 0xFF. + * This is to work around the bug introduced by commit d532f3d26716a39dfd4b88d687bd344fbe77e390 + */ +#define KVM_ASID_MASK(x) ((x) 0xFF) + struct kvm; struct kvm_run; struct kvm_vcpu; diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c index 2b2bac9..b8eee34 100644 --- a/arch/mips/kvm/kvm_mips_emul.c +++ b/arch/mips/kvm/kvm_mips_emul.c @@ -525,16 +525,16 @@ kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc, uint32_t cause, printk(MTCz, cop0-reg[EBASE]: %#lx\n, kvm_read_c0_guest_ebase(cop0)); } else if (rd == MIPS_CP0_TLB_HI sel == 0) { - uint32_t nasid = ASID_MASK(vcpu-arch.gprs[rt]); + uint32_t nasid = KVM_ASID_MASK(vcpu-arch.gprs[rt]); if ((KSEGX(vcpu-arch.gprs[rt]) != CKSEG0) - (ASID_MASK(kvm_read_c0_guest_entryhi(cop0)) + (KVM_ASID_MASK(kvm_read_c0_guest_entryhi(cop0)) != nasid)) { kvm_debug (MTCz, change ASID from %#lx to %#lx\n, - ASID_MASK(kvm_read_c0_guest_entryhi(cop0)), -ASID_MASK(vcpu-arch.gprs[rt])); + KVM_ASID_MASK(kvm_read_c0_guest_entryhi(cop0)), + KVM_ASID_MASK(vcpu-arch.gprs[rt])); /* Blow away the shadow host TLBs */ kvm_mips_flush_host_tlb(1); @@ -986,7 +986,7 @@ kvm_mips_emulate_cache(uint32_t inst, uint32_t *opc, uint32_t cause, * resulting handler will do the right thing */ index = kvm_mips_guest_tlb_lookup(vcpu, (va VPN2_MASK) | - ASID_MASK(kvm_read_c0_guest_entryhi(cop0))); + KVM_ASID_MASK(kvm_read_c0_guest_entryhi(cop0))); if (index 0) { vcpu-arch.host_cp0_entryhi = (va VPN2_MASK); @@ -1151,7 +1151,7 @@ kvm_mips_emulate_tlbmiss_ld(unsigned long cause, uint32_t *opc, struct kvm_vcpu_arch *arch = vcpu-arch; enum emulation_result er = EMULATE_DONE; unsigned long entryhi = (vcpu-arch. host_cp0_badvaddr VPN2_MASK) | - ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); + KVM_ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); if ((kvm_read_c0_guest_status(cop0) ST0_EXL) == 0) { /* save old pc */ @@ -1198,7 +1198,7 @@ kvm_mips_emulate_tlbinv_ld(unsigned long cause, uint32_t *opc, enum emulation_result er = EMULATE_DONE; unsigned long entryhi = (vcpu-arch.host_cp0_badvaddr VPN2_MASK) | - ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); + KVM_ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); if ((kvm_read_c0_guest_status(cop0) ST0_EXL) == 0) { /* save old pc */ @@ -1243,7 +1243,7 @@ kvm_mips_emulate_tlbmiss_st(unsigned long cause, uint32_t *opc, struct kvm_vcpu_arch *arch = vcpu-arch; enum emulation_result er = EMULATE_DONE; unsigned long entryhi = (vcpu-arch.host_cp0_badvaddr VPN2_MASK) | - ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); + KVM_ASID_MASK(kvm_read_c0_guest_entryhi(cop0)); if ((kvm_read_c0_guest_status(cop0) ST0_EXL) == 0) { /* save old pc */ @@ -1287,7 +1287,7 @@ kvm_mips_emulate_tlbinv_st(unsigned long cause, uint32_t *opc, struct kvm_vcpu_arch *arch = vcpu-arch
Re: [PATCH 2/2] KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock()
On May 14, 2013, at 2:27 AM, Gleb Natapov wrote: +EXPORT_SYMBOL(min_low_pfn); /* defined by bootmem.c, but not exported by generic code */ + What you need this for? It is not used anywhere in this patch and by mips/kvm code in general. I did some digging around myself, since the linker keeps complaining that it can't find min_low_pfn when compiling the KVM module. It seems that it is indirectly pulled in by the cache management functions. Regards Sanjay -- 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 2/2] KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock()
On May 15, 2013, at 10:30 AM, Gleb Natapov wrote: On Wed, May 15, 2013 at 09:54:24AM -0700, David Daney wrote: On 05/15/2013 08:54 AM, Sanjay Lal wrote: On May 14, 2013, at 2:27 AM, Gleb Natapov wrote: +EXPORT_SYMBOL(min_low_pfn); /* defined by bootmem.c, but not exported by generic code */ + What you need this for? It is not used anywhere in this patch and by mips/kvm code in general. I did some digging around myself, since the linker keeps complaining that it can't find min_low_pfn when compiling the KVM module. It seems that it is indirectly pulled in by the cache management functions. If it is really needed, then the export should probably be done at the site of the min_low_pfn definition, not in some random architecture file. Definitely. We cannot snick it here like that. Please drop it from this patch. I did export min_low_pfn where it was defined (in .../mm/bootmem.c) as part of the original patch set. It conflicted with the ia64/metag ports. min_low_pfn is exported in arch/ia64/kernel/ia64_ksyms.c and in arch/metag/kernel/metag_ksyms.c. There was some chatter about this when the KVM/MIPS code ended up in linux-next. From what I can gather, the maintainers for the other architectures agreed that exporting this symbol in bootmem.c was fine and should flow from the MIPS tree. I'll do that as part of v2 of the patch set. Regards Sanjay -- 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/2] KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock()
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_tlb.c | 38 +- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c index 89511a9..218075f 100644 --- a/arch/mips/kvm/kvm_tlb.c +++ b/arch/mips/kvm/kvm_tlb.c @@ -16,7 +16,10 @@ #include linux/mm.h #include linux/delay.h #include linux/module.h +#include linux/bootmem.h #include linux/kvm_host.h +#include linux/srcu.h + #include asm/cpu.h #include asm/bootinfo.h @@ -36,6 +39,8 @@ /* Use VZ EntryHi.EHINV to invalidate TLB entries */ #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) (PAGE_SHIFT + 1))) +EXPORT_SYMBOL(min_low_pfn); /* defined by bootmem.c, but not exported by generic code */ + atomic_t kvm_mips_instance; EXPORT_SYMBOL(kvm_mips_instance); @@ -169,21 +174,27 @@ void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu) } } -static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) +static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) { + int srcu_idx, err = 0; pfn_t pfn; if (kvm-arch.guest_pmap[gfn] != KVM_INVALID_PAGE) - return; + return 0; +srcu_idx = srcu_read_lock(kvm-srcu); pfn = kvm_mips_gfn_to_pfn(kvm, gfn); if (kvm_mips_is_error_pfn(pfn)) { - panic(Couldn't get pfn for gfn %# PRIx64 !\n, gfn); + kvm_err(Couldn't get pfn for gfn %# PRIx64 !\n, gfn); + err = -EFAULT; + goto out; } kvm-arch.guest_pmap[gfn] = pfn; - return; +out: + srcu_read_unlock(kvm-srcu, srcu_idx); + return err; } /* Translate guest KSEG0 addresses to Host PA */ @@ -207,7 +218,10 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu, gva); return KVM_INVALID_PAGE; } - kvm_mips_map_page(vcpu-kvm, gfn); + + if (kvm_mips_map_page(vcpu-kvm, gfn) 0) + return KVM_INVALID_ADDR; + return (kvm-arch.guest_pmap[gfn] PAGE_SHIFT) + offset; } @@ -310,8 +324,11 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr, even = !(gfn 0x1); vaddr = badvaddr (PAGE_MASK 1); - kvm_mips_map_page(vcpu-kvm, gfn); - kvm_mips_map_page(vcpu-kvm, gfn ^ 0x1); + if (kvm_mips_map_page(vcpu-kvm, gfn) 0) + return -1; + + if (kvm_mips_map_page(vcpu-kvm, gfn ^ 0x1) 0) + return -1; if (even) { pfn0 = kvm-arch.guest_pmap[gfn]; @@ -389,8 +406,11 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, pfn0 = 0; pfn1 = 0; } else { - kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo0) PAGE_SHIFT); - kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo1) PAGE_SHIFT); + if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo0) PAGE_SHIFT) 0) + return -1; + + if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb-tlb_lo1) PAGE_SHIFT) 0) + return -1; pfn0 = kvm-arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb-tlb_lo0) PAGE_SHIFT]; pfn1 = kvm-arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb-tlb_lo1) PAGE_SHIFT]; -- 1.7.11.3 -- 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] KVM/MIPS32: Fixes for Linux 3.10
The following patch set fixes a couple of issues with KVM/MIPS32 in Linux 3.10. - As suggested by Gleb, wrap calls to gfn_to_pfn() with srcu_read_lock/unlock(). - kvm_mips_map_page() now returns an error code to it's callers, instead of calling panic() if it cannot find a mapping for a particular gfn. - Follow the latest convention and move the kvm.h API file under uapi/... -- Sanjay Lal (2): KVM/MIPS32: Move include/asm/kvm.h = include/uapi/asm/kvm.h since it is a user visible API. KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock() arch/mips/include/asm/kvm.h | 55 arch/mips/include/uapi/asm/kvm.h | 55 arch/mips/kvm/kvm_tlb.c | 38 --- 3 files changed, 84 insertions(+), 64 deletions(-) delete mode 100644 arch/mips/include/asm/kvm.h create mode 100644 arch/mips/include/uapi/asm/kvm.h -- 1.7.11.3 -- 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] KVM/MIPS32: Move include/asm/kvm.h = include/uapi/asm/kvm.h since it is a user visible API.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/kvm.h | 55 arch/mips/include/uapi/asm/kvm.h | 55 2 files changed, 55 insertions(+), 55 deletions(-) delete mode 100644 arch/mips/include/asm/kvm.h create mode 100644 arch/mips/include/uapi/asm/kvm.h diff --git a/arch/mips/include/asm/kvm.h b/arch/mips/include/asm/kvm.h deleted file mode 100644 index 85789ea..000 --- a/arch/mips/include/asm/kvm.h +++ /dev/null @@ -1,55 +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 sanj...@kymasys.com -*/ - -#ifndef __LINUX_KVM_MIPS_H -#define __LINUX_KVM_MIPS_H - -#include linux/types.h - -#define __KVM_MIPS - -#define N_MIPS_COPROC_REGS 32 -#define N_MIPS_COPROC_SEL 8 - -/* for KVM_GET_REGS and KVM_SET_REGS */ -struct kvm_regs { - __u32 gprs[32]; - __u32 hi; - __u32 lo; - __u32 pc; - - __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; -}; - -/* for KVM_GET_SREGS and KVM_SET_SREGS */ -struct kvm_sregs { -}; - -/* for KVM_GET_FPU and KVM_SET_FPU */ -struct kvm_fpu { -}; - -struct kvm_debug_exit_arch { -}; - -/* for KVM_SET_GUEST_DEBUG */ -struct kvm_guest_debug_arch { -}; - -struct kvm_mips_interrupt { - /* in */ - __u32 cpu; - __u32 irq; -}; - -/* definition of registers in kvm_run */ -struct kvm_sync_regs { -}; - -#endif /* __LINUX_KVM_MIPS_H */ diff --git a/arch/mips/include/uapi/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h new file mode 100644 index 000..85789ea --- /dev/null +++ b/arch/mips/include/uapi/asm/kvm.h @@ -0,0 +1,55 @@ +/* +* 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 sanj...@kymasys.com +*/ + +#ifndef __LINUX_KVM_MIPS_H +#define __LINUX_KVM_MIPS_H + +#include linux/types.h + +#define __KVM_MIPS + +#define N_MIPS_COPROC_REGS 32 +#define N_MIPS_COPROC_SEL 8 + +/* for KVM_GET_REGS and KVM_SET_REGS */ +struct kvm_regs { + __u32 gprs[32]; + __u32 hi; + __u32 lo; + __u32 pc; + + __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; +}; + +/* for KVM_GET_SREGS and KVM_SET_SREGS */ +struct kvm_sregs { +}; + +/* for KVM_GET_FPU and KVM_SET_FPU */ +struct kvm_fpu { +}; + +struct kvm_debug_exit_arch { +}; + +/* for KVM_SET_GUEST_DEBUG */ +struct kvm_guest_debug_arch { +}; + +struct kvm_mips_interrupt { + /* in */ + __u32 cpu; + __u32 irq; +}; + +/* definition of registers in kvm_run */ +struct kvm_sync_regs { +}; + +#endif /* __LINUX_KVM_MIPS_H */ -- 1.7.11.3 -- 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] KVM/MIPS32: Fixes for Linux 3.10
On May 13, 2013, at 2:07 PM, David Daney wrote: Sanjay, Have you looked at: http://www.linux-mips.org/archives/linux-mips/2013-05/msg00049.html We should start working toward unifying the KVM interface. David Daney. Hey David, I am currently in the process of integrating and testing the new ABI. I'll need a couple of days. Regards Sanjay -- 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: Fix ABI for compatibility with 64-bit guests.
On May 6, 2013, at 3:39 PM, David Daney wrote: /* for KVM_GET_REGS and KVM_SET_REGS */ +/* + * If Config[AT] is zero (32-bit CPU), the register contents are + * stored in the lower 32-bits of the struct kvm_regs fields and sign + * extended to 64-bits. + */ struct kvm_regs { - __u32 gprs[32]; - __u32 hi; - __u32 lo; - __u32 pc; + /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ + __u64 gpr[32]; + __u64 hi, lo; + __u64 pc; +}; - __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; Hi David, I'll try out the diff with QEMU and confirm that it works as expected. Could you just leave the GPR field in kvm_regs as gprs. Its a minor change but avoids diffs that just replace gprs with gpr. Regards Sanjay -- 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] KVM/MIPS32: Sync up with latest KVM API changes
On Mar 18, 2013, at 12:04 PM, Jonas Gorski wrote: On 15 March 2013 03:09, Sanjay Lal sanj...@kymasys.com wrote: - Rename KVM_MEMORY_SLOTS - KVM_USER_MEM_SLOTS - Fix kvm_arch_{prepare,commit}_memory_region() - Also remove kvm_arch_set_memory_region which was unused. I just stumbled upon the build issue caused by the first item and can confirm that this patch fixes it. I guess this is a replacement for KVM/MIPS32: define KVM_USER_MEM_SLOTS (which doesn't apply anyway because of missing spaces)? If yes, then you should mark the old one as superseded in http://patchwork.linux-mips.org/. And maybe include here that it fixes a build issue. Regards Jonas Hi Jonas, will do. Regards and thanks Sanjay -- 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] KVM/MIPS32: define KVM_USER_MEM_SLOTS
ARCH=mips, config=fuloong2e_defconfig: akpm3:/usr/src/25 make arch/mips/kernel/early_printk.o ... CC arch/mips/kernel/asm-offsets.s In file included from arch/mips/kernel/asm-offsets.c:20: include/linux/kvm_host.h:334: error: `KVM_USER_MEM_SLOTS' undeclared here (not in a function) Reported-by: Andrew Morton a...@linux-foundation.org Cc: Alex Williamson alex.william...@redhat.com Cc: Marcelo Tosatti mtosa...@redhat.com Cc: Gleb Natapov g...@redhat.com Cc: Ralf Baechle r...@linux-mips.org Signed-off-by: Andrew Morton a...@linux-foundation.org Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/kvm_host.h |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff -puN arch/mips/include/asm/kvm_host.h~mips-define-kvm_user_mem_slots arch/mips/include/asm/kvm_host.h --- a/arch/mips/include/asm/kvm_host.h~mips-define-kvm_user_mem_slots +++ a/arch/mips/include/asm/kvm_host.h @@ -21,7 +21,7 @@ #define KVM_MAX_VCPUS 1 -#define KVM_MEMORY_SLOTS 8 +#define KVM_USER_MEM_SLOTS 8 /* memory slots that does not exposed to userspace */ #define KVM_PRIVATE_MEM_SLOTS 0 signature.asc Description: Message signed with OpenPGP using GPGMail
[PATCH] KVM/MIPS32: Sync up with latest KVM API changes
- Rename KVM_MEMORY_SLOTS - KVM_USER_MEM_SLOTS - Fix kvm_arch_{prepare,commit}_memory_region() - Also remove kvm_arch_set_memory_region which was unused. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/kvm_host.h | 2 +- arch/mips/kvm/kvm_mips.c | 12 ++-- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index c8cddd1..143875c 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -21,7 +21,7 @@ #define KVM_MAX_VCPUS 1 -#define KVM_MEMORY_SLOTS 8 +#define KVM_USER_MEM_SLOTS 8 /* memory slots that does not exposed to userspace */ #define KVM_PRIVATE_MEM_SLOTS 0 diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c index 15ee558..2e60b1c 100644 --- a/arch/mips/kvm/kvm_mips.c +++ b/arch/mips/kvm/kvm_mips.c @@ -198,14 +198,6 @@ kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) return -EINVAL; } -int -kvm_arch_set_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - struct kvm_memory_slot old, int user_alloc) -{ - return 0; -} - void kvm_arch_free_memslot(struct kvm_memory_slot *free, struct kvm_memory_slot *dont) { @@ -220,14 +212,14 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, struct kvm_memory_slot *memslot, struct kvm_memory_slot old, struct kvm_userspace_memory_region *mem, - int user_alloc) + bool user_alloc) { return 0; } void kvm_arch_commit_memory_region(struct kvm *kvm, struct kvm_userspace_memory_region *mem, - struct kvm_memory_slot old, int user_alloc) + struct kvm_memory_slot old, bool user_alloc) { unsigned long npages = 0; int i, err = 0; -- 1.7.11.3 -- 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: [Qemu-devel] [PATCH 11/12] KVM/MIPS: MIPS specfic APIs for KVM.
On Mar 2, 2013, at 7:45 AM, Peter Maydell wrote: On 2 March 2013 15:18, Sanjay Lal sanj...@kymasys.com wrote: +/* If we have an interrupt but the guest is not ready to receive an + * interrupt, request an interrupt window exit. This will + * cause a return to userspace as soon as the guest is ready to + * receive interrupts. + */ +if ((env-interrupt_request CPU_INTERRUPT_HARD)) { +run-request_interrupt_window = 1; +} else { +run-request_interrupt_window = 0; +} +} Does MIPS really need x86-style fully-synchronised delivery of interrupts from userspace to the kernel? Don't copy x86 unless you know it's really what your architecture requires. -- PMM Sorry my bad, this was from an older snapshot of the code. The whole request_interrupt_window code has been deprecated and will be removed from the v2 of patch set. Regards Sanjay -- 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: [Qemu-devel] [PATCH 01/12] KVM/MIPS: Bootcode for MIPS SMP configurations with a GCMP
On Mar 2, 2013, at 12:03 PM, Peter Maydell wrote: On 2 March 2013 15:18, Sanjay Lal sanj...@kymasys.com wrote: --- /dev/null +++ b/hw/mips_cps_bootcode.h @@ -0,0 +1,310 @@ +/* Sample boot code for 1004K CPS (Coherent Processing System.) + * Not Generic for all Release 2 or higher MIPS32 or MIPS64 processors + * + * Copyright (c) 2006,2008 MIPS Technologies, Inc. All rights reserved. + */ (a) All rights reserved means you can't put this in QEMU. (b) huge binary blob in a hex array? Yuck. Would it be better to release the boot code as a binary ROM image? That would address both (a) and (b)? Regards and thanks Sanjay -- 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: [Qemu-devel] [PATCH 03/12] KVM/MIPS: Add save/restore state APIs for saving/restoring KVM guests.
On Mar 2, 2013, at 7:27 AM, Peter Maydell wrote: 2013/3/2 Sanjay Lal sanj...@kymasys.com: +static void gt64xxx_save(QEMUFile *f, void *opaque) +{ +GT64120State *s = opaque; + +/* CPU Configuration */ +qemu_put_be32s(f, s-regs[GT_CPU]); +qemu_put_be32s(f, s-regs[GT_MULTI]); Definitely no new save/load functions like this in new code, please. Use a VMState struct. thanks -- PMM Will do for v2 of the patch set. Regards Sanjay -- 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
[Qemu-devel][PATCH 01/12] KVM/MIPS: Bootcode for MIPS SMP configurations with a GCMP
--- hw/mips_cps_bootcode.h | 310 + 1 file changed, 310 insertions(+) create mode 100644 hw/mips_cps_bootcode.h diff --git a/hw/mips_cps_bootcode.h b/hw/mips_cps_bootcode.h new file mode 100644 index 000..40289a4 --- /dev/null +++ b/hw/mips_cps_bootcode.h @@ -0,0 +1,310 @@ +/* Sample boot code for 1004K CPS (Coherent Processing System.) + * Not Generic for all Release 2 or higher MIPS32 or MIPS64 processors + * + * Copyright (c) 2006,2008 MIPS Technologies, Inc. All rights reserved. + */ + +#ifndef __MIPS_CPS_BOOTCODE_H__ +#define __MIPS_CPS_BOOTCODE_H__ + +#ifdef TARGET_WORDS_BIGENDIAN +#error CPS bootcode for MIPS Big Endian target not available yet +#else +static unsigned char __boot_cps_data[] = { + 0x3f,0x01,0x00,0x10,0x00,0x48,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x3f,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x00,0x70,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x3f,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +
[Qemu-devel][PATCH 01/12] MIPS: Bootcode for MIPS SMP configurations with a GCMP
--- hw/mips_cps_bootcode.h | 310 + 1 file changed, 310 insertions(+) create mode 100644 hw/mips_cps_bootcode.h diff --git a/hw/mips_cps_bootcode.h b/hw/mips_cps_bootcode.h new file mode 100644 index 000..40289a4 --- /dev/null +++ b/hw/mips_cps_bootcode.h @@ -0,0 +1,310 @@ +/* Sample boot code for 1004K CPS (Coherent Processing System.) + * Not Generic for all Release 2 or higher MIPS32 or MIPS64 processors + * + * Copyright (c) 2006,2008 MIPS Technologies, Inc. All rights reserved. + */ + +#ifndef __MIPS_CPS_BOOTCODE_H__ +#define __MIPS_CPS_BOOTCODE_H__ + +#ifdef TARGET_WORDS_BIGENDIAN +#error CPS bootcode for MIPS Big Endian target not available yet +#else +static unsigned char __boot_cps_data[] = { + 0x3f,0x01,0x00,0x10,0x00,0x48,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x3f,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x00,0x70,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x3f,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +
[Qemu-devel][PATCH 02/12] KVM/MIPS: GIC emulation for SMP guests.
GCMP_GCB_CMxMASK_MASK_MSK GCMPGCBMSK(CMxMASK_MASK, 16) +#define GCMP_GCB_CMxMASK_CMREGTGT_SHF 0 +#define GCMP_GCB_CMxMASK_CMREGTGT_MSK GCMPGCBMSK(CMxMASK_CMREGTGT, 2) +#define GCMP_GCB_CMxMASK_CMREGTGT_MEM 0 +#define GCMP_GCB_CMxMASK_CMREGTGT_MEM1 1 +#define GCMP_GCB_CMxMASK_CMREGTGT_IOCU1 2 +#define GCMP_GCB_CMxMASK_CMREGTGT_IOCU2 3 + + +/* Core local/Core other control block registers */ +#define GCMP_CCB_RESETR_OFS0x /* Reset Release */ +#define GCMP_CCB_RESETR_INRESET_SHF 0 +#define GCMP_CCB_RESETR_INRESET_MSK GCMPCCBMSK(RESETR_INRESET, 16) +#define GCMP_CCB_COHCTL_OFS0x0008 /* Coherence Control */ +#define GCMP_CCB_COHCTL_DOMAIN_SHF0 +#define GCMP_CCB_COHCTL_DOMAIN_MSKGCMPCCBMSK(COHCTL_DOMAIN, 8) +#define GCMP_CCB_CFG_OFS 0x0010 /* Config */ +#define GCMP_CCB_CFG_IOCUTYPE_SHF 10 +#define GCMP_CCB_CFG_IOCUTYPE_MSK GCMPCCBMSK(CFG_IOCUTYPE, 2) +#define GCMP_CCB_CFG_IOCUTYPE_CPU0 +#define GCMP_CCB_CFG_IOCUTYPE_NCIOCU 1 +#define GCMP_CCB_CFG_IOCUTYPE_CIOCU 2 +#define GCMP_CCB_CFG_NUMVPE_SHF 0 +#define GCMP_CCB_CFG_NUMVPE_MSK GCMPCCBMSK(CFG_NUMVPE, 10) +#define GCMP_CCB_OTHER_OFS 0x0018 /* Other Address */ +#define GCMP_CCB_OTHER_CORENUM_SHF16 +#define GCMP_CCB_OTHER_CORENUM_MSKGCMPCCBMSK(OTHER_CORENUM, 16) +#define GCMP_CCB_RESETBASE_OFS 0x0020 /* Reset Exception Base */ +#define GCMP_CCB_RESETBASE_BEV_SHF12 +#define GCMP_CCB_RESETBASE_BEV_MSKGCMPCCBMSK(RESETBASE_BEV, 20) +#define GCMP_CCB_ID_OFS0x0028 /* Identification */ +#define GCMP_CCB_DINTGROUP_OFS 0x0030 /* DINT Group Participate */ +#define GCMP_CCB_DBGGROUP_OFS 0x0100 /* DebugBreak Group */ + +#endif /* _ASM_GCMPREGS_H */ diff --git a/hw/mips_gic.c b/hw/mips_gic.c new file mode 100644 index 000..b477b7a --- /dev/null +++ b/hw/mips_gic.c @@ -0,0 +1,418 @@ +/* + * 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 sanj...@kymasys.com +*/ + +#include hw.h +#include qemu/bitmap.h +#include exec/memory.h +#include sysemu/sysemu.h + +#ifdef CONFIG_KVM +#include sysemu/kvm.h +#include kvm_mips.h +#endif + +#include mips_gic.h +#include mips_gcmpregs.h + +//#define DEBUG + +#ifdef DEBUG +#define DPRINTF(fmt, ...) fprintf(stderr, %s: fmt, __FUNCTION__, ##__VA_ARGS__) +#else +#define DPRINTF(fmt, ...) +#endif + +/* Support upto 4 VPEs */ +#define NUMVPES 4 + +/* XXXKYMA: Spoof a bit of the GCR as well, just enough to get Linux to detect it */ +typedef struct gic_t +{ +CPUMIPSState *env[NR_CPUS]; +MemoryRegion gcr_mem, gic_mem; + +qemu_irq *irqs; + +/* GCR Registers */ +uint32_t gcr_gic_base_reg; + +/* Shared Section Registers */ +uint32_t gic_gl_intr_pol_reg[8]; +uint32_t gic_gl_intr_trigtype_reg[8]; +uint32_t gic_gl_intr_pending_reg[8]; +uint32_t gic_gl_intr_mask_reg[8]; + +uint32_t gic_gl_map_pin[256]; + +/* Sparse array, need a better way */ +uint32_t gic_gl_map_vpe[0x7fa]; + +/* VPE Local Section Registers */ +/* VPE Other Section Registers, aliased to local, use the other field to access the correct instance */ +uint32_t gic_local_vpe_regs[NUMVPES][0x1000]; + +/* User Mode Visible Section Registers */ +} gic_t; + + +static uint64_t +gic_read(void *opaque, hwaddr addr, unsigned size) +{ +int reg; +gic_t *gic = (gic_t *) opaque; + +DPRINTF(addr: %# PRIx64 , size: %#x\n, addr, size); + +switch (addr) { +case GIC_SH_CONFIG_OFS: +return 0x804 | ((NUMVPES - 1) GIC_SH_CONFIG_NUMVPES_MSK); +break; + +case GIC_SH_POL_31_0_OFS: +case GIC_SH_POL_63_32_OFS: +case GIC_SH_POL_95_64_OFS: +case GIC_SH_POL_127_96_OFS: +case GIC_SH_POL_159_128_OFS: +case GIC_SH_POL_191_160_OFS: +case GIC_SH_POL_223_192_OFS: +case GIC_SH_POL_255_224_OFS: +reg = (addr - GIC_SH_POL_31_0_OFS) / 4; +return gic-gic_gl_intr_pol_reg[reg]; +break; + +case GIC_SH_TRIG_31_0_OFS: +case GIC_SH_TRIG_63_32_OFS: +case GIC_SH_TRIG_95_64_OFS: +case GIC_SH_TRIG_127_96_OFS: +case GIC_SH_TRIG_159_128_OFS: +case GIC_SH_TRIG_191_160_OFS: +case GIC_SH_TRIG_223_192_OFS: +case GIC_SH_TRIG_255_224_OFS: +reg = (addr - GIC_SH_TRIG_31_0_OFS) / 4; +return gic-gic_gl_intr_trigtype_reg[reg]; +break; + +case GIC_SH_RMASK_31_0_OFS: +case GIC_SH_RMASK_63_32_OFS: +case GIC_SH_RMASK_95_64_OFS: +case GIC_SH_RMASK_127_96_OFS: +case GIC_SH_RMASK_159_128_OFS: +case GIC_SH_RMASK_191_160_OFS: +case GIC_SH_RMASK_223_192_OFS: +case GIC_SH_RMASK_255_224_OFS: +break; + +case
[Qemu-devel][PATCH 05/12] KVM/MIPS: In KVM mode, inject IRQ2 (I/O) interupts via ioctls(). COP0 emulation is in-kernel
--- hw/mips_int.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/hw/mips_int.c b/hw/mips_int.c index 6423fd0..6c655af 100644 --- a/hw/mips_int.c +++ b/hw/mips_int.c @@ -23,6 +23,8 @@ #include hw.h #include mips_cpudevs.h #include cpu.h +#include sysemu/kvm.h +#include kvm_mips.h static void cpu_mips_irq_request(void *opaque, int irq, int level) { @@ -33,8 +35,21 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level) if (level) { env-CP0_Cause |= 1 (irq + CP0Ca_IP); + +#ifdef CONFIG_KVM +if (kvm_enabled() irq == 2) { +kvm_mips_set_interrupt (env, irq, level); +} +#endif + } else { env-CP0_Cause = ~(1 (irq + CP0Ca_IP)); + +#ifdef CONFIG_KVM +if (kvm_enabled() irq == 2) { +kvm_mips_set_interrupt (env, irq, level); +} +#endif } if (env-CP0_Cause CP0Ca_IP_mask) { -- 1.7.11.3 -- 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
[Qemu-devel][PATCH 03/12] KVM/MIPS: Add save/restore state APIs for saving/restoring KVM guests.
--- hw/gt64xxx.c | 317 +++ 1 file changed, 317 insertions(+) diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c index 977a2c5..3583ca8 100644 --- a/hw/gt64xxx.c +++ b/hw/gt64xxx.c @@ -31,6 +31,8 @@ //#define DEBUG +#define GT64XXX_VM_VERSION1 + #ifdef DEBUG #define DPRINTF(fmt, ...) fprintf(stderr, %s: fmt, __FUNCTION__, ##__VA_ARGS__) #else @@ -1092,6 +1094,317 @@ static void gt64120_reset(void *opaque) gt64120_pci_mapping(s); } +static void gt64xxx_save(QEMUFile *f, void *opaque) +{ +GT64120State *s = opaque; + +/* CPU Configuration */ +qemu_put_be32s(f, s-regs[GT_CPU]); +qemu_put_be32s(f, s-regs[GT_MULTI]); + +/* CPU Address decode */ +qemu_put_be32s(f, s-regs[GT_SCS10LD]); +qemu_put_be32s(f, s-regs[GT_SCS10HD]); +qemu_put_be32s(f, s-regs[GT_SCS32LD]); +qemu_put_be32s(f, s-regs[GT_SCS32HD]); +qemu_put_be32s(f, s-regs[GT_CS20LD]); +qemu_put_be32s(f, s-regs[GT_CS20HD]); +qemu_put_be32s(f, s-regs[GT_CS3BOOTLD]); +qemu_put_be32s(f, s-regs[GT_CS3BOOTHD]); + +qemu_put_be32s(f, s-regs[GT_PCI0IOLD]); +qemu_put_be32s(f, s-regs[GT_PCI0IOHD]); +qemu_put_be32s(f, s-regs[GT_PCI0M0LD]); +qemu_put_be32s(f, s-regs[GT_PCI0M0HD]); +qemu_put_be32s(f, s-regs[GT_ISD]); +qemu_put_be32s(f, s-regs[GT_PCI0M1LD]); +qemu_put_be32s(f, s-regs[GT_PCI0M1HD]); +qemu_put_be32s(f, s-regs[GT_PCI1IOLD]); +qemu_put_be32s(f, s-regs[GT_PCI1IOHD]); +qemu_put_be32s(f, s-regs[GT_PCI1M0LD]); +qemu_put_be32s(f, s-regs[GT_PCI1M0HD]); +qemu_put_be32s(f, s-regs[GT_PCI1M1LD]); +qemu_put_be32s(f, s-regs[GT_PCI1M1HD]); + +qemu_put_be32s(f, s-regs[GT_SCS10AR]); +qemu_put_be32s(f, s-regs[GT_SCS32AR]); +qemu_put_be32s(f, s-regs[GT_CS20R]); +qemu_put_be32s(f, s-regs[GT_CS3BOOTR]); + +qemu_put_be32s(f, s-regs[GT_PCI0IOREMAP]); +qemu_put_be32s(f, s-regs[GT_PCI0M0REMAP]); +qemu_put_be32s(f, s-regs[GT_PCI0M1REMAP]); +qemu_put_be32s(f, s-regs[GT_PCI1IOREMAP]); +qemu_put_be32s(f, s-regs[GT_PCI1M0REMAP]); +qemu_put_be32s(f, s-regs[GT_PCI1M1REMAP]); + +/* CPU Error Report */ +qemu_put_be32s(f, s-regs[GT_CPUERR_ADDRLO]); +qemu_put_be32s(f, s-regs[GT_CPUERR_ADDRHI]); +qemu_put_be32s(f, s-regs[GT_CPUERR_DATALO]); +qemu_put_be32s(f, s-regs[GT_CPUERR_DATAHI]); +qemu_put_be32s(f, s-regs[GT_CPUERR_PARITY]); + +/* CPU Sync Barrier */ +qemu_put_be32s(f, s-regs[GT_PCI0SYNC]); +qemu_put_be32s(f, s-regs[GT_PCI1SYNC]); + +/* SDRAM and Device Address Decode */ +qemu_put_be32s(f, s-regs[GT_SCS0LD]); +qemu_put_be32s(f, s-regs[GT_SCS0HD]); +qemu_put_be32s(f, s-regs[GT_SCS1LD]); +qemu_put_be32s(f, s-regs[GT_SCS1HD]); +qemu_put_be32s(f, s-regs[GT_SCS2LD]); +qemu_put_be32s(f, s-regs[GT_SCS2HD]); +qemu_put_be32s(f, s-regs[GT_SCS3LD]); +qemu_put_be32s(f, s-regs[GT_SCS3HD]); +qemu_put_be32s(f, s-regs[GT_CS0LD]); +qemu_put_be32s(f, s-regs[GT_CS0HD]); +qemu_put_be32s(f, s-regs[GT_CS1LD]); +qemu_put_be32s(f, s-regs[GT_CS1HD]); +qemu_put_be32s(f, s-regs[GT_CS2LD]); +qemu_put_be32s(f, s-regs[GT_CS2HD]); +qemu_put_be32s(f, s-regs[GT_CS3LD]); +qemu_put_be32s(f, s-regs[GT_CS3HD]); +qemu_put_be32s(f, s-regs[GT_BOOTLD]); +qemu_put_be32s(f, s-regs[GT_BOOTHD]); +qemu_put_be32s(f, s-regs[GT_ADERR]); + +/* SDRAM Configuration */ +qemu_put_be32s(f, s-regs[GT_SDRAM_CFG]); +qemu_put_be32s(f, s-regs[GT_SDRAM_OPMODE]); +qemu_put_be32s(f, s-regs[GT_SDRAM_BM]); +qemu_put_be32s(f, s-regs[GT_SDRAM_ADDRDECODE]); + +/* SDRAM Parameters */ +qemu_put_be32s(f, s-regs[GT_SDRAM_B0]); +qemu_put_be32s(f, s-regs[GT_SDRAM_B1]); +qemu_put_be32s(f, s-regs[GT_SDRAM_B2]); +qemu_put_be32s(f, s-regs[GT_SDRAM_B3]); + +/* ECC */ +qemu_put_be32s(f, s-regs[GT_ECC_ERRDATALO]); +qemu_put_be32s(f, s-regs[GT_ECC_ERRDATAHI]); +qemu_put_be32s(f, s-regs[GT_ECC_MEM]); +qemu_put_be32s(f, s-regs[GT_ECC_CALC]); +qemu_put_be32s(f, s-regs[GT_ECC_ERRADDR]); + +/* Device Parameters */ +qemu_put_be32s(f, s-regs[GT_DEV_B0]); +qemu_put_be32s(f, s-regs[GT_DEV_B1]); +qemu_put_be32s(f, s-regs[GT_DEV_B2]); +qemu_put_be32s(f, s-regs[GT_DEV_B3]); +qemu_put_be32s(f, s-regs[GT_DEV_BOOT]); + +/* DMA registers are all zeroed at reset */ + +/* Timer/Counter */ +qemu_put_be32s(f, s-regs[GT_TC0]); +qemu_put_be32s(f, s-regs[GT_TC1]); +qemu_put_be32s(f, s-regs[GT_TC2]); +qemu_put_be32s(f, s-regs[GT_TC3]); +qemu_put_be32s(f, s-regs[GT_TC_CONTROL]); + +/* PCI Internal */ +qemu_put_be32s(f, s-regs[GT_PCI0_CMD]); +qemu_put_be32s(f, s-regs[GT_PCI0_CMD]); +qemu_put_be32s(f, s-regs[GT_PCI0_TOR]); +qemu_put_be32s(f, s-regs[GT_PCI0_BS_SCS10]); +qemu_put_be32s(f, s-regs[GT_PCI0_BS_SCS32]); +qemu_put_be32s(f, s-regs[GT_PCI0_BS_CS20]); +qemu_put_be32s(f, s-regs[GT_PCI0_BS_CS3BT]); +qemu_put_be32s(f,
[Qemu-devel][PATCH 04/12] KVM/MIPS: Do not start the periodic timer in KVM mode. Compare/Count timer interrupts are handled in-kernel.
--- hw/mips_timer.c | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/hw/mips_timer.c b/hw/mips_timer.c index 83c400c..0c86a3b 100644 --- a/hw/mips_timer.c +++ b/hw/mips_timer.c @@ -19,11 +19,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - #include hw.h #include mips_cpudevs.h #include qemu/timer.h +#include sysemu/kvm.h + + #define TIMER_FREQ 100 * 1000 * 1000 /* XXX: do not use a global */ @@ -141,7 +143,10 @@ static void mips_timer_cb (void *opaque) void cpu_mips_clock_init (CPUMIPSState *env) { -env-timer = qemu_new_timer_ns(vm_clock, mips_timer_cb, env); -env-CP0_Compare = 0; -cpu_mips_store_count(env, 1); +/* If we're in KVM mode, don't start the periodic timer, that is handled in kernel */ +if (!kvm_enabled()) { +env-timer = qemu_new_timer_ns(vm_clock, mips_timer_cb, env); +env-CP0_Compare = 0; +cpu_mips_store_count(env, 1); +} } -- 1.7.11.3 -- 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
[Qemu-devel][PATCH 06/12] KVM/MIPS: Define APIs to convert Guest KSEG0 - Guest Physical addresses.
In trap and emulate mode both the guest kernel and guest userspace execute in UM: Guest User address space: 0x - 0x4000 Guest Kernel Unmapped: 0x4000 - 0x6000 Guest Kernel Mapped:0x6000 - 0x8000 --- hw/mips_addr.c| 14 ++ hw/mips_cpudevs.h | 4 2 files changed, 18 insertions(+) diff --git a/hw/mips_addr.c b/hw/mips_addr.c index aa1c7d8..c24d2d9 100644 --- a/hw/mips_addr.c +++ b/hw/mips_addr.c @@ -22,13 +22,27 @@ #include hw.h #include mips_cpudevs.h +#include sysemu/kvm.h + uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr) { return addr 0x7fffll; } + +uint64_t cpu_mips_kvm_um_kseg0_to_phys(void *opaque, uint64_t addr) +{ +return addr 0x3fffll; +} + uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr) { return addr | ~0x7fffll; } + + +uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr) +{ +return addr | 0x4000ll; +} diff --git a/hw/mips_cpudevs.h b/hw/mips_cpudevs.h index 6bea24b..9e5af37 100644 --- a/hw/mips_cpudevs.h +++ b/hw/mips_cpudevs.h @@ -6,6 +6,10 @@ uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr); uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr); +uint64_t cpu_mips_kvm_um_kseg0_to_phys(void *opaque, uint64_t addr); +uint64_t cpu_mips_kvm_um_phys_to_kseg0(void *opaque, uint64_t addr); + + /* mips_int.c */ void cpu_mips_irq_init_cpu(CPUMIPSState *env); -- 1.7.11.3 -- 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
[Qemu-devel][PATCH 12/12] KVM/MIPS: General KVM support and support for SMP Guests
- In KVM mode the bootrom is loaded and executed from the last 1MB of DRAM. - Use the CPS bootrom from MIPS in KVM mode. This allows bootstrapping of multiple cores. - Add suport for MIPS GIC emulation for SMP Guests. --- hw/mips_malta.c | 192 +--- 1 file changed, 126 insertions(+), 66 deletions(-) diff --git a/hw/mips_malta.c b/hw/mips_malta.c index 2a150df..e04aa4a 100644 --- a/hw/mips_malta.c +++ b/hw/mips_malta.c @@ -48,6 +48,13 @@ #include sysemu/blockdev.h #include exec/address-spaces.h #include sysbus.h /* SysBusDevice */ +#include qemu/bitmap.h +#include mips_gic.h +#include sysemu/kvm.h +#include linux/kvm.h +#include kvm_mips.h + +#include mips_cps_bootcode.h //#define DEBUG_BOARD_INIT @@ -514,27 +521,36 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, /* Small bootloader */ p = (uint32_t *)base; -stl_raw(p++, 0x0bf00160); /* j 0x1fc00580 */ -stl_raw(p++, 0x); /* nop */ -/* YAMON service vector */ -stl_raw(base + 0x500, 0xbfc00580); /* start: */ -stl_raw(base + 0x504, 0xbfc0083c); /* print_count: */ -stl_raw(base + 0x520, 0xbfc00580); /* start: */ -stl_raw(base + 0x52c, 0xbfc00800); /* flush_cache: */ -stl_raw(base + 0x534, 0xbfc00808); /* print: */ -stl_raw(base + 0x538, 0xbfc00800); /* reg_cpu_isr: */ -stl_raw(base + 0x53c, 0xbfc00800); /* unred_cpu_isr: */ -stl_raw(base + 0x540, 0xbfc00800); /* reg_ic_isr: */ -stl_raw(base + 0x544, 0xbfc00800); /* unred_ic_isr: */ -stl_raw(base + 0x548, 0xbfc00800); /* reg_esr: */ -stl_raw(base + 0x54c, 0xbfc00800); /* unreg_esr: */ -stl_raw(base + 0x550, 0xbfc00800); /* getchar: */ -stl_raw(base + 0x554, 0xbfc00800); /* syscon_read: */ +if (kvm_enabled()) { +memcpy((void *)base, (void *)__boot_cps_data, sizeof(__boot_cps_data)); +/* Second part of the bootloader */ +p = (uint32_t *) (base + 0x100); +} +else { +stl_raw(p++, 0x0bf00160); /* j 0x1fc00580 */ +stl_raw(p++, 0x); /* nop */ + +/* YAMON service vector */ +stl_raw(base + 0x500, 0xbfc00580); /* start: */ +stl_raw(base + 0x504, 0xbfc0083c); /* print_count: */ +stl_raw(base + 0x520, 0xbfc00580); /* start: */ +stl_raw(base + 0x52c, 0xbfc00800); /* flush_cache: */ +stl_raw(base + 0x534, 0xbfc00808); /* print: */ +stl_raw(base + 0x538, 0xbfc00800); /* reg_cpu_isr: */ +stl_raw(base + 0x53c, 0xbfc00800); /* unred_cpu_isr: */ +stl_raw(base + 0x540, 0xbfc00800); /* reg_ic_isr: */ +stl_raw(base + 0x544, 0xbfc00800); /* unred_ic_isr: */ +stl_raw(base + 0x548, 0xbfc00800); /* reg_esr: */ +stl_raw(base + 0x54c, 0xbfc00800); /* unreg_esr: */ +stl_raw(base + 0x550, 0xbfc00800); /* getchar: */ +stl_raw(base + 0x554, 0xbfc00800); /* syscon_read: */ + +p = (uint32_t *) (base + 0x580); +} /* Second part of the bootloader */ -p = (uint32_t *) (base + 0x580); stl_raw(p++, 0x24040002); /* addiu a0, zero, 2 */ stl_raw(p++, 0x3c1d | (((ENVP_ADDR - 64) 16) 0x)); /* lui sp, high(ENVP_ADDR) */ stl_raw(p++, 0x37bd | ((ENVP_ADDR - 64) 0x));/* ori sp, sp, low(ENVP_ADDR) */ @@ -603,48 +619,49 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, stl_raw(p++, 0x); /* nop */ /* YAMON subroutines */ -p = (uint32_t *) (base + 0x800); -stl_raw(p++, 0x03e8); /* jr ra */ -stl_raw(p++, 0x2402); /* li v0,0 */ - /* 808 YAMON print */ -stl_raw(p++, 0x03e06821); /* move t5,ra */ -stl_raw(p++, 0x00805821); /* move t3,a0 */ -stl_raw(p++, 0x00a05021); /* move t2,a1 */ -stl_raw(p++, 0x9144); /* lbu a0,0(t2) */ -stl_raw(p++, 0x254a0001); /* addiu t2,t2,1 */ -stl_raw(p++, 0x1085); /* beqz a0,834 */ -stl_raw(p++, 0x); /* nop */ -stl_raw(p++, 0x0ff0021c); /* jal 870 */ -stl_raw(p++, 0x); /* nop */ -stl_raw(p++, 0x08000205); /* j 814 */ -stl_raw(p++, 0x); /* nop */ -stl_raw(p++, 0x01a8);
[Qemu-devel][PATCH 07/12] KVM/MIPS: QEMU - Kernel interface for KVM/MIPS
--- linux-headers/asm-mips/kvm.h | 94 +++ linux-headers/asm-mips/kvm_para.h | 10 + 2 files changed, 104 insertions(+) create mode 100644 linux-headers/asm-mips/kvm.h create mode 100644 linux-headers/asm-mips/kvm_para.h diff --git a/linux-headers/asm-mips/kvm.h b/linux-headers/asm-mips/kvm.h new file mode 100644 index 000..6d37e5c --- /dev/null +++ b/linux-headers/asm-mips/kvm.h @@ -0,0 +1,94 @@ +/* + * 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 sanj...@kymasys.com + */ + +#ifndef __LINUX_KVM_MIPS_H +#define __LINUX_KVM_MIPS_H + +#include linux/types.h + +#define __KVM_MIPS + +#define N_MIPS_COPROC_REGS 32 +#define N_MIPS_COPROC_SEL 8 + +/* + * Coprocessor 0 register names + */ +#defineMIPS_CP0_TLB_INDEX 0 +#defineMIPS_CP0_TLB_RANDOM 1 +#defineMIPS_CP0_TLB_LOW2 +#defineMIPS_CP0_TLB_LO02 +#defineMIPS_CP0_TLB_LO13 +#defineMIPS_CP0_TLB_CONTEXT4 +#defineMIPS_CP0_TLB_PG_MASK5 +#defineMIPS_CP0_TLB_WIRED 6 +#defineMIPS_CP0_HWRENA 7 +#defineMIPS_CP0_BAD_VADDR 8 +#defineMIPS_CP0_COUNT 9 +#defineMIPS_CP0_TLB_HI 10 +#defineMIPS_CP0_COMPARE11 +#defineMIPS_CP0_STATUS 12 +#defineMIPS_CP0_CAUSE 13 +#defineMIPS_CP0_EXC_PC 14 +#defineMIPS_CP0_PRID 15 +#defineMIPS_CP0_CONFIG 16 +#defineMIPS_CP0_LLADDR 17 +#defineMIPS_CP0_WATCH_LO 18 +#defineMIPS_CP0_WATCH_HI 19 +#defineMIPS_CP0_TLB_XCONTEXT 20 +#defineMIPS_CP0_ECC26 +#defineMIPS_CP0_CACHE_ERR 27 +#defineMIPS_CP0_TAG_LO 28 +#defineMIPS_CP0_TAG_HI 29 +#defineMIPS_CP0_ERROR_PC 30 +#defineMIPS_CP0_DEBUG 23 +#defineMIPS_CP0_DEPC 24 +#defineMIPS_CP0_PERFCNT25 +#defineMIPS_CP0_ERRCTL 26 +#defineMIPS_CP0_DATA_LO28 +#defineMIPS_CP0_DATA_HI29 +#defineMIPS_CP0_DESAVE 31 + + +/* for KVM_GET_REGS and KVM_SET_REGS */ +struct kvm_regs { +__u32 gprs[32]; +__u32 hi; +__u32 lo; +__u32 pc; + +ulong cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; +}; + +/* for KVM_GET_SREGS and KVM_SET_SREGS */ +struct kvm_sregs { +}; + +/* for KVM_GET_FPU and KVM_SET_FPU */ +struct kvm_fpu { +}; + +struct kvm_debug_exit_arch { +}; + +/* for KVM_SET_GUEST_DEBUG */ +struct kvm_guest_debug_arch { +}; + +/* definition of registers in kvm_run */ +struct kvm_sync_regs { +}; + +struct kvm_mips_interrupt { + /* in */ +__u32 cpu; + __u32 irq; +}; + +#endif /* __LINUX_KVM_MIPS_H */ diff --git a/linux-headers/asm-mips/kvm_para.h b/linux-headers/asm-mips/kvm_para.h new file mode 100644 index 000..d1058b4 --- /dev/null +++ b/linux-headers/asm-mips/kvm_para.h @@ -0,0 +1,10 @@ +/* + * 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 sanj...@kymasys.com + */ + + -- 1.7.11.3 -- 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
[Qemu-devel][PATCH 08/12] KVM/MIPS: Enable KVM/MIPS for MIPS targets. Add MIPS GIC code to the build.
--- configure | 17 +++-- hw/mips/Makefile.objs | 2 +- target-mips/Makefile.objs | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/configure b/configure index bf5970f..5447661 100755 --- a/configure +++ b/configure @@ -1370,7 +1370,12 @@ case $cpu in bigendian=yes fi ;; - hppa|m68k|mips|mips64|ppc|ppc64|s390|s390x|sparc|sparc64) + mips|mips64) +if check_define __MIPSEB__; then + bigendian=yes +fi + ;; + hppa|m68k|ppc|ppc64|s390|s390x|sparc|sparc64) bigendian=yes ;; esac @@ -3844,6 +3849,9 @@ if test $linux = yes ; then # For most CPUs the kernel architecture name and QEMU CPU name match. linux_arch=$cpu ;; + mips|mips64) +symlink $source_path/linux-headers/asm-mips linux-headers/asm +;; esac # For non-KVM architectures we will not have asm headers if [ -e $source_path/linux-headers/asm-$linux_arch ]; then @@ -4074,7 +4082,7 @@ case $target_arch2 in echo CONFIG_NO_XEN=y $config_target_mak esac case $target_arch2 in - i386|x86_64|ppcemb|ppc|ppc64|s390x) + i386|x86_64|ppcemb|ppc|ppc64|s390x|mipsel|mips) # Make sure the target and host cpus are compatible if test $kvm = yes -a $target_softmmu = yes -a \ \( $target_arch2 = $cpu -o \ @@ -4082,6 +4090,8 @@ case $target_arch2 in \( $target_arch2 = ppc64 -a $cpu = ppc \) -o \ \( $target_arch2 = ppc-a $cpu = ppc64 \) -o \ \( $target_arch2 = ppcemb -a $cpu = ppc64 \) -o \ + \( $target_arch2 = mipsel -a $cpu = mips \) -o \ + \( $target_arch2 = mips -a $cpu = mips \) -o \ \( $target_arch2 = x86_64 -a $cpu = i386 \) -o \ \( $target_arch2 = i386 -a $cpu = x86_64 \) \) ; then echo CONFIG_KVM=y $config_target_mak @@ -4285,6 +4295,9 @@ if test $target_linux_user = yes -o $target_bsd_user = yes ; then *) ldflags=$linker_script $ldflags ;; + mips|mipsel|mipseb|mips64) +symlink $source_path/linux-headers/asm-mips linux-headers/asm +;; esac fi diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs index 29a5d0d..c013bac 100644 --- a/hw/mips/Makefile.objs +++ b/hw/mips/Makefile.objs @@ -1,6 +1,6 @@ obj-y = mips_r4k.o mips_jazz.o mips_malta.o mips_mipssim.o obj-y += mips_addr.o mips_timer.o mips_int.o -obj-y += gt64xxx.o mc146818rtc.o +obj-y += gt64xxx.o mc146818rtc.o mips_gic.o obj-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o obj-y := $(addprefix ../,$(obj-y)) diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs index 119c816..1956190 100644 --- a/target-mips/Makefile.objs +++ b/target-mips/Makefile.objs @@ -1,2 +1,3 @@ obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o obj-$(CONFIG_SOFTMMU) += machine.o +obj-$(CONFIG_KVM) += kvm.o -- 1.7.11.3 -- 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
[Qemu-devel][PATCH 09/12] KVM/MIPS: set sigmask length to 16 for MIPS targets.
--- kvm-all.c | 5 + 1 file changed, 5 insertions(+) diff --git a/kvm-all.c b/kvm-all.c index 4decfdc..2ac9e88 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -1966,7 +1966,12 @@ int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset) sigmask = g_malloc(sizeof(*sigmask) + sizeof(*sigset)); +#ifdef TARGET_MIPS +/* seems to be 16 for MIPS */ +sigmask-len = 16; +#else sigmask-len = 8; +#endif memcpy(sigmask-sigset, sigset, sizeof(*sigset)); r = kvm_vcpu_ioctl(cpu, KVM_SET_SIGNAL_MASK, sigmask); g_free(sigmask); -- 1.7.11.3 -- 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 v2 11/18] KVM/MIPS32: Routines to handle specific traps/exceptions while executing the guest.
On Feb 18, 2013, at 1:44 AM, Gleb Natapov wrote: On Fri, Feb 15, 2013 at 11:10:46AM -0500, Sanjay Lal wrote: On Feb 6, 2013, at 8:20 AM, Gleb Natapov wrote: On Wed, Nov 21, 2012 at 06:34:09PM -0800, Sanjay Lal wrote: +static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva) +{ + gpa_t gpa; + uint32_t kseg = KSEGX(gva); + + if ((kseg == CKSEG0) || (kseg == CKSEG1)) You seems to be using KVM_GUEST_KSEGX variants on gva in all other places. Why not here? This function is invoked to handle 2 scenarios: (1) Parse the boot code config tables setup by QEMU's Malta emulation. The pointers in the tables are actual KSEG0 addresses (unmapped, cached) and not Guest KSEG0 addresses. Where is it called for that purpose? The only place where gva_to_gpa callback is called is in kvm/kvm_mips_emul.c:kvm_mips_emulate_(store|load) Load/stores from/to KSEG1 generate the Address Error Load/Store exceptions. The handler calls kvm_mips_emul.c:kvm_mips_emulate_(store|load) which then call the gva_to_gpa callback. (2) Handle I/O accesses by the guest. On MIPS platforms, I/O device registers are mapped into the KSEG1 address space (unmapped, uncached). Again like (1) these are actual KSEG1 addresses, which cause an exception and are passed onto QEMU for I/O emulation. So guest KSEG1 registers is mapped to 0xA000-0xBFFF ranges just like on a host? Can you give corresponding segment names to those ranges Guest User address space: 0x - 0x4000 (useg?) Guest Kernel Unmapped: 0x4000 - 0x6000 (kseg0?) Guest Kernel Mapped:0x6000 - 0x8000 (?) Yes, now that you mention it :-). I'll add a corresponding Guest Kernel KSEG1 segment name. Regards Sanjay -- 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 v2 07/18] KVM/MIPS32: MMU/TLB operations for the Guest.
On Feb 15, 2013, at 1:41 PM, Gleb Natapov wrote: On Fri, Feb 15, 2013 at 01:19:29PM -0500, Sanjay Lal wrote: On Feb 6, 2013, at 7:08 AM, Gleb Natapov wrote: +static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) +{ + pfn_t pfn; + + if (kvm-arch.guest_pmap[gfn] != KVM_INVALID_PAGE) + return; + + pfn =kvm_mips_gfn_to_pfn(kvm, gfn); This call should be in srcu read section since it access memory slots which are srcu protected. You should test with RCU debug enabled. kvm_mips_gfn_to_pfn just maps to gfn_to_pfn. I don't see an instance where gfn_to_pfn is in a scru read section? Where are you looking? On x86 if vcpu is not in a guest mode it is in srcu read section. The lock is taken immediately after exit and released before entry. This is because x86 access memory slots a lot. Other arches, that do not access memory slots as much, take the lock around each individual access. As far as I see this is the only place in MIPS kvm where this is needed. Ah I see what you mean. I'll wrap the access in a scru read section. + +uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu) +{ + uint32_t inst; + struct mips_coproc *cop0 __unused = vcpu-arch.cop0; + int index; + ulong paddr, flags; + + if (KVM_GUEST_KSEGX((ulong) opc) KVM_GUEST_KSEG0 || + KVM_GUEST_KSEGX((ulong) opc) == KVM_GUEST_KSEG23) { + local_irq_save(flags); + index = kvm_mips_host_tlb_lookup(vcpu, (ulong) opc); + if (index = 0) { + inst = *(opc); Here and in some more places below you access __user memory. Shouldn't you use get_user() to access it? What prevents the kernel crash by access fault here if userspace remaps the memory to be non-readable? Hmm, may be it uses guest translation here so it cannot happen, but still, sparse will not be happy and kvm_mips_translate_guest_kseg0_to_hpa() case below uses host translation anyway. Actually, I don't need the __user declaration in most cases, since KVM/MIPS handles mapping the page (if needed) and does not rely on the usual kernel mechanisms. Yes I see that you check/populate tlb for non KVM_GUEST_KSEG0 access, for kvm_mips_translate_guest_kseg0_to_hpa() you do not, but now I notice that you are not using the address directly but uses CKSEG0ADDR() on it, which, as far as I can tell, gives you kernel mapping for the page, correct? Why this is better than using get_user()? To save tlb entries? Couple of reasons, KVM/MIPS uses its own TLB handlers while the guest is running, so get_user is not an option, and (2) it does save on TLBs when accessing the guest memory via KSEG0. -- 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 v2 11/18] KVM/MIPS32: Routines to handle specific traps/exceptions while executing the guest.
On Feb 6, 2013, at 8:20 AM, Gleb Natapov wrote: On Wed, Nov 21, 2012 at 06:34:09PM -0800, Sanjay Lal wrote: +static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva) +{ +gpa_t gpa; +uint32_t kseg = KSEGX(gva); + +if ((kseg == CKSEG0) || (kseg == CKSEG1)) You seems to be using KVM_GUEST_KSEGX variants on gva in all other places. Why not here? This function is invoked to handle 2 scenarios: (1) Parse the boot code config tables setup by QEMU's Malta emulation. The pointers in the tables are actual KSEG0 addresses (unmapped, cached) and not Guest KSEG0 addresses. (2) Handle I/O accesses by the guest. On MIPS platforms, I/O device registers are mapped into the KSEG1 address space (unmapped, uncached). Again like (1) these are actual KSEG1 addresses, which cause an exception and are passed onto QEMU for I/O emulation. Regards Sanjay -- 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 v2 07/18] KVM/MIPS32: MMU/TLB operations for the Guest.
On Feb 6, 2013, at 7:08 AM, Gleb Natapov wrote: +static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) +{ +pfn_t pfn; + +if (kvm-arch.guest_pmap[gfn] != KVM_INVALID_PAGE) +return; + +pfn =kvm_mips_gfn_to_pfn(kvm, gfn); This call should be in srcu read section since it access memory slots which are srcu protected. You should test with RCU debug enabled. kvm_mips_gfn_to_pfn just maps to gfn_to_pfn. I don't see an instance where gfn_to_pfn is in a scru read section? + +uint32_t kvm_get_inst(uint32_t *opc, struct kvm_vcpu *vcpu) +{ +uint32_t inst; +struct mips_coproc *cop0 __unused = vcpu-arch.cop0; +int index; +ulong paddr, flags; + +if (KVM_GUEST_KSEGX((ulong) opc) KVM_GUEST_KSEG0 || +KVM_GUEST_KSEGX((ulong) opc) == KVM_GUEST_KSEG23) { +local_irq_save(flags); +index = kvm_mips_host_tlb_lookup(vcpu, (ulong) opc); +if (index = 0) { +inst = *(opc); Here and in some more places below you access __user memory. Shouldn't you use get_user() to access it? What prevents the kernel crash by access fault here if userspace remaps the memory to be non-readable? Hmm, may be it uses guest translation here so it cannot happen, but still, sparse will not be happy and kvm_mips_translate_guest_kseg0_to_hpa() case below uses host translation anyway. Actually, I don't need the __user declaration in most cases, since KVM/MIPS handles mapping the page (if needed) and does not rely on the usual kernel mechanisms. -- 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 v2 09/18] KVM/MIPS32: COP0 accesses profiling.
On Feb 6, 2013, at 8:17 AM, Gleb Natapov wrote: On Wed, Nov 21, 2012 at 06:34:07PM -0800, Sanjay Lal wrote: +int kvm_mips_dump_stats(struct kvm_vcpu *vcpu) +{ +int i, j __unused; +#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS +printk(\nKVM VCPU[%d] COP0 Access Profile:\n, vcpu-vcpu_id); +for (i = 0; i N_MIPS_COPROC_REGS; i++) { +for (j = 0; j N_MIPS_COPROC_SEL; j++) { +if (vcpu-arch.cop0-stat[i][j]) +printk(%s[%d]: %lu\n, kvm_cop0_str[i], j, + vcpu-arch.cop0-stat[i][j]); +} +} +#endif + +return 0; +} You need to use ftrace event for that. Much more flexible with perf integration and no need to recompile to enabled/disable. -- Gleb. Agreed, I'll start using trace for keeping track of COP0 accesses. Regards Sanjay -- 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 v2 00/18] KVM for MIPS32 Processors
On Jan 24, 2013, at 10:05 AM, Ralf Baechle wrote: On Wed, Nov 21, 2012 at 06:33:58PM -0800, Sanjay Lal wrote: I've queued the patch set. I've done a few stylistic changes such as getting rid of all use of ulong and u_long data types in favor of unsigned long. I also ran into the following modpost error ERROR: kvm_arch_vcpu_postcreate [arch/mips/kvm/kvm.ko] undefined! which I fixed by adding a trivial kvm_arch_vcpu_postcreate function: intkvm_arch_vcpu_postcreate((struct kvm_vcpu *vcpu) { return 0; } which may or may not be sufficient. Enabling CONFIG_KVM_MIPS_VZ was causing build errors. Since the support code for the VZ ASE is not part of this series, I've ripped that out entirely. As for the __unused references, some are indeed unused with no apparent reason for why the variables shouldn't be removed. There are also variables marked __unused which are being used - so no point in marking them. I've sorted that, too. Ralf Thanks Ralf. the kvm_arch_vcpu_postcreate() fix is fine, as are the others. Regards Sanjay -- 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 v2 00/18] KVM for MIPS32 Processors
On Nov 26, 2012, at 1:53 PM, David Daney wrote: I have several general questions about this patch... On 11/21/2012 06:33 PM, Sanjay Lal wrote: The following patchset implements KVM support for MIPS32R2 processors, using Trap Emulate, with basic runtime binary translation to improve performance. The goal has been to keep the Guest kernel changes to a minimum. What is the point of minimizing guest kernel changes? Because you are using an invented memory map, instead of the architecturally defined map, there is no hope of running a single kernel image both natively and as a guest. So why do you care about how many changes there are. It makes porting the code easier. Since we need a special guest kernel, keeping the changes to minimum helps when migrating from one Linux version to another. At this point we've migrated the code from 2.6.32 to 3.7 with 3.0 along the way, without any issues and anything more than an automatic merge. The patch is against Linux 3.7-rc6. This is Version 2 of the patch set. There is a companion patchset for QEMU that adds KVM support for the MIPS target. KVM/MIPS should support MIPS32-R2 processors and beyond. It has been tested on the following platforms: - Malta Board with FPGA based 34K (Little Endian). - Sigma Designs TangoX board with a 24K based 8654 SoC (Little Endian). - Malta Board with 74K @ 1GHz (Little Endian). - OVPSim MIPS simulator from Imperas emulating a Malta board with 24Kc and 1074Kc cores (Little Endian). Unlike x86, there is no concept of a canonical MIPS system for you to implement. So the choice of emulating a Malta or one of the SigmaDesigns boards doesn't seem to me to give you anything. Why not just define the guest system to be exactly the facilities provided by the VirtIO drivers? The above list is a list of host systems that we've tested KVM/MIPS on. The guest kernel runs on the Malta system that is emulated by QEMU regardless of the host system. And yes we do support VirtIO devices on the emulated Malta board to speed up I/O, but since they attach to the emulated systems' PCI bus, we still need a kernel and system that supports PCI. Just an FYI, we'll be posting the QEMU patch set shortly. Perhaps it is obvious from the patches, but I wasn't able to figure out how you solve the problem of the Root/Host kernel clobbering the K0 and K1 registers in its exception handlers. These registers are also used by the Guest kernel (aren't they)? Yes k0/k1 do need to be saved as they are used by both the guest and host kernels. The code is in kvm_locore.S around line 250 where the L1 exception vectors are installed. Regards Sanjay -- 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 02/18] KVM/MIPS32: Arch specific KVM data structures.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/kvm.h | 55 arch/mips/include/asm/kvm_host.h | 669 +++ 2 files changed, 724 insertions(+) create mode 100644 arch/mips/include/asm/kvm.h create mode 100644 arch/mips/include/asm/kvm_host.h diff --git a/arch/mips/include/asm/kvm.h b/arch/mips/include/asm/kvm.h new file mode 100644 index 000..85789ea --- /dev/null +++ b/arch/mips/include/asm/kvm.h @@ -0,0 +1,55 @@ +/* +* 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 sanj...@kymasys.com +*/ + +#ifndef __LINUX_KVM_MIPS_H +#define __LINUX_KVM_MIPS_H + +#include linux/types.h + +#define __KVM_MIPS + +#define N_MIPS_COPROC_REGS 32 +#define N_MIPS_COPROC_SEL 8 + +/* for KVM_GET_REGS and KVM_SET_REGS */ +struct kvm_regs { + __u32 gprs[32]; + __u32 hi; + __u32 lo; + __u32 pc; + + __u32 cp0reg[N_MIPS_COPROC_REGS][N_MIPS_COPROC_SEL]; +}; + +/* for KVM_GET_SREGS and KVM_SET_SREGS */ +struct kvm_sregs { +}; + +/* for KVM_GET_FPU and KVM_SET_FPU */ +struct kvm_fpu { +}; + +struct kvm_debug_exit_arch { +}; + +/* for KVM_SET_GUEST_DEBUG */ +struct kvm_guest_debug_arch { +}; + +struct kvm_mips_interrupt { + /* in */ + __u32 cpu; + __u32 irq; +}; + +/* definition of registers in kvm_run */ +struct kvm_sync_regs { +}; + +#endif /* __LINUX_KVM_MIPS_H */ diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h new file mode 100644 index 000..181fa58 --- /dev/null +++ b/arch/mips/include/asm/kvm_host.h @@ -0,0 +1,669 @@ +/* +* 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 sanj...@kymasys.com +*/ + +#ifndef __MIPS_KVM_HOST_H__ +#define __MIPS_KVM_HOST_H__ + +#include linux/mutex.h +#include linux/hrtimer.h +#include linux/interrupt.h +#include linux/types.h +#include linux/kvm.h +#include linux/kvm_types.h +#include linux/threads.h +#include linux/spinlock.h + + +#define KVM_MAX_VCPUS 1 +#define KVM_MEMORY_SLOTS 8 +/* memory slots that does not exposed to userspace */ +#define KVM_PRIVATE_MEM_SLOTS 0 + +#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 + +/* Don't support huge pages */ +#define KVM_HPAGE_GFN_SHIFT(x) 0 + +/* We don't currently support large pages. */ +#define KVM_NR_PAGE_SIZES 1 +#define KVM_PAGES_PER_HPAGE(x) 1 + + + +/* Special address that contains the comm page, used for reducing # of traps */ +#define KVM_GUEST_COMMPAGE_ADDR 0x0 + +#define KVM_GUEST_KERNEL_MODE(vcpu) ((kvm_read_c0_guest_status(vcpu-arch.cop0) (ST0_EXL | ST0_ERL)) || \ + ((kvm_read_c0_guest_status(vcpu-arch.cop0) KSU_USER) == 0)) + +#define KVM_GUEST_KUSEG 0xUL +#define KVM_GUEST_KSEG0 0x4000UL +#define KVM_GUEST_KSEG230x6000UL +#define KVM_GUEST_KSEGX(a) ((_ACAST32_(a)) 0x6000) +#define KVM_GUEST_CPHYSADDR(a) ((_ACAST32_(a)) 0x1fff) + +#define KVM_GUEST_CKSEG0ADDR(a)(KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG0) +#define KVM_GUEST_CKSEG1ADDR(a)(KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG1) +#define KVM_GUEST_CKSEG23ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG23) + +/* + * Map an address to a certain kernel segment + */ +#define KVM_GUEST_KSEG0ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG0) +#define KVM_GUEST_KSEG1ADDR(a) (KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG1) +#define KVM_GUEST_KSEG23ADDR(a)(KVM_GUEST_CPHYSADDR(a) | KVM_GUEST_KSEG23) + +#define KVM_INVALID_PAGE0xdeadbeef +#define KVM_INVALID_INST0xdeadbeef +#define KVM_INVALID_ADDR0xdeadbeef + +#define KVM_MALTA_GUEST_RTC_ADDR0xb870UL + +#ifndef __unused +#define __unused __attribute__((unused)) +#endif + +#define GUEST_TICKS_PER_JIFFY (4000/HZ) +#define MS_TO_NS(x) (x * 1E6L) + +#define CAUSEB_DC 27 +#define CAUSEF_DC (_ULCAST_(1)27) + +struct kvm; +struct kvm_run; +struct kvm_vcpu; +struct kvm_interrupt; + +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); +extern bool(*kvm_mips_is_error_pfn) (pfn_t pfn); + +struct kvm_vm_stat { + u32 remote_tlb_flush; +}; + +struct kvm_vcpu_stat { + u32 wait_exits; + u32 cache_exits; + u32 signal_exits; + u32 int_exits; + u32 cop_unusable_exits; + u32 tlbmod_exits; + u32 tlbmiss_ld_exits; + u32 tlbmiss_st_exits; + u32
[PATCH v2 00/18] KVM for MIPS32 Processors
The following patchset implements KVM support for MIPS32R2 processors, using Trap Emulate, with basic runtime binary translation to improve performance. The goal has been to keep the Guest kernel changes to a minimum. The patch is against Linux 3.7-rc6. This is Version 2 of the patch set. There is a companion patchset for QEMU that adds KVM support for the MIPS target. KVM/MIPS should support MIPS32-R2 processors and beyond. It has been tested on the following platforms: - Malta Board with FPGA based 34K (Little Endian). - Sigma Designs TangoX board with a 24K based 8654 SoC (Little Endian). - Malta Board with 74K @ 1GHz (Little Endian). - OVPSim MIPS simulator from Imperas emulating a Malta board with 24Kc and 1074Kc cores (Little Endian). Both Guest kernel and Guest Userspace execute in UM. The Guest address space is as folows: Guest User address space: 0x - 0x4000 Guest Kernel Unmapped: 0x4000 - 0x6000 Guest Kernel Mapped:0x6000 - 0x8000 As a result, Guest Usermode virtual memory is limited to 1GB. Relase Notes (1) 16K Page Size: Both Host Kernel and Guest Kernel should have the same page size, currently at least 16K. Note that due to cache aliasing issues, 4K page sizes are NOT supported. (2) No HugeTLB/Large Page Support: Both the host kernel and Guest kernel should have the page size set to at least 16K. This will be implemented in a future release. (3) SMP Guests to not work Linux-3.7-rc2 based SMP guest hangs due to the following code sequence in the generated TLB handlers: LL/TLBP/SC Since the TLBP instruction causes a trap the reservation gets cleared when we ERET back to the guest. This causes the guest to hang in an infinite loop. As a workaround, make sure that CONFIG_SMP is disabled for Guest kernels. This will be fixed in a future release. (4) FPU support: Currently KVM/MIPS emulates a 24K CPU without a FPU. This will be fixed in a future release -- Sanjay Lal (18): KVM/MIPS32: Infrastructure/build files. KVM/MIPS32: Arch specific KVM data structures. KVM/MIPS32: Entry point for trampolining to the guest and trap handlers. KVM/MIPS32: MIPS arch specific APIs for KVM KVM/MIPS32: KVM Guest kernel support. KVM/MIPS32: Privileged instruction/target branch emulation. KVM/MIPS32: MMU/TLB operations for the Guest. KVM/MIPS32: Release notes and KVM module Makefile KVM/MIPS32: COP0 accesses profiling. KVM/MIPS32: Guest interrupt delivery. KVM/MIPS32: Routines to handle specific traps/exceptions while executing the guest. MIPS: Export routines needed by the KVM module. MIPS: If KVM is enabled then use the KVM specific routine to flush the TLBs on a ASID wrap. MIPS: ASM offsets for VCPU arch specific fields. MIPS: Pull in MIPS fix: fix endless loop when processing signals for kernel tasks. MIPS: Export symbols used by KVM/MIPS module KVM/MIPS32: Do not call vcpu_load when injecting interrupts. KVM/MIPS32: Binary patching of select privileged instructions. arch/mips/Kbuild|4 + arch/mips/Kconfig | 18 + arch/mips/configs/malta_kvm_defconfig | 2268 +++ arch/mips/configs/malta_kvm_guest_defconfig | 2237 ++ arch/mips/include/asm/kvm.h | 55 + arch/mips/include/asm/kvm_host.h| 669 arch/mips/include/asm/mach-generic/spaces.h |9 +- arch/mips/include/asm/mmu_context.h |6 + arch/mips/include/asm/processor.h |5 + arch/mips/include/asm/uaccess.h | 11 +- arch/mips/kernel/asm-offsets.c | 66 + arch/mips/kernel/binfmt_elfo32.c|4 + arch/mips/kernel/cevt-r4k.c |4 + arch/mips/kernel/entry.S|7 +- arch/mips/kernel/smp.c |1 + arch/mips/kernel/traps.c|7 +- arch/mips/kvm/00README.txt | 31 + arch/mips/kvm/Kconfig | 60 + arch/mips/kvm/Makefile | 17 + arch/mips/kvm/kvm_cb.c | 14 + arch/mips/kvm/kvm_locore.S | 651 arch/mips/kvm/kvm_mips.c| 965 arch/mips/kvm/kvm_mips_comm.h | 23 + arch/mips/kvm/kvm_mips_commpage.c | 37 + arch/mips/kvm/kvm_mips_dyntrans.c | 149 ++ arch/mips/kvm/kvm_mips_emul.c | 1840 ++ arch/mips/kvm/kvm_mips_int.c| 243 +++ arch/mips/kvm/kvm_mips_int.h| 49 + arch/mips/kvm/kvm_mips_opcode.h | 24 + arch/mips/kvm/kvm_mips_stats.c | 81 + arch/mips/kvm/kvm_tlb.c | 932 +++ arch/mips/kvm/kvm_trap_emul.c | 482 ++ arch/mips/kvm/trace.h
[PATCH v2 18/18] KVM/MIPS32: Binary patching of select privileged instructions.
Currently, the following instructions are translated: - CACHE (indexed) - CACHE (va based): translated to a synci, overkill on D-CACHE operations, but still much faster than a trap. - mfc0/mtc0: the virtual COP0 registers for the guest are implemented as 2-D array [COP#][SEL] and this is mapped into the guest kernel address space @ VA 0x0. mfc0/mtc0 operations are transformed to load/stores. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips_comm.h | 23 ++ arch/mips/kvm/kvm_mips_commpage.c | 37 ++ arch/mips/kvm/kvm_mips_dyntrans.c | 149 ++ 3 files changed, 209 insertions(+) create mode 100644 arch/mips/kvm/kvm_mips_comm.h create mode 100644 arch/mips/kvm/kvm_mips_commpage.c create mode 100644 arch/mips/kvm/kvm_mips_dyntrans.c diff --git a/arch/mips/kvm/kvm_mips_comm.h b/arch/mips/kvm/kvm_mips_comm.h new file mode 100644 index 000..7e903ec --- /dev/null +++ b/arch/mips/kvm/kvm_mips_comm.h @@ -0,0 +1,23 @@ +/* +* 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. +* +* KVM/MIPS: commpage: mapped into get kernel space +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#ifndef __KVM_MIPS_COMMPAGE_H__ +#define __KVM_MIPS_COMMPAGE_H__ + +struct kvm_mips_commpage { + struct mips_coproc cop0;/* COP0 state is mapped into Guest kernel via commpage */ +}; + +#define KVM_MIPS_COMM_EIDI_OFFSET 0x0 + +extern void kvm_mips_commpage_init(struct kvm_vcpu *vcpu); + +#endif /* __KVM_MIPS_COMMPAGE_H__ */ diff --git a/arch/mips/kvm/kvm_mips_commpage.c b/arch/mips/kvm/kvm_mips_commpage.c new file mode 100644 index 000..3873b1e --- /dev/null +++ b/arch/mips/kvm/kvm_mips_commpage.c @@ -0,0 +1,37 @@ +/* +* 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. +* +* commpage, currently used for Virtual COP0 registers. +* Mapped into the guest kernel @ 0x0. +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/errno.h +#include linux/err.h +#include linux/module.h +#include linux/vmalloc.h +#include linux/fs.h +#include linux/bootmem.h +#include asm/page.h +#include asm/cacheflush.h +#include asm/mmu_context.h + +#include linux/kvm_host.h + +#include kvm_mips_comm.h + +void kvm_mips_commpage_init(struct kvm_vcpu *vcpu) +{ + struct kvm_mips_commpage *page = vcpu-arch.kseg0_commpage; + memset(page, 0, sizeof(struct kvm_mips_commpage)); + + /* Specific init values for fields */ + vcpu-arch.cop0 = page-cop0; + memset(vcpu-arch.cop0, 0, sizeof(struct mips_coproc)); + + return; +} diff --git a/arch/mips/kvm/kvm_mips_dyntrans.c b/arch/mips/kvm/kvm_mips_dyntrans.c new file mode 100644 index 000..c657b37 --- /dev/null +++ b/arch/mips/kvm/kvm_mips_dyntrans.c @@ -0,0 +1,149 @@ +/* +* 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. +* +* KVM/MIPS: Binary Patching for privileged instructions, reduces traps. +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/errno.h +#include linux/err.h +#include linux/kvm_host.h +#include linux/module.h +#include linux/vmalloc.h +#include linux/fs.h +#include linux/bootmem.h + +#include kvm_mips_comm.h + +#define SYNCI_TEMPLATE 0x041f +#define SYNCI_BASE(x) (((x) 21) 0x1f) +#define SYNCI_OFFSET((x) 0x) + +#define LW_TEMPLATE 0x8c00 +#define CLEAR_TEMPLATE 0x0020 +#define SW_TEMPLATE 0xac00 + +int +kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc, + struct kvm_vcpu *vcpu) +{ + int result = 0; + ulong kseg0_opc; + uint32_t synci_inst = 0x0; + + /* Replace the CACHE instruction, with a NOP */ + kseg0_opc = + CKSEG0ADDR(kvm_mips_translate_guest_kseg0_to_hpa + (vcpu, (ulong) opc)); + memcpy((void *)kseg0_opc, (void *)synci_inst, sizeof(uint32_t)); + mips32_SyncICache(kseg0_opc, 32); + + return result; +} + +/* + * Address based CACHE instructions are transformed into synci(s). A little heavy + * for just D-cache invalidates, but avoids an expensive trap + */ +int +kvm_mips_trans_cache_va(uint32_t inst, uint32_t *opc, + struct kvm_vcpu *vcpu) +{ + int result = 0; + ulong kseg0_opc; + uint32_t synci_inst = SYNCI_TEMPLATE, base, offset; + + base = (inst 21) 0x1f; + offset = inst 0x; + synci_inst |= (base 21); + synci_inst |= offset; + + kseg0_opc
[PATCH v2 14/18] MIPS: ASM offsets for VCPU arch specific fields.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kernel/asm-offsets.c | 66 ++ 1 file changed, 66 insertions(+) diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 0c4bce4..66895de 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -17,6 +17,8 @@ #include asm/ptrace.h #include asm/processor.h +#include linux/kvm_host.h + void output_ptreg_defines(void) { COMMENT(MIPS pt_regs offsets.); @@ -329,3 +331,67 @@ void output_pbe_defines(void) BLANK(); } #endif + +void output_kvm_defines(void) +{ + COMMENT( KVM/MIPS Specfic offsets. ); + DEFINE(VCPU_ARCH_SIZE, sizeof(struct kvm_vcpu_arch)); + OFFSET(VCPU_RUN, kvm_vcpu, run); + OFFSET(VCPU_HOST_ARCH, kvm_vcpu, arch); + + OFFSET(VCPU_HOST_EBASE, kvm_vcpu_arch, host_ebase); + OFFSET(VCPU_GUEST_EBASE, kvm_vcpu_arch, guest_ebase); + + OFFSET(VCPU_HOST_STACK, kvm_vcpu_arch, host_stack); + OFFSET(VCPU_HOST_GP, kvm_vcpu_arch, host_gp); + + OFFSET(VCPU_HOST_CP0_BADVADDR, kvm_vcpu_arch, host_cp0_badvaddr); + OFFSET(VCPU_HOST_CP0_CAUSE, kvm_vcpu_arch, host_cp0_cause); + OFFSET(VCPU_HOST_EPC, kvm_vcpu_arch, host_cp0_epc); + OFFSET(VCPU_HOST_ENTRYHI, kvm_vcpu_arch, host_cp0_entryhi); + + OFFSET(VCPU_GUEST_INST, kvm_vcpu_arch, guest_inst); + + OFFSET(VCPU_R0, kvm_vcpu_arch, gprs[0]); + OFFSET(VCPU_R1, kvm_vcpu_arch, gprs[1]); + OFFSET(VCPU_R2, kvm_vcpu_arch, gprs[2]); + OFFSET(VCPU_R3, kvm_vcpu_arch, gprs[3]); + OFFSET(VCPU_R4, kvm_vcpu_arch, gprs[4]); + OFFSET(VCPU_R5, kvm_vcpu_arch, gprs[5]); + OFFSET(VCPU_R6, kvm_vcpu_arch, gprs[6]); + OFFSET(VCPU_R7, kvm_vcpu_arch, gprs[7]); + OFFSET(VCPU_R8, kvm_vcpu_arch, gprs[8]); + OFFSET(VCPU_R9, kvm_vcpu_arch, gprs[9]); + OFFSET(VCPU_R10, kvm_vcpu_arch, gprs[10]); + OFFSET(VCPU_R11, kvm_vcpu_arch, gprs[11]); + OFFSET(VCPU_R12, kvm_vcpu_arch, gprs[12]); + OFFSET(VCPU_R13, kvm_vcpu_arch, gprs[13]); + OFFSET(VCPU_R14, kvm_vcpu_arch, gprs[14]); + OFFSET(VCPU_R15, kvm_vcpu_arch, gprs[15]); + OFFSET(VCPU_R16, kvm_vcpu_arch, gprs[16]); + OFFSET(VCPU_R17, kvm_vcpu_arch, gprs[17]); + OFFSET(VCPU_R18, kvm_vcpu_arch, gprs[18]); + OFFSET(VCPU_R19, kvm_vcpu_arch, gprs[19]); + OFFSET(VCPU_R20, kvm_vcpu_arch, gprs[20]); + OFFSET(VCPU_R21, kvm_vcpu_arch, gprs[21]); + OFFSET(VCPU_R22, kvm_vcpu_arch, gprs[22]); + OFFSET(VCPU_R23, kvm_vcpu_arch, gprs[23]); + OFFSET(VCPU_R24, kvm_vcpu_arch, gprs[24]); + OFFSET(VCPU_R25, kvm_vcpu_arch, gprs[25]); + OFFSET(VCPU_R26, kvm_vcpu_arch, gprs[26]); + OFFSET(VCPU_R27, kvm_vcpu_arch, gprs[27]); + OFFSET(VCPU_R28, kvm_vcpu_arch, gprs[28]); + OFFSET(VCPU_R29, kvm_vcpu_arch, gprs[29]); + OFFSET(VCPU_R30, kvm_vcpu_arch, gprs[30]); + OFFSET(VCPU_R31, kvm_vcpu_arch, gprs[31]); + OFFSET(VCPU_LO, kvm_vcpu_arch, lo); + OFFSET(VCPU_HI, kvm_vcpu_arch, hi); + OFFSET(VCPU_PC, kvm_vcpu_arch, pc); + OFFSET(VCPU_COP0, kvm_vcpu_arch, cop0); + OFFSET(VCPU_GUEST_KERNEL_ASID, kvm_vcpu_arch, guest_kernel_asid); + OFFSET(VCPU_GUEST_USER_ASID, kvm_vcpu_arch, guest_user_asid); + + OFFSET(COP0_TLB_HI, mips_coproc, reg[MIPS_CP0_TLB_HI][0]); + OFFSET(COP0_STATUS, mips_coproc, reg[MIPS_CP0_STATUS][0]); + BLANK(); +} -- 1.7.11.3 -- 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 12/18] MIPS: Export routines needed by the KVM module.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/mm/c-r4k.c | 6 -- arch/mips/mm/cache.c | 1 + arch/mips/mm/tlb-r4k.c | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 2b61462..1923063 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -136,7 +136,8 @@ static void __cpuinit r4k_blast_dcache_page_indexed_setup(void) r4k_blast_dcache_page_indexed = blast_dcache64_page_indexed; } -static void (* r4k_blast_dcache)(void); +void (* r4k_blast_dcache)(void); +EXPORT_SYMBOL(r4k_blast_dcache); static void __cpuinit r4k_blast_dcache_setup(void) { @@ -264,7 +265,8 @@ static void __cpuinit r4k_blast_icache_page_indexed_setup(void) r4k_blast_icache_page_indexed = blast_icache64_page_indexed; } -static void (* r4k_blast_icache)(void); +void (* r4k_blast_icache)(void); +EXPORT_SYMBOL(r4k_blast_icache); static void __cpuinit r4k_blast_icache_setup(void) { diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 07cec44..5aeb3eb 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -48,6 +48,7 @@ void (*flush_icache_all)(void); EXPORT_SYMBOL_GPL(local_flush_data_cache_page); EXPORT_SYMBOL(flush_data_cache_page); +EXPORT_SYMBOL(flush_icache_all); #ifdef CONFIG_DMA_NONCOHERENT diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 4b9b935..fd30887 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -13,6 +13,7 @@ #include linux/smp.h #include linux/mm.h #include linux/hugetlb.h +#include linux/module.h #include asm/cpu.h #include asm/bootinfo.h @@ -94,6 +95,7 @@ void local_flush_tlb_all(void) FLUSH_ITLB; EXIT_CRITICAL(flags); } +EXPORT_SYMBOL(local_flush_tlb_all); /* All entries common to a mm share an asid. To effectively flush these entries, we just bump the asid. */ -- 1.7.11.3 -- 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 07/18] KVM/MIPS32: MMU/TLB operations for the Guest.
- Note that this file is statically linked with the rest of the host kernel (KSEG0). This is because kernel modules are loaded into mapped space on MIPS and we want to make sure that we don't get any host kernel TLB faults while manipulating TLBs. - Virtual Guest TLBs are implemented as 64 entry array regardless of the number of host TLB entries. - Shadow TLBs map Guest virtual addresses to Host physical addresses. - TLB miss handling details: Guest KSEG0 TLBMISS (0x4000 – 0x6000): Transparent to the Guest. Guest KSEG2/3 (0x6000 – 0x8000) Guest UM TLBMISS (0x – 0x4000) Lookup in Guest/Virtual TLB If an entry doesn’t match deliver appropriate TLBMISS LD/ST exception to the guest If entry does exist in the Guest TLB and is NOT Valid Deliver TLB invalid exception to the guest If entry does exist in the Guest TLB and is VALID Inject the TLB entry into the Shadow TLB Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_tlb.c | 932 1 file changed, 932 insertions(+) create mode 100644 arch/mips/kvm/kvm_tlb.c diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c new file mode 100644 index 000..2d24333 --- /dev/null +++ b/arch/mips/kvm/kvm_tlb.c @@ -0,0 +1,932 @@ +/* +* 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. +* +* KVM/MIPS TLB handling, this file is part of the Linux host kernel so that +* TLB handlers run from KSEG0 +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/init.h +#include linux/sched.h +#include linux/smp.h +#include linux/mm.h +#include linux/delay.h +#include linux/module.h +#include linux/kvm_host.h + +#include asm/cpu.h +#include asm/bootinfo.h +#include asm/mmu_context.h +#include asm/pgtable.h +#include asm/cacheflush.h + +#undef CONFIG_MIPS_MT +#include asm/r4kcache.h +#define CONFIG_MIPS_MT + +#define KVM_GUEST_PC_TLB0 +#define KVM_GUEST_SP_TLB1 + +#define PRIx64 llx + +/* Use VZ EntryHi.EHINV to invalidate TLB entries */ +#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) (PAGE_SHIFT + 1))) + +atomic_t kvm_mips_instance; +EXPORT_SYMBOL(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); + +void (*kvm_mips_release_pfn_clean) (pfn_t pfn); +EXPORT_SYMBOL(kvm_mips_release_pfn_clean); + +bool(*kvm_mips_is_error_pfn) (pfn_t pfn); +EXPORT_SYMBOL(kvm_mips_is_error_pfn); + +uint32_t kvm_mips_get_kernel_asid(struct kvm_vcpu *vcpu) +{ + return vcpu-arch.guest_kernel_asid[smp_processor_id()] ASID_MASK; +} + + +uint32_t kvm_mips_get_user_asid(struct kvm_vcpu *vcpu) +{ + return vcpu-arch.guest_user_asid[smp_processor_id()] ASID_MASK; +} + +inline uint32_t kvm_mips_get_commpage_asid (struct kvm_vcpu *vcpu) +{ + return vcpu-kvm-arch.commpage_tlb; +} + + +/* + * Structure defining an tlb entry data set. + */ + +void kvm_mips_dump_host_tlbs(void) +{ + struct kvm_mips_tlb tlb; + int i; + ulong flags; + unsigned long old_entryhi; + unsigned long old_pagemask; + + local_irq_save(flags); + + old_entryhi = read_c0_entryhi(); + old_pagemask = read_c0_pagemask(); + + printk(HOST TLBs:\n); + printk(ASID: %#lx\n, read_c0_entryhi() ASID_MASK); + + for (i = 0; i current_cpu_data.tlbsize; i++) { + write_c0_index(i); + mtc0_tlbw_hazard(); + + tlb_read(); + tlbw_use_hazard(); + + tlb.tlb_hi = read_c0_entryhi(); + tlb.tlb_lo0 = read_c0_entrylo0(); + tlb.tlb_lo1 = read_c0_entrylo1(); + tlb.tlb_mask = read_c0_pagemask(); + + printk(TLB%c%3d Hi 0x%08lx , + (tlb.tlb_lo0 | tlb.tlb_lo1) MIPS3_PG_V ? ' ' : '*', + i, tlb.tlb_hi); + printk(Lo0=0x%09 PRIx64 %c%c attr %lx , + (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo0), + (tlb.tlb_lo0 MIPS3_PG_D) ? 'D' : ' ', + (tlb.tlb_lo0 MIPS3_PG_G) ? 'G' : ' ', + (tlb.tlb_lo0 3) 7); + printk(Lo1=0x%09 PRIx64 %c%c attr %lx sz=%lx\n, + (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo1), + (tlb.tlb_lo1 MIPS3_PG_D) ? 'D' : ' ', + (tlb.tlb_lo1 MIPS3_PG_G) ? 'G' : ' ', + (tlb.tlb_lo1 3) 7, tlb.tlb_mask); + } + write_c0_entryhi(old_entryhi); + write_c0_pagemask(old_pagemask); + mtc0_tlbw_hazard(); + local_irq_restore(flags); +} + +void
[PATCH v2 08/18] KVM/MIPS32: Release notes and KVM module Makefile
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/00README.txt | 31 +++ arch/mips/kvm/Makefile | 17 + 2 files changed, 48 insertions(+) create mode 100644 arch/mips/kvm/00README.txt create mode 100644 arch/mips/kvm/Makefile diff --git a/arch/mips/kvm/00README.txt b/arch/mips/kvm/00README.txt new file mode 100644 index 000..daaf280 --- /dev/null +++ b/arch/mips/kvm/00README.txt @@ -0,0 +1,31 @@ +KVM/MIPS Trap Emulate Release Notes += + +(1) KVM/MIPS should support MIPS32R2 and beyond. It has been tested on the following platforms: +Malta Board with FPGA based 34K +Sigma Designs TangoX board with a 24K based 8654 SoC. +Malta Board with 74K @ 1GHz + +(2) Both Guest kernel and Guest Userspace execute in UM. +Guest User address space: 0x - 0x4000 +Guest Kernel Unmapped: 0x4000 - 0x6000 +Guest Kernel Mapped:0x6000 - 0x8000 + +Guest Usermode virtual memory is limited to 1GB. + +(2) 16K Page Sizes: Both Host Kernel and Guest Kernel should have the same page size, currently at least 16K. +Note that due to cache aliasing issues, 4K page sizes are NOT supported. + +(3) No HugeTLB Support +Both the host kernel and Guest kernel should have the page size set to 16K. +This will be implemented in a future release. + +(4) KVM/MIPS does not have support for SMP Guests +Linux-3.7-rc2 based SMP guest hangs due to the following code sequence in the generated TLB handlers: + LL/TLBP/SC. Since the TLBP instruction causes a trap the reservation gets cleared + when we ERET back to the guest. This causes the guest to hang in an infinite loop. + This will be fixed in a future release. + +(5) Use Host FPU +Currently KVM/MIPS emulates a 24K CPU without a FPU. +This will be fixed in a future release diff --git a/arch/mips/kvm/Makefile b/arch/mips/kvm/Makefile new file mode 100644 index 000..f3ed378 --- /dev/null +++ b/arch/mips/kvm/Makefile @@ -0,0 +1,17 @@ +# Makefile for KVM support for MIPS +# + +common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o) + +EXTRA_CFLAGS += -Ivirt/kvm -Iarch/mips/kvm + +kvm-objs := $(common-objs) kvm_mips.o kvm_mips_emul.o kvm_locore.o kvm_mips_int.o \ +kvm_mips_stats.o kvm_mips_commpage.o kvm_mips_dyntrans.o + +ifdef CONFIG_KVM_MIPS_VZ +kvm-objs += kvm_vz.o +else +kvm-objs += kvm_trap_emul.o +endif +obj-$(CONFIG_KVM) += kvm.o +obj-y += kvm_tlb.o kvm_cb.o -- 1.7.11.3 -- 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 16/18] MIPS: Export symbols used by KVM/MIPS module
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kernel/smp.c | 1 + mm/bootmem.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 9005bf9..60ea489 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -83,6 +83,7 @@ static inline void set_cpu_sibling_map(int cpu) } struct plat_smp_ops *mp_ops; +EXPORT_SYMBOL(mp_ops); __cpuinit void register_smp_ops(struct plat_smp_ops *ops) { diff --git a/mm/bootmem.c b/mm/bootmem.c index f468185..a424028 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -32,6 +32,7 @@ EXPORT_SYMBOL(contig_page_data); unsigned long max_low_pfn; unsigned long min_low_pfn; +EXPORT_SYMBOL(min_low_pfn); unsigned long max_pfn; bootmem_data_t bootmem_node_data[MAX_NUMNODES] __initdata; -- 1.7.11.3 -- 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 10/18] KVM/MIPS32: Guest interrupt delivery.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips_int.c | 243 +++ arch/mips/kvm/kvm_mips_int.h | 49 + 2 files changed, 292 insertions(+) create mode 100644 arch/mips/kvm/kvm_mips_int.c create mode 100644 arch/mips/kvm/kvm_mips_int.h diff --git a/arch/mips/kvm/kvm_mips_int.c b/arch/mips/kvm/kvm_mips_int.c new file mode 100644 index 000..12450d9 --- /dev/null +++ b/arch/mips/kvm/kvm_mips_int.c @@ -0,0 +1,243 @@ +/* +* 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. +* +* KVM/MIPS: Interrupt delivery +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/errno.h +#include linux/err.h +#include linux/module.h +#include linux/vmalloc.h +#include linux/fs.h +#include linux/bootmem.h +#include asm/page.h +#include asm/cacheflush.h + +#include linux/kvm_host.h + +#include kvm_mips_int.h + +void kvm_mips_queue_irq(struct kvm_vcpu *vcpu, uint32_t priority) +{ + set_bit(priority, vcpu-arch.pending_exceptions); +} + +void kvm_mips_dequeue_irq(struct kvm_vcpu *vcpu, uint32_t priority) +{ + clear_bit(priority, vcpu-arch.pending_exceptions); +} + +void kvm_mips_queue_timer_int_cb(struct kvm_vcpu *vcpu) +{ + /* Cause bits to reflect the pending timer interrupt, +* the EXC code will be set when we are actually +* delivering the interrupt: +*/ + kvm_set_c0_guest_cause(vcpu-arch.cop0, (C_IRQ5 | C_TI)); + + /* Queue up an INT exception for the core */ + kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_TIMER); + +} + +void kvm_mips_dequeue_timer_int_cb(struct kvm_vcpu *vcpu) +{ + kvm_clear_c0_guest_cause(vcpu-arch.cop0, (C_IRQ5 | C_TI)); + kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_TIMER); +} + +void +kvm_mips_queue_io_int_cb(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq) +{ + int intr = (int)irq-irq; + + /* Cause bits to reflect the pending IO interrupt, +* the EXC code will be set when we are actually +* delivering the interrupt: +*/ + switch (intr) { + case 2: + kvm_set_c0_guest_cause(vcpu-arch.cop0, (C_IRQ0)); + /* Queue up an INT exception for the core */ + kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IO); + break; + + case 3: + kvm_set_c0_guest_cause(vcpu-arch.cop0, (C_IRQ1)); + kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IPI_1); + break; + + case 4: + kvm_set_c0_guest_cause(vcpu-arch.cop0, (C_IRQ2)); + kvm_mips_queue_irq(vcpu, MIPS_EXC_INT_IPI_2); + break; + + default: + break; + } + +} + +void +kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu, + struct kvm_mips_interrupt *irq) +{ + int intr = (int)irq-irq; + switch (intr) { + case -2: + kvm_clear_c0_guest_cause(vcpu-arch.cop0, (C_IRQ0)); + kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IO); + break; + + case -3: + kvm_clear_c0_guest_cause(vcpu-arch.cop0, (C_IRQ1)); + kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_1); + break; + + case -4: + kvm_clear_c0_guest_cause(vcpu-arch.cop0, (C_IRQ2)); + kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_IPI_2); + break; + + default: + break; + } + +} + +/* Deliver the interrupt of the corresponding priority, if possible. */ +int +kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority, + uint32_t cause) +{ + int allowed = 0; + uint32_t exccode; + + struct kvm_vcpu_arch *arch = vcpu-arch; + struct mips_coproc *cop0 __unused = vcpu-arch.cop0; + + switch (priority) { + case MIPS_EXC_INT_TIMER: + if ((kvm_read_c0_guest_status(cop0) ST0_IE) +(!(kvm_read_c0_guest_status(cop0) (ST0_EXL | ST0_ERL))) +(kvm_read_c0_guest_status(cop0) IE_IRQ5)) { + allowed = 1; + exccode = T_INT; + } + break; + + case MIPS_EXC_INT_IO: + if ((kvm_read_c0_guest_status(cop0) ST0_IE) +(!(kvm_read_c0_guest_status(cop0) (ST0_EXL | ST0_ERL))) +(kvm_read_c0_guest_status(cop0) IE_IRQ0)) { + allowed = 1; + exccode = T_INT; + } + break; + + case MIPS_EXC_INT_IPI_1: + if ((kvm_read_c0_guest_status(cop0) ST0_IE) +(!(kvm_read_c0_guest_status(cop0) (ST0_EXL | ST0_ERL))) +(kvm_read_c0_guest_status(cop0) IE_IRQ1
[PATCH v2 11/18] KVM/MIPS32: Routines to handle specific traps/exceptions while executing the guest.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_cb.c| 14 ++ arch/mips/kvm/kvm_trap_emul.c | 482 ++ 2 files changed, 496 insertions(+) create mode 100644 arch/mips/kvm/kvm_cb.c create mode 100644 arch/mips/kvm/kvm_trap_emul.c diff --git a/arch/mips/kvm/kvm_cb.c b/arch/mips/kvm/kvm_cb.c new file mode 100644 index 000..313c2e3 --- /dev/null +++ b/arch/mips/kvm/kvm_cb.c @@ -0,0 +1,14 @@ +/* + * 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: Yann Le Du l...@kymasys.com + */ + +#include linux/export.h +#include linux/kvm_host.h + +struct kvm_mips_callbacks *kvm_mips_callbacks; +EXPORT_SYMBOL(kvm_mips_callbacks); diff --git a/arch/mips/kvm/kvm_trap_emul.c b/arch/mips/kvm/kvm_trap_emul.c new file mode 100644 index 000..e20fff0 --- /dev/null +++ b/arch/mips/kvm/kvm_trap_emul.c @@ -0,0 +1,482 @@ +/* +* 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. +* +* KVM/MIPS: Deliver/Emulate exceptions to the guest kernel +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/errno.h +#include linux/err.h +#include linux/module.h +#include linux/vmalloc.h + +#include linux/kvm_host.h + +#include kvm_mips_opcode.h +#include kvm_mips_int.h + +static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva) +{ + gpa_t gpa; + uint32_t kseg = KSEGX(gva); + + if ((kseg == CKSEG0) || (kseg == CKSEG1)) + gpa = CPHYSADDR(gva); + else { + printk(%s: cannot find GPA for GVA: %#lx\n, __func__, gva); + kvm_mips_dump_host_tlbs(); + gpa = KVM_INVALID_ADDR; + } + +#ifdef DEBUG + kvm_debug(%s: gva %#lx, gpa: %#llx\n, __func__, gva, gpa); +#endif + + return gpa; +} + + +static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu) +{ + struct kvm_run *run = vcpu-run; + uint32_t __user *opc = (uint32_t __user *) vcpu-arch.pc; + ulong cause = vcpu-arch.host_cp0_cause; + enum emulation_result er = EMULATE_DONE; + int ret = RESUME_GUEST; + + if (((cause CAUSEF_CE) CAUSEB_CE) == 1) { + er = kvm_mips_emulate_fpu_exc(cause, opc, run, vcpu); + } else + er = kvm_mips_emulate_inst(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; + + case EMULATE_WAIT: + run-exit_reason = KVM_EXIT_INTR; + ret = RESUME_HOST; + break; + + default: + BUG(); + } + return ret; +} + +static int kvm_trap_emul_handle_tlb_mod(struct kvm_vcpu *vcpu) +{ + struct kvm_run *run = vcpu-run; + uint32_t __user *opc = (uint32_t __user *) vcpu-arch.pc; + ulong cause = vcpu-arch.host_cp0_cause; + ulong badvaddr = vcpu-arch.host_cp0_badvaddr; + enum emulation_result er = EMULATE_DONE; + int ret = RESUME_GUEST; + + if (KVM_GUEST_KSEGX(badvaddr) KVM_GUEST_KSEG0 + || KVM_GUEST_KSEGX(badvaddr) == KVM_GUEST_KSEG23) { +#ifdef DEBUG + kvm_debug + (USER/KSEG23 ADDR TLB MOD fault: cause %#lx, PC: %p, BadVaddr: %#lx\n, +cause, opc, badvaddr); +#endif + er = kvm_mips_handle_tlbmod(cause, opc, run, vcpu); + + if (er == EMULATE_DONE) + ret = RESUME_GUEST; + else { + run-exit_reason = KVM_EXIT_INTERNAL_ERROR; + ret = RESUME_HOST; + } + } else if (KVM_GUEST_KSEGX(badvaddr) == KVM_GUEST_KSEG0) { + /* XXXKYMA: The guest kernel does not expect to get this fault when we are not +* using HIGHMEM. Need to address this in a HIGHMEM kernel +*/ + printk + (TLB MOD fault not handled, cause %#lx, PC: %p, BadVaddr: %#lx\n, +cause, opc, badvaddr); + kvm_mips_dump_host_tlbs(); + kvm_arch_vcpu_dump_regs(vcpu); + run-exit_reason = KVM_EXIT_INTERNAL_ERROR; + ret = RESUME_HOST; + } else { + printk + (Illegal TLB Mod fault address , cause %#lx, PC: %p, BadVaddr: %#lx\n, +cause, opc, badvaddr); + kvm_mips_dump_host_tlbs(); + kvm_arch_vcpu_dump_regs(vcpu); + run-exit_reason
[PATCH v2 09/18] KVM/MIPS32: COP0 accesses profiling.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips_stats.c | 81 ++ 1 file changed, 81 insertions(+) create mode 100644 arch/mips/kvm/kvm_mips_stats.c diff --git a/arch/mips/kvm/kvm_mips_stats.c b/arch/mips/kvm/kvm_mips_stats.c new file mode 100644 index 000..e442a26 --- /dev/null +++ b/arch/mips/kvm/kvm_mips_stats.c @@ -0,0 +1,81 @@ +/* +* 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. +* +* KVM/MIPS: COP0 access histogram +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/kvm_host.h + +char *kvm_mips_exit_types_str[MAX_KVM_MIPS_EXIT_TYPES] = { + WAIT, + CACHE, + Signal, + Interrupt, + COP0/1 Unusable, + TLB Mod, + TLB Miss (LD), + TLB Miss (ST), + Address Err (ST), + Address Error (LD), + System Call, + Reserved Inst, + Break Inst, + D-Cache Flushes, +}; + +char *kvm_cop0_str[N_MIPS_COPROC_REGS] = { + Index, + Random, + EntryLo0, + EntryLo1, + Context, + PG Mask, + Wired, + HWREna, + BadVAddr, + Count, + EntryHI, + Compare, + Status, + Cause, + EXC PC, + PRID, + Config, + LLAddr, + Watch Lo, + Watch Hi, + X Context, + Reserved, + Impl Dep, + Debug, + DEPC, + PerfCnt, + ErrCtl, + CacheErr, + TagLo, + TagHi, + ErrorEPC, + DESAVE +}; + +int kvm_mips_dump_stats(struct kvm_vcpu *vcpu) +{ + int i, j __unused; +#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS + printk(\nKVM VCPU[%d] COP0 Access Profile:\n, vcpu-vcpu_id); + for (i = 0; i N_MIPS_COPROC_REGS; i++) { + for (j = 0; j N_MIPS_COPROC_SEL; j++) { + if (vcpu-arch.cop0-stat[i][j]) + printk(%s[%d]: %lu\n, kvm_cop0_str[i], j, + vcpu-arch.cop0-stat[i][j]); + } + } +#endif + + return 0; +} -- 1.7.11.3 -- 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 17/18] KVM/MIPS32: Do not call vcpu_load when injecting interrupts.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- virt/kvm/kvm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index be70035..ecd96ce 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1880,7 +1880,7 @@ static long kvm_vcpu_ioctl(struct file *filp, if (vcpu-kvm-mm != current-mm) return -EIO; -#if defined(CONFIG_S390) || defined(CONFIG_PPC) +#if defined(CONFIG_S390) || defined(CONFIG_PPC) || defined(CONFIG_MIPS) /* * Special cases: vcpu ioctls that are asynchronous to vcpu execution, * so vcpu_load() would break it. -- 1.7.11.3 -- 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 15/18] MIPS: Pull in MIPS fix: fix endless loop when processing signals for kernel tasks.
This bug is discussed in: http://lkml.indiana.edu/hypermail/linux/kernel/1205.2/00719.html Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kernel/entry.S | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index a6c1332..9b00362 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -36,6 +36,11 @@ FEXPORT(ret_from_exception) FEXPORT(ret_from_irq) LONG_S s0, TI_REGS($28) FEXPORT(__ret_from_irq) +/* + * We can be coming here from a syscall done in the kernel space, + * e.g. a failed kernel_execve(). + */ +resume_userspace_check: LONG_L t0, PT_STATUS(sp) # returning to kernel mode? andit0, t0, KU_USER beqzt0, resume_kernel @@ -162,7 +167,7 @@ work_notifysig: # deal with pending signals and movea0, sp li a1, 0 jal do_notify_resume# a2 already loaded - j resume_userspace + j resume_userspace_check FEXPORT(syscall_exit_partial) local_irq_disable # make sure need_resched doesn't -- 1.7.11.3 -- 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 06/18] KVM/MIPS32: Privileged instruction/target branch emulation.
- The Guest kernel is run in UM and privileged instructions cause a trap. - If the instruction causing the trap is in a branch delay slot, the branch needs to be emulated to figure out the PC @ which the guest will resume execution. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips_emul.c | 1840 +++ arch/mips/kvm/kvm_mips_opcode.h | 24 + 2 files changed, 1864 insertions(+) create mode 100644 arch/mips/kvm/kvm_mips_emul.c create mode 100644 arch/mips/kvm/kvm_mips_opcode.h diff --git a/arch/mips/kvm/kvm_mips_emul.c b/arch/mips/kvm/kvm_mips_emul.c new file mode 100644 index 000..dc4960b --- /dev/null +++ b/arch/mips/kvm/kvm_mips_emul.c @@ -0,0 +1,1840 @@ +/* +* 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. +* +* KVM/MIPS: Instruction/Exception emulation +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/errno.h +#include linux/err.h +#include linux/kvm_host.h +#include linux/module.h +#include linux/vmalloc.h +#include linux/fs.h +#include linux/bootmem.h +#include linux/random.h +#include asm/page.h +#include asm/cacheflush.h +#include asm/cpu-info.h +#include asm/mmu_context.h +#include asm/tlbflush.h +#include asm/inst.h + +#undef CONFIG_MIPS_MT +#include asm/r4kcache.h +#define CONFIG_MIPS_MT + +#include kvm_mips_opcode.h +#include kvm_mips_int.h +#include kvm_mips_comm.h + +#include trace.h + +static int debug __unused; + +/* + * Compute the return address and do emulate branch simulation, if required. + * This function should be called only in branch delay slot active. + */ +u_long kvm_compute_return_epc(struct kvm_vcpu *vcpu, u_long instpc) +{ + unsigned int dspcontrol; + union mips_instruction insn; + struct kvm_vcpu_arch *arch = vcpu-arch; + long epc = instpc; + long nextpc = KVM_INVALID_INST; + + if (epc 3) + goto unaligned; + + /* +* Read the instruction +*/ + insn.word = kvm_get_inst((uint32_t *) epc, vcpu); + + if (insn.word == KVM_INVALID_INST) + return KVM_INVALID_INST; + + switch (insn.i_format.opcode) { + /* +* jr and jalr are in r_format format. +*/ + case spec_op: + switch (insn.r_format.func) { + case jalr_op: + arch-gprs[insn.r_format.rd] = epc + 8; + /* Fall through */ + case jr_op: + nextpc = arch-gprs[insn.r_format.rs]; + break; + } + break; + + /* +* This group contains: +* bltz_op, bgez_op, bltzl_op, bgezl_op, +* bltzal_op, bgezal_op, bltzall_op, bgezall_op. +*/ + case bcond_op: + switch (insn.i_format.rt) { + case bltz_op: + case bltzl_op: + if ((long)arch-gprs[insn.i_format.rs] 0) + epc = epc + 4 + (insn.i_format.simmediate 2); + else + epc += 8; + nextpc = epc; + break; + + case bgez_op: + case bgezl_op: + if ((long)arch-gprs[insn.i_format.rs] = 0) + epc = epc + 4 + (insn.i_format.simmediate 2); + else + epc += 8; + nextpc = epc; + break; + + case bltzal_op: + case bltzall_op: + arch-gprs[31] = epc + 8; + if ((long)arch-gprs[insn.i_format.rs] 0) + epc = epc + 4 + (insn.i_format.simmediate 2); + else + epc += 8; + nextpc = epc; + break; + + case bgezal_op: + case bgezall_op: + arch-gprs[31] = epc + 8; + if ((long)arch-gprs[insn.i_format.rs] = 0) + epc = epc + 4 + (insn.i_format.simmediate 2); + else + epc += 8; + nextpc = epc; + break; + case bposge32_op: + if (!cpu_has_dsp) + goto sigill; + + dspcontrol = rddsp(0x01); + + if (dspcontrol = 32) { + epc = epc + 4 + (insn.i_format.simmediate 2); + } else + epc += 8; + nextpc = epc
[PATCH v2 04/18] KVM/MIPS32: MIPS arch specific APIs for KVM
- Implements the arch specific APIs for KVM, some are stubs for MIPS - kvm_mips_handle_exit(): Main 'C' distpatch routine for handling exceptions while in Guest mode. - Also implements in-kernel timer interrupt support for the guest. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips.c | 965 +++ arch/mips/kvm/trace.h| 46 +++ 2 files changed, 1011 insertions(+) create mode 100644 arch/mips/kvm/kvm_mips.c create mode 100644 arch/mips/kvm/trace.h diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c new file mode 100644 index 000..e239d73 --- /dev/null +++ b/arch/mips/kvm/kvm_mips.c @@ -0,0 +1,965 @@ +/* + * 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. + * + * KVM/MIPS: MIPS specific KVM APIs + * + * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. + * Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/errno.h +#include linux/err.h +#include linux/module.h +#include linux/vmalloc.h +#include linux/fs.h +#include linux/bootmem.h +#include asm/page.h +#include asm/cacheflush.h +#include asm/mmu_context.h + +#include linux/kvm_host.h + +#include kvm_mips_int.h +#include kvm_mips_comm.h + +#define CREATE_TRACE_POINTS +#include trace.h + +#ifndef VECTORSPACING +#define VECTORSPACING 0x100/* for EI/VI mode */ +#endif + +#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU +struct kvm_stats_debugfs_item debugfs_entries[] = { + { wait, VCPU_STAT(wait_exits) }, + { cache, VCPU_STAT(cache_exits) }, + { signal, VCPU_STAT(signal_exits) }, + { interrupt, VCPU_STAT(int_exits) }, + { cop_unsuable, VCPU_STAT(cop_unusable_exits) }, + { tlbmod, VCPU_STAT(tlbmod_exits) }, + { tlbmiss_ld, VCPU_STAT(tlbmiss_ld_exits) }, + { tlbmiss_st, VCPU_STAT(tlbmiss_st_exits) }, + { addrerr_st, VCPU_STAT(addrerr_st_exits) }, + { addrerr_ld, VCPU_STAT(addrerr_ld_exits) }, + { syscall, VCPU_STAT(syscall_exits) }, + { resvd_inst, VCPU_STAT(resvd_inst_exits) }, + { break_inst, VCPU_STAT(break_inst_exits) }, + { flush_dcache, VCPU_STAT(flush_dcache_exits) }, + { halt_wakeup, VCPU_STAT(halt_wakeup) }, + {NULL} +}; + +static int kvm_mips_reset_vcpu(struct kvm_vcpu *vcpu) +{ + int i; + for_each_possible_cpu(i) { + vcpu-arch.guest_kernel_asid[i] = 0; + vcpu-arch.guest_user_asid[i] = 0; + } + return 0; +} + +gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) +{ + return gfn; +} + +/* XXXKYMA: We are simulatoring a processor that has the WII bit set in Config7, so we + * are runnable if interrupts are pending + */ +int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) +{ + return !!(vcpu-arch.pending_exceptions); +} + +int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) +{ + return 1; +} + +int kvm_arch_hardware_enable(void *garbage) +{ + return 0; +} + +void kvm_arch_hardware_disable(void *garbage) +{ +} + +int kvm_arch_hardware_setup(void) +{ + return 0; +} + +void kvm_arch_hardware_unsetup(void) +{ +} + +void kvm_arch_check_processor_compat(void *rtn) +{ + int *r = (int *)rtn; + *r = 0; + return; +} + +static void kvm_mips_init_tlbs(struct kvm *kvm) +{ + ulong wired; + + /* Add a wired entry to the TLB, it is used to map the commpage to the Guest kernel */ + wired = read_c0_wired(); + write_c0_wired(wired + 1); + mtc0_tlbw_hazard(); + kvm-arch.commpage_tlb = wired; + + kvm_debug([%d] commpage TLB: %d\n, smp_processor_id(), + kvm-arch.commpage_tlb); +} + +static void kvm_mips_init_vm_percpu(void *arg) +{ + struct kvm *kvm = (struct kvm *)arg; + + kvm_mips_init_tlbs(kvm); + kvm_mips_callbacks-vm_init(kvm); + +} + +int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) +{ + if (atomic_inc_return(kvm_mips_instance) == 1) { + kvm_info(%s: 1st KVM instance, setup host TLB parameters\n, +__func__); + on_each_cpu(kvm_mips_init_vm_percpu, kvm, 1); + } + + + return 0; +} + +void kvm_mips_free_vcpus(struct kvm *kvm) +{ + unsigned int i; + struct kvm_vcpu *vcpu; + + /* Put the pages we reserved for the guest pmap */ + for (i = 0; i kvm-arch.guest_pmap_npages; i++) { + if (kvm-arch.guest_pmap[i] != KVM_INVALID_PAGE) + kvm_mips_release_pfn_clean(kvm-arch.guest_pmap[i]); + } + + if (kvm-arch.guest_pmap) + kfree(kvm-arch.guest_pmap); + + kvm_for_each_vcpu(i, vcpu, kvm) { + kvm_arch_vcpu_free(vcpu); + } + + mutex_lock(kvm-lock); + + for (i = 0; i atomic_read(kvm-online_vcpus); i++) + kvm-vcpus[i] = NULL; + + atomic_set(kvm
[PATCH v2 05/18] KVM/MIPS32: KVM Guest kernel support.
Both Guest kernel and Guest Userspace execute in UM. The memory map is as follows: Guest User address space: 0x - 0x4000 Guest Kernel Unmapped: 0x4000 - 0x6000 Guest Kernel Mapped:0x6000 - 0x8000 - Guest Usermode virtual memory is limited to 1GB. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/mach-generic/spaces.h | 9 - arch/mips/include/asm/processor.h | 5 + arch/mips/include/asm/uaccess.h | 11 ++- arch/mips/kernel/binfmt_elfo32.c| 4 arch/mips/kernel/cevt-r4k.c | 4 arch/mips/kernel/traps.c| 7 ++- arch/mips/mti-malta/malta-time.c| 13 + 7 files changed, 50 insertions(+), 3 deletions(-) diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h index d7a9efd..ff64289 100644 --- a/arch/mips/include/asm/mach-generic/spaces.h +++ b/arch/mips/include/asm/mach-generic/spaces.h @@ -20,14 +20,21 @@ #endif #ifdef CONFIG_32BIT - +#ifdef CONFIG_KVM_GUEST +#define CAC_BASE _AC(0x4000, UL) +#else #define CAC_BASE _AC(0x8000, UL) +#endif #define IO_BASE_AC(0xa000, UL) #define UNCAC_BASE _AC(0xa000, UL) #ifndef MAP_BASE +#ifdef CONFIG_KVM_GUEST +#define MAP_BASE _AC(0x6000, UL) +#else #define MAP_BASE _AC(0xc000, UL) #endif +#endif /* * Memory above this physical address will be considered highmem. diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 5e33fab..7df9f06 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -44,11 +44,16 @@ extern unsigned int vced_count, vcei_count; #define SPECIAL_PAGES_SIZE PAGE_SIZE #ifdef CONFIG_32BIT +#ifdef CONFIG_KVM_GUEST +/* User space process size is limited to 1GB in KVM Guest Mode */ +#define TASK_SIZE 0x3fff8000UL +#else /* * User space process size: 2GB. This is hardcoded into a few places, * so don't change it unless you know what you are doing. */ #define TASK_SIZE 0x7fff8000UL +#endif #ifdef __KERNEL__ #define STACK_TOP_MAX TASK_SIZE diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 3b92efe..61ec84d 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -23,7 +23,11 @@ */ #ifdef CONFIG_32BIT -#define __UA_LIMIT 0x8000UL +#ifdef CONFIG_KVM_GUEST +#define __UA_LIMIT 0x4000UL +#else +#define __UA_LIMIT 0x8000UL +#endif #define __UA_ADDR .word #define __UA_LAla @@ -55,8 +59,13 @@ extern u64 __ua_limit; * address in this range it's the process's problem, not ours :-) */ +#ifdef CONFIG_KVM_GUEST +#define KERNEL_DS ((mm_segment_t) { 0x8000UL }) +#define USER_DS((mm_segment_t) { 0xC000UL }) +#else #define KERNEL_DS ((mm_segment_t) { 0UL }) #define USER_DS((mm_segment_t) { __UA_LIMIT }) +#endif #define VERIFY_READ0 #define VERIFY_WRITE 1 diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index ff44823..8793ead 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -48,7 +48,11 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; __res; \ }) +#ifdef CONFIG_KVM_GUEST +#define TASK32_SIZE0x3fff8000UL +#else #define TASK32_SIZE0x7fff8000UL +#endif #undef ELF_ET_DYN_BASE #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 7532392..eebb05b 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -118,6 +118,10 @@ int c0_compare_int_usable(void) unsigned int delta; unsigned int cnt; +#ifdef CONFIG_KVM_GUEST +return 1; +#endif + /* * IP7 already pending? Try to clear it by acking the timer. */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 9260986..1413aef 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1709,7 +1709,12 @@ void __init trap_init(void) ebase = (unsigned long) __alloc_bootmem(size, 1 fls(size), 0); } else { - ebase = CKSEG0; +#ifdef CONFIG_KVM_GUEST +#define KVM_GUEST_KSEG0 0x4000 +ebase = KVM_GUEST_KSEG0; +#else +ebase = CKSEG0; +#endif if (cpu_has_mips_r2) ebase += (read_c0_ebase() 0x3000); } diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 115f5bc..1e6bd99 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c @@ -72,6 +72,19 @@ static unsigned int __init
[PATCH v2 13/18] MIPS: If KVM is enabled then use the KVM specific routine to flush the TLBs on a ASID wrap.
Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/mmu_context.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 9b02cfb..10a3fd2 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h @@ -112,15 +112,21 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) static inline void get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) { + extern void kvm_local_flush_tlb_all(void); unsigned long asid = asid_cache(cpu); if (! ((asid += ASID_INC) ASID_MASK) ) { if (cpu_has_vtag_icache) flush_icache_all(); +#ifdef CONFIG_VIRTUALIZATION + kvm_local_flush_tlb_all(); /* start new asid cycle */ +#else local_flush_tlb_all(); /* start new asid cycle */ +#endif if (!asid) /* fix version if needed */ asid = ASID_FIRST_VERSION; } + cpu_context(cpu, mm) = asid_cache(cpu) = asid; } -- 1.7.11.3 -- 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 03/18] KVM/MIPS32: Entry point for trampolining to the guest and trap handlers.
- __kvm_mips_vcpu_run: main entry point to enter guest, we save kernel context, load up guest context from and ERET to guest context. - mips32_exception: L1 exception handler(s), save k0/k1 and jump to main handlers. - mips32_GuestException: Generic exception handlers for exceptions/interrupts while in guest context. Save guest context, restore some kernel context and jump to main 'C' handler: kvm_mips_handle_exit() Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_locore.S | 651 + 1 file changed, 651 insertions(+) create mode 100644 arch/mips/kvm/kvm_locore.S diff --git a/arch/mips/kvm/kvm_locore.S b/arch/mips/kvm/kvm_locore.S new file mode 100644 index 000..43e7d3f --- /dev/null +++ b/arch/mips/kvm/kvm_locore.S @@ -0,0 +1,651 @@ +/* +* 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. +* +* Main entry point for the guest, exception handling. +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include asm/asm.h +#include asm/asmmacro.h +#include asm/regdef.h +#include asm/mipsregs.h +#include asm/stackframe.h +#include asm/asm-offsets.h + + +#define _C_LABEL(x) x +#define MIPSX(name) mips32_ ## name +#define CALLFRAME_SIZ 32 + +/* + * VECTOR + * exception vector entrypoint + */ +#define VECTOR(x, regmask) \ +.ent_C_LABEL(x),0; \ +EXPORT(x); + +#define VECTOR_END(x) \ +EXPORT(x); + +/* Overload, Danger Will Robinson!! */ +#define PT_HOST_ASIDPT_BVADDR +#define PT_HOST_USERLOCAL PT_EPC + +#define CP0_DDATA_LO$28,3 +#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(11) /* Resume host? */ + +#define RESUME_GUEST0 +#define RESUME_HOST RESUME_FLAG_HOST + +/* + * __kvm_mips_vcpu_run: entry point to the guest + * a0: run + * a1: vcpu + */ + +FEXPORT(__kvm_mips_vcpu_run) +.setpush +.setnoreorder +.setnoat + +/* k0/k1 not being used in host kernel context */ + addiu k1,sp, -PT_SIZE +LONG_S $0, PT_R0(k1) +LONG_S $1, PT_R1(k1) +LONG_S $2, PT_R2(k1) +LONG_S $3, PT_R3(k1) + +LONG_S $4, PT_R4(k1) +LONG_S $5, PT_R5(k1) +LONG_S $6, PT_R6(k1) +LONG_S $7, PT_R7(k1) + +LONG_S $8, PT_R8(k1) +LONG_S $9, PT_R9(k1) +LONG_S $10, PT_R10(k1) +LONG_S $11, PT_R11(k1) +LONG_S $12, PT_R12(k1) +LONG_S $13, PT_R13(k1) +LONG_S $14, PT_R14(k1) +LONG_S $15, PT_R15(k1) +LONG_S $16, PT_R16(k1) +LONG_S $17, PT_R17(k1) + +LONG_S $18, PT_R18(k1) +LONG_S $19, PT_R19(k1) +LONG_S $20, PT_R20(k1) +LONG_S $21, PT_R21(k1) +LONG_S $22, PT_R22(k1) +LONG_S $23, PT_R23(k1) +LONG_S $24, PT_R24(k1) +LONG_S $25, PT_R25(k1) + + /* XXXKYMA k0/k1 not saved, not being used if we got here through an ioctl() */ + +LONG_S $28, PT_R28(k1) +LONG_S $29, PT_R29(k1) +LONG_S $30, PT_R30(k1) +LONG_S $31, PT_R31(k1) + +/* Save hi/lo */ + mflov0 + LONG_S v0, PT_LO(k1) + mfhiv1 + LONG_S v1, PT_HI(k1) + + /* Save host status */ + mfc0v0, CP0_STATUS + LONG_S v0, PT_STATUS(k1) + + /* Save host ASID, shove it into the BVADDR location */ + mfc0v1,CP0_ENTRYHI + andiv1, 0xff + LONG_S v1, PT_HOST_ASID(k1) + +/* Save DDATA_LO, will be used to store pointer to vcpu */ +mfc0v1, CP0_DDATA_LO +LONG_S v1, PT_HOST_USERLOCAL(k1) + +/* DDATA_LO has pointer to vcpu */ +mtc0a1,CP0_DDATA_LO + +/* Offset into vcpu-arch */ + addiu k1, a1, VCPU_HOST_ARCH + +/* Save the host stack to VCPU, used for exception processing when we exit from the Guest */ +LONG_S sp, VCPU_HOST_STACK(k1) + +/* Save the kernel gp as well */ +LONG_S gp, VCPU_HOST_GP(k1) + + /* Setup status register for running the guest in UM, interrupts are disabled */ + li k0,(ST0_EXL | KSU_USER| ST0_BEV) + mtc0k0,CP0_STATUS +ehb + +/* load up the new EBASE */ +LONG_L k0, VCPU_GUEST_EBASE(k1) +mtc0k0,CP0_EBASE + +/* Now that the new EBASE has been loaded
Re: [PATCH 04/20] KVM/MIPS32: MIPS arch specific APIs for KVM
On Nov 1, 2012, at 11:18 AM, Avi Kivity wrote: + +/* Set the appropriate status bits based on host CPU features, before we hit the scheduler */ +kvm_mips_set_c0_status(); + +local_irq_enable(); Ah, so you handle exits with interrupts enabled. But that's not how we usually do it; the standard pattern is while (can continue) disable interrupts enter guest enable interrupts process exit A bit more detail here. KVM/MIPS has its own set of exception handlers which are separate from the host kernel's handlers. We switch between the 2 sets of handlers by setting the Exception Base Register (EBASE). We enable host interrupts just before we switch to guest context so that we trap when the host gets a timer or I/O interrupt. When an exception does occur in guest context, the KVM/MIPS handlers will save the guest context, and switch back to the default host kernel exception handlers. We enter the C handler (kvm_mips_handle_exit()) with interrupts disabled, and explicitly enable them there. This allows the host kernel to handle any pending interrupts. The sequence is as follows while (can continue) disable interrupts trampoline code to save host kernel context, load guest context enable host interrupts enter guest context KVM/MIPS trap handler (called with interrupts disabled, per MIPS architecture) Restore host Linux context, setup stack to handle exception Jump to C handler Enable interrupts before handling VM exit. Regards Sanjay -- 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 07/20] KVM/MIPS32: Dynamic binary translation of select privileged instructions.
On Nov 1, 2012, at 11:24 AM, Avi Kivity wrote: On 10/31/2012 05:19 PM, Sanjay Lal wrote: Currently, the following instructions are translated: - CACHE (indexed) - CACHE (va based): translated to a synci, overkill on D-CACHE operations, but still much faster than a trap. - mfc0/mtc0: the virtual COP0 registers for the guest are implemented as 2-D array [COP#][SEL] and this is mapped into the guest kernel address space @ VA 0x0. mfc0/mtc0 operations are transformed to load/stores. Seems to be more of binary patching, yes? Binary translation usually involves hiding the translated code so the guest is not able to detect that it is patched. -- error compiling committee.c: too many arguments to function -- 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 -- 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 07/20] KVM/MIPS32: Dynamic binary translation of select privileged instructions.
On Nov 1, 2012, at 11:24 AM, Avi Kivity wrote: On 10/31/2012 05:19 PM, Sanjay Lal wrote: Currently, the following instructions are translated: - CACHE (indexed) - CACHE (va based): translated to a synci, overkill on D-CACHE operations, but still much faster than a trap. - mfc0/mtc0: the virtual COP0 registers for the guest are implemented as 2-D array [COP#][SEL] and this is mapped into the guest kernel address space @ VA 0x0. mfc0/mtc0 operations are transformed to load/stores. Seems to be more of binary patching, yes? Binary translation usually involves hiding the translated code so the guest is not able to detect that it is patched. Now that you mention it, I think binary patching would be more applicable. If the self-aware guest ever compared the code it would realize that it has changed. Regards Sanjay -- 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 02/20] KVM/MIPS32: Arch specific KVM data structures.
On Nov 1, 2012, at 11:04 AM, Avi Kivity wrote: On 10/31/2012 05:18 PM, Sanjay Lal wrote: + +/* Special address that contains the comm page, used for reducing # of traps */ +#define KVM_GUEST_COMMPAGE_ADDR 0x0 + +struct kvm_arch +{ +/* Guest GVA-HPA page table */ +ulong *guest_pmap; +ulong guest_pmap_npages; + +/* Wired host TLB used for the commpage */ +int commpage_tlb; + +pfn_t (*gfn_to_pfn) (struct kvm *kvm, gfn_t gfn); +void (*release_pfn_clean) (pfn_t pfn); +bool (*is_error_pfn) (pfn_t pfn); Why this indirection? Do those functions change at runtime? On MIPS, kernel modules are executed from mapped space, which requires TLBs. The TLB handling code is statically linked with the rest of the kernel (kvm_tlb.c) to avoid the possibility of double faulting. The problem is that the code references routines that are part of the the KVM module, which are only available once the module is loaded, hence the indirection. + +struct kvm_mips_callbacks { +int (*handle_cop_unusable)(struct kvm_vcpu *vcpu); +int (*handle_tlb_mod)(struct kvm_vcpu *vcpu); +int (*handle_tlb_ld_miss)(struct kvm_vcpu *vcpu); +int (*handle_tlb_st_miss)(struct kvm_vcpu *vcpu); +int (*handle_addr_err_st)(struct kvm_vcpu *vcpu); +int (*handle_addr_err_ld)(struct kvm_vcpu *vcpu); +int (*handle_syscall)(struct kvm_vcpu *vcpu); +int (*handle_res_inst)(struct kvm_vcpu *vcpu); +int (*handle_break)(struct kvm_vcpu *vcpu); +gpa_t (*gva_to_gpa)(gva_t gva); +void (*queue_timer_int)(struct kvm_vcpu *vcpu); +void (*dequeue_timer_int)(struct kvm_vcpu *vcpu); +void (*queue_io_int)(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq); +void (*dequeue_io_int)(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq); +int (*irq_deliver)(struct kvm_vcpu *vcpu, unsigned int priority, uint32_t cause); +int (*irq_clear)(struct kvm_vcpu *vcpu, unsigned int priority, uint32_t cause); +int (*vcpu_ioctl_get_regs)(struct kvm_vcpu *vcpu, struct kvm_regs *regs); +int (*vcpu_ioctl_set_regs)(struct kvm_vcpu *vcpu, struct kvm_regs *regs); +int (*vcpu_init)(struct kvm_vcpu *vcpu); +}; We use callbacks on x86 because we have two separate implementations (svm and vmx). Will that be the case on MIPS? If not, use direct calls. We will eventually have separate implementations based on the features supported by H/W. -- 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/20] KVM for MIPS32 Processors
On Nov 1, 2012, at 10:51 AM, Avi Kivity wrote: On 10/31/2012 05:17 PM, Sanjay Lal wrote: The following patchset implements KVM support for MIPS32R2 processors, using Trap Emulate, with basic runtime binary translation to improve performance. The goal has been to keep the Guest kernel changes to a minimum. The patch is against Linux 3.7-rc2. There is a companion patchset for QEMU that adds KVM support for the MIPS target. KVM/MIPS should support MIPS32-R2 processors and beyond. It has been tested on the following platforms: - Malta Board with FPGA based 34K (Little Endian). - Sigma Designs TangoX board with a 24K based 8654 SoC (Little Endian). - Malta Board with 74K @ 1GHz (Little Endian). - OVPSim MIPS simulator from Imperas emulating a Malta board with 24Kc and 1074Kc cores (Little Endian). Both Guest kernel and Guest Userspace execute in UM. The Guest address space is as folows: Guest User address space: 0x - 0x4000 Guest Kernel Unmapped: 0x4000 - 0x6000 Guest Kernel Mapped:0x6000 - 0x8000 As a result, Guest Usermode virtual memory is limited to 1GB. Relase Notes (1) 16K Page Size: Both Host Kernel and Guest Kernel should have the same page size, currently at least 16K. Note that due to cache aliasing issues, 4K page sizes are NOT supported. (2) No HugeTLB/Large Page Support: Both the host kernel and Guest kernel should have the page size set to at least 16K. This will be implemented in a future release. (3) SMP Guests to not work Linux-3.7-rc2 based SMP guest hangs due to the following code sequence in the generated TLB handlers: LL/TLBP/SC Since the TLBP instruction causes a trap the reservation gets cleared when we ERET back to the guest. This causes the guest to hang in an infinite loop. As a workaround, make sure that CONFIG_SMP is disabled for Guest kernels. This will be fixed in a future release. (4) FPU support: Currently KVM/MIPS emulates a 24K CPU without a FPU. This will be fixed in a future release Thanks for posting this, new architectures are always a welcome addition. Some general notes: - please read and follow Documentation/CodingStyle. In general the patches are okay except for indentation (use tabs, not spaces, and set your editor tab width to 8). I'll definitely be re-formatting the code based on the recommended coding style and running the patches through checkpatch.pl for v2 of the patch set. Regards Sanjay -- 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/20] KVM/MIPS32: MIPS arch specific APIs for KVM
- Implements the arch specific APIs for KVM, some are stubs for MIPS - kvm_mips_handle_exit(): Main 'C' distpatch routine for handling exceptions while in Guest mode. - Also implements in-kernel timer interrupt support for the guest. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_mips.c | 1016 ++ 1 file changed, 1016 insertions(+) create mode 100644 arch/mips/kvm/kvm_mips.c diff --git a/arch/mips/kvm/kvm_mips.c b/arch/mips/kvm/kvm_mips.c new file mode 100644 index 000..eb84568 --- /dev/null +++ b/arch/mips/kvm/kvm_mips.c @@ -0,0 +1,1016 @@ +/* +* 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. +* +* KVM/MIPS: MIPS specific KVM APIs +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/errno.h +#include linux/err.h +#include linux/module.h +#include linux/vmalloc.h +#include linux/fs.h +#include linux/bootmem.h +#include asm/page.h +#include asm/cacheflush.h +#include asm/mmu_context.h + +#include linux/kvm_host.h + +#include kvm_mips_int.h +#include kvm_mips_stats.h +#include kvm_mips_comm.h + +#ifndef VECTORSPACING +#define VECTORSPACING 0x100 /* for EI/VI mode */ +#endif + +struct kvm_stats_debugfs_item debugfs_entries[] = { +{NULL} +}; + +static int +kvm_mips_reset_vcpu (struct kvm_vcpu *vcpu) +{ +int i; +for (i = 0; i NR_CPUS; i++) { +vcpu-arch.guest_kernel_asid[i] = 0; +vcpu-arch.guest_user_asid[i] = 0; +} +return 0; +} + +gfn_t +unalias_gfn(struct kvm *kvm, gfn_t gfn) +{ +return gfn; +} + +/* XXXKYMA: We are simulatoring a processor that has the WII bit set in Config7, so we + * are runnable if interrupts are pending + */ +int +kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu) +{ +return !!(vcpu-arch.pending_exceptions); +} + +int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) +{ + return 1; +} + +int +kvm_arch_hardware_enable(void *garbage) +{ +return 0; +} + +void +kvm_arch_hardware_disable(void *garbage) +{ +} + +int +kvm_arch_hardware_setup(void) +{ +return 0; +} + +void +kvm_arch_hardware_unsetup(void) +{ +} + +void +kvm_arch_check_processor_compat(void *rtn) +{ +int *r = (int *) rtn; +*r = 0; +return; +} + +static void +kvm_mips_init_tlbs (void *arg) +{ +ulong flags, wired; +struct kvm *kvm = (struct kvm *) arg; + +ENTER_CRITICAL(flags); +/* Add a wired entry to the TLB, it is used to map the commpage to the Guest kernel */ +wired = read_c0_wired(); +write_c0_wired(wired + 1); +mtc0_tlbw_hazard(); +kvm-arch.commpage_tlb = wired; +EXIT_CRITICAL(flags); + +kvm_debug([%d] commpage TLB: %d\n, smp_processor_id(), kvm-arch.commpage_tlb); +} + +int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) +{ + int cpu; + +if (atomic_inc_return(kvm_mips_instance) == 1) { +kvm_info(%s: 1st KVM instance, setup host TLB parameters\n, __func__); + for_each_online_cpu(cpu) { + smp_call_function_single(cpu, kvm_mips_init_tlbs, kvm, 1); +} +} + +kvm-arch.gfn_to_pfn = gfn_to_pfn; +kvm-arch.release_pfn_clean = kvm_release_pfn_clean; +kvm-arch.is_error_pfn = is_error_pfn; + + return 0; +} + + +void +kvm_mips_free_vcpus(struct kvm *kvm) +{ +unsigned int i; +struct kvm_vcpu *vcpu; + +/* Put the pages we reserved for the guest pmap */ +for (i = 0; i kvm-arch.guest_pmap_npages; i++) { +if (kvm-arch.guest_pmap[i] != KVM_INVALID_PAGE) +kvm-arch.release_pfn_clean(kvm-arch.guest_pmap[i]); +} + +if (kvm-arch.guest_pmap) +kfree(kvm-arch.guest_pmap); + +kvm_for_each_vcpu(i, vcpu, kvm) { +kvm_arch_vcpu_free(vcpu); +} + +mutex_lock(kvm-lock); + +for (i = 0; i atomic_read(kvm-online_vcpus); i++) +kvm-vcpus[i] = NULL; + +atomic_set(kvm-online_vcpus, 0); + +mutex_unlock(kvm-lock); +} + +void +kvm_arch_sync_events(struct kvm *kvm) +{ +} + +static void +kvm_mips_uninit_tlbs (void *arg) +{ +/* Restore wired count */ +write_c0_wired(0); +mtc0_tlbw_hazard(); +/* Clear out all the TLBs */ +kvm_local_flush_tlb_all(); +} + + +void +kvm_arch_destroy_vm(struct kvm *kvm) +{ +int cpu; +kvm_mips_free_vcpus(kvm); + +/* If this is the last instance, restore wired count */ +if (atomic_dec_return(kvm_mips_instance) == 0) { +kvm_info(%s: last KVM instance, restoring TLB parameters\n, __func__); + for_each_online_cpu(cpu) { +smp_call_function_single(cpu, kvm_mips_uninit_tlbs, NULL, 1); +} +} +} + +long +kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) +{ +return -EINVAL; +} + +int +kvm_arch_set_memory_region(struct kvm *kvm, + struct
[PATCH 05/20] KVM/MIPS32: KVM Guest kernel support.
Both Guest kernel and Guest Userspace execute in UM. The memory map is as follows: Guest User address space: 0x - 0x4000 Guest Kernel Unmapped: 0x4000 - 0x6000 Guest Kernel Mapped:0x6000 - 0x8000 - Guest Usermode virtual memory is limited to 1GB. Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/include/asm/mach-generic/spaces.h | 9 - arch/mips/include/asm/processor.h | 5 + arch/mips/include/asm/uaccess.h | 15 --- arch/mips/kernel/binfmt_elfo32.c| 6 +- arch/mips/kernel/cevt-r4k.c | 4 arch/mips/kernel/traps.c| 7 ++- arch/mips/mti-malta/malta-time.c| 13 + 7 files changed, 53 insertions(+), 6 deletions(-) diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h index d7a9efd..ff64289 100644 --- a/arch/mips/include/asm/mach-generic/spaces.h +++ b/arch/mips/include/asm/mach-generic/spaces.h @@ -20,14 +20,21 @@ #endif #ifdef CONFIG_32BIT - +#ifdef CONFIG_KVM_GUEST +#define CAC_BASE _AC(0x4000, UL) +#else #define CAC_BASE _AC(0x8000, UL) +#endif #define IO_BASE_AC(0xa000, UL) #define UNCAC_BASE _AC(0xa000, UL) #ifndef MAP_BASE +#ifdef CONFIG_KVM_GUEST +#define MAP_BASE _AC(0x6000, UL) +#else #define MAP_BASE _AC(0xc000, UL) #endif +#endif /* * Memory above this physical address will be considered highmem. diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 5e33fab..7df9f06 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -44,11 +44,16 @@ extern unsigned int vced_count, vcei_count; #define SPECIAL_PAGES_SIZE PAGE_SIZE #ifdef CONFIG_32BIT +#ifdef CONFIG_KVM_GUEST +/* User space process size is limited to 1GB in KVM Guest Mode */ +#define TASK_SIZE 0x3fff8000UL +#else /* * User space process size: 2GB. This is hardcoded into a few places, * so don't change it unless you know what you are doing. */ #define TASK_SIZE 0x7fff8000UL +#endif #ifdef __KERNEL__ #define STACK_TOP_MAX TASK_SIZE diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 3b92efe..aba9751 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -23,7 +23,11 @@ */ #ifdef CONFIG_32BIT -#define __UA_LIMIT 0x8000UL +#ifdef CONFIG_KVM_GUEST +#define __UA_LIMIT 0x4000UL +#else +#define __UA_LIMIT 0x8000UL +#endif #define __UA_ADDR .word #define __UA_LAla @@ -55,8 +59,13 @@ extern u64 __ua_limit; * address in this range it's the process's problem, not ours :-) */ -#define KERNEL_DS ((mm_segment_t) { 0UL }) -#define USER_DS((mm_segment_t) { __UA_LIMIT }) +#ifdef CONFIG_KVM_GUEST +#define KERNEL_DS ((mm_segment_t) { 0x8000UL }) +#define USER_DS((mm_segment_t) { 0xC000UL }) +#else +#define KERNEL_DS ((mm_segment_t) { 0UL }) +#define USER_DS((mm_segment_t) { __UA_LIMIT }) +#endif #define VERIFY_READ0 #define VERIFY_WRITE 1 diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index ff44823..54f3904 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -48,7 +48,11 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; __res; \ }) -#define TASK32_SIZE0x7fff8000UL +#ifdef CONFIG_KVM_GUEST +#define TASK32_SIZE0x3fff8000UL +#else +#define TASK32_SIZE0x7fff8000UL +#endif #undef ELF_ET_DYN_BASE #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 7532392..eebb05b 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -118,6 +118,10 @@ int c0_compare_int_usable(void) unsigned int delta; unsigned int cnt; +#ifdef CONFIG_KVM_GUEST +return 1; +#endif + /* * IP7 already pending? Try to clear it by acking the timer. */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 9260986..1413aef 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1709,7 +1709,12 @@ void __init trap_init(void) ebase = (unsigned long) __alloc_bootmem(size, 1 fls(size), 0); } else { - ebase = CKSEG0; +#ifdef CONFIG_KVM_GUEST +#define KVM_GUEST_KSEG0 0x4000 +ebase = KVM_GUEST_KSEG0; +#else +ebase = CKSEG0; +#endif if (cpu_has_mips_r2) ebase += (read_c0_ebase() 0x3000); } diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index
[PATCH 08/20] KVM/MIPS32: MMU/TLB operations for the Guest.
- Note that this file is statically linked with the rest of the host kernel (KSEG0). This is because kernel modules are loaded into mapped space on MIPS and we want to make sure that we don't get any host kernel TLB faults while manipulating TLBs. - Virtual Guest TLBs are implemented as 64 entry array regardless of the number of host TLB entries. - Shadow TLBs map Guest virtual addresses to Host physical addresses. - TLB miss handling details: Guest KSEG0 TLBMISS (0x4000 – 0x6000): Transparent to the Guest. Guest KSEG2/3 (0x6000 – 0x8000) Guest UM TLBMISS (0x – 0x4000) Lookup in Guest/Virtual TLB If an entry doesn’t match deliver appropriate TLBMISS LD/ST exception to the guest If entry does exist in the Guest TLB and is NOT Valid Deliver TLB invalid exception to the guest If entry does exist in the Guest TLB and is VALID Inject the TLB entry into the Shadow TLB Signed-off-by: Sanjay Lal sanj...@kymasys.com --- arch/mips/kvm/kvm_tlb.c | 889 1 file changed, 889 insertions(+) create mode 100644 arch/mips/kvm/kvm_tlb.c diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c new file mode 100644 index 000..dea3868 --- /dev/null +++ b/arch/mips/kvm/kvm_tlb.c @@ -0,0 +1,889 @@ +/* +* 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. +* +* KVM/MIPS TLB handling, this file is part of the Linux host kernel so that +* TLB handlers run from KSEG0 +* +* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. +* Authors: Sanjay Lal sanj...@kymasys.com +*/ + +#include linux/init.h +#include linux/sched.h +#include linux/smp.h +#include linux/mm.h +#include linux/delay.h +#include linux/module.h +#include linux/kvm_host.h + +#include asm/cpu.h +#include asm/bootinfo.h +#include asm/mmu_context.h +#include asm/pgtable.h +#include asm/cacheflush.h + +#undef CONFIG_MIPS_MT +#include asm/r4kcache.h +#define CONFIG_MIPS_MT + +#include kvm_mips_stats.h + + +#define KVM_GUEST_PC_TLB0 +#define KVM_GUEST_SP_TLB1 + +#define PRIx64 llx + +#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) (PAGE_SHIFT + 1))) + +atomic_t kvm_mips_instance; +EXPORT_SYMBOL(kvm_mips_instance); + +/* + * Structure defining an tlb entry data set. + */ + +void +kvm_mips_dump_host_tlbs(void) +{ +struct kvm_mips_tlb tlb; +int i; +ulong flags; +unsigned long old_entryhi; +unsigned long old_pagemask; + +ENTER_CRITICAL(flags); + +old_entryhi = read_c0_entryhi(); +old_pagemask = read_c0_pagemask(); + +printk(HOST TLBs:\n); +printk(ASID: %#lx\n, read_c0_entryhi() ASID_MASK); + +for (i = 0; i current_cpu_data.tlbsize; i++) { +write_c0_index(i); +mtc0_tlbw_hazard(); + +tlb_read(); +tlbw_use_hazard(); + +tlb.tlb_hi = read_c0_entryhi(); +tlb.tlb_lo0 = read_c0_entrylo0(); +tlb.tlb_lo1 = read_c0_entrylo1(); +tlb.tlb_mask = read_c0_pagemask(); + +printk(TLB%c%3d Hi 0x%08lx , + (tlb.tlb_lo0 | tlb.tlb_lo1) MIPS3_PG_V ? ' ' : '*', + i, tlb.tlb_hi); +printk(Lo0=0x%09 PRIx64 %c%c attr %lx , + (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo0), + (tlb.tlb_lo0 MIPS3_PG_D) ? 'D' : ' ', + (tlb.tlb_lo0 MIPS3_PG_G) ? 'G' : ' ', (tlb.tlb_lo0 3) 7); +printk(Lo1=0x%09 PRIx64 %c%c attr %lx sz=%lx\n, + (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo1), + (tlb.tlb_lo1 MIPS3_PG_D) ? 'D' : ' ', + (tlb.tlb_lo1 MIPS3_PG_G) ? 'G' : ' ', + (tlb.tlb_lo1 3) 7, tlb.tlb_mask); +} +write_c0_entryhi(old_entryhi); +write_c0_pagemask(old_pagemask); +mtc0_tlbw_hazard(); +EXIT_CRITICAL(flags); +} + +void +kvm_mips_dump_guest_tlbs(struct kvm_vcpu *vcpu) +{ +int i; +struct kvm_mips_tlb tlb; +struct mips_coproc *cop0 __unused = vcpu-arch.cop0; + +printk(Guest TLBs:\n); +printk(Guest EntryHi: %#lx\n, kvm_read_c0_guest_entryhi(cop0)); + +for (i = 0; i KVM_MIPS_GUEST_TLB_SIZE; i++) { +tlb = vcpu-arch.guest_tlb[i]; +printk(TLB%c%3d Hi 0x%08lx , + (tlb.tlb_lo0 | tlb.tlb_lo1) MIPS3_PG_V ? ' ' : '*', + i, tlb.tlb_hi); +printk(Lo0=0x%09 PRIx64 %c%c attr %lx , + (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo0), + (tlb.tlb_lo0 MIPS3_PG_D) ? 'D' : ' ', + (tlb.tlb_lo0 MIPS3_PG_G) ? 'G' : ' ', (tlb.tlb_lo0 3) 7); +printk(Lo1=0x%09 PRIx64 %c%c attr %lx sz=%lx\n, + (uint64_t) mips3_tlbpfn_to_paddr(tlb.tlb_lo1), + (tlb.tlb_lo1 MIPS3_PG_D) ? 'D' : ' ', + (tlb.tlb_lo1 MIPS3_PG_G) ? 'G' : ' ', + (tlb.tlb_lo1 3) 7