33
44//! Command line arguments and parsing for openhcl_boot.
55
6+ use crate :: boot_logger:: log;
67use underhill_confidentiality:: OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME ;
78
8- /// Enable the private VTL2 GPA pool for page allocations. This is only enabled
9- /// via the command line, because in order to support the VTL2 GPA pool
10- /// generically, the boot shim must read serialized data from the previous
11- /// OpenHCL instance on a servicing boot in order to guarantee the same memory
12- /// layout is presented.
9+ /// Enable the private VTL2 GPA pool for page allocations.
1310///
14- /// The value specified is the number of 4K pages to reserve for the pool.
11+ /// Possible values:
12+ /// * `release`: Use the release version of the lookup table (default), or device tree.
13+ /// * `debug`: Use the debug version of the lookup table, or device tree.
14+ /// * `off`: Disable the VTL2 GPA pool.
15+ /// * `<num_pages>`: Explicitly specify the size of the VTL2 GPA pool.
1516///
16- /// TODO: Remove this commandline once support for reading saved state is
17- /// supported in openhcl_boot.
17+ /// See `Vtl2GpaPoolConfig` for more details.
18+ const IGVM_VTL2_GPA_POOL_CONFIG : & str = "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=" ;
19+
20+ /// Test-legacy/test-compat override for `OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG`.
21+ /// (otherwise, tests cannot modify the VTL2 GPA pool config different from what
22+ /// may be in the manifest).
1823const ENABLE_VTL2_GPA_POOL : & str = "OPENHCL_ENABLE_VTL2_GPA_POOL=" ;
1924
2025/// Options controlling sidecar.
@@ -29,10 +34,59 @@ const SIDECAR: &str = "OPENHCL_SIDECAR=";
2934/// Disable NVME keep alive regardless if the host supports it.
3035const DISABLE_NVME_KEEP_ALIVE : & str = "OPENHCL_DISABLE_NVME_KEEP_ALIVE=" ;
3136
37+ /// Lookup table to use for VTL2 GPA pool size heuristics.
38+ #[ derive( Debug , PartialEq , Clone , Copy ) ]
39+ pub enum Vtl2GpaPoolLookupTable {
40+ Release ,
41+ Debug ,
42+ }
43+
44+ #[ derive( Debug , PartialEq , Clone , Copy ) ]
45+ pub enum Vtl2GpaPoolConfig {
46+ /// Use heuristics to determine the VTL2 GPA pool size.
47+ /// Reserve a default size based on the amount of VTL2 ram and
48+ /// number of vCPUs. The point of this method is to account for cases where
49+ /// we retrofit the private pool into existing deployments that do not
50+ /// specify it explicitly.
51+ ///
52+ /// If the host specifies a size via the device tree, that size will be used
53+ /// instead.
54+ ///
55+ /// The lookup table specifies whether to use the debug or release
56+ /// heuristics (as the dev manifests provide different amounts of VTL2 RAM).
57+ Heuristics ( Vtl2GpaPoolLookupTable ) ,
58+
59+ /// Explicitly disable the VTL2 private pool.
60+ Off ,
61+
62+ /// Explicitly specify the size of the VTL2 GPA pool in pages.
63+ Pages ( u64 ) ,
64+ }
65+
66+ impl < S : AsRef < str > > From < S > for Vtl2GpaPoolConfig {
67+ fn from ( arg : S ) -> Self {
68+ match arg. as_ref ( ) {
69+ "debug" => Vtl2GpaPoolConfig :: Heuristics ( Vtl2GpaPoolLookupTable :: Debug ) ,
70+ "release" => Vtl2GpaPoolConfig :: Heuristics ( Vtl2GpaPoolLookupTable :: Release ) ,
71+ "off" => Vtl2GpaPoolConfig :: Off ,
72+ _ => {
73+ let num = arg. as_ref ( ) . parse :: < u64 > ( ) . unwrap_or ( 0 ) ;
74+ // A size of 0 or failure to parse is treated as disabling
75+ // the pool.
76+ if num == 0 {
77+ Vtl2GpaPoolConfig :: Off
78+ } else {
79+ Vtl2GpaPoolConfig :: Pages ( num)
80+ }
81+ }
82+ }
83+ }
84+ }
85+
3286#[ derive( Debug , PartialEq ) ]
3387pub struct BootCommandLineOptions {
3488 pub confidential_debug : bool ,
35- pub enable_vtl2_gpa_pool : Option < u64 > ,
89+ pub enable_vtl2_gpa_pool : Vtl2GpaPoolConfig ,
3690 pub sidecar : bool ,
3791 pub sidecar_logging : bool ,
3892 pub disable_nvme_keep_alive : bool ,
@@ -42,7 +96,7 @@ impl BootCommandLineOptions {
4296 pub const fn new ( ) -> Self {
4397 BootCommandLineOptions {
4498 confidential_debug : false ,
45- enable_vtl2_gpa_pool : None ,
99+ enable_vtl2_gpa_pool : Vtl2GpaPoolConfig :: Heuristics ( Vtl2GpaPoolLookupTable :: Release ) , // use the release config by default
46100 sidecar : true , // sidecar is enabled by default
47101 sidecar_logging : false ,
48102 disable_nvme_keep_alive : false ,
@@ -53,19 +107,25 @@ impl BootCommandLineOptions {
53107impl BootCommandLineOptions {
54108 /// Parse arguments from a command line.
55109 pub fn parse ( & mut self , cmdline : & str ) {
110+ let mut override_vtl2_gpa_pool: Option < Vtl2GpaPoolConfig > = None ;
56111 for arg in cmdline. split_whitespace ( ) {
57112 if arg. starts_with ( OPENHCL_CONFIDENTIAL_DEBUG_ENV_VAR_NAME ) {
58113 let arg = arg. split_once ( '=' ) . map ( |( _, arg) | arg) ;
59114 if arg. is_some_and ( |a| a != "0" ) {
60115 self . confidential_debug = true ;
61116 }
117+ } else if arg. starts_with ( IGVM_VTL2_GPA_POOL_CONFIG ) {
118+ if let Some ( ( _, arg) ) = arg. split_once ( '=' ) {
119+ self . enable_vtl2_gpa_pool = Vtl2GpaPoolConfig :: from ( arg) ;
120+ } else {
121+ log ! ( "WARNING: Missing value for IGVM_VTL2_GPA_POOL_CONFIG argument" ) ;
122+ }
62123 } else if arg. starts_with ( ENABLE_VTL2_GPA_POOL ) {
63- self . enable_vtl2_gpa_pool = arg. split_once ( '=' ) . and_then ( |( _, arg) | {
64- let num = arg. parse :: < u64 > ( ) . unwrap_or ( 0 ) ;
65- // A size of 0 or failure to parse is treated as disabling
66- // the pool.
67- if num == 0 { None } else { Some ( num) }
68- } ) ;
124+ if let Some ( ( _, arg) ) = arg. split_once ( '=' ) {
125+ override_vtl2_gpa_pool = Some ( Vtl2GpaPoolConfig :: from ( arg) ) ;
126+ } else {
127+ log ! ( "WARNING: Missing value for ENABLE_VTL2_GPA_POOL argument" ) ;
128+ }
69129 } else if arg. starts_with ( SIDECAR ) {
70130 if let Some ( ( _, arg) ) = arg. split_once ( '=' ) {
71131 for arg in arg. split ( ',' ) {
@@ -84,6 +144,14 @@ impl BootCommandLineOptions {
84144 }
85145 }
86146 }
147+
148+ if let Some ( override_config) = override_vtl2_gpa_pool {
149+ self . enable_vtl2_gpa_pool = override_config;
150+ log ! (
151+ "INFO: Overriding VTL2 GPA pool config to {:?} from command line" ,
152+ override_config
153+ ) ;
154+ }
87155 }
88156}
89157
@@ -99,34 +167,53 @@ mod tests {
99167
100168 #[ test]
101169 fn test_vtl2_gpa_pool_parsing ( ) {
102- assert_eq ! (
103- parse_boot_command_line( "OPENHCL_ENABLE_VTL2_GPA_POOL=1" ) ,
104- BootCommandLineOptions {
105- enable_vtl2_gpa_pool: Some ( 1 ) ,
106- ..BootCommandLineOptions :: new( )
107- }
108- ) ;
109- assert_eq ! (
110- parse_boot_command_line( "OPENHCL_ENABLE_VTL2_GPA_POOL=0" ) ,
111- BootCommandLineOptions {
112- enable_vtl2_gpa_pool: None ,
113- ..BootCommandLineOptions :: new( )
114- }
115- ) ;
116- assert_eq ! (
117- parse_boot_command_line( "OPENHCL_ENABLE_VTL2_GPA_POOL=asdf" ) ,
118- BootCommandLineOptions {
119- enable_vtl2_gpa_pool: None ,
120- ..BootCommandLineOptions :: new( )
121- }
122- ) ;
123- assert_eq ! (
124- parse_boot_command_line( "OPENHCL_ENABLE_VTL2_GPA_POOL=512" ) ,
125- BootCommandLineOptions {
126- enable_vtl2_gpa_pool: Some ( 512 ) ,
127- ..BootCommandLineOptions :: new( )
128- }
129- ) ;
170+ for ( cmdline, expected) in [
171+ (
172+ // default
173+ "" ,
174+ Vtl2GpaPoolConfig :: Heuristics ( Vtl2GpaPoolLookupTable :: Release ) ,
175+ ) ,
176+ (
177+ "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=1" ,
178+ Vtl2GpaPoolConfig :: Pages ( 1 ) ,
179+ ) ,
180+ (
181+ "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=0" ,
182+ Vtl2GpaPoolConfig :: Off ,
183+ ) ,
184+ (
185+ "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=asdf" ,
186+ Vtl2GpaPoolConfig :: Off ,
187+ ) ,
188+ (
189+ "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=512" ,
190+ Vtl2GpaPoolConfig :: Pages ( 512 ) ,
191+ ) ,
192+ (
193+ "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=off" ,
194+ Vtl2GpaPoolConfig :: Off ,
195+ ) ,
196+ (
197+ "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=debug" ,
198+ Vtl2GpaPoolConfig :: Heuristics ( Vtl2GpaPoolLookupTable :: Debug ) ,
199+ ) ,
200+ (
201+ "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=release" ,
202+ Vtl2GpaPoolConfig :: Heuristics ( Vtl2GpaPoolLookupTable :: Release ) ,
203+ ) ,
204+ (
205+ // OPENHCL_ENABLE_VTL2_GPA_POOL= takes precedence over OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=
206+ "OPENHCL_IGVM_VTL2_GPA_POOL_CONFIG=release OPENHCL_ENABLE_VTL2_GPA_POOL=debug" ,
207+ Vtl2GpaPoolConfig :: Heuristics ( Vtl2GpaPoolLookupTable :: Debug ) ,
208+ ) ,
209+ ] {
210+ assert_eq ! (
211+ parse_boot_command_line( cmdline) . enable_vtl2_gpa_pool,
212+ expected,
213+ "Failed parsing VTL2 GPA pool config from command line: {}" ,
214+ cmdline
215+ ) ;
216+ }
130217 }
131218
132219 #[ test]
0 commit comments