Skip to content

Commit 26ab618

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 26ab618

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

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

Comments
 (0)