diff --git a/ocaml/idl/datamodel.ml b/ocaml/idl/datamodel.ml index 15f1c4c66c..aaf4157e02 100644 --- a/ocaml/idl/datamodel.ml +++ b/ocaml/idl/datamodel.ml @@ -6519,12 +6519,39 @@ end (** PCI devices *) module PCI = struct + let disable_dom0_access = + call ~name:"disable_dom0_access" ~lifecycle:[] + ~doc: + "Hide a PCI device from the dom0 kernel. (Takes affect after next \ + boot.)" + ~params:[(Ref _pci, "self", "The PCI to hide")] + ~allowed_roles:_R_POOL_OP () + + let enable_dom0_access = + call ~name:"enable_dom0_access" ~lifecycle:[] + ~doc: + "Unhide a PCI device from the dom0 kernel. (Takes affect after next \ + boot.)" + ~params:[(Ref _pci, "self", "The PCI to unhide")] + ~allowed_roles:_R_POOL_OP () + + let is_dom0_access_enabled = + call ~name:"is_dom0_access_enabled" ~lifecycle:[] + ~doc: + "Returns whether the PCI device is accessible from the dom0 kernel on \ + boot." + ~params:[(Ref _pci, "self", "The PCI")] + ~result:(Bool, "Whether the PCI is accessible from the dom0 kernel") + ~allowed_roles:_R_POOL_OP () + let t = create_obj ~name:_pci ~descr:"A PCI device" ~doccomments:[] ~gen_constructor_destructor:false ~gen_events:true ~in_db:true ~lifecycle:[(Published, rel_boston, "")] - ~messages:[] ~messages_default_allowed_roles:_R_POOL_OP - ~persist:PersistEverything ~in_oss_since:None ~db_logging:Log_destroy + ~messages: + [disable_dom0_access; enable_dom0_access; is_dom0_access_enabled] + ~messages_default_allowed_roles:_R_POOL_OP ~persist:PersistEverything + ~in_oss_since:None ~db_logging:Log_destroy ~contents: [ uid _pci ~lifecycle:[(Published, rel_boston, "")] diff --git a/ocaml/xapi-cli-server/cli_frontend.ml b/ocaml/xapi-cli-server/cli_frontend.ml index 55d884db9d..89f6e33c8d 100644 --- a/ocaml/xapi-cli-server/cli_frontend.ml +++ b/ocaml/xapi-cli-server/cli_frontend.ml @@ -3680,6 +3680,35 @@ let rec cmdtable_data : (string * cmd_spec) list = ; flags= [] } ) + ; ( "pci-enable-dom0-access" + , { + reqd= ["uuid"] + ; optn= [] + ; help= "Enable PCI access to dom0." + ; implementation= No_fd Cli_operations.pci_enable_dom0_access + ; flags= [] + } + ) + ; ( "pci-disable-dom0-access" + , { + reqd= ["uuid"] + ; optn= [] + ; help= "Disable PCI access to dom0." + ; implementation= No_fd Cli_operations.pci_disable_dom0_access + ; flags= [] + } + ) + ; ( "pci-is-dom0-access-enabled" + , { + reqd= ["uuid"] + ; optn= [] + ; help= + "Returns whether the PCI device is accessible from the dom0 kernel \ + on boot." + ; implementation= No_fd Cli_operations.is_dom0_access_enabled + ; flags= [] + } + ) ] let cmdtable : (string, cmd_spec) Hashtbl.t = Hashtbl.create 50 diff --git a/ocaml/xapi-cli-server/cli_operations.ml b/ocaml/xapi-cli-server/cli_operations.ml index 6766a5161f..fdc65e7c0f 100644 --- a/ocaml/xapi-cli-server/cli_operations.ml +++ b/ocaml/xapi-cli-server/cli_operations.ml @@ -1329,6 +1329,11 @@ let gen_cmds rpc session_id = ] rpc session_id ) + ; Client.PCI.( + mk get_all_records_where get_by_uuid pci_record "pci" [] + ["uuid"; "vendor-name"; "device-name"; "pci-id"] + rpc session_id + ) ] let message_create (_ : printer) rpc session_id params = @@ -7473,6 +7478,26 @@ let lvhd_enable_thin_provisioning _printer rpc session_id params = ["sr-uuid"; "initial-allocation"; "allocation-quantum"] ) +let pci_enable_dom0_access _printer rpc session_id params = + let uuid = List.assoc "uuid" params in + let ref = Client.PCI.get_by_uuid ~rpc ~session_id ~uuid in + Client.PCI.enable_dom0_access ~rpc ~session_id ~self:ref + +let pci_disable_dom0_access _printer rpc session_id params = + let uuid = List.assoc "uuid" params in + let ref = Client.PCI.get_by_uuid ~rpc ~session_id ~uuid in + Client.PCI.disable_dom0_access ~rpc ~session_id ~self:ref + +let is_dom0_access_enabled printer rpc session_id params = + let uuid = List.assoc "uuid" params in + let ref = Client.PCI.get_by_uuid ~rpc ~session_id ~uuid in + printer + (Cli_printer.PMsg + (Bool.to_string + (Client.PCI.is_dom0_access_enabled ~rpc ~session_id ~self:ref) + ) + ) + module PVS_site = struct let introduce printer rpc session_id params = let name_label = List.assoc "name-label" params in diff --git a/ocaml/xapi-cli-server/records.ml b/ocaml/xapi-cli-server/records.ml index 6648d75587..ab824958a2 100644 --- a/ocaml/xapi-cli-server/records.ml +++ b/ocaml/xapi-cli-server/records.ml @@ -5500,3 +5500,80 @@ let observer_record rpc session_id observer = () ] } + +let pci_record rpc session_id pci = + let _ref = ref pci in + let empty_record = + ToGet (fun () -> Client.PCI.get_record ~rpc ~session_id ~self:!_ref) + in + let record = ref empty_record in + let x () = lzy_get record in + let pci_record p = + ref (ToGet (fun () -> Client.PCI.get_record ~rpc ~session_id ~self:p)) + in + let xp0 p = lzy_get (pci_record p) in + { + setref= + (fun r -> + _ref := r ; + record := empty_record + ) + ; setrefrec= + (fun (a, b) -> + _ref := a ; + record := Got b + ) + ; record= x + ; getref= (fun () -> !_ref) + ; fields= + [ + make_field ~name:"uuid" ~get:(fun () -> (x ()).API.pCI_uuid) () + ; make_field ~name:"vendor-name" + ~get:(fun () -> try (x ()).API.pCI_vendor_name with _ -> nid) + () + ; make_field ~name:"device-name" + ~get:(fun () -> try (x ()).API.pCI_device_name with _ -> nid) + () + ; make_field ~name:"driver-name" + ~get:(fun () -> try (x ()).API.pCI_driver_name with _ -> nid) + () + ; make_field ~name:"host-uuid" + ~get:(fun () -> + try get_uuid_from_ref (x ()).API.pCI_host with _ -> nid + ) + () + ; make_field ~name:"host-name-label" + ~get:(fun () -> + try get_name_from_ref (x ()).API.pCI_host with _ -> nid + ) + () + ; make_field ~name:"pci-id" + ~get:(fun () -> try (x ()).API.pCI_pci_id with _ -> nid) + () + ; make_field ~name:"dependencies" + ~get:(fun () -> + map_and_concat + (fun pci -> (xp0 pci).API.pCI_pci_id) + (x ()).API.pCI_dependencies + ) + ~get_set:(fun () -> + List.map + (fun pci -> (xp0 pci).API.pCI_pci_id) + (x ()).API.pCI_dependencies + ) + () + ; make_field ~name:"other-config" + ~get:(fun () -> + Record_util.s2sm_to_string "; " (x ()).API.pCI_other_config + ) + ~add_to_map:(fun key value -> + Client.PCI.add_to_other_config ~rpc ~session_id ~self:pci ~key + ~value + ) + ~remove_from_map:(fun key -> + Client.PCI.remove_from_other_config ~rpc ~session_id ~self:pci ~key + ) + ~get_map:(fun () -> (x ()).API.pCI_other_config) + () + ] + } diff --git a/ocaml/xapi/message_forwarding.ml b/ocaml/xapi/message_forwarding.ml index b2eb86c805..4efc51e6b6 100644 --- a/ocaml/xapi/message_forwarding.ml +++ b/ocaml/xapi/message_forwarding.ml @@ -5867,7 +5867,31 @@ functor module Secret = Local.Secret - module PCI = struct end + module PCI = struct + let disable_dom0_access ~__context ~self = + info "PCI.disable_dom0_access: pci = '%s'" (pci_uuid ~__context self) ; + let host = Db.PCI.get_host ~__context ~self in + let local_fn = Local.PCI.disable_dom0_access ~self in + do_op_on ~__context ~local_fn ~host (fun session_id rpc -> + Client.PCI.disable_dom0_access ~rpc ~session_id ~self + ) + + let enable_dom0_access ~__context ~self = + info "PCI.enable_dom0_access: pci = '%s'" (pci_uuid ~__context self) ; + let host = Db.PCI.get_host ~__context ~self in + let local_fn = Local.PCI.enable_dom0_access ~self in + do_op_on ~__context ~local_fn ~host (fun session_id rpc -> + Client.PCI.enable_dom0_access ~rpc ~session_id ~self + ) + + let is_dom0_access_enabled ~__context ~self = + info "PCI.is_dom0_access_enabled: pci = '%s'" (pci_uuid ~__context self) ; + let host = Db.PCI.get_host ~__context ~self in + let local_fn = Local.PCI.is_dom0_access_enabled ~self in + do_op_on ~__context ~local_fn ~host (fun session_id rpc -> + Client.PCI.is_dom0_access_enabled ~rpc ~session_id ~self + ) + end module VTPM = struct let create ~__context ~vM ~is_unique = diff --git a/ocaml/xapi/xapi_pci.ml b/ocaml/xapi/xapi_pci.ml index 6e72c366ec..a988e42b05 100644 --- a/ocaml/xapi/xapi_pci.ml +++ b/ocaml/xapi/xapi_pci.ml @@ -319,3 +319,10 @@ let get_system_display_device () = ) None items with _ -> None + +let disable_dom0_access ~__context ~self = Pciops.hide_pci ~__context self + +let enable_dom0_access ~__context ~self = Pciops.unhide_pci ~__context self + +let is_dom0_access_enabled ~__context ~self = + not (Pciops.is_pci_hidden ~__context self) diff --git a/ocaml/xapi/xapi_pci.mli b/ocaml/xapi/xapi_pci.mli index dd71dfffcc..af96037ba7 100644 --- a/ocaml/xapi/xapi_pci.mli +++ b/ocaml/xapi/xapi_pci.mli @@ -51,3 +51,12 @@ val disable_system_display_device : unit -> unit val dequarantine : __context:Context.t -> Xenops_interface.Pci.address -> unit (** dequarantine a PCI device. This is idempotent. *) + +val disable_dom0_access : __context:Context.t -> self:API.ref_PCI -> unit +(** Hide a PCI device from the dom0 kernel. (Takes affect after next boot.) *) + +val enable_dom0_access : __context:Context.t -> self:API.ref_PCI -> unit +(** Unhide a PCI device from the dom0 kernel. (Takes affect after next boot.) *) + +val is_dom0_access_enabled : __context:Context.t -> self:API.ref_PCI -> bool +(** Check whether a PCI device will be hidden from the dom0 kernel on boot. *)