mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-15 05:11:32 +00:00
KVM: ppc: Add extra E500 exceptions
e500 has additional interrupt vectors (and corresponding IVORs) for SPE and performance monitoring interrupts. Signed-off-by: Liu Yu <yu.liu@freescale.com> Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com> Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
bdc89f13ec
commit
bb3a8a178d
@ -42,7 +42,12 @@
|
||||
#define BOOKE_INTERRUPT_DTLB_MISS 13
|
||||
#define BOOKE_INTERRUPT_ITLB_MISS 14
|
||||
#define BOOKE_INTERRUPT_DEBUG 15
|
||||
#define BOOKE_MAX_INTERRUPT 15
|
||||
|
||||
/* E500 */
|
||||
#define BOOKE_INTERRUPT_SPE_UNAVAIL 32
|
||||
#define BOOKE_INTERRUPT_SPE_FP_DATA 33
|
||||
#define BOOKE_INTERRUPT_SPE_FP_ROUND 34
|
||||
#define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
|
||||
|
||||
#define RESUME_FLAG_NV (1<<0) /* Reload guest nonvolatile state? */
|
||||
#define RESUME_FLAG_HOST (1<<1) /* Resume host? */
|
||||
|
@ -150,7 +150,7 @@ struct kvm_vcpu_arch {
|
||||
u32 tbu;
|
||||
u32 tcr;
|
||||
u32 tsr;
|
||||
u32 ivor[16];
|
||||
u32 ivor[64];
|
||||
ulong ivpr;
|
||||
u32 pir;
|
||||
|
||||
|
@ -118,6 +118,9 @@ static int kvmppc_booke_irqprio_deliver(struct kvm_vcpu *vcpu,
|
||||
case BOOKE_IRQPRIO_DATA_STORAGE:
|
||||
case BOOKE_IRQPRIO_INST_STORAGE:
|
||||
case BOOKE_IRQPRIO_FP_UNAVAIL:
|
||||
case BOOKE_IRQPRIO_SPE_UNAVAIL:
|
||||
case BOOKE_IRQPRIO_SPE_FP_DATA:
|
||||
case BOOKE_IRQPRIO_SPE_FP_ROUND:
|
||||
case BOOKE_IRQPRIO_AP_UNAVAIL:
|
||||
case BOOKE_IRQPRIO_ALIGNMENT:
|
||||
allowed = 1;
|
||||
@ -261,6 +264,21 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
r = RESUME_GUEST;
|
||||
break;
|
||||
|
||||
case BOOKE_INTERRUPT_SPE_UNAVAIL:
|
||||
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_UNAVAIL);
|
||||
r = RESUME_GUEST;
|
||||
break;
|
||||
|
||||
case BOOKE_INTERRUPT_SPE_FP_DATA:
|
||||
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_DATA);
|
||||
r = RESUME_GUEST;
|
||||
break;
|
||||
|
||||
case BOOKE_INTERRUPT_SPE_FP_ROUND:
|
||||
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_SPE_FP_ROUND);
|
||||
r = RESUME_GUEST;
|
||||
break;
|
||||
|
||||
case BOOKE_INTERRUPT_DATA_STORAGE:
|
||||
vcpu->arch.dear = vcpu->arch.fault_dear;
|
||||
vcpu->arch.esr = vcpu->arch.fault_esr;
|
||||
|
@ -31,18 +31,24 @@
|
||||
#define BOOKE_IRQPRIO_ALIGNMENT 2
|
||||
#define BOOKE_IRQPRIO_PROGRAM 3
|
||||
#define BOOKE_IRQPRIO_FP_UNAVAIL 4
|
||||
#define BOOKE_IRQPRIO_SYSCALL 5
|
||||
#define BOOKE_IRQPRIO_AP_UNAVAIL 6
|
||||
#define BOOKE_IRQPRIO_DTLB_MISS 7
|
||||
#define BOOKE_IRQPRIO_ITLB_MISS 8
|
||||
#define BOOKE_IRQPRIO_MACHINE_CHECK 9
|
||||
#define BOOKE_IRQPRIO_DEBUG 10
|
||||
#define BOOKE_IRQPRIO_CRITICAL 11
|
||||
#define BOOKE_IRQPRIO_WATCHDOG 12
|
||||
#define BOOKE_IRQPRIO_EXTERNAL 13
|
||||
#define BOOKE_IRQPRIO_FIT 14
|
||||
#define BOOKE_IRQPRIO_DECREMENTER 15
|
||||
#define BOOKE_IRQPRIO_MAX 15
|
||||
#define BOOKE_IRQPRIO_SPE_UNAVAIL 5
|
||||
#define BOOKE_IRQPRIO_SPE_FP_DATA 6
|
||||
#define BOOKE_IRQPRIO_SPE_FP_ROUND 7
|
||||
#define BOOKE_IRQPRIO_SYSCALL 8
|
||||
#define BOOKE_IRQPRIO_AP_UNAVAIL 9
|
||||
#define BOOKE_IRQPRIO_DTLB_MISS 10
|
||||
#define BOOKE_IRQPRIO_ITLB_MISS 11
|
||||
#define BOOKE_IRQPRIO_MACHINE_CHECK 12
|
||||
#define BOOKE_IRQPRIO_DEBUG 13
|
||||
#define BOOKE_IRQPRIO_CRITICAL 14
|
||||
#define BOOKE_IRQPRIO_WATCHDOG 15
|
||||
#define BOOKE_IRQPRIO_EXTERNAL 16
|
||||
#define BOOKE_IRQPRIO_FIT 17
|
||||
#define BOOKE_IRQPRIO_DECREMENTER 18
|
||||
#define BOOKE_IRQPRIO_PERFORMANCE_MONITOR 19
|
||||
#define BOOKE_IRQPRIO_MAX 19
|
||||
|
||||
extern unsigned long kvmppc_booke_handlers;
|
||||
|
||||
/* Helper function for "full" MSR writes. No need to call this if only EE is
|
||||
* changing. */
|
||||
|
@ -86,6 +86,9 @@ KVM_HANDLER BOOKE_INTERRUPT_WATCHDOG
|
||||
KVM_HANDLER BOOKE_INTERRUPT_DTLB_MISS
|
||||
KVM_HANDLER BOOKE_INTERRUPT_ITLB_MISS
|
||||
KVM_HANDLER BOOKE_INTERRUPT_DEBUG
|
||||
KVM_HANDLER BOOKE_INTERRUPT_SPE_UNAVAIL
|
||||
KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_DATA
|
||||
KVM_HANDLER BOOKE_INTERRUPT_SPE_FP_ROUND
|
||||
|
||||
_GLOBAL(kvmppc_handler_len)
|
||||
.long kvmppc_handler_1 - kvmppc_handler_0
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <asm/kvm_e500.h>
|
||||
#include <asm/kvm_ppc.h>
|
||||
|
||||
#include "booke.h"
|
||||
#include "e500_tlb.h"
|
||||
|
||||
void kvmppc_core_load_host_debugstate(struct kvm_vcpu *vcpu)
|
||||
@ -133,12 +134,29 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
|
||||
|
||||
static int kvmppc_e500_init(void)
|
||||
{
|
||||
int r;
|
||||
int r, i;
|
||||
unsigned long ivor[3];
|
||||
unsigned long max_ivor = 0;
|
||||
|
||||
r = kvmppc_booke_init();
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* copy extra E500 exception handlers */
|
||||
ivor[0] = mfspr(SPRN_IVOR32);
|
||||
ivor[1] = mfspr(SPRN_IVOR33);
|
||||
ivor[2] = mfspr(SPRN_IVOR34);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (ivor[i] > max_ivor)
|
||||
max_ivor = ivor[i];
|
||||
|
||||
memcpy((void *)kvmppc_booke_handlers + ivor[i],
|
||||
kvmppc_handlers_start + (i + 16) * kvmppc_handler_len,
|
||||
kvmppc_handler_len);
|
||||
}
|
||||
flush_icache_range(kvmppc_booke_handlers,
|
||||
kvmppc_booke_handlers + max_ivor + kvmppc_handler_len);
|
||||
|
||||
return kvm_init(NULL, sizeof(struct kvmppc_vcpu_e500), THIS_MODULE);
|
||||
}
|
||||
|
||||
|
@ -107,6 +107,20 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs)
|
||||
case SPRN_HID1:
|
||||
vcpu_e500->hid1 = vcpu->arch.gpr[rs]; break;
|
||||
|
||||
/* extra exceptions */
|
||||
case SPRN_IVOR32:
|
||||
vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] = vcpu->arch.gpr[rs];
|
||||
break;
|
||||
case SPRN_IVOR33:
|
||||
vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] = vcpu->arch.gpr[rs];
|
||||
break;
|
||||
case SPRN_IVOR34:
|
||||
vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] = vcpu->arch.gpr[rs];
|
||||
break;
|
||||
case SPRN_IVOR35:
|
||||
vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] = vcpu->arch.gpr[rs];
|
||||
break;
|
||||
|
||||
default:
|
||||
emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
|
||||
}
|
||||
@ -160,6 +174,19 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt)
|
||||
case SPRN_HID1:
|
||||
vcpu->arch.gpr[rt] = vcpu_e500->hid1; break;
|
||||
|
||||
/* extra exceptions */
|
||||
case SPRN_IVOR32:
|
||||
vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
|
||||
break;
|
||||
case SPRN_IVOR33:
|
||||
vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
|
||||
break;
|
||||
case SPRN_IVOR34:
|
||||
vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
|
||||
break;
|
||||
case SPRN_IVOR35:
|
||||
vcpu->arch.gpr[rt] = vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
|
||||
break;
|
||||
default:
|
||||
emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user