@@ -46,7 +46,6 @@ use virt_support_x86emu::emulate::TranslateGvaSupport;
46
46
use virt_support_x86emu:: translate:: TranslateCachingInfo ;
47
47
use virt_support_x86emu:: translate:: TranslationRegisters ;
48
48
use zerocopy:: FromZeros ;
49
- use zerocopy:: IntoBytes ;
50
49
51
50
impl < T , B : HardwareIsolatedBacking > UhHypercallHandler < ' _ , ' _ , T , B > {
52
51
fn validate_register_access (
@@ -603,7 +602,11 @@ impl<T, B: HardwareIsolatedBacking> UhHypercallHandler<'_, '_, T, B> {
603
602
. with_msr_sysenter_eip_write ( true )
604
603
. with_msr_sysenter_esp_write ( true )
605
604
. with_msr_sfmask_write ( true )
606
- . with_msr_tsc_aux_write ( true ) ;
605
+ . with_msr_tsc_aux_write ( true )
606
+ . with_msr_xss_write ( true )
607
+ . with_msr_scet_write ( true )
608
+ . with_msr_pls_ssp_write ( true )
609
+ . with_msr_interrupt_ssp_table_addr_write ( true ) ;
607
610
608
611
if reg. value . as_u64 ( ) & !u64:: from ( supported_controls) != 0 {
609
612
return Err ( HvError :: InvalidRegisterValue ) ;
@@ -613,21 +616,22 @@ impl<T, B: HardwareIsolatedBacking> UhHypercallHandler<'_, '_, T, B> {
613
616
hvdef:: HvRegisterCrInterceptControl :: from ( reg. value . as_u64 ( ) ) ;
614
617
615
618
if let virt:: IsolationType :: Snp = self . vp . partition . isolation {
616
- // TODO: panic if this fails?
617
- self . vp . runner . set_vp_registers_hvcall (
618
- Vtl :: Vtl1 ,
619
- [ (
620
- HvX64RegisterName :: CrInterceptControl ,
621
- u64:: from ( intercept_control) ,
622
- ) ] ,
623
- ) ?;
619
+ // Intercept control is always managed by the hypervisor, so any request
620
+ // here is only opportunistic. Make the request directly with the
621
+ // hypervisor. Since intercept control always applies to VTL 1 control of
622
+ // VTL 0 state, the VTL 1 intercept control register is set here.
623
+ self . vp
624
+ . runner
625
+ . set_vp_registers_hvcall (
626
+ Vtl :: Vtl1 ,
627
+ [ (
628
+ HvX64RegisterName :: CrInterceptControl ,
629
+ u64:: from ( intercept_control) ,
630
+ ) ] ,
631
+ )
632
+ . expect ( "setting intercept control succeeds" ) ;
624
633
}
625
634
626
- tracing:: info!(
627
- "setting intecept control for vp {}" ,
628
- self . vp. vp_index( ) . index( )
629
- ) ;
630
-
631
635
self . vp
632
636
. backing
633
637
. cvm_state_mut ( )
@@ -650,7 +654,7 @@ impl<T, B: HardwareIsolatedBacking> UhHypercallHandler<'_, '_, T, B> {
650
654
vtl1. reg_intercept . cr4_mask = reg. value . as_u64 ( ) ;
651
655
}
652
656
HvX64RegisterName :: CrInterceptIa32MiscEnableMask => {
653
- vtl1. reg_intercept . ia32_misc_enable_mask = reg. value . as_u64 ( ) ; // TODO is this ever used?
657
+ vtl1. reg_intercept . ia32_misc_enable_mask = reg. value . as_u64 ( ) ;
654
658
}
655
659
_ => unreachable ! ( ) ,
656
660
}
@@ -1029,7 +1033,7 @@ impl<T, B: HardwareIsolatedBacking>
1029
1033
target_vtl : Vtl ,
1030
1034
vp_context : & hvdef:: hypercall:: InitialVpContextX64 ,
1031
1035
) -> HvResult < ( ) > {
1032
- tracing:: info !(
1036
+ tracing:: debug !(
1033
1037
vp_index = self . vp. vp_index( ) . index( ) ,
1034
1038
target_vp,
1035
1039
?target_vtl,
@@ -1683,10 +1687,7 @@ impl<B: HardwareIsolatedBacking> UhProcessor<'_, B> {
1683
1687
if vtl == GuestVtl :: Vtl1 {
1684
1688
assert ! ( * self . cvm_vp_inner( ) . vtl1_enable_called. lock( ) ) ;
1685
1689
if let InitialVpContextOperation :: EnableVpVtl = start_enable_vtl_state. operation {
1686
- self . backing . cvm_state_mut ( ) . vtl1 = Some ( crate :: GuestVsmVpState {
1687
- vtl0_exit_pending_event : None ,
1688
- reg_intercept : Default :: default ( ) ,
1689
- } ) ;
1690
+ self . backing . cvm_state_mut ( ) . vtl1 = Some ( crate :: GuestVsmVpState :: new ( ) ) ;
1690
1691
}
1691
1692
}
1692
1693
@@ -1722,15 +1723,9 @@ impl<B: HardwareIsolatedBacking> UhProcessor<'_, B> {
1722
1723
for ( reg, value) in protected_registers {
1723
1724
if self . cvm_is_protected_register_write ( vtl, reg, value) {
1724
1725
// In this case, it doesn't matter what VTL the calling
1725
- // VP was in, fail the startup. No need to send an
1726
+ // VP was in, just fail the startup. No need to send an
1726
1727
// intercept message.
1727
- //
1728
- // TODO: figure out the correct return error type
1729
- return Err ( UhRunVpError :: State (
1730
- crate :: processor:: vp_state:: Error :: SetRegisters (
1731
- hcl:: ioctl:: Error :: SetRegisters ( HvError :: AccessDenied ) ,
1732
- ) ,
1733
- ) ) ;
1728
+ return Err ( UhRunVpError :: StateAccessDenied ) ;
1734
1729
}
1735
1730
}
1736
1731
}
@@ -1877,6 +1872,8 @@ impl<B: HardwareIsolatedBacking> UhProcessor<'_, B> {
1877
1872
self . backing . cvm_state ( ) . vtl1 . is_some ( )
1878
1873
}
1879
1874
1875
+ /// Returns whether a higher VTL has registered for write intercepts on the
1876
+ /// register.
1880
1877
pub ( crate ) fn cvm_is_protected_register_write (
1881
1878
& self ,
1882
1879
vtl : GuestVtl ,
@@ -1918,20 +1915,21 @@ impl<B: HardwareIsolatedBacking> UhProcessor<'_, B> {
1918
1915
false
1919
1916
}
1920
1917
1921
- pub ( crate ) fn cvm_handle_secure_register_write (
1918
+ /// Checks if a higher VTL registered for write intercepts on the register,
1919
+ /// and sends the intercept as required.
1920
+ pub ( crate ) fn cvm_protect_secure_register_write (
1922
1921
& mut self ,
1923
1922
vtl : GuestVtl ,
1924
1923
reg : HvX64RegisterName ,
1925
1924
value : u64 ,
1926
- ) {
1927
- if self . cvm_is_protected_register_write ( vtl, reg, value) {
1928
- let intercept_message =
1929
- B :: generate_register_intercept_message ( self , vtl, self . vp_index ( ) , reg, value) ;
1930
-
1931
- let hv_message = hvdef:: HvMessage :: new (
1932
- hvdef:: HvMessageType :: HvMessageTypeRegisterIntercept ,
1933
- 0 ,
1934
- intercept_message. as_bytes ( ) ,
1925
+ ) -> bool {
1926
+ let send_intercept = self . cvm_is_protected_register_write ( vtl, reg, value) ;
1927
+ if send_intercept {
1928
+ let intercept_message = B :: generate_intercept_message (
1929
+ self ,
1930
+ vtl,
1931
+ self . vp_index ( ) ,
1932
+ crate :: processor:: InterceptMessageType :: Register { reg, value } ,
1935
1933
) ;
1936
1934
1937
1935
tracing:: debug!(
@@ -1943,42 +1941,16 @@ impl<B: HardwareIsolatedBacking> UhProcessor<'_, B> {
1943
1941
self . inner . post_message (
1944
1942
GuestVtl :: Vtl1 ,
1945
1943
hvdef:: HV_SYNIC_INTERCEPTION_SINT_INDEX ,
1946
- & hv_message ,
1944
+ & intercept_message ,
1947
1945
) ;
1948
-
1949
- // Once the intercept message has been posted, no further
1950
- // processing is required. Do not advance the instruction
1951
- // pointer here, since the instruction pointer must continue to
1952
- // point to the instruction that generated the intercept.
1953
-
1954
- return ;
1955
1946
}
1956
1947
1957
- match reg {
1958
- HvX64RegisterName :: Cr0 => {
1959
- B :: set_cr0 ( self , vtl, value) ;
1960
- }
1961
- HvX64RegisterName :: Cr4 => {
1962
- B :: set_cr4 ( self , vtl, value) ;
1963
- }
1964
- HvX64RegisterName :: Xfem => self
1965
- . access_state ( vtl. into ( ) )
1966
- . set_xcr ( & virt:: vp:: Xcr0 { value } )
1967
- . unwrap ( ) ,
1968
- _ => {
1969
- // If an unexpected intercept has been received, then the host
1970
- // must have enabled an intercept that was not desired. Since
1971
- // the intercept cannot correctly be emulated, this must be
1972
- // treated as a fatal error.
1973
- panic ! ( "unexpected secure register" )
1974
- }
1975
- }
1976
-
1977
- B :: advance_to_next_instruction ( self , vtl) ;
1948
+ send_intercept
1978
1949
}
1979
1950
1980
- // TODO: maybe rename this, since it does sent the intercept message.
1981
- pub ( crate ) fn cvm_is_protected_msr_write ( & self , vtl : GuestVtl , msr : u32 ) -> bool {
1951
+ /// Checks if a higher VTL registered for write intercepts on the MSR, and
1952
+ /// sends the intercept as required.
1953
+ pub ( crate ) fn cvm_protect_msr_write ( & self , vtl : GuestVtl , msr : u32 ) -> bool {
1982
1954
if vtl == GuestVtl :: Vtl0 && self . backing . cvm_state ( ) . vtl1 . is_some ( ) {
1983
1955
let configured_intercepts = self
1984
1956
. backing
@@ -2015,21 +1987,19 @@ impl<B: HardwareIsolatedBacking> UhProcessor<'_, B> {
2015
1987
} ;
2016
1988
2017
1989
if generate_intercept {
2018
- let intercept_message =
2019
- B :: generate_msr_intercept_message ( self , vtl, self . vp_index ( ) , msr) ;
2020
-
2021
- let hv_message = hvdef:: HvMessage :: new (
2022
- hvdef:: HvMessageType :: HvMessageTypeMsrIntercept ,
2023
- 0 ,
2024
- intercept_message. as_bytes ( ) ,
1990
+ let intercept_message = B :: generate_intercept_message (
1991
+ self ,
1992
+ vtl,
1993
+ self . vp_index ( ) ,
1994
+ crate :: processor:: InterceptMessageType :: Msr { msr } ,
2025
1995
) ;
2026
1996
2027
- tracing:: info !( ?msr, "sending intercept to vtl 1 for secure msr write" ) ;
1997
+ tracing:: debug !( ?msr, "sending intercept to vtl 1 for secure msr write" ) ;
2028
1998
2029
1999
self . inner . post_message (
2030
2000
GuestVtl :: Vtl1 ,
2031
2001
hvdef:: HV_SYNIC_INTERCEPTION_SINT_INDEX ,
2032
- & hv_message ,
2002
+ & intercept_message ,
2033
2003
) ;
2034
2004
2035
2005
return true ;
0 commit comments