Add hypervisor trap handling, using HSRR0/HSRR1
Summary: Some hypervisor exceptions on POWER architecture only save state to HSRR0/HSRR1. Until we have bhyve on POWER, use a lightweight exception frontend which copies HSRR0/HSRR1 into SRR0/SRR1, and run the normal trap handler. The first user of this is the Hypervisor Virtualization Interrupt, which targets the XIVE interrupt controller on POWER9. Reviewed By: nwhitehorn Differential Revision: https://reviews.freebsd.org/D15487
This commit is contained in:
parent
39eef2f45a
commit
5321c01b50
@ -148,6 +148,7 @@ extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
|
|||||||
|
|
||||||
extern void *rstcode, *rstcodeend;
|
extern void *rstcode, *rstcodeend;
|
||||||
extern void *trapcode, *trapcodeend;
|
extern void *trapcode, *trapcodeend;
|
||||||
|
extern void *hypertrapcode, *hypertrapcodeend;
|
||||||
extern void *generictrap, *generictrap64;
|
extern void *generictrap, *generictrap64;
|
||||||
extern void *alitrap, *aliend;
|
extern void *alitrap, *aliend;
|
||||||
extern void *dsitrap, *dsiend;
|
extern void *dsitrap, *dsiend;
|
||||||
@ -360,6 +361,11 @@ aim_cpu_init(vm_offset_t toc)
|
|||||||
bcopy(&restorebridge, (void *)EXC_TRC, trap_offset);
|
bcopy(&restorebridge, (void *)EXC_TRC, trap_offset);
|
||||||
bcopy(&restorebridge, (void *)EXC_BPT, trap_offset);
|
bcopy(&restorebridge, (void *)EXC_BPT, trap_offset);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
trapsize = (size_t)&hypertrapcodeend - (size_t)&hypertrapcode;
|
||||||
|
bcopy(&hypertrapcode, (void *)(EXC_HEA + trap_offset), trapsize);
|
||||||
|
bcopy(&hypertrapcode, (void *)(EXC_HMI + trap_offset), trapsize);
|
||||||
|
bcopy(&hypertrapcode, (void *)(EXC_HVI + trap_offset), trapsize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstcodeend -
|
bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstcodeend -
|
||||||
|
@ -446,6 +446,20 @@ CNAME(trapcode):
|
|||||||
blrl /* Branch to generictrap */
|
blrl /* Branch to generictrap */
|
||||||
CNAME(trapcodeend):
|
CNAME(trapcodeend):
|
||||||
|
|
||||||
|
/* Same thing for traps setting HSRR0/HSS1 */
|
||||||
|
.globl CNAME(hypertrapcode),CNAME(hypertrapcodeend)
|
||||||
|
.p2align 3
|
||||||
|
CNAME(hypertrapcode):
|
||||||
|
mtsprg1 %r1 /* save SP */
|
||||||
|
mflr %r1 /* Save the old LR in r1 */
|
||||||
|
mtsprg2 %r1 /* And then in SPRG2 */
|
||||||
|
ld %r1,TRAP_GENTRAP(0)
|
||||||
|
addi %r1,%r1,(generichypertrap-generictrap)
|
||||||
|
mtlr %r1
|
||||||
|
li %r1, 0xe0 /* How to get the vector from LR */
|
||||||
|
blrl /* Branch to generictrap */
|
||||||
|
CNAME(hypertrapcodeend):
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For SLB misses: do special things for the kernel
|
* For SLB misses: do special things for the kernel
|
||||||
*
|
*
|
||||||
@ -757,6 +771,13 @@ realtrap:
|
|||||||
* SPRG2 - Original LR
|
* SPRG2 - Original LR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
generichypertrap:
|
||||||
|
mtsprg3 %r1
|
||||||
|
mfspr %r1, SPR_HSRR0
|
||||||
|
mtsrr0 %r1
|
||||||
|
mfspr %r1, SPR_HSRR1
|
||||||
|
mtsrr1 %r1
|
||||||
|
mfsprg3 %r1
|
||||||
.globl CNAME(generictrap)
|
.globl CNAME(generictrap)
|
||||||
generictrap:
|
generictrap:
|
||||||
/* Save R1 for computing the exception vector */
|
/* Save R1 for computing the exception vector */
|
||||||
|
@ -86,6 +86,7 @@ powerpc_interrupt(struct trapframe *framep)
|
|||||||
|
|
||||||
switch (framep->exc) {
|
switch (framep->exc) {
|
||||||
case EXC_EXI:
|
case EXC_EXI:
|
||||||
|
case EXC_HVI:
|
||||||
critical_enter();
|
critical_enter();
|
||||||
PIC_DISPATCH(root_pic, framep);
|
PIC_DISPATCH(root_pic, framep);
|
||||||
critical_exit();
|
critical_exit();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user