Skip to content

Commit

Permalink
Merge pull request #466 from Freax13/fix/hv
Browse files Browse the repository at this point in the history
some fixes for the #HV handler
  • Loading branch information
joergroedel authored Oct 15, 2024
2 parents 6d545ba + 8f368f8 commit c1c9110
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 19 deletions.
18 changes: 9 additions & 9 deletions kernel/src/cpu/idt/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ hv_not_vmpl_switch:
// point, there are two possibilities. If RIP is before the IRET
// instruction itself, then the RSP at the time of #HV exception
// points to the register context that was established for the previous
// exceptoin. In that case, the current RSP can be changed to point
// exception. In that case, the current RSP can be changed to point
// to that exception context, and the #HV can be handled using that
// register context, and when #HV processing completes, the subsequent
// end-of-interrupt flow will restore the context at the time of the
Expand Down Expand Up @@ -171,7 +171,7 @@ restart_hv:
// register state at the time of the exception that was returning at
// the time the #HV arrived.
// At this point, RCX holds the stack pointer at the time of the
// IRET taht was aborted. The first QWORD below that pointer is
// IRET that was aborted. The first QWORD below that pointer is
// reserved for the dummy error code, then the three QWORDS below that
// will hold the RAX, RBX, and RCX values, which are presently stored
// in the top three QWORDs of the current stack.
Expand All @@ -185,7 +185,7 @@ restart_hv:

continue_hv:
// At this point, only the dummy error code and first three registers
// have been pushed onto the stack. Push the remainder o construct a
// have been pushed onto the stack. Push the remainder to construct a
// full exception context.
pushq %rdx
pushq %rsi
Expand Down Expand Up @@ -214,19 +214,14 @@ handle_as_hv_with_doorbell:
call process_hv_events
// fall through to default_return

.globl return_new_task
return_new_task:
call setup_new_task
jmp default_return

.globl default_return
default_return:
// Ensure that interrupts are disabled before attempting any return.
cli
testb $3, 17*8(%rsp) // Check CS in exception frame
jnz return_user
return_all_paths:
// If interrupts were prerviously available, then check whether any #HV
// If interrupts were previously available, then check whether any #HV
// events are pending. If so, proceed as if the original trap was
// #HV.
testl $0x200, 18*8(%rsp) // check EFLAGS.IF in exception frame
Expand Down Expand Up @@ -274,6 +269,11 @@ return_user:
// Put user-mode specific return code here
jmp return_all_paths

.globl return_new_task
return_new_task:
call setup_new_task
jmp default_return

// #DE Divide-by-Zero-Error Exception (Vector 0)
default_entry_no_ist name=de handler=panic error_code=0 vector=0

Expand Down
19 changes: 9 additions & 10 deletions kernel/src/cpu/percpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ pub struct PerCpu {
ghcb: OnceCell<GhcbPage>,

/// `#HV` doorbell page for this CPU.
hv_doorbell: OnceCell<&'static HVDoorbell>,
hv_doorbell: Cell<Option<&'static HVDoorbell>>,

init_stack: Cell<Option<VirtAddr>>,
ist: IstStacks,
Expand Down Expand Up @@ -341,7 +341,7 @@ impl PerCpu {

shared: PerCpuShared::new(apic_id),
ghcb: OnceCell::new(),
hv_doorbell: OnceCell::new(),
hv_doorbell: Cell::new(None),
init_stack: Cell::new(None),
ist: IstStacks::new(),
current_stack: Cell::new(MemoryRegion::new(VirtAddr::null(), 0)),
Expand Down Expand Up @@ -408,17 +408,14 @@ impl PerCpu {
}

pub fn hv_doorbell(&self) -> Option<&'static HVDoorbell> {
self.hv_doorbell.get().copied()
self.hv_doorbell.get()
}

/// Gets a pointer to the location of the HV doorbell pointer in the
/// PerCpu structure. Pointers and references have the same layout, so
/// the return type is equivalent to `*const *const HVDoorbell`.
pub fn hv_doorbell_addr(&self) -> *const &'static HVDoorbell {
self.hv_doorbell
.get()
.map(ptr::from_ref)
.unwrap_or(ptr::null())
self.hv_doorbell.as_ptr().cast()
}

pub fn get_top_of_stack(&self) -> VirtAddr {
Expand Down Expand Up @@ -488,9 +485,11 @@ impl PerCpu {

fn setup_hv_doorbell(&self) -> Result<(), SvsmError> {
let doorbell = allocate_hv_doorbell_page(current_ghcb())?;
self.hv_doorbell
.set(doorbell)
.expect("Attempted to reinitialize the HV doorbell page");
assert!(
self.hv_doorbell.get().is_none(),
"Attempted to reinitialize the HV doorbell page"
);
self.hv_doorbell.set(Some(doorbell));
Ok(())
}

Expand Down

0 comments on commit c1c9110

Please sign in to comment.