Skip to content

Commit fe356e7

Browse files
author
Frediano Ziglio
committed
CA-418993: Enable PCI ROM BAR before attempting to give permissions to the VM
Currently the VM is not able to access the ROM as the host ROM BAR is disabled and not set. Signed-off-by: Frediano Ziglio <frediano.ziglio@citrix.com>
1 parent 87cc97b commit fe356e7

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

ocaml/xenopsd/xc/device.ml

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)