Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/core/shim.S
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@
* shim restores X11 from the saved frame before
* ERET so the EL0 caller never observes this hint.)
* #7 MRS trap (host reads reg from ESR ISS; returns value in x0)
* #9 W^X toggle (x0=FAR, x1=type: 0=exec->RX, 1=write->RW)
* #9 W^X toggle (x0=FAR, x1=type: 0=exec->RX, 1=write->RW.
* On return, X8==0 means retry after W^X TLBI;
* X8==2 means host delivered a signal frame and the
* shim must drop the saved fault frame.)
* #10 BRK from EL0 (SIGTRAP delivery / ptrace-stop; GPRs in frame)
* #11 EL0 fault (SIGSEGV/SIGILL delivery; GPRs in frame.
* On return the host sets X8 to the same TLBI
Expand Down Expand Up @@ -1119,6 +1122,8 @@ handle_inst_abort:
1: mrs x0, far_el1 /* Faulting address */
mov x1, #0 /* Type 0 = instruction fault -> flip to RX */
hvc #9
cmp x8, #2
b.eq exec_drop_frame
b tlbi_restore_eret

/* handle_data_abort: EC=0x24: Data abort from lower EL
Expand All @@ -1143,6 +1148,8 @@ handle_data_abort:
mrs x0, far_el1 /* Faulting address */
mov x1, #1 /* Type 1 = write fault -> flip to RW */
hvc #9
cmp x8, #2
b.eq exec_drop_frame
b tlbi_restore_eret

/* handle_el0_fault: Deliver SIGSEGV/SIGILL for EL0 faults
Expand Down
8 changes: 8 additions & 0 deletions src/syscall/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2065,8 +2065,16 @@ int vcpu_run_loop(hv_vcpu_t vcpu,
* so the next syscall epilogue does not re-flush the W^X
* page. cpu_tlbi_req is per-vCPU, so this only touches our
* own slot -- concurrent vCPUs are unaffected.
*
* The HVC #9 shim now consumes X8 as a post-HVC marker:
* 0 means W^X succeeded and the shim should run the TLBI
* retry epilogue; 2 means signal_deliver_fault installed a
* handler frame and the shim must drop its saved frame.
* Clear X8 here so a guest's pre-fault X8 value cannot be
* misread as the frame-drop marker after a normal toggle.
*/
tlbi_request_clear();
hv_vcpu_set_reg(vcpu, HV_REG_X8, 0);
break;
}

Expand Down
8 changes: 5 additions & 3 deletions src/syscall/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1735,9 +1735,11 @@ static int deliver_signal_locked(hv_vcpu_t vcpu,
/* If delivery happens while returning from the syscall HVC path, the shim
* still has the interrupted syscall frame on its EL1 stack. Tell it to drop
* that frame so the handler PC/SP/LR/args installed above are not
* overwritten before ERET. Fault/BRK delivery paths ignore this marker. The
* EL0-preemption path resumes straight into the handler at EL0 with no shim
* frame to drop, so the marker is neither needed nor consulted.
* overwritten before ERET. HVC #9 fault fallback uses the same marker when
* it materializes a SIGSEGV frame; HVC #11 and BRK delivery paths do not
* consume it. The EL0-preemption path resumes straight into the handler at
* EL0 with no shim frame to drop, so the marker is neither needed nor
* consulted.
*/
if (!el0_preempt)
hv_vcpu_set_reg(vcpu, HV_REG_X8, 2);
Expand Down
Loading