@@ -1104,6 +1104,8 @@ module PCI = struct
11041104 (* same as libxl_internal: PROC_PCI_NUM_RESOURCES *)
11051105 let _proc_pci_num_resources = 7
11061106
1107+ let _proc_pci_rom_resource = 6
1108+
11071109 (* same as libxl_internal: PCI_BAR_IO *)
11081110 let _pci_bar_io = 0x01n
11091111
@@ -1226,7 +1228,7 @@ module PCI = struct
12261228 if i < _proc_pci_num_resources then
12271229 Scanf. sscanf addr " 0x%nx 0x%nx 0x%nx"
12281230 @@ fun scan_start scan_end scan_flags ->
1229- if scan_start <> 0n then
1231+ if scan_start <> 0n then (
12301232 let scan_size = Nativeint. (sub scan_end scan_start |> succ) in
12311233 if Nativeint. (logand scan_flags _pci_bar_io > 0n ) then
12321234 Xenctrl. domain_ioport_permission xc domid
@@ -1240,7 +1242,57 @@ module PCI = struct
12401242 shift_right_logical (add _page_size scan_size |> pred) 12
12411243 )
12421244 in
1245+ (* Linux disables the ROM BARs if not used and by default does
1246+ not set the start address.
1247+ Force it to set the address using "rom" file.
1248+ This method works also with lockdown mode enabled. *)
1249+ let enable_rom start =
1250+ (* read current configured ROM address to check if enabled *)
1251+ let config_fn = Filename. concat sysfs_pci_dev " config" in
1252+ let out = Bytes. make 4 '\x00' in
1253+ let fd =
1254+ Unix. openfile config_fn [Unix. O_RDONLY ; Unix. O_CLOEXEC ] 0
1255+ in
1256+ let current_addr =
1257+ finally
1258+ (fun () ->
1259+ Unix. (lseek fd 0x30 SEEK_SET ) |> ignore ;
1260+ (* this is a virtual file that control PCI configuration,
1261+ it will either fail or return 4 *)
1262+ Unix. (read fd out 0 4 ) |> ignore ;
1263+ Nativeint. (
1264+ logand (of_int32 (Bytes. get_int32_ne out 0 )) 0xfffff800n
1265+ )
1266+ )
1267+ (fun () -> Unix. close fd)
1268+ in
1269+ if current_addr <> start then (
1270+ (* to enable output "1" on "rom" file and try to read it *)
1271+ let rom_fn = Filename. concat sysfs_pci_dev " rom" in
1272+ let fd =
1273+ Unix. openfile rom_fn [Unix. O_WRONLY ; Unix. O_CLOEXEC ] 0
1274+ in
1275+ finally
1276+ (fun () ->
1277+ Unix. (single_write fd (Bytes. of_string " 1\n " ) 0 2 ) |> ignore
1278+ )
1279+ (fun () -> Unix. close fd) ;
1280+ let fd =
1281+ Unix. openfile rom_fn [Unix. O_RDONLY ; Unix. O_CLOEXEC ] 0
1282+ in
1283+ finally
1284+ (fun () ->
1285+ (* ignore any error, the ROM could be not correct,
1286+ just trying to read does the trick *)
1287+ try Unix. (read fd out 0 4 ) |> ignore with _ -> ()
1288+ )
1289+ (fun () -> Unix. close fd)
1290+ )
1291+ in
1292+ if i = _proc_pci_rom_resource then
1293+ enable_rom scan_start ;
12431294 Xenctrl. domain_iomem_permission xc domid scan_start scan_size true
1295+ )
12441296 in
12451297 let xcext = Xenctrlext. get_handle () in
12461298 ignore (quarantine host) ;
0 commit comments