From 25f5e14869b02d369e16ab3980900b71fea2f78e Mon Sep 17 00:00:00 2001 From: David Scott Date: Mon, 11 Oct 2010 23:00:16 +0100 Subject: [PATCH] CA-46050: allow more than 2 PCI devices to be hotplugged into a domain (!) There is much confusion about the meaning of the X in (X, (domain, bus, path, func)). Sometimes it means "order the device was plugged"; other times it means something more device related. With this change, more than 2 devices can be plugged into a domain and the #devices and plug order remains constant over reboot. Signed-off-by: David Scott --- ocaml/xapi/vmops.ml | 4 ++-- ocaml/xenops/device.ml | 21 ++++++++++++--------- ocaml/xenops/device.mli | 2 +- ocaml/xenops/xenops.ml | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/ocaml/xapi/vmops.ml b/ocaml/xapi/vmops.ml index bc066d0c..8ad15f9b 100644 --- a/ocaml/xapi/vmops.ml +++ b/ocaml/xapi/vmops.ml @@ -506,12 +506,12 @@ let plug_pcidevs_noexn ~__context ~vm domid pcidevs = (fun xc xs -> if (Xc.domain_getinfo xc domid).Xc.hvm_guest then begin List.iter - (fun (devid, devices) -> + (fun (_, devices) -> Device.PCI.bind devices; List.iter (fun ((a, b, c, d) as device) -> debug "hotplugging PCI device %04x:%02x:%02x.%01x into domid: %d" a b c d domid; - Device.PCI.plug ~xc ~xs device domid devid + Device.PCI.plug ~xc ~xs device domid ) devices ) (sort_pcidevs pcidevs) end diff --git a/ocaml/xenops/device.ml b/ocaml/xenops/device.ml index 3094a993..92b476cf 100644 --- a/ocaml/xenops/device.ml +++ b/ocaml/xenops/device.ml @@ -1174,25 +1174,28 @@ let wait_device_model ~xc ~xs domid = xs.Xs.rm (device_model_state_path xs be_domid domid); answer -(* Return a list of PCI devices *) -let list ~xc ~xs domid = +(* Given a domid, return a list of [ X, (domain, bus, dev, func) ] where X indicates the order in + which the device was plugged. *) +let read_pcidir ~xc ~xs domid = let path = device_model_pci_device_path xs 0 domid in let prefix = "dev-" in let all = List.filter (String.startswith prefix) (try xs.Xs.directory path with Xb.Noent -> []) in (* The values are the PCI device (domain, bus, dev, func) strings *) - let pairs = List.map (fun x -> x, xs.Xs.read (path ^ "/" ^ x)) all in let device_number_of_string x = (* remove the silly prefix *) int_of_string (String.sub x (String.length prefix) (String.length x - (String.length prefix))) in - let pairs' = List.map (fun (x, y) -> device_number_of_string x, of_string y) pairs in + let pairs = List.map (fun x -> device_number_of_string x, of_string (xs.Xs.read (path ^ "/" ^ x))) all in (* Sort into the order the devices were plugged *) - let sorted = List.sort (fun a b -> compare (fst a) (fst b)) pairs' in - (* Assume the PCI bus ID is 0 *) - List.map (fun (_, y) -> 0, y) sorted + List.sort (fun a b -> compare (fst a) (fst b)) pairs + +(* Return a list of PCI devices *) +let list ~xc ~xs domid = + (* replace the sort index with the default '0' -- XXX must figure out whether this matters to anyone *) + List.map (fun (_, y) -> (0, y)) (read_pcidir ~xc ~xs domid) -let plug ~xc ~xs (domain, bus, dev, func) domid devid = - let current = list ~xc ~xs domid in +let plug ~xc ~xs (domain, bus, dev, func) domid = + let current = read_pcidir ~xc ~xs domid in let next_idx = List.fold_left max (-1) (List.map fst current) + 1 in let pci = to_string (domain, bus, dev, func) in diff --git a/ocaml/xenops/device.mli b/ocaml/xenops/device.mli index 6dd153cd..fa034ff3 100644 --- a/ocaml/xenops/device.mli +++ b/ocaml/xenops/device.mli @@ -145,7 +145,7 @@ sig val reset : xs:Xs.xsh -> device -> unit val bind : (int * int * int * int) list -> unit val plug : xc:Xc.handle -> xs:Xs.xsh - -> (int * int * int * int) -> Xc.domid -> int -> unit + -> (int * int * int * int) -> Xc.domid -> unit val unplug : xc:Xc.handle -> xs:Xs.xsh -> (int * int * int * int) -> Xc.domid -> unit val list : xc:Xc.handle -> xs:Xs.xsh -> Xc.domid -> (int * (int * int * int * int)) list diff --git a/ocaml/xenops/xenops.ml b/ocaml/xenops/xenops.ml index 08148fb1..5a13cc97 100644 --- a/ocaml/xenops/xenops.ml +++ b/ocaml/xenops/xenops.ml @@ -258,7 +258,7 @@ let add_pci ~xc ~xs ~hvm ~domid ~devid ~pci = let plug_pci ~xc ~xs ~domid ~devid ~pci = let pcidev = pci_of_string pci in - Device.PCI.plug ~xc ~xs pcidev domid devid + Device.PCI.plug ~xc ~xs pcidev domid let unplug_pci ~xc ~xs ~domid ~devid ~pci = let pcidev = pci_of_string pci in -- 2.39.5