-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cpu/idt: add CPUID handling in stage 2 #VC handler
TODO: not complete yet Signed-off-by: Thomas Leroy <[email protected]>
- Loading branch information
Showing
4 changed files
with
119 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,27 +5,108 @@ | |
// Author: Joerg Roedel <[email protected]> | ||
|
||
use super::idt::common::X86ExceptionContext; | ||
use crate::cpu::cpuid::{cpuid_table_raw, dump_cpuid_table, CpuidLeaf}; | ||
use crate::cpu::extable::handle_exception_table; | ||
use crate::cpu::X86GeneralRegs; | ||
use crate::debug::gdbstub::svsm_gdbstub::handle_db_exception; | ||
use crate::error::SvsmError; | ||
|
||
pub const SVM_EXIT_EXCP_BASE: usize = 0x40; | ||
pub const SVM_EXIT_CPUID: usize = 0x72; | ||
pub const X86_TRAP_DB: usize = 0x01; | ||
pub const X86_TRAP: usize = SVM_EXIT_EXCP_BASE + X86_TRAP_DB; | ||
|
||
#[derive(Clone, Copy, Debug)] | ||
pub enum VcError { | ||
Unsupported, | ||
VMMError, | ||
DecodeFailed, | ||
Exception, | ||
Retry, | ||
} | ||
|
||
impl From<VcError> for SvsmError { | ||
fn from(e: VcError) -> Self { | ||
Self::Vc(e) | ||
} | ||
} | ||
|
||
pub fn stage2_handle_vc_exception(ctx: &mut X86ExceptionContext) { | ||
let err = ctx.error_code; | ||
let rip = ctx.frame.rip; | ||
|
||
// If the debugger is enabled then handle the DB exception | ||
// by directly invoking the exception hander | ||
if err == (SVM_EXIT_EXCP_BASE + X86_TRAP_DB) { | ||
handle_db_exception(ctx); | ||
return; | ||
let ret = match err { | ||
// If the debugger is enabled then handle the DB exception | ||
// by directly invoking the exception handler | ||
X86_TRAP_DB => { | ||
handle_db_exception(ctx); | ||
Ok(()) | ||
} | ||
|
||
SVM_EXIT_CPUID => handle_cpuid(ctx), | ||
_ => Err(SvsmError::Vc(VcError::Unsupported)), | ||
}; | ||
|
||
if ret.is_err() { | ||
panic!( | ||
"Unhandled #VC exception RIP {:#018x} error code: {:#018x}: error: {:?}", | ||
rip, | ||
err, | ||
ret.err() | ||
); | ||
} | ||
|
||
vc_finish_insn(ctx); | ||
} | ||
|
||
fn handle_cpuid(ctx: &mut X86ExceptionContext) -> Result<(), SvsmError> { | ||
let regs = &mut ctx.regs; | ||
|
||
/* | ||
* For SEV-ES/SEV-SNP, we can use the CPUID table already defined and populated with | ||
* firmware information. | ||
* We choose for now not to call the hypervisor to perform CPUID, since it's no trusted. | ||
* Since GHCB is not needed to handle CPUID with the firmware table, we can call the handler | ||
* very soon in stage 2. | ||
*/ | ||
snp_cpuid(regs)?; | ||
|
||
Ok(()) | ||
} | ||
|
||
fn snp_cpuid(regs: &mut X86GeneralRegs) -> Result<(), SvsmError> { | ||
let leaf = &mut CpuidLeaf::new(regs.rax as u32, regs.rcx as u32); | ||
|
||
let ret = match cpuid_table_raw(leaf.cpuid_fn, leaf.cpuid_subfn, 0, 0) { | ||
None => Err(SvsmError::Vc(VcError::Unsupported)), | ||
Some(v) => Ok(v), | ||
}?; | ||
|
||
leaf.eax = ret.eax; | ||
leaf.ebx = ret.ebx; | ||
leaf.ecx = ret.ecx; | ||
leaf.edx = ret.edx; | ||
|
||
snp_cpuid_postprocess(leaf)?; | ||
|
||
regs.rax = leaf.eax as usize; | ||
regs.rbx = leaf.ebx as usize; | ||
regs.rcx = leaf.ecx as usize; | ||
regs.rdx = leaf.edx as usize; | ||
|
||
Ok(()) | ||
} | ||
|
||
fn snp_cpuid_postprocess(leaf: &mut CpuidLeaf) -> Result<(), VcError> { | ||
// TODO(tleroy): complete this | ||
match leaf.cpuid_fn { | ||
_ => Ok(()), | ||
} | ||
} | ||
|
||
panic!( | ||
"Unhandled #VC exception RIP {:#018x} error code: {:#018x}", | ||
rip, err | ||
); | ||
fn vc_finish_insn(ctx: &mut X86ExceptionContext) { | ||
//TODO(tleroy): add insn info in context | ||
// ctx.frame.rip += | ||
} | ||
|
||
pub fn handle_vc_exception(ctx: &mut X86ExceptionContext) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters