| _ -> failwith "unknown snapshot mode"
type config_pci = {
- pci_bind: bool; pci_domain: int; pci_bus: int; pci_slot: int; pci_func: int;
+ pci_bind: bool;
+ pci_domain: int;
+ pci_bus: int;
+ pci_slot: int;
+ pci_func: int;
+ pci_msitranslate: int option;
+ pci_power_mgmt: int option;
}
type config_disk = {
vpt_align: int option;
extra_local_watches: string list;
extra_vm_watches: string list;
- pci_msitranslate: int;
+ global_pci_msitranslate: int;
sound: string option;
inject_sci: int;
}
let config_pci_of_string s =
(* format is : domain:bus:slot.func *)
- let pcistruct =
- try Scanf.sscanf s "%d,bind,%x:%x:%x.%x" (fun id a b c d -> id, true, (a, b, c, d))
- with _ ->
- Scanf.sscanf s "%d,%x:%x:%x.%x" (fun id a b c d -> id, false, (a, b, c, d))
+ let l = String.split ',' s in
+ let id, bind, pcidev_str, params =
+ match l with
+ | id :: "bind" :: pcidev :: params ->
+ int_of_string id, true, pcidev, params
+ | id :: pcidev :: params ->
+ int_of_string id, false, pcidev, params
+ | _ ->
+ failwith "unexpected format for pci config"
+ in
+ let pcidev =
+ try Scanf.sscanf pcidev_str "%x:%x:%x.%x" (fun a b c d -> (a, b, c, d))
+ with _ -> failwith "unexpected format for pci descriptor"
+ in
+ let split_kv s =
+ match String.split ~limit:2 '=' s with
+ | k :: v :: [] -> k, v
+ | _ -> failwith "expected key value in params"
+ in
+ let params = List.map split_kv params in
+ let msitranslate =
+ try Some (int_of_string (snd (List.find (fun p -> fst p = "msitranslate") params)))
+ with Not_found -> None
+ in
+ let power_mgmt =
+ try Some (int_of_string (snd (List.find (fun p -> fst p = "power_mgmt") params)))
+ with Not_found -> None
in
- pcistruct
+ id, bind, pcidev, msitranslate, power_mgmt
let config_nic_of_string vm_uuid s =
let generate_random_mac () =
| "vpt-align" -> string_of_int_option cfg.vpt_align
| "power-management" -> string_of_int cfg.power_management
| "oem-features" -> string_of_int cfg.oem_features
- | "pci-msitranslate" -> string_of_int cfg.pci_msitranslate
+ | "pci-msitranslate" -> string_of_int cfg.global_pci_msitranslate
| "inject-sci" -> string_of_int cfg.inject_sci
| _ -> raise (Unknown_field field)
| "vpt-align" -> { cfg with vpt_align = int_option_of_string value }
| "power-management" -> { cfg with power_management = int_of_string value }
| "oem-features" -> { cfg with oem_features = int_of_string value }
- | "pci-msitranslate" -> { cfg with pci_msitranslate = int_of_string value }
+ | "pci-msitranslate" -> { cfg with global_pci_msitranslate = int_of_string value }
| "inject-sci" -> { cfg with inject_sci = int_of_string value }
| _ -> raise (Unknown_field field)
end;
let pcis =
let ids = ref [] in
- List.iter (fun (id, _, _) ->
+ List.iter (fun (id, _, _, _, _) ->
if not (List.mem id !ids) then
ids := id :: !ids
) !pcis;
List.map (fun id ->
- let ds = List.map (fun (_, bind, (a, b, c, d)) ->
- { pci_bind = bind; pci_domain = a; pci_bus = b; pci_slot = c; pci_func = d; }
- ) (List.filter (fun (x, _, _) -> x = id) !pcis) in
+ let ds = List.map (fun (_, bind, (a, b, c, d), msitranslate, power_mgmt) ->
+ {
+ pci_bind = bind;
+ pci_domain = a;
+ pci_bus = b;
+ pci_slot = c;
+ pci_func = d;
+ pci_msitranslate = msitranslate;
+ pci_power_mgmt = power_mgmt;
+ }
+ ) (List.filter (fun (x, _, _, _, _) -> x = id) !pcis) in
id, ds
) !ids
in
snapshot_mode = !snapshot_mode;
extra_local_watches = List.rev !extra_local_watches;
extra_vm_watches = List.rev !extra_vm_watches;
- pci_msitranslate = !pci_msitranslate;
+ global_pci_msitranslate = !pci_msitranslate;
sound = !sound;
inject_sci = !inject_sci;
}