Commit d116e812 authored by Deng-Cheng Zhu's avatar Deng-Cheng Zhu Committed by Paolo Bonzini

MIPS: KVM: Reformat code and comments

No logic changes inside.
Signed-off-by: default avatarDeng-Cheng Zhu <dengcheng.zhu@imgtec.com>
Reviewed-by: default avatarJames Hogan <james.hogan@imgtec.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 85949977
...@@ -359,13 +359,17 @@ enum emulation_result { ...@@ -359,13 +359,17 @@ enum emulation_result {
#define MIPS3_PG_FRAME 0x3fffffc0 #define MIPS3_PG_FRAME 0x3fffffc0
#define VPN2_MASK 0xffffe000 #define VPN2_MASK 0xffffe000
#define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && \ #define TLB_IS_GLOBAL(x) (((x).tlb_lo0 & MIPS3_PG_G) && \
((x).tlb_lo1 & MIPS3_PG_G)) ((x).tlb_lo1 & MIPS3_PG_G))
#define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK) #define TLB_VPN2(x) ((x).tlb_hi & VPN2_MASK)
#define TLB_ASID(x) ((x).tlb_hi & ASID_MASK) #define TLB_ASID(x) ((x).tlb_hi & ASID_MASK)
#define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) \ #define TLB_IS_VALID(x, va) (((va) & (1 << PAGE_SHIFT)) \
? ((x).tlb_lo1 & MIPS3_PG_V) \ ? ((x).tlb_lo1 & MIPS3_PG_V) \
: ((x).tlb_lo0 & MIPS3_PG_V)) : ((x).tlb_lo0 & MIPS3_PG_V))
#define TLB_HI_VPN2_HIT(x, y) ((TLB_VPN2(x) & ~(x).tlb_mask) == \
((y) & VPN2_MASK & ~(x).tlb_mask))
#define TLB_HI_ASID_HIT(x, y) (TLB_IS_GLOBAL(x) || \
TLB_ASID(x) == ((y) & ASID_MASK))
struct kvm_mips_tlb { struct kvm_mips_tlb {
long tlb_mask; long tlb_mask;
......
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
#include <asm/mipsmtregs.h> #include <asm/mipsmtregs.h>
#include <asm/uaccess.h> /* for segment_eq() */ #include <asm/uaccess.h> /* for segment_eq() */
extern void (*r4k_blast_dcache)(void);
extern void (*r4k_blast_icache)(void);
/* /*
* This macro return a properly sign-extended address suitable as base address * This macro return a properly sign-extended address suitable as base address
* for indexed cache operations. Two issues here: * for indexed cache operations. Two issues here:
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <asm/stackframe.h> #include <asm/stackframe.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#define _C_LABEL(x) x #define _C_LABEL(x) x
#define MIPSX(name) mips32_ ## name #define MIPSX(name) mips32_ ## name
#define CALLFRAME_SIZ 32 #define CALLFRAME_SIZ 32
...@@ -91,7 +90,10 @@ FEXPORT(__kvm_mips_vcpu_run) ...@@ -91,7 +90,10 @@ FEXPORT(__kvm_mips_vcpu_run)
LONG_S $24, PT_R24(k1) LONG_S $24, PT_R24(k1)
LONG_S $25, PT_R25(k1) LONG_S $25, PT_R25(k1)
/* XXXKYMA k0/k1 not saved, not being used if we got here through an ioctl() */ /*
* XXXKYMA k0/k1 not saved, not being used if we got here through
* an ioctl()
*/
LONG_S $28, PT_R28(k1) LONG_S $28, PT_R28(k1)
LONG_S $29, PT_R29(k1) LONG_S $29, PT_R29(k1)
...@@ -132,7 +134,10 @@ FEXPORT(__kvm_mips_vcpu_run) ...@@ -132,7 +134,10 @@ FEXPORT(__kvm_mips_vcpu_run)
/* Save the kernel gp as well */ /* Save the kernel gp as well */
LONG_S gp, VCPU_HOST_GP(k1) LONG_S gp, VCPU_HOST_GP(k1)
/* Setup status register for running the guest in UM, interrupts are disabled */ /*
* Setup status register for running the guest in UM, interrupts
* are disabled
*/
li k0, (ST0_EXL | KSU_USER | ST0_BEV) li k0, (ST0_EXL | KSU_USER | ST0_BEV)
mtc0 k0, CP0_STATUS mtc0 k0, CP0_STATUS
ehb ehb
...@@ -152,7 +157,6 @@ FEXPORT(__kvm_mips_vcpu_run) ...@@ -152,7 +157,6 @@ FEXPORT(__kvm_mips_vcpu_run)
mtc0 k0, CP0_STATUS mtc0 k0, CP0_STATUS
ehb ehb
/* Set Guest EPC */ /* Set Guest EPC */
LONG_L t0, VCPU_PC(k1) LONG_L t0, VCPU_PC(k1)
mtc0 t0, CP0_EPC mtc0 t0, CP0_EPC
...@@ -165,7 +169,7 @@ FEXPORT(__kvm_mips_load_asid) ...@@ -165,7 +169,7 @@ FEXPORT(__kvm_mips_load_asid)
INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */ INT_ADDIU t1, k1, VCPU_GUEST_KERNEL_ASID /* (BD) */
INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */ INT_ADDIU t1, k1, VCPU_GUEST_USER_ASID /* else user */
1: 1:
/* t1: contains the base of the ASID array, need to get the cpu id */ /* t1: contains the base of the ASID array, need to get the cpu id */
LONG_L t2, TI_CPU($28) /* smp_processor_id */ LONG_L t2, TI_CPU($28) /* smp_processor_id */
INT_SLL t2, t2, 2 /* x4 */ INT_SLL t2, t2, 2 /* x4 */
REG_ADDU t3, t1, t2 REG_ADDU t3, t1, t2
...@@ -229,9 +233,7 @@ FEXPORT(__kvm_mips_load_k0k1) ...@@ -229,9 +233,7 @@ FEXPORT(__kvm_mips_load_k0k1)
eret eret
VECTOR(MIPSX(exception), unknown) VECTOR(MIPSX(exception), unknown)
/* /* Find out what mode we came from and jump to the proper handler. */
* Find out what mode we came from and jump to the proper handler.
*/
mtc0 k0, CP0_ERROREPC #01: Save guest k0 mtc0 k0, CP0_ERROREPC #01: Save guest k0
ehb #02: ehb #02:
...@@ -239,7 +241,8 @@ VECTOR(MIPSX(exception), unknown) ...@@ -239,7 +241,8 @@ VECTOR(MIPSX(exception), unknown)
INT_SRL k0, k0, 10 #03: Get rid of CPUNum INT_SRL k0, k0, 10 #03: Get rid of CPUNum
INT_SLL k0, k0, 10 #04 INT_SLL k0, k0, 10 #04
LONG_S k1, 0x3000(k0) #05: Save k1 @ offset 0x3000 LONG_S k1, 0x3000(k0) #05: Save k1 @ offset 0x3000
INT_ADDIU k0, k0, 0x2000 #06: Exception handler is installed @ offset 0x2000 INT_ADDIU k0, k0, 0x2000 #06: Exception handler is
# installed @ offset 0x2000
j k0 #07: jump to the function j k0 #07: jump to the function
nop #08: branch delay slot nop #08: branch delay slot
VECTOR_END(MIPSX(exceptionEnd)) VECTOR_END(MIPSX(exceptionEnd))
...@@ -248,7 +251,6 @@ VECTOR_END(MIPSX(exceptionEnd)) ...@@ -248,7 +251,6 @@ VECTOR_END(MIPSX(exceptionEnd))
/* /*
* Generic Guest exception handler. We end up here when the guest * Generic Guest exception handler. We end up here when the guest
* does something that causes a trap to kernel mode. * does something that causes a trap to kernel mode.
*
*/ */
NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
/* Get the VCPU pointer from DDTATA_LO */ /* Get the VCPU pointer from DDTATA_LO */
...@@ -290,9 +292,7 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) ...@@ -290,9 +292,7 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
LONG_S $30, VCPU_R30(k1) LONG_S $30, VCPU_R30(k1)
LONG_S $31, VCPU_R31(k1) LONG_S $31, VCPU_R31(k1)
/* We need to save hi/lo and restore them on /* We need to save hi/lo and restore them on the way out */
* the way out
*/
mfhi t0 mfhi t0
LONG_S t0, VCPU_HI(k1) LONG_S t0, VCPU_HI(k1)
...@@ -321,8 +321,10 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) ...@@ -321,8 +321,10 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
/* Save pointer to run in s0, will be saved by the compiler */ /* Save pointer to run in s0, will be saved by the compiler */
move s0, a0 move s0, a0
/* Save Host level EPC, BadVaddr and Cause to VCPU, useful to /*
* process the exception */ * Save Host level EPC, BadVaddr and Cause to VCPU, useful to
* process the exception
*/
mfc0 k0,CP0_EPC mfc0 k0,CP0_EPC
LONG_S k0, VCPU_PC(k1) LONG_S k0, VCPU_PC(k1)
...@@ -351,7 +353,6 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) ...@@ -351,7 +353,6 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
LONG_L k0, VCPU_HOST_EBASE(k1) LONG_L k0, VCPU_HOST_EBASE(k1)
mtc0 k0,CP0_EBASE mtc0 k0,CP0_EBASE
/* Now that the new EBASE has been loaded, unset BEV and KSU_USER */ /* Now that the new EBASE has been loaded, unset BEV and KSU_USER */
.set at .set at
and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE) and v0, v0, ~(ST0_EXL | KSU_USER | ST0_IE)
...@@ -369,7 +370,8 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) ...@@ -369,7 +370,8 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
/* Saved host state */ /* Saved host state */
INT_ADDIU sp, sp, -PT_SIZE INT_ADDIU sp, sp, -PT_SIZE
/* XXXKYMA do we need to load the host ASID, maybe not because the /*
* XXXKYMA do we need to load the host ASID, maybe not because the
* kernel entries are marked GLOBAL, need to verify * kernel entries are marked GLOBAL, need to verify
*/ */
...@@ -383,9 +385,11 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra) ...@@ -383,9 +385,11 @@ NESTED (MIPSX(GuestException), CALLFRAME_SIZ, ra)
/* Jump to handler */ /* Jump to handler */
FEXPORT(__kvm_mips_jump_to_handler) FEXPORT(__kvm_mips_jump_to_handler)
/* XXXKYMA: not sure if this is safe, how large is the stack?? /*
* XXXKYMA: not sure if this is safe, how large is the stack??
* Now jump to the kvm_mips_handle_exit() to see if we can deal * Now jump to the kvm_mips_handle_exit() to see if we can deal
* with this in the kernel */ * with this in the kernel
*/
PTR_LA t9, kvm_mips_handle_exit PTR_LA t9, kvm_mips_handle_exit
jalr.hb t9 jalr.hb t9
INT_ADDIU sp, sp, -CALLFRAME_SIZ /* BD Slot */ INT_ADDIU sp, sp, -CALLFRAME_SIZ /* BD Slot */
...@@ -394,7 +398,8 @@ FEXPORT(__kvm_mips_jump_to_handler) ...@@ -394,7 +398,8 @@ FEXPORT(__kvm_mips_jump_to_handler)
di di
ehb ehb
/* XXXKYMA: k0/k1 could have been blown away if we processed /*
* XXXKYMA: k0/k1 could have been blown away if we processed
* an exception while we were handling the exception from the * an exception while we were handling the exception from the
* guest, reload k1 * guest, reload k1
*/ */
...@@ -402,7 +407,8 @@ FEXPORT(__kvm_mips_jump_to_handler) ...@@ -402,7 +407,8 @@ FEXPORT(__kvm_mips_jump_to_handler)
move k1, s1 move k1, s1
INT_ADDIU k1, k1, VCPU_HOST_ARCH INT_ADDIU k1, k1, VCPU_HOST_ARCH
/* Check return value, should tell us if we are returning to the /*
* Check return value, should tell us if we are returning to the
* host (handle I/O etc)or resuming the guest * host (handle I/O etc)or resuming the guest
*/ */
andi t0, v0, RESUME_HOST andi t0, v0, RESUME_HOST
...@@ -521,8 +527,10 @@ __kvm_mips_return_to_host: ...@@ -521,8 +527,10 @@ __kvm_mips_return_to_host:
LONG_L $0, PT_R0(k1) LONG_L $0, PT_R0(k1)
LONG_L $1, PT_R1(k1) LONG_L $1, PT_R1(k1)
/* r2/v0 is the return code, shift it down by 2 (arithmetic) /*
* to recover the err code */ * r2/v0 is the return code, shift it down by 2 (arithmetic)
* to recover the err code
*/
INT_SRA k0, v0, 2 INT_SRA k0, v0, 2
move $2, k0 move $2, k0
...@@ -566,7 +574,6 @@ __kvm_mips_return_to_host: ...@@ -566,7 +574,6 @@ __kvm_mips_return_to_host:
PTR_LI k0, 0x2000000F PTR_LI k0, 0x2000000F
mtc0 k0, CP0_HWRENA mtc0 k0, CP0_HWRENA
/* Restore RA, which is the address we will return to */ /* Restore RA, which is the address we will return to */
LONG_L ra, PT_R31(k1) LONG_L ra, PT_R31(k1)
j ra j ra
......
This diff is collapsed.
/* /*
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* KVM/MIPS: commpage: mapped into get kernel space * KVM/MIPS: commpage: mapped into get kernel space
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com> * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/ */
#ifndef __KVM_MIPS_COMMPAGE_H__ #ifndef __KVM_MIPS_COMMPAGE_H__
#define __KVM_MIPS_COMMPAGE_H__ #define __KVM_MIPS_COMMPAGE_H__
struct kvm_mips_commpage { struct kvm_mips_commpage {
struct mips_coproc cop0; /* COP0 state is mapped into Guest kernel via commpage */ /* COP0 state is mapped into Guest kernel via commpage */
struct mips_coproc cop0;
}; };
#define KVM_MIPS_COMM_EIDI_OFFSET 0x0 #define KVM_MIPS_COMM_EIDI_OFFSET 0x0
......
/* /*
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* commpage, currently used for Virtual COP0 registers. * commpage, currently used for Virtual COP0 registers.
* Mapped into the guest kernel @ 0x0. * Mapped into the guest kernel @ 0x0.
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com> * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/ */
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
void kvm_mips_commpage_init(struct kvm_vcpu *vcpu) void kvm_mips_commpage_init(struct kvm_vcpu *vcpu)
{ {
struct kvm_mips_commpage *page = vcpu->arch.kseg0_commpage; struct kvm_mips_commpage *page = vcpu->arch.kseg0_commpage;
memset(page, 0, sizeof(struct kvm_mips_commpage)); memset(page, 0, sizeof(struct kvm_mips_commpage));
/* Specific init values for fields */ /* Specific init values for fields */
......
/* /*
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* KVM/MIPS: Binary Patching for privileged instructions, reduces traps. * KVM/MIPS: Binary Patching for privileged instructions, reduces traps.
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com> * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/ */
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -28,9 +28,8 @@ ...@@ -28,9 +28,8 @@
#define CLEAR_TEMPLATE 0x00000020 #define CLEAR_TEMPLATE 0x00000020
#define SW_TEMPLATE 0xac000000 #define SW_TEMPLATE 0xac000000
int int kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc,
kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
struct kvm_vcpu *vcpu)
{ {
int result = 0; int result = 0;
unsigned long kseg0_opc; unsigned long kseg0_opc;
...@@ -47,12 +46,11 @@ kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc, ...@@ -47,12 +46,11 @@ kvm_mips_trans_cache_index(uint32_t inst, uint32_t *opc,
} }
/* /*
* Address based CACHE instructions are transformed into synci(s). A little heavy * Address based CACHE instructions are transformed into synci(s). A little
* for just D-cache invalidates, but avoids an expensive trap * heavy for just D-cache invalidates, but avoids an expensive trap
*/ */
int int kvm_mips_trans_cache_va(uint32_t inst, uint32_t *opc,
kvm_mips_trans_cache_va(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
struct kvm_vcpu *vcpu)
{ {
int result = 0; int result = 0;
unsigned long kseg0_opc; unsigned long kseg0_opc;
...@@ -72,8 +70,7 @@ kvm_mips_trans_cache_va(uint32_t inst, uint32_t *opc, ...@@ -72,8 +70,7 @@ kvm_mips_trans_cache_va(uint32_t inst, uint32_t *opc,
return result; return result;
} }
int int kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
{ {
int32_t rt, rd, sel; int32_t rt, rd, sel;
uint32_t mfc0_inst; uint32_t mfc0_inst;
...@@ -115,8 +112,7 @@ kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu) ...@@ -115,8 +112,7 @@ kvm_mips_trans_mfc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
return 0; return 0;
} }
int int kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
kvm_mips_trans_mtc0(uint32_t inst, uint32_t *opc, struct kvm_vcpu *vcpu)
{ {
int32_t rt, rd, sel; int32_t rt, rd, sel;
uint32_t mtc0_inst = SW_TEMPLATE; uint32_t mtc0_inst = SW_TEMPLATE;
......
This diff is collapsed.
/* /*
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* KVM/MIPS: Interrupt delivery * KVM/MIPS: Interrupt delivery
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com> * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/ */
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -34,7 +34,8 @@ void kvm_mips_dequeue_irq(struct kvm_vcpu *vcpu, uint32_t priority) ...@@ -34,7 +34,8 @@ void kvm_mips_dequeue_irq(struct kvm_vcpu *vcpu, uint32_t priority)
void kvm_mips_queue_timer_int_cb(struct kvm_vcpu *vcpu) void kvm_mips_queue_timer_int_cb(struct kvm_vcpu *vcpu)
{ {
/* Cause bits to reflect the pending timer interrupt, /*
* Cause bits to reflect the pending timer interrupt,
* the EXC code will be set when we are actually * the EXC code will be set when we are actually
* delivering the interrupt: * delivering the interrupt:
*/ */
...@@ -51,12 +52,13 @@ void kvm_mips_dequeue_timer_int_cb(struct kvm_vcpu *vcpu) ...@@ -51,12 +52,13 @@ void kvm_mips_dequeue_timer_int_cb(struct kvm_vcpu *vcpu)
kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_TIMER); kvm_mips_dequeue_irq(vcpu, MIPS_EXC_INT_TIMER);
} }
void void kvm_mips_queue_io_int_cb(struct kvm_vcpu *vcpu,
kvm_mips_queue_io_int_cb(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq) struct kvm_mips_interrupt *irq)
{ {
int intr = (int)irq->irq; int intr = (int)irq->irq;
/* Cause bits to reflect the pending IO interrupt, /*
* Cause bits to reflect the pending IO interrupt,
* the EXC code will be set when we are actually * the EXC code will be set when we are actually
* delivering the interrupt: * delivering the interrupt:
*/ */
...@@ -83,11 +85,11 @@ kvm_mips_queue_io_int_cb(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq) ...@@ -83,11 +85,11 @@ kvm_mips_queue_io_int_cb(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq)
} }
void void kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu,
kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu, struct kvm_mips_interrupt *irq)
struct kvm_mips_interrupt *irq)
{ {
int intr = (int)irq->irq; int intr = (int)irq->irq;
switch (intr) { switch (intr) {
case -2: case -2:
kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ0)); kvm_clear_c0_guest_cause(vcpu->arch.cop0, (C_IRQ0));
...@@ -111,9 +113,8 @@ kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu, ...@@ -111,9 +113,8 @@ kvm_mips_dequeue_io_int_cb(struct kvm_vcpu *vcpu,
} }
/* Deliver the interrupt of the corresponding priority, if possible. */ /* Deliver the interrupt of the corresponding priority, if possible. */
int int kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority, uint32_t cause)
uint32_t cause)
{ {
int allowed = 0; int allowed = 0;
uint32_t exccode; uint32_t exccode;
...@@ -164,7 +165,6 @@ kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority, ...@@ -164,7 +165,6 @@ kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
/* Are we allowed to deliver the interrupt ??? */ /* Are we allowed to deliver the interrupt ??? */
if (allowed) { if (allowed) {
if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
/* save old pc */ /* save old pc */
kvm_write_c0_guest_epc(cop0, arch->pc); kvm_write_c0_guest_epc(cop0, arch->pc);
...@@ -195,9 +195,8 @@ kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority, ...@@ -195,9 +195,8 @@ kvm_mips_irq_deliver_cb(struct kvm_vcpu *vcpu, unsigned int priority,
return allowed; return allowed;
} }
int int kvm_mips_irq_clear_cb(struct kvm_vcpu *vcpu, unsigned int priority,
kvm_mips_irq_clear_cb(struct kvm_vcpu *vcpu, unsigned int priority, uint32_t cause)
uint32_t cause)
{ {
return 1; return 1;
} }
......
/* /*
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* KVM/MIPS: Interrupts * KVM/MIPS: Interrupts
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com> * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/ */
/* MIPS Exception Priorities, exceptions (including interrupts) are queued up /*
* MIPS Exception Priorities, exceptions (including interrupts) are queued up
* for the guest in the order specified by their priorities * for the guest in the order specified by their priorities
*/ */
...@@ -27,6 +28,9 @@ ...@@ -27,6 +28,9 @@
#define MIPS_EXC_MAX 12 #define MIPS_EXC_MAX 12
/* XXXSL More to follow */ /* XXXSL More to follow */
extern char mips32_exception[], mips32_exceptionEnd[];
extern char mips32_GuestException[], mips32_GuestExceptionEnd[];
#define C_TI (_ULCAST_(1) << 30) #define C_TI (_ULCAST_(1) << 30)
#define KVM_MIPS_IRQ_DELIVER_ALL_AT_ONCE (0) #define KVM_MIPS_IRQ_DELIVER_ALL_AT_ONCE (0)
......
/* /*
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com> * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/
/*
* Define opcode values not defined in <asm/isnt.h>
*/ */
/* Define opcode values not defined in <asm/isnt.h> */
#ifndef __KVM_MIPS_OPCODE_H__ #ifndef __KVM_MIPS_OPCODE_H__
#define __KVM_MIPS_OPCODE_H__ #define __KVM_MIPS_OPCODE_H__
/* COP0 Ops */ /* COP0 Ops */
#define mfmcz_op 0x0b /* 01011 */ #define mfmcz_op 0x0b /* 01011 */
#define wrpgpr_op 0x0e /* 01110 */ #define wrpgpr_op 0x0e /* 01110 */
/* COP0 opcodes (only if COP0 and CO=1): */ /* COP0 opcodes (only if COP0 and CO=1): */
#define wait_op 0x20 /* 100000 */ #define wait_op 0x20 /* 100000 */
#endif /* __KVM_MIPS_OPCODE_H__ */ #endif /* __KVM_MIPS_OPCODE_H__ */
/* /*
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* KVM/MIPS: COP0 access histogram * KVM/MIPS: COP0 access histogram
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com> * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/ */
#include <linux/kvm_host.h> #include <linux/kvm_host.h>
......
This diff is collapsed.
/* /*
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* KVM/MIPS: Deliver/Emulate exceptions to the guest kernel * KVM/MIPS: Deliver/Emulate exceptions to the guest kernel
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com> * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/ */
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -37,7 +37,6 @@ static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva) ...@@ -37,7 +37,6 @@ static gpa_t kvm_trap_emul_gva_to_gpa_cb(gva_t gva)
return gpa; return gpa;
} }
static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu) static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu)
{ {
struct kvm_run *run = vcpu->run; struct kvm_run *run = vcpu->run;
...@@ -46,9 +45,9 @@ static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu) ...@@ -46,9 +45,9 @@ static int kvm_trap_emul_handle_cop_unusable(struct kvm_vcpu *vcpu)
enum emulation_result er = EMULATE_DONE; enum emulation_result er = EMULATE_DONE;
int ret = RESUME_GUEST; int ret = RESUME_GUEST;
if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 1) { if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 1)
er = kvm_mips_emulate_fpu_exc(cause, opc, run, vcpu); er = kvm_mips_emulate_fpu_exc(cause, opc, run, vcpu);
} else else
er = kvm_mips_emulate_inst(cause, opc, run, vcpu); er = kvm_mips_emulate_inst(cause, opc, run, vcpu);
switch (er) { switch (er) {
...@@ -83,9 +82,8 @@ static int kvm_trap_emul_handle_tlb_mod(struct kvm_vcpu *vcpu) ...@@ -83,9 +82,8 @@ static int kvm_trap_emul_handle_tlb_mod(struct kvm_vcpu *vcpu)
if (KVM_GUEST_KSEGX(badvaddr) < KVM_GUEST_KSEG0 if (KVM_GUEST_KSEGX(badvaddr) < KVM_GUEST_KSEG0
|| KVM_GUEST_KSEGX(badvaddr) == KVM_GUEST_KSEG23) { || KVM_GUEST_KSEGX(badvaddr) == KVM_GUEST_KSEG23) {
kvm_debug kvm_debug("USER/KSEG23 ADDR TLB MOD fault: cause %#lx, PC: %p, BadVaddr: %#lx\n",
("USER/KSEG23 ADDR TLB MOD fault: cause %#lx, PC: %p, BadVaddr: %#lx\n", cause, opc, badvaddr);
cause, opc, badvaddr);
er = kvm_mips_handle_tlbmod(cause, opc, run, vcpu); er = kvm_mips_handle_tlbmod(cause, opc, run, vcpu);
if (er == EMULATE_DONE) if (er == EMULATE_DONE)
...@@ -95,8 +93,10 @@ static int kvm_trap_emul_handle_tlb_mod(struct kvm_vcpu *vcpu) ...@@ -95,8 +93,10 @@ static int kvm_trap_emul_handle_tlb_mod(struct kvm_vcpu *vcpu)
ret = RESUME_HOST; ret = RESUME_HOST;
} }
} else if (KVM_GUEST_KSEGX(badvaddr) == KVM_GUEST_KSEG0) { } 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 * 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 printk
("TLB MOD fault not handled, cause %#lx, PC: %p, BadVaddr: %#lx\n", ("TLB MOD fault not handled, cause %#lx, PC: %p, BadVaddr: %#lx\n",
...@@ -134,9 +134,8 @@ static int kvm_trap_emul_handle_tlb_st_miss(struct kvm_vcpu *vcpu) ...@@ -134,9 +134,8 @@ static int kvm_trap_emul_handle_tlb_st_miss(struct kvm_vcpu *vcpu)
} }
} else if (KVM_GUEST_KSEGX(badvaddr) < KVM_GUEST_KSEG0 } else if (KVM_GUEST_KSEGX(badvaddr) < KVM_GUEST_KSEG0
|| KVM_GUEST_KSEGX(badvaddr) == KVM_GUEST_KSEG23) { || KVM_GUEST_KSEGX(badvaddr) == KVM_GUEST_KSEG23) {
kvm_debug kvm_debug("USER ADDR TLB LD fault: cause %#lx, PC: %p, BadVaddr: %#lx\n",
("USER ADDR TLB LD fault: cause %#lx, PC: %p, BadVaddr: %#lx\n", cause, opc, badvaddr);
cause, opc, badvaddr);
er = kvm_mips_handle_tlbmiss(cause, opc, run, vcpu); er = kvm_mips_handle_tlbmiss(cause, opc, run, vcpu);
if (er == EMULATE_DONE) if (er == EMULATE_DONE)
ret = RESUME_GUEST; ret = RESUME_GUEST;
...@@ -145,8 +144,9 @@ static int kvm_trap_emul_handle_tlb_st_miss(struct kvm_vcpu *vcpu) ...@@ -145,8 +144,9 @@ static int kvm_trap_emul_handle_tlb_st_miss(struct kvm_vcpu *vcpu)
ret = RESUME_HOST; ret = RESUME_HOST;
} }
} else if (KVM_GUEST_KSEGX(badvaddr) == KVM_GUEST_KSEG0) { } else if (KVM_GUEST_KSEGX(badvaddr) == KVM_GUEST_KSEG0) {
/* All KSEG0 faults are handled by KVM, as the guest kernel does not /*
* expect to ever get them * All KSEG0 faults are handled by KVM, as the guest kernel does
* not expect to ever get them
*/ */
if (kvm_mips_handle_kseg0_tlb_fault if (kvm_mips_handle_kseg0_tlb_fault
(vcpu->arch.host_cp0_badvaddr, vcpu) < 0) { (vcpu->arch.host_cp0_badvaddr, vcpu) < 0) {
...@@ -154,9 +154,8 @@ static int kvm_trap_emul_handle_tlb_st_miss(struct kvm_vcpu *vcpu) ...@@ -154,9 +154,8 @@ static int kvm_trap_emul_handle_tlb_st_miss(struct kvm_vcpu *vcpu)
ret = RESUME_HOST; ret = RESUME_HOST;
} }
} else { } else {
kvm_err kvm_err("Illegal TLB LD fault address , cause %#lx, PC: %p, BadVaddr: %#lx\n",
("Illegal TLB LD fault address , cause %#lx, PC: %p, BadVaddr: %#lx\n", cause, opc, badvaddr);
cause, opc, badvaddr);
kvm_mips_dump_host_tlbs(); kvm_mips_dump_host_tlbs();
kvm_arch_vcpu_dump_regs(vcpu); kvm_arch_vcpu_dump_regs(vcpu);
run->exit_reason = KVM_EXIT_INTERNAL_ERROR; run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
...@@ -185,11 +184,14 @@ static int kvm_trap_emul_handle_tlb_ld_miss(struct kvm_vcpu *vcpu) ...@@ -185,11 +184,14 @@ static int kvm_trap_emul_handle_tlb_ld_miss(struct kvm_vcpu *vcpu)
kvm_debug("USER ADDR TLB ST fault: PC: %#lx, BadVaddr: %#lx\n", kvm_debug("USER ADDR TLB ST fault: PC: %#lx, BadVaddr: %#lx\n",
vcpu->arch.pc, badvaddr); vcpu->arch.pc, badvaddr);
/* User Address (UA) fault, this could happen if /*
* (1) TLB entry not present/valid in both Guest and shadow host TLBs, in this * User Address (UA) fault, this could happen if
* case we pass on the fault to the guest kernel and let it handle it. * (1) TLB entry not present/valid in both Guest and shadow host
* (2) TLB entry is present in the Guest TLB but not in the shadow, in this * TLBs, in this case we pass on the fault to the guest
* case we inject the TLB from the Guest TLB into the shadow host TLB * kernel and let it handle it.
* (2) TLB entry is present in the Guest TLB but not in the
* shadow, in this case we inject the TLB from the Guest TLB
* into the shadow host TLB
*/ */
er = kvm_mips_handle_tlbmiss(cause, opc, run, vcpu); er = kvm_mips_handle_tlbmiss(cause, opc, run, vcpu);
...@@ -349,9 +351,9 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu) ...@@ -349,9 +351,9 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu)
uint32_t config1; uint32_t config1;
int vcpu_id = vcpu->vcpu_id; int vcpu_id = vcpu->vcpu_id;
/* Arch specific stuff, set up config registers properly so that the /*
* guest will come up as expected, for now we simulate a * Arch specific stuff, set up config registers properly so that the
* MIPS 24kc * guest will come up as expected, for now we simulate a MIPS 24kc
*/ */
kvm_write_c0_guest_prid(cop0, 0x00019300); kvm_write_c0_guest_prid(cop0, 0x00019300);
kvm_write_c0_guest_config(cop0, kvm_write_c0_guest_config(cop0,
...@@ -373,14 +375,15 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu) ...@@ -373,14 +375,15 @@ static int kvm_trap_emul_vcpu_setup(struct kvm_vcpu *vcpu)
kvm_write_c0_guest_config2(cop0, MIPS_CONFIG2); kvm_write_c0_guest_config2(cop0, MIPS_CONFIG2);
/* MIPS_CONFIG2 | (read_c0_config2() & 0xfff) */ /* MIPS_CONFIG2 | (read_c0_config2() & 0xfff) */
kvm_write_c0_guest_config3(cop0, kvm_write_c0_guest_config3(cop0, MIPS_CONFIG3 | (0 << CP0C3_VInt) |
MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << (1 << CP0C3_ULRI));
CP0C3_ULRI));
/* Set Wait IE/IXMT Ignore in Config7, IAR, AR */ /* Set Wait IE/IXMT Ignore in Config7, IAR, AR */
kvm_write_c0_guest_config7(cop0, (MIPS_CONF7_WII) | (1 << 10)); kvm_write_c0_guest_config7(cop0, (MIPS_CONF7_WII) | (1 << 10));
/* Setup IntCtl defaults, compatibilty mode for timer interrupts (HW5) */ /*
* Setup IntCtl defaults, compatibilty mode for timer interrupts (HW5)
*/
kvm_write_c0_guest_intctl(cop0, 0xFC000000); kvm_write_c0_guest_intctl(cop0, 0xFC000000);
/* Put in vcpu id as CPUNum into Ebase Reg to handle SMP Guests */ /* Put in vcpu id as CPUNum into Ebase Reg to handle SMP Guests */
......
/* /*
* This file is subject to the terms and conditions of the GNU General Public * 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 * License. See the file "COPYING" in the main directory of this archive
* for more details. * for more details.
* *
* Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
* Authors: Sanjay Lal <sanjayl@kymasys.com> * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/ */
#if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ) #if !defined(_TRACE_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_KVM_H #define _TRACE_KVM_H
...@@ -17,9 +17,7 @@ ...@@ -17,9 +17,7 @@
#define TRACE_INCLUDE_PATH . #define TRACE_INCLUDE_PATH .
#define TRACE_INCLUDE_FILE trace #define TRACE_INCLUDE_FILE trace
/* /* Tracepoints for VM eists */
* Tracepoints for VM eists
*/
extern char *kvm_mips_exit_types_str[MAX_KVM_MIPS_EXIT_TYPES]; extern char *kvm_mips_exit_types_str[MAX_KVM_MIPS_EXIT_TYPES];
TRACE_EVENT(kvm_exit, TRACE_EVENT(kvm_exit,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment