@@ -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,45 @@ 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 current_addr =
1254+ Unixext. with_file config_fn [Unix. O_RDONLY ; Unix. O_CLOEXEC ] 0
1255+ (fun fd ->
1256+ Unix. (lseek fd 0x30 SEEK_SET ) |> ignore ;
1257+ (* this is a virtual file that control PCI configuration,
1258+ it will either fail or return 4 *)
1259+ Unix. (read fd out 0 4 ) |> ignore ;
1260+ Nativeint. (
1261+ logand (of_int32 (Bytes. get_int32_le out 0 )) 0xfffff800n
1262+ )
1263+ )
1264+ in
1265+ if current_addr <> start then (
1266+ (* to enable output "1" on "rom" file and try to read it *)
1267+ let rom_fn = Filename. concat sysfs_pci_dev " rom" in
1268+ Unixext. with_file rom_fn [Unix. O_WRONLY ; Unix. O_CLOEXEC ] 0
1269+ (fun fd ->
1270+ Unix. (single_write fd (Bytes. of_string " 1\n " ) 0 2 ) |> ignore
1271+ ) ;
1272+ Unixext. with_file rom_fn [Unix. O_RDONLY ; Unix. O_CLOEXEC ] 0
1273+ (fun fd ->
1274+ (* ignore any error, the ROM could be not correct,
1275+ just trying to read does the trick *)
1276+ try Unix. (read fd out 0 4 ) |> ignore with _ -> ()
1277+ )
1278+ )
1279+ in
1280+ if i = _proc_pci_rom_resource then
1281+ enable_rom scan_start ;
12431282 Xenctrl. domain_iomem_permission xc domid scan_start scan_size true
1283+ )
12441284 in
12451285 let xcext = Xenctrlext. get_handle () in
12461286 ignore (quarantine host) ;
0 commit comments