-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SEV-SNP support #1269
base: cc_quark_amd_sev_snp
Are you sure you want to change the base?
SEV-SNP support #1269
Changes from all commits
ae30da1
0a6a0a3
72b9469
7fdfed6
750189f
389fe1f
a93372c
b9b06cd
67f20c8
3d60428
9b9015c
8f33366
0f628cb
30f3850
dafbdd6
802a65b
db960de
489c0c6
41e58c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,14 @@ use super::super::threadmgr::task_sched::*; | |
use super::super::MainRun; | ||
use super::super::SignalDef::*; | ||
use super::super::SHARESPACE; | ||
cfg_cc! { | ||
use super::super::qlib::cc::sev_snp::{VCResult,SVMExitDef,snp_active,C_BIT_MASK}; | ||
use super::super::qlib::cc::sev_snp::ghcb::*; | ||
use alloc::slice; | ||
use super::super::qlib::cc::sev_snp::vc::*; | ||
use yaxpeax_arch::LengthedInstruction; | ||
use core::sync::atomic::Ordering; | ||
} | ||
|
||
#[derive(Clone, Copy, Debug, core::cmp::PartialEq)] | ||
pub enum ExceptionStackVec { | ||
|
@@ -83,6 +91,7 @@ extern "C" { | |
pub fn simd_fp_handler(); | ||
pub fn virtualization_handler(); | ||
pub fn security_handler(); | ||
pub fn vmm_communication_handler(); | ||
} | ||
|
||
pub static IDT: Singleton<idt::Idt> = Singleton::<idt::Idt>::New(); | ||
|
@@ -126,7 +135,8 @@ pub unsafe fn InitSingleton() { | |
idt.set_handler(19, simd_fp_handler).set_stack_index(0); | ||
idt.set_handler(20, virtualization_handler) | ||
.set_stack_index(0); | ||
|
||
idt.set_handler(29, vmm_communication_handler) | ||
.set_stack_index(0); | ||
idt.set_handler(30, security_handler).set_stack_index(0); | ||
|
||
IDT.Init(idt); | ||
|
@@ -425,11 +435,20 @@ bitflags! { | |
|
||
#[no_mangle] | ||
pub extern "C" fn PageFaultHandler(ptRegs: &mut PtRegs, errorCode: u64) { | ||
#[cfg(feature = "cc")] | ||
let mut cr2: u64; | ||
#[cfg(not(feature = "cc"))] | ||
let cr2: u64; | ||
unsafe { asm!("mov {0}, cr2", out(reg) cr2 ) }; | ||
let cr3: u64; | ||
unsafe { asm!("mov {0}, cr3", out(reg) cr3 ) }; | ||
|
||
#[cfg(feature = "cc")] | ||
if snp_active() { | ||
let c_bit_mask = C_BIT_MASK.load(Ordering::Relaxed); | ||
cr2 &= !c_bit_mask; | ||
shrik3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
CPULocal::Myself().SetMode(VcpuMode::Kernel); | ||
let currTask = Task::Current(); | ||
//currTask.mm.VcpuLeave(); | ||
|
@@ -773,3 +792,111 @@ pub extern "C" fn TripleFaultHandler(sf: &mut PtRegs) { | |
info!("\nTripleFaultHandler: at {:#x}\n{:#?}", sf.rip, sf); | ||
loop {} | ||
} | ||
|
||
#[cfg(feature = "cc")] | ||
#[no_mangle] | ||
pub extern "C" fn VmmCommunicationHandler(sf: &mut PtRegs, errorCode: u64) { | ||
use crate::Kernel_cc::LOG_AVAILABLE; | ||
let log_available = LOG_AVAILABLE.load(core::sync::atomic::Ordering::Acquire); | ||
let from_user = sf.cs & 0x3 != 0; | ||
if from_user { | ||
CPULocal::Myself().SetMode(VcpuMode::Kernel); | ||
let currTask = Task::Current(); | ||
let mut rflags = sf.eflags; | ||
rflags &= !USER_FLAGS_CLEAR; | ||
rflags |= USER_FLAGS_SET; | ||
sf.eflags = rflags; | ||
sf.ss |= 3; | ||
currTask.SaveFp(); | ||
} | ||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you please remove this. And also any leftover commented code that you don't need. Also consider using |
||
if log_available && errorCode != SVMExitDef::SVM_EXIT_IOIO { | ||
info!( | ||
"Enter VC Handler errorCode:{}, PtRegs:{:#x?}", | ||
errorCode, sf | ||
); | ||
} | ||
*/ | ||
let mut res = VCResult::EsDecodeFailed; | ||
let code_ptr = sf.rip; | ||
let code_slice; | ||
unsafe { | ||
code_slice = slice::from_raw_parts_mut(code_ptr as *mut u8, 15); | ||
} | ||
|
||
let mut ins_length = 0; | ||
let decoder = yaxpeax_x86::amd64::InstDecoder::default(); | ||
match decoder.decode_slice(code_slice) { | ||
Ok(i) => { | ||
match errorCode { | ||
SVMExitDef::SVM_EXIT_CPUID => res = vc_handle_cpuid(sf), | ||
SVMExitDef::SVM_EXIT_INVD => res = VCResult::EsUnsupported, | ||
SVMExitDef::SVM_EXIT_MONITOR => res = VCResult::EsOk, | ||
SVMExitDef::SVM_EXIT_MWAIT => res = VCResult::EsOk, | ||
//mmio not supported yet | ||
SVMExitDef::SVM_EXIT_NPF => res = VCResult::EsUnsupported, | ||
_ => { | ||
let mut vcpuid = 0; | ||
if log_available { | ||
vcpuid = crate::qlib::kernel::asm::GetVcpuId(); | ||
} | ||
let ghcb_option: &mut Option<GhcbHandle<'_>> = &mut *GHCB[vcpuid].lock(); | ||
let ghcb = ghcb_option.as_mut().unwrap(); | ||
ghcb.invalidate(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why we need to do |
||
res = vc_handle_exitcode_ghcb(&i, ghcb, errorCode, sf); | ||
} | ||
} | ||
ins_length = i.len().to_const(); | ||
} | ||
Err(_) => (), | ||
} | ||
|
||
const UD: u64 = 6; | ||
const GP: u64 = 13; | ||
const AC: u64 = 17; | ||
match res { | ||
VCResult::EsOk => { | ||
sf.rip += ins_length as u64; | ||
} | ||
VCResult::EsUnsupported => { | ||
panic!( | ||
"Unsupported exit-code 0x{:x} in #VC exception (IP: 0x{:x})", | ||
errorCode, sf.rip | ||
) | ||
} | ||
VCResult::EsVmmError => { | ||
panic!( | ||
"Failure in communication with VMM (exit-code 0x{:x} IP: 0x{:x})", | ||
errorCode, sf.rip | ||
) | ||
} | ||
VCResult::EsDecodeFailed => { | ||
panic!( | ||
"Failed to decode instruction (exit-code 0x{:x} IP: 0x{:x})", | ||
errorCode, sf.rip | ||
) | ||
} | ||
VCResult::EsException(e) => { | ||
info!("Get VCResult::EsException({})", e); | ||
match e { | ||
UD => ExceptionHandler(ExceptionStackVec::InvalidOpcode, sf, 0), | ||
GP => ExceptionHandler(ExceptionStackVec::GeneralProtectionFault, sf, errorCode), | ||
AC => ExceptionHandler(ExceptionStackVec::AlignmentCheck, sf, errorCode), | ||
e => panic!( | ||
"Failed to decode EsException (exit-code 0x{:x} IP: 0x{:x} Exception 0x{:x})", | ||
errorCode, sf.rip, e | ||
), | ||
} | ||
} | ||
VCResult::EsRetry => (), | ||
} | ||
if from_user { | ||
let currTask = Task::Current(); | ||
currTask.RestoreFp(); | ||
} | ||
return; | ||
} | ||
|
||
#[cfg(not(feature = "cc"))] | ||
#[no_mangle] | ||
pub extern "C" fn VmmCommunicationHandler(_sf: &mut PtRegs, _errorCode: u64) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using relative paths was a mistake and will be fixed later. Perhaps consider ditch this pattern in new code already.