@@ -1593,9 +1593,21 @@ pub mod simple {
15931593
15941594 flux_rs:: defs! {
15951595
1596- // #[hide]
15971596 fn available_region_setup( i: int, old: HardwareState , new: HardwareState ) -> bool {
1598- true
1597+ let cfg = map_select( new. pmpcfg_registers, i / 4 ) ;
1598+ let region_offset = i % 4 ;
1599+
1600+ if region_offset == 0 {
1601+ extract( cfg, 0x00000018 , 3 ) == 0 && !bit( cfg, 1 << 7 )
1602+ } else if region_offset == 1 {
1603+ extract( cfg, 0x00001800 , 11 ) == 0 && !bit( cfg, 1 << 15 )
1604+ } else if region_offset == 2 {
1605+ extract( cfg, 0x00180000 , 19 ) == 0 && !bit( cfg, 1 << 23 )
1606+ } else if region_offset == 3 {
1607+ extract( cfg, 0x18000000 , 27 ) == 0 && !bit( cfg, 1 << 31 )
1608+ } else {
1609+ false
1610+ }
15991611 }
16001612
16011613 // forall j, j >= 0 && j < i -> available_region_setup(i, hardware_state)
@@ -1632,35 +1644,76 @@ pub mod simple {
16321644 // well revoke access to a kernel region!
16331645
16341646 #[ flux_rs:: sig( fn ( i: usize , hw_state: & strg HardwareState [ @old] )
1635- -> Result <{ i32 | all_available_regions_setup_up_to( i, new ) && available_region_setup ( i , old , new) } , ( ) >
1647+ -> Result <{ i32 | all_available_regions_setup_up_to( i + 1 , new) } , ( ) >
16361648 requires all_available_regions_setup_up_to( i, old)
16371649 ensures hw_state: HardwareState [ #new]
16381650 ) ]
1639- // #[flux_rs::trusted]
16401651 fn configure_initial_pmp_idx (
16411652 i : usize ,
16421653 hardware_state : & mut HardwareState ,
16431654 ) -> Result < i32 , ( ) > {
1655+ // NOTE: works over PMP entries - hence the mod 4 arithmetic when
1656+ // checking a PMPCFG
1657+
1658+ let old: HardwareState = hardware_state. snapshot ( ) ;
1659+
16441660 // Read the entry's CSR:
1645- let pmpcfg_csr = csr:: CSR . pmpconfig_get ( i / 4 ) ;
1661+ #[ flux_rs:: trusted( reason = "TCB" ) ]
1662+ #[ flux_rs:: sig( fn ( i: usize , & HardwareState [ @hw] ) -> usize [ bv_bv32_to_int( map_select( hw. pmpcfg_registers, i) ) ] ) ]
1663+ fn pmpconfig_get ( i : usize , _: & HardwareState ) -> usize {
1664+ csr:: CSR . pmpconfig_get ( i)
1665+ }
1666+
1667+ let pmpcfg_csr = pmpconfig_get ( i / 4 , & hardware_state) ;
1668+
1669+ #[ flux_rs:: trusted( reason = "Flux integer conversion" ) ]
1670+ #[ flux_rs:: sig( fn ( x: usize ) -> u8 [ bv_bv32_to_int( extract( bv_int_to_bv32( x) , 0xFF , 0 ) ) ] ) ]
1671+ fn usize_to_u8_truncate ( x : usize ) -> u8 {
1672+ x as u8
1673+ }
1674+
1675+ #[ flux_rs:: trusted( reason = "Flux integer conversion" ) ]
1676+ // NOTE: trusted because usize == u32 here
1677+ #[ flux_rs:: sig( fn ( x: usize ) -> u32 [ x] requires x <= u32 :: MAX ) ]
1678+ fn usize_to_u32 ( x : usize ) -> u32 {
1679+ x as u32
1680+ }
1681+
1682+ flux_rs:: assert ( ( i % 4 ) * 8 <= 24 ) ;
16461683
16471684 // Extract the entry's pmpcfg octet:
1648- let pmpcfg: LocalRegisterCopyU8 < pmpcfg_octet:: Register > = LocalRegisterCopyU8 :: new (
1649- pmpcfg_csr. overflowing_shr ( ( ( i % 4 ) * 8 ) as u32 ) . 0 as u8 ,
1650- ) ;
1685+ let pmpcfg: LocalRegisterCopyU8 < pmpcfg_octet:: Register > =
1686+ LocalRegisterCopyU8 :: new ( usize_to_u8_truncate ( super :: overflowing_shr (
1687+ pmpcfg_csr,
1688+ usize_to_u32 ( ( i % 4 ) * 8 ) ,
1689+ ) ) ) ;
16511690
16521691 // As outlined above, we never touch a locked region. Thus, bail
16531692 // out if it's locked:
16541693 if pmpcfg. is_set ( pmpcfg_octet:: l ( ) ) {
1655- // return Err(());
1694+ return Err ( ( ) ) ;
16561695 }
16571696
16581697 // Now that it's not locked, we can be sure that regardless of
16591698 // any ePMP bits, this region is either ignored or entirely
16601699 // denied for machine-mode access. Hence, we can change it in
16611700 // arbitrary ways without breaking our own memory access. Try to
16621701 // flip the R/W/X bits:
1663- csr:: CSR . pmpconfig_set ( i / 4 , pmpcfg_csr ^ ( 7 << ( ( i % 4 ) * 8 ) ) ) ;
1702+ use flux_rs:: bitvec:: BV32 ;
1703+ // pmpcfg_csr ^ (7 << ((i % 4) * 8))
1704+ // change xor to (a | b) & !(a & b)
1705+
1706+ #[ flux_rs:: sig( fn ( x: BV32 , y: BV32 ) -> BV32 [ ( x | y) & bv_not( x & y) ] ) ]
1707+ fn xor ( x : BV32 , y : BV32 ) -> BV32 {
1708+ ( x | y) & !( x & y)
1709+ }
1710+
1711+ let rwx_bits = xor (
1712+ BV32 :: from ( pmpcfg_csr as u32 ) ,
1713+ ( BV32 :: from ( 7 ) << BV32 :: from ( usize_to_u32 ( ( i % 4 ) * 8 ) ) ) ,
1714+ ) ;
1715+ let rwx_bits: u32 = rwx_bits. into ( ) ;
1716+ super :: pmpconfig_set ( i / 4 , rwx_bits as usize , hardware_state) ;
16641717
16651718 // Check if the CSR changed:
16661719 if pmpcfg_csr == csr:: CSR . pmpconfig_get ( i / 4 ) {
@@ -1671,8 +1724,13 @@ pub mod simple {
16711724 }
16721725
16731726 // Finally, turn the region off:
1674- csr:: CSR . pmpconfig_set ( i / 4 , pmpcfg_csr & !( 0x18 << ( ( i % 4 ) * 8 ) ) ) ;
1727+ let off_bits = BV32 :: from ( pmpcfg_csr as u32 )
1728+ & !( BV32 :: from ( 0x18 ) << BV32 :: from ( usize_to_u32 ( ( i % 4 ) * 8 ) ) ) ;
1729+ let off_bits: u32 = off_bits. into ( ) ;
1730+
1731+ super :: pmpconfig_set ( i / 4 , off_bits as usize , hardware_state) ;
16751732
1733+ all_available_regions_setup_up_to_step ( i, & old, hardware_state) ;
16761734 Ok ( 1669 )
16771735 }
16781736
@@ -1698,7 +1756,6 @@ pub mod simple {
16981756 }
16991757 let old = hardware_state. snapshot ( ) ;
17001758 configure_initial_pmp_idx ( i, hardware_state) ?;
1701- all_available_regions_setup_up_to_step ( i, & old, hardware_state) ;
17021759 assert_setup ( i + 1 , & hardware_state) ;
17031760 match configure_initial_pmp_tail ( i + 1 , hardware_state, available_entries) {
17041761 Ok ( _) => return Ok ( 100 ) ,
@@ -1749,14 +1806,8 @@ pub mod simple {
17491806 // Note: these pre and post conditions (all_regions_configured) seem silly
17501807 // but we need them because otherwise Flux forgets
17511808 // all state after we return
1752- requires
1753- all_regions_configured_correctly_up_to( i, og_hw) &&
1754- i % 2 == 0
1755- ensures hw_state: HardwareState { new_hw:
1756- all_regions_configured_correctly_up_to( i + 2 , new_hw)
1757- // region_configured_correctly(er, og_hw, new_hw, i) && region_configured_correctly(or, og_hw, new_hw, i + 1)
1758- // && all_regions_configured_correctly_up_to(i, new_hw)
1759- }
1809+ requires all_regions_configured_correctly_up_to( i, og_hw) && i % 2 == 0
1810+ ensures hw_state: HardwareState { new_hw: all_regions_configured_correctly_up_to( i + 2 , new_hw) }
17601811 ) ]
17611812 fn configure_region_pair (
17621813 i : usize ,
@@ -1840,7 +1891,6 @@ pub mod simple {
18401891 // all state after we return
18411892 requires all_regions_configured_correctly_up_to( i, og_hw) && i % 2 == 0
18421893 ensures hw_state: HardwareState { new_hw:
1843- // region_configured_correctly(er, og_hw, new_hw, i) &&
18441894 all_regions_configured_correctly_up_to( i + 1 , new_hw)
18451895 }
18461896 ) ]
@@ -2249,14 +2299,8 @@ pub mod kernel_protection {
22492299 // Note: these pre and post conditions (all_regions_configured) seem silly
22502300 // but we need them because otherwise Flux forgets
22512301 // all state after we return
2252- requires
2253- all_regions_configured_correctly_up_to( i, og_hw) &&
2254- i % 2 == 0
2255- ensures hw_state: HardwareState { new_hw:
2256- all_regions_configured_correctly_up_to( i + 2 , new_hw)
2257- // region_configured_correctly(er, og_hw, new_hw, i) && region_configured_correctly(or, og_hw, new_hw, i + 1)
2258- // && all_regions_configured_correctly_up_to(i, new_hw)
2259- }
2302+ requires all_regions_configured_correctly_up_to( i, og_hw) && i % 2 == 0
2303+ ensures hw_state: HardwareState { new_hw: all_regions_configured_correctly_up_to( i + 2 , new_hw) }
22602304 ) ]
22612305 fn configure_region_pair (
22622306 i : usize ,
@@ -2339,10 +2383,7 @@ pub mod kernel_protection {
23392383 // but we need them because otherwise Flux forgets
23402384 // all state after we return
23412385 requires all_regions_configured_correctly_up_to( i, og_hw) && i % 2 == 0
2342- ensures hw_state: HardwareState { new_hw:
2343- // region_configured_correctly(er, og_hw, new_hw, i) &&
2344- all_regions_configured_correctly_up_to( i + 1 , new_hw)
2345- }
2386+ ensures hw_state: HardwareState { new_hw: all_regions_configured_correctly_up_to( i + 1 , new_hw) }
23462387 ) ]
23472388 fn configure_region (
23482389 i : usize ,
0 commit comments