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