Skip to content

Commit 930ffb3

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 503495d commit 930ffb3

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

ocaml/xenopsd/xc/device.ml

Lines changed: 41 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

@@ -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

Comments
 (0)