Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 48 participants
- 40227 discussions
Re: [libvirt] [Qemu-devel] [PATCH for-2.9 15/17] target-i386: Define static "base" CPU model
by Eduardo Habkost 20 Dec '16
by Eduardo Habkost 20 Dec '16
20 Dec '16
On Mon, Dec 05, 2016 at 07:18:47PM +0100, David Hildenbrand wrote:
> Am 02.12.2016 um 22:18 schrieb Eduardo Habkost:
> > The query-cpu-model-expand QMP command needs at least one static
> > model, to allow the "static" expansion mode to be implemented.
> > Instead of defining static versions of every CPU model, define a
> > "base" CPU model that has absolutely no feature flag enabled.
> >
>
> Introducing separate ones makes feature lists presented to the user much
> shorter (and therefore easier to maintain). But I don't know how libvirt
> wants to deal with models on x86 in the future.
I understand that having a larger set of static models would make
expansions shorter. But I worry that by defining a complete set
of static models on x86 would require extra maintenance work on
the QEMU side with no visible benefit for libvirt.
I would like to hear from libvirt developers what they think. I
still don't know what they plan to use the type=static expansion
results for.
>
> How long is the static expansion on a recent intel CPU?
CPU model "Broadwell" returns 165 entries on return.model.props:
(QEMU) query-cpu-model-expansion type=static model={"name":"Broadwell"}
{"return": {"migration-safe": true, "model": {"name": "base", "props": {"pfthreshold": false, "pku": false, "rtm": true, "tsc-deadline": true, "xstore-en": false, "tsc-scale": false, "abm": true, "ia64": false, "kvm-mmu": false, "xsaveopt": true, "tce": false, "smep": true, "fpu": true, "xcrypt": false, "clflush": true, "flushbyasid": false, "kvm-steal-time": false, "lm": true, "tsc": true, "adx": true, "fxsr": true, "tm": false, "xgetbv1": false, "xstore": false, "vme": false, "vendor": "GenuineIntel", "arat": true, "de": true, "aes": true, "pse": true, "ds-cpl": false, "tbm": false, "sse": true, "phe-en": false, "f16c": true, "ds": false, "mpx": false, "tsc-adjust": false, "avx512f": false, "avx2": true, "pbe": false, "cx16": true, "avx512pf": false, "movbe": true, "perfctr-nb": false, "ospke": false, "avx512ifma": false, "stepping": 2, "sep": true, "sse4a": false, "avx512dq": false, "avx512-4vnniw": false, "xsave": true, "pmm": false, "hle": true, "est": false, "xop": false, "smx": false, "monitor": false, "avx512er": false, "apic": true, "sse4.1": true, "sse4.2": true, "pause-filter": false, "lahf-lm": true, "kvm-nopiodelay": false, "acpi": false, "mmx": true, "osxsave": false, "pcommit": false, "mtrr": true, "clwb": false, "dca": false, "pdcm": false, "xcrypt-en": false, "3dnow": false, "invtsc": false, "tm2": false, "hypervisor": true, "kvmclock-stable-bit": false, "fxsr-opt": false, "pcid": true, "lbrv": false, "avx512-4fmaps": false, "svm-lock": false, "popcnt": true, "nrip-save": false, "avx512vl": false, "x2apic": true, "kvmclock": false, "smap": true, "family": 6, "min-level": 13, "dtes64": false, "ace2": false, "fma4": false, "xtpr": false, "avx512bw": false, "nx": true, "lwp": false, "msr": true, "ace2-en": false, "decodeassists": false, "perfctr-core": false, "pge": true, "pn": false, "fma": true, "nodeid-msr": false, "cx8": true, "mce": true, "avx512cd": false, "cr8legacy": false, "mca": true, "pni": true, "rdseed": true, "osvw": false, "fsgsbase": true, "model-id": "Intel Core Processor (Broadwell)", "cmp-legacy": false, "kvm-pv-unhalt": false, "rdtscp": true, "mmxext": false, "cid": false, "vmx": false, "ssse3": true, "extapic": false, "pse36": true, "min-xlevel": 2147483656, "ibs": false, "avx": true, "syscall": true, "umip": false, "invpcid": true, "bmi1": true, "bmi2": true, "vmcb-clean": false, "erms": true, "cmov": true, "misalignsse": false, "clflushopt": false, "pat": true, "3dnowprefetch": true, "rdpid": false, "pae": true, "wdt": false, "skinit": false, "pmm-en": false, "phe": false, "3dnowext": false, "lmce": false, "ht": false, "pdpe1gb": false, "kvm-pv-eoi": false, "npt": false, "xsavec": false, "pclmulqdq": true, "svm": false, "sse2": true, "ss": false, "topoext": false, "rdrand": true, "avx512vbmi": false, "kvm-asyncpf": false, "xsaves": false, "model": 61}}, "static": true}}
--
Eduardo
3
4
This effort started primarily to address some ideas/thoughts brought
up in https://bugzilla.redhat.com/show_bug.cgi?id=1332019 although as
things were updated, it seems that using storage volume definitions
wouldn't be necessary since the same data can be obtained via the
virDomainGetBlockInfo API.
Still since code had been written - I figured I'd posted it and see
what kind of feedback it got.
The first patch just adds the <physical> element to the output XML
and documents it thusly.
The 2nd/3rd patch take a different approach adding virStorageVolInfoFlags
which could take a single flag indicating that the caller would prefer
to return the "physical" value instead of the "allocation" value. Yes,
kind of a hack, but since we cannot extend _virStorageVolInfo to add
a physical it's a mechanism to allow fetching the data using existing
structures. Sure a virStorageVolStats API could be created as well,
but I figured I'd see how this went first before thinking about that.
John Ferlan (3):
conf: Display <physical> in output of voldef
storage: Introduce virStorageVolInfoFlags
virsh: Allow display of the physical volume size
daemon/remote.c | 38 +++++++++++++++++++++++++++++
docs/formatstorage.html.in | 5 ++++
include/libvirt/libvirt-storage.h | 11 +++++++++
src/conf/storage_conf.c | 6 +++++
src/driver-storage.h | 6 +++++
src/libvirt-storage.c | 51 +++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 5 ++++
src/remote/remote_driver.c | 37 ++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 20 ++++++++++++++-
src/remote_protocol-structs | 10 ++++++++
src/storage/storage_driver.c | 24 +++++++++++++++---
tools/virsh-volume.c | 37 +++++++++++++++++++++++++---
tools/virsh.pod | 8 ++++--
13 files changed, 247 insertions(+), 11 deletions(-)
--
2.7.4
2
6
[libvirt] [PATCH 0/2] cgroup: unavailable controller prevents controller disabling
by Boris Fiuczynski 20 Dec '16
by Boris Fiuczynski 20 Dec '16
20 Dec '16
The problem description is covered in patch one.
I added patch two as an optional enhancement removing some complexity and
improving readability. If this finds common agreement it should simply be
squashed into the first patch of this series.
Boris Fiuczynski (2):
cgroup: unavailable controller prevents controller disabling
cgroup: reduce complexity of controller disabling
src/util/vircgroup.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
--
2.5.5
2
6
[libvirt] [PATCH] qemu: Adjust qemuDomainGetBlockInfo data for sparse backed files
by John Ferlan 20 Dec '16
by John Ferlan 20 Dec '16
20 Dec '16
According to commit id '0282ca45a' the 'physical' value should
essentially be the last offset of the image or the host physical
size in bytes of the image container. However, commit id '15fa84ac'
refactored the GetBlockInfo to use the same returned data as the
GetStatsBlock API for an active domain. For the 'entry->physical'
that would end up being the "actual-size" as set through the
qemuMonitorJSONBlockStatsUpdateCapacityOne (commit '7b11f5e5').
Digging deeper into QEMU code one finds that actual_size is
filled in using the same algorithm as GetBlockInfo has used for
setting the 'allocation' field when the domain is inactive.
The difference in values is seen primarily in sparse raw files
and other container type files (such as qcow2), which will return
a smaller value via the stat API for 'st_blocks'. Additionally
for container files, the 'capacity' field (populated via the
QEMU "virtual-size" value) may be slightly different (smaller)
in order to accomodate the overhead for the container. For
sparse files, the state 'st_size' field is returned.
This patch thus alters the allocation and physical values for
sparse backed storage files to be more appropriate to the API
contract. The result for GetBlockInfo is the following:
capacity: logical size in bytes of the image (how much storage
the guest will see)
allocation: host storage in bytes occupied by the image (such
as highest allocated extent if there are no holes,
similar to 'du')
physical: host physical size in bytes of the image container
(last offset, similar to 'ls')
NB: The GetStatsBlock API allows a different contract for the
values:
"block.<num>.allocation" - offset of the highest written sector
as unsigned long long.
"block.<num>.capacity" - logical size in bytes of the block device
backing image as unsigned long long.
"block.<num>.physical" - physical size in bytes of the container
of the backing image as unsigned long long.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
Initially based on a question posed on libvirt-users:
https://www.redhat.com/archives/libvirt-users/2016-November/msg00050.html
related to determining whether the provided physical value for an
inactive guest would be valid I found that virDomainGetBlockInfo was
returning different results for capacity and physical when the domain
was running. As I dug deeper I found Eric Blake's commit regarding how
libvirt uses/describes the allocation, capacity, and physical and felt
that the changes made to virDomainGetBlockInfo especially for sparse files
and "container" files (such as qcow2) would essentially provide incorrect
and perhaps unexpected results.
If it's felt that the live/active domain should return/display the same
as the virConnectGetAllDomainStats, then I can drop the patch. I guess I
find it odd that the physical size could be 4K matching the allocation
value for a sparse file. Likewise, for a fully preallocated file was
showing an allocation value of 0 since wr_highest_offset hadn't yet
been updated.
I've been testing with a guest with different types of "file" and "block"
storage backings where the 'block' storage is essentially iSCSI devices
added to the guest. Logically the changes result in what I'd expect for
results based upon reading the API docs.
src/qemu/qemu_driver.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 88778d4..c537891 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11808,13 +11808,29 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
info->allocation = entry->wr_highest_offset;
}
- if (entry->physical) {
- info->physical = entry->physical;
- } else {
+ /* Unlike GetStatsBlock, this API has defined the expected return values
+ * for allocation and physical slightly differently.
+ *
+ * Having a zero for either or if they're the same is an indication that
+ * there's a sparse file backing this device. In this case, we'll force
+ * the setting of physical based on the on disk file size.
+ *
+ * Additionally, if qemu hasn't written to the file yet, then set the
+ * allocation to whatever qemu returned for physical (e.g. the "actual-
+ * size" from the json query) as that will match the expected allocation
+ * value for this API. */
+ if (entry->physical == 0 || info->allocation == 0 ||
+ info->allocation == entry->physical) {
+ info->allocation = entry->physical;
+ if (info->allocation == 0)
+ info->allocation = entry->physical;
+
if (qemuDomainStorageUpdatePhysical(driver, cfg, vm, disk->src) < 0)
goto endjob;
info->physical = disk->src->physical;
+ } else {
+ info->physical = entry->physical;
}
info->capacity = entry->capacity;
--
2.7.4
2
1
For instance:
hellolibvirt/hellolibvirt.c: In function 'showDomains':
hellolibvirt/hellolibvirt.c:100:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (i = 0; i < numNames; i++) {
^
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
examples/admin/client_info.c | 2 +-
examples/admin/client_limits.c | 2 +-
examples/admin/list_clients.c | 2 +-
examples/admin/list_servers.c | 2 +-
examples/admin/threadpool_params.c | 2 +-
examples/domsuspend/suspend.c | 2 +-
examples/domtop/domtop.c | 7 +++----
examples/hellolibvirt/hellolibvirt.c | 2 +-
examples/openauth/openauth.c | 2 +-
9 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/examples/admin/client_info.c b/examples/admin/client_info.c
index 314a0902b..57e9cd71e 100644
--- a/examples/admin/client_info.c
+++ b/examples/admin/client_info.c
@@ -102,7 +102,7 @@ int main(int argc, char **argv)
virAdmClientPtr clnt = NULL; /* which client get identity for */
virTypedParameterPtr params = NULL; /* where to store identity info */
int nparams = 0;
- size_t i = 0;
+ ssize_t i = 0;
char *timestr = NULL;
if (argc != 3) {
diff --git a/examples/admin/client_limits.c b/examples/admin/client_limits.c
index 2d5b75489..2a1d6314c 100644
--- a/examples/admin/client_limits.c
+++ b/examples/admin/client_limits.c
@@ -9,7 +9,7 @@ int main(int argc, char **argv)
virAdmServerPtr srv = NULL; /* which server to work with */
virTypedParameterPtr params = NULL;
int nparams = 0;
- size_t i;
+ ssize_t i;
if (argc != 2) {
fprintf(stderr, "One argument specifying the server which to work "
diff --git a/examples/admin/list_clients.c b/examples/admin/list_clients.c
index 3b4496e30..21ea4d818 100644
--- a/examples/admin/list_clients.c
+++ b/examples/admin/list_clients.c
@@ -50,7 +50,7 @@ int main(int argc, char **argv)
virAdmConnectPtr conn = NULL;
virAdmServerPtr srv = NULL; /* which server list the clients from */
virAdmClientPtr *clients = NULL; /* where to store the servers */
- size_t i = 0;
+ ssize_t i = 0;
int count = 0;
if (argc != 2) {
diff --git a/examples/admin/list_servers.c b/examples/admin/list_servers.c
index 1f6f4c6cf..420fd5fb7 100644
--- a/examples/admin/list_servers.c
+++ b/examples/admin/list_servers.c
@@ -8,7 +8,7 @@ int main(void)
virAdmConnectPtr conn = NULL;
virAdmServerPtr *servers = NULL; /* where to store the servers */
virAdmServerPtr *tmp = NULL;
- size_t i = 0;
+ ssize_t i = 0;
int count = 0;
/* first, open a connection to the daemon */
diff --git a/examples/admin/threadpool_params.c b/examples/admin/threadpool_params.c
index ee9ce83c1..43c71184a 100644
--- a/examples/admin/threadpool_params.c
+++ b/examples/admin/threadpool_params.c
@@ -9,7 +9,7 @@ int main(int argc, char **argv)
virAdmServerPtr srv = NULL; /* which server to work with */
virTypedParameterPtr params = NULL;
int nparams = 0;
- size_t i;
+ ssize_t i;
if (argc != 2) {
fprintf(stderr, "One argument specifying the server which to work "
diff --git a/examples/domsuspend/suspend.c b/examples/domsuspend/suspend.c
index 3e3f70e23..493a4b7b2 100644
--- a/examples/domsuspend/suspend.c
+++ b/examples/domsuspend/suspend.c
@@ -156,7 +156,7 @@ fetch_domains(virConnectPtr conn)
{
int num_domains, ret = -1;
virDomainPtr *domains = NULL;
- size_t i;
+ ssize_t i;
const int list_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
DEBUG("Fetching list of running domains");
diff --git a/examples/domtop/domtop.c b/examples/domtop/domtop.c
index 22839947d..5a798154a 100644
--- a/examples/domtop/domtop.c
+++ b/examples/domtop/domtop.c
@@ -161,7 +161,7 @@ fetch_domains(virConnectPtr conn)
{
int num_domains, ret = -1;
virDomainPtr *domains = NULL;
- size_t i;
+ ssize_t i;
const int list_flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE;
DEBUG("Fetching list of running domains");
@@ -189,8 +189,7 @@ fetch_domains(virConnectPtr conn)
}
static void
-print_cpu_usage(const char *dom_name,
- size_t cpu,
+print_cpu_usage(size_t cpu,
size_t ncpus,
unsigned long long then,
virTypedParameterPtr then_params,
@@ -334,7 +333,7 @@ do_top(virConnectPtr conn,
goto cleanup;
}
- print_cpu_usage(dom_name, 0, max_id,
+ print_cpu_usage(0, max_id,
then.tv_sec * 1000000 + then.tv_usec,
then_params, then_nparams,
now.tv_sec * 1000000 + now.tv_usec,
diff --git a/examples/hellolibvirt/hellolibvirt.c b/examples/hellolibvirt/hellolibvirt.c
index c64fa9658..02c440198 100644
--- a/examples/hellolibvirt/hellolibvirt.c
+++ b/examples/hellolibvirt/hellolibvirt.c
@@ -55,7 +55,7 @@ static int
showDomains(virConnectPtr conn)
{
int ret = 0, numNames, numInactiveDomains, numActiveDomains;
- size_t i;
+ ssize_t i;
int flags = VIR_CONNECT_LIST_DOMAINS_ACTIVE |
VIR_CONNECT_LIST_DOMAINS_INACTIVE;
virDomainPtr *nameList = NULL;
diff --git a/examples/openauth/openauth.c b/examples/openauth/openauth.c
index 0be977ef8..7a8254bb1 100644
--- a/examples/openauth/openauth.c
+++ b/examples/openauth/openauth.c
@@ -91,7 +91,7 @@ static int
showDomains(virConnectPtr conn)
{
int ret = 0, numNames, numInactiveDomains, numActiveDomains;
- size_t i;
+ ssize_t i;
char **nameList = NULL;
numActiveDomains = virConnectNumOfDomains(conn);
--
2.11.0
2
1
Re: [libvirt] [Qemu-ppc] [RFC PATCH qemu] spapr_pci: Create PCI-express root bus by default
by Andrea Bolognani 19 Dec '16
by Andrea Bolognani 19 Dec '16
19 Dec '16
On Tue, 2016-11-01 at 13:46 +1100, David Gibson wrote:
> On Mon, Oct 31, 2016 at 03:10:23PM +1100, Alexey Kardashevskiy wrote:
> >
> > On 31/10/16 13:53, David Gibson wrote:
> > >
> > > On Fri, Oct 28, 2016 at 12:07:12PM +0200, Greg Kurz wrote:
> > > >
> > > > On Fri, 28 Oct 2016 18:56:40 +1100
> > > > Alexey Kardashevskiy <aik(a)ozlabs.ru> wrote:
> > > >
> > > > >
> > > > > At the moment sPAPR PHB creates a root buf of TYPE_PCI_BUS type.
> > > > > This means that vfio-pci devices attached to it (and this is
> > > > > a default behaviour) hide PCIe extended capabilities as
> > > > > the bus does not pass a pci_bus_is_express(pdev->bus) check.
> > > > >
> > > > > This changes adds a default PCI bus type property to sPAPR PHB
> > > > > and uses TYPE_PCIE_BUS if none passed; older machines get TYPE_PCI_BUS
> > > > > for backward compatibility as a bus type is used in the bus name
> > > > > so the root bus name becomes "pcie.0" instead of "pci.0".
> > > > >
> > > > > Signed-off-by: Alexey Kardashevskiy <aik(a)ozlabs.ru>
> > > > > ---
> > > > >
> > > > > What can possibly go wrong with such change of a name?
> > > > > From devices prospective, I cannot see any.
> > > > >
> > > > > libvirt might get upset as "pci.0" will not be available,
> > > > > will it make sense to create pcie.0 as a root bus and always
> > > > > add a PCIe->PCI bridge and name its bus "pci.0"?
> > > > >
> > > > > Or create root bus from TYPE_PCIE_BUS and force name to "pci.0"?
> > > > > pci_register_bus() can do this.
> > > > >
> > > > >
> > > > > ---
> > > > > hw/ppc/spapr.c | 5 +++++
> > > > > hw/ppc/spapr_pci.c | 5 ++++-
> > > > > include/hw/pci-host/spapr.h | 1 +
> > > > > 3 files changed, 10 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> > > > > index 0b3820b..a268511 100644
> > > > > --- a/hw/ppc/spapr.c
> > > > > +++ b/hw/ppc/spapr.c
> > > > > @@ -2541,6 +2541,11 @@ DEFINE_SPAPR_MACHINE(2_8, "2.8", true);
> > > > > .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
> > > > > .property = "mem64_win_size", \
> > > > > .value = "0", \
> > > > > + }, \
> > > > > + { \
> > > > > + .driver = TYPE_SPAPR_PCI_HOST_BRIDGE, \
> > > > > + .property = "root_bus_type", \
> > > > > + .value = TYPE_PCI_BUS, \
> > > > > },
> > > > >
> > > > > static void phb_placement_2_7(sPAPRMachineState *spapr, uint32_t index,
> > > > > diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
> > > > > index 7cde30e..2fa1f22 100644
> > > > > --- a/hw/ppc/spapr_pci.c
> > > > > +++ b/hw/ppc/spapr_pci.c
> > > > > @@ -1434,7 +1434,9 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
> > > > > bus = pci_register_bus(dev, NULL,
> > > > > pci_spapr_set_irq, pci_spapr_map_irq, sphb,
> > > > > &sphb->memspace, &sphb->iospace,
> > > > > - PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS);
> > > > > + PCI_DEVFN(0, 0), PCI_NUM_PINS,
> > > > > + sphb->root_bus_type ? sphb->root_bus_type :
> > > > > + TYPE_PCIE_BUS);
> > > >
> > > > Shouldn't we ensure that sphb->root_bus_type is either TYPE_PCIE_BUS or
> > > > TYPE_PCI_BUS ?
> > >
> > > Yes, I think so. In fact, I think it would be better to make the
> > > property a boolean that just selects PCI-E, rather than this which
> > > exposes qemu (semi-)internal type names on the comamnd line.
> >
> > Sure, a "pcie-root" boolean property should do.
> >
> > However this is not my main concern, I rather wonder if we have to have
> > pci.0 when we pick PCIe for the root.
>
> Right.
>
> I've added Andrea Bologna to the CC list to get a libvirt perspective.
Thanks for doing so: changes such as this one can have quite
an impact on the upper layers of the stack, so the earliest
libvirt is involved in the discussion the better.
I'm going to go a step further and cross-post to libvir-list
in order to give other libvirt contributors a chance to chime
in too.
> Andrea,
>
> To summarise the issue here:
> * As I've said before the PAPR spec kinda-sorta abstracts the
> difference between vanilla PCI and PCI-E
> * However, because within qemu we're declaring the bus as PCI that
> means some PCI-E devices aren't working right
> * In particular it means that PCI-E extended config space isn't
> available
>
> The proposal is to change (on newer machine types) the spapr PHB code
> to declare a PCI-E bus instead. AIUI this still won't make the root
> complex guest visible (which it's not supposed to be under PAPR), and
> the guest shouldn't see a difference in most cases - it will still see
> the PAPR abstracted PCIish bus, but will now be able to get extended
> config space.
>
> The possible problem from a libvirt perspective is that doing this in
> the simplest way in qemu would change the name of the default bus from
> pci.0 to pcie.0. We have two suggested ways to mitigate this:
> 1) Automatically create a PCI-E to PCI bridge, so that new machine
> types will have both a pcie.0 and pci.0 bus
> 2) Force the name of the bus to be pci.0, even though it's treated
> as PCI-E in other ways.
>
> We're trying to work out exactly what will and won't cause trouble for
> libvirt.
Option 2) is definitely a no-no, as we don't want to be piling
up even more hacks and architecture-specific code: the PCI
Express Root Bus should be called pcie.0, just as it is on q35
and mach-virt machine types.
Option 1) doesn't look too bad, but devices that are added
automatically by QEMU are an issue since we need to hardcode
knowledge of them into libvirt if we want the rest of the PCI
address allocation logic to handle them correctly.
Moreover libvirt now has the ability of building a legacy PCI
topology without user intervention, if needed to plug in
legacy devices, on machines that have a PCI Express Root Bus,
which makes the additional bridge fully redundant...
... or at least it would, if we actually had a proper
PCIe-to-PCI bridge; AFAIK, though, the closest we have is the
i82801b11-bridge that is Intel-specific despite having so far
been abused as a generic PCIe-to-PCI bridge. I'm not even
sure whether it would work at all on ppc64.
Moving from legacy PCI to PCI Express would definitely be an
improvement, in my opinion. As mentioned, that's already the
case for at least two other architectures, so the more we can
standardize on that, the better.
That said, considering that a big part of the PCI address
allocation logic is based off whether the specific machine
type exposes a legay PCI Root Bus or a PCI Express Root Bus,
libvirt will need a way to be able to tell which one is which.
Version checks are pretty much out of the question, as they
fail as soon as downstream releases enter the picture. A
few ways we could deal with the situation:
1) switch to PCI Express on newer machine types, and
expose some sort of capability through QMP so that
libvirt can know about the switch
2) switch between legacy PCI and PCI Express based on a
machine type option. libvirt would be able to find out
whether the option is available or not, and default to
either
<controller type='pci' model='pci-root'/>
or
<controller type='pci' model='pcie-root'/>
based on that. In order to support multiple PHBs
properly, those would have to be switchable with an
option as well
3) create an entirely new machine type, eg. pseries-pcie
or whatever someone with the ability to come up with
decent names can suggest :) That would make ppc64
similar to x86, where i440fx and q35 have different
root buses. libvirt would learn about the new machine
type, know that it has a PCI Express Root Bus, and
behave accordingly
Option 1) would break horribly with existing libvirt
versions, and so would Option 2) if we default to using
PCI Express. Option 2) with default to legacy PCI and
option 3) would work just fine with existing libvirt
versions AFAICT, but wouldn't of course expose the new
capabilities.
Option 3) is probably the one that will be less confusing
to users; we might even decide to take the chance and fix
other small annoyances with the current pseries machine
type, if there's any. On the other hand, it might very well
be considered to be too big a hammer for such a small nail.
--
Andrea Bolognani / Red Hat / Virtualization
9
32
The github.com/rgbkrk/libvirt-go bindings were the most complete
bindings historically, but their API coverage stops at 1.2.4,
with exception of a couple of newer APIs.
The new bindings at http://libvirt.org/git/?p=libvirt-go.git;a=log
how have (almost[1]) 100% API coverage all the way to 2.5.0. They also
expose the APIs in a way that allows for much stronger go type
checking by the compiler, and expose typed parameters as explicit
structs. Finally the bindings are able to conditionally compile against
any libvirt version 1.2.0 -> 2.5.0 without use of go build tags.
Change the docs to point to these new bindings, since they'll be
a better bet for users long term.
[1] virEvent & virStream callbacks are still TODO to be fixed
real soon.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
docs/bindings.html.in | 4 ++--
docs/docs.html.in | 2 +-
docs/downloads.html.in | 15 +++++++++++++++
3 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/docs/bindings.html.in b/docs/bindings.html.in
index 7fe26df..dc15576 100644
--- a/docs/bindings.html.in
+++ b/docs/bindings.html.in
@@ -15,8 +15,8 @@
<a href="csharp.html">C# bindings</a>.
</li>
<li>
- <strong>Go</strong>: Kyle Kelley et al. are developing
- <a href="https://github.com/rgbkrk/libvirt-go">Go bindings</a>.
+ <strong>Go</strong>: Daniel Berrange develops
+ <a href="https://godoc.org/github.com/libvirt/libvirt-go">Go bindings</a>.
</li>
<li>
<strong>Java</strong>: Daniel Veillard develops
diff --git a/docs/docs.html.in b/docs/docs.html.in
index b0d200b..60489a0 100644
--- a/docs/docs.html.in
+++ b/docs/docs.html.in
@@ -57,7 +57,7 @@
<dt><a href="bindings.html">Language bindings</a></dt>
<dd>Bindings of the libvirt API for
<a href="csharp.html">c#</a>,
- <a href="https://github.com/rgbkrk/libvirt-go">go</a>,
+ <a href="https://godoc.org/github.com/libvirt/libvirt-go">go</a>,
<a href="java.html">java</a>,
<a href="http://libvirt.org/ocaml/">ocaml</a>.
<a href="http://search.cpan.org/dist/Sys-Virt/">perl</a>,
diff --git a/docs/downloads.html.in b/docs/downloads.html.in
index dd96409..3a6ea91 100644
--- a/docs/downloads.html.in
+++ b/docs/downloads.html.in
@@ -57,6 +57,21 @@
</td>
</tr>
<tr>
+ <td>Go</td>
+ <td>
+ <a href="ftp://libvirt.org/libvirt/go/">ftp</a>
+ <a href="http://libvirt.org/sources/go/">http</a>
+ <a href="https://libvirt.org/sources/go/">https</a>
+ </td>
+ <td>
+ <a href="http://libvirt.org/git/?p=libvirt-go.git;a=summary">libvirt</a>
+ </td>
+ <td>
+ <a href="https://gitlab.com/libvirt/libvirt-go">gitlab</a>
+ <a href="https://github.com/libvirt/libvirt-go">github</a>
+ </td>
+ </tr>
+ <tr>
<td>Java</td>
<td>
<a href="ftp://libvirt.org/libvirt/java/">ftp</a>
--
2.9.3
2
1
Follow up of commit 340bb6b7 to add unit tests for the QED format
support. Also add missing QED case in xenFormatXLDisk()
---
src/xenconfig/xen_xl.c | 5 +++++
tests/xlconfigdata/test-disk-positional-parms-full.cfg | 2 +-
tests/xlconfigdata/test-disk-positional-parms-full.xml | 6 ++++++
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/xenconfig/xen_xl.c b/src/xenconfig/xen_xl.c
index 048ecd579..65d8ffc63 100644
--- a/src/xenconfig/xen_xl.c
+++ b/src/xenconfig/xen_xl.c
@@ -1050,6 +1050,11 @@ xenFormatXLDisk(virConfValuePtr list, virDomainDiskDefPtr disk)
case VIR_STORAGE_FILE_QCOW2:
virBufferAddLit(&buf, "qcow2");
break;
+#ifdef LIBXL_HAVE_QED
+ case VIR_STORAGE_FILE_QED:
+ virBufferAddLit(&buf, "qed");
+ break;
+#endif
/* set default */
default:
virBufferAddLit(&buf, "raw");
diff --git a/tests/xlconfigdata/test-disk-positional-parms-full.cfg b/tests/xlconfigdata/test-disk-positional-parms-full.cfg
index 217d4dccf..20421ffc1 100644
--- a/tests/xlconfigdata/test-disk-positional-parms-full.cfg
+++ b/tests/xlconfigdata/test-disk-positional-parms-full.cfg
@@ -22,4 +22,4 @@ parallel = "none"
serial = "none"
builder = "hvm"
boot = "d"
-disk = [ "/dev/HostVG/XenGuest2,raw,hda,rw,backendtype=phy", "/var/lib/libvirt/images/XenGuest2-home,qcow2,hdb,rw", "/root/boot.iso,raw,hdc,ro,devtype=cdrom" ]
+disk = [ "/dev/HostVG/XenGuest2,raw,hda,rw,backendtype=phy", "/var/lib/libvirt/images/XenGuest2-home,qcow2,hdb,rw", "/root/boot.iso,raw,hdc,ro,devtype=cdrom", "/var/lib/libvirt/images/XenGuest2-qed,qed,hdd,rw", ]
diff --git a/tests/xlconfigdata/test-disk-positional-parms-full.xml b/tests/xlconfigdata/test-disk-positional-parms-full.xml
index 1bc5b436e..9c2fb41b7 100644
--- a/tests/xlconfigdata/test-disk-positional-parms-full.xml
+++ b/tests/xlconfigdata/test-disk-positional-parms-full.xml
@@ -39,6 +39,12 @@
<readonly/>
<address type='drive' controller='0' bus='1' target='0' unit='0'/>
</disk>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qed'/>
+ <source file='/var/lib/libvirt/images/XenGuest2-qed'/>
+ <target dev='hdd' bus='ide'/>
+ <address type='drive' controller='0' bus='1' target='0' unit='1'/>
+ </disk>
<controller type='ide' index='0'/>
<interface type='bridge'>
<mac address='00:16:3e:66:92:9c'/>
--
2.11.0
3
2
19 Dec '16
In the website reorg we accidentally lost all links to the nice
reformatted news.html file. Add a link on the front page, and
also extend the download page table so that it includes links
to API docs and news files for each module (where available)
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
docs/downloads.html.in | 12 ++++++++++++
docs/index.html.in | 1 +
2 files changed, 13 insertions(+)
diff --git a/docs/downloads.html.in b/docs/downloads.html.in
index 3a6ea91..d56e17b 100644
--- a/docs/downloads.html.in
+++ b/docs/downloads.html.in
@@ -20,6 +20,7 @@
<th>Releases</th>
<th>GIT Repo</th>
<th>GIT Mirrors</th>
+ <th>Resources</th>
</tr>
</thead>
<tbody>
@@ -37,6 +38,10 @@
<a href="https://gitlab.com/libvirt/libvirt">gitlab</a>
<a href="https://github.com/libvirt/libvirt">github</a>
</td>
+ <td>
+ <a href="html/index.html">api ref</a>
+ <a href="news.html">changes</a>
+ </td>
</tr>
<tr>
<th colspan="7">Language bindings</th>
@@ -70,6 +75,9 @@
<a href="https://gitlab.com/libvirt/libvirt-go">gitlab</a>
<a href="https://github.com/libvirt/libvirt-go">github</a>
</td>
+ <td>
+ <a href="https://godoc.org/github.com/libvirt/libvirt-go">api ref</a>
+ </td>
</tr>
<tr>
<td>Java</td>
@@ -113,6 +121,10 @@
<a href="https://gitlab.com/libvirt/libvirt-perl">gitlab</a>
<a href="https://github.com/libvirt/libvirt-perl">github</a>
</td>
+ <td>
+ <a href="http://search.cpan.org/dist/Sys-Virt/">api ref</a>
+ <a href="http://libvirt.org/git/?p=libvirt-perl.git;a=blob;f=Changes;hb=HEAD">changes</a>
+ </td>
</tr>
<tr>
<td>PHP</td>
diff --git a/docs/index.html.in b/docs/index.html.in
index bcb47f7..31bd6e0 100644
--- a/docs/index.html.in
+++ b/docs/index.html.in
@@ -41,6 +41,7 @@
<li>targets Linux, FreeBSD, <a href="windows.html">Windows</a> and OS-X</li>
<li>is used by many <a href="apps.html">applications</a></li>
</ul>
+ <p>Recent / forthcoming <a href="news.html">release changes</a></p>
</div>
<div class="panel">
--
2.9.3
2
1
Previously the way Fedora installed /usr/bin/nosetests allowed it
to be invoked with either python 2 or 3. Since Fedora 25 though,
it contains a module name that only exists on python 2. So we need
to be more intelligent and pick a different nosetests binary per
version.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
setup.py | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
This is technically a CI build breaker fix for rawhide, but it
could do with review so I've not pushed it yet.
diff --git a/setup.py b/setup.py
index bbcfe87..0d65763 100755
--- a/setup.py
+++ b/setup.py
@@ -277,6 +277,20 @@ class my_test(Command):
self.build_platlib = os.path.join(self.build_base,
'lib' + plat_specifier)
+ def find_nosetests_path(self):
+ paths = [
+ "/usr/bin/nosetests-%d.%d" % (sys.version_info[0],
+ sys.version_info[1]),
+ "/usr/bin/nosetests-%d" % (sys.version_info[0]),
+ "/usr/bin/nosetests",
+ ]
+
+ for path in paths:
+ if os.path.exists(path):
+ return path
+
+ raise Exception("Cannot find any nosetests binary")
+
def run(self):
"""
Run test suite
@@ -289,7 +303,8 @@ class my_test(Command):
else:
os.environ["PYTHONPATH"] = self.build_platlib
self.spawn([sys.executable, "sanitytest.py", self.build_platlib, apis[0]])
- self.spawn([sys.executable, "/usr/bin/nosetests"])
+ nose = self.find_nosetests_path()
+ self.spawn([sys.executable, nose])
class my_clean(clean):
--
2.9.3
2
1
https://bugzilla.redhat.com/show_bug.cgi?id=1369281
---
examples/apparmor/libvirt-qemu | 1 +
1 file changed, 1 insertion(+)
diff --git a/examples/apparmor/libvirt-qemu b/examples/apparmor/libvirt-qemu
index 11381d4df0..a07291d583 100644
--- a/examples/apparmor/libvirt-qemu
+++ b/examples/apparmor/libvirt-qemu
@@ -21,6 +21,7 @@
/dev/ptmx rw,
/dev/kqemu rw,
@{PROC}/*/status r,
+ @{PROC}/@{pid}/task/@{tid}/comm rw,
@{PROC}/sys/kernel/cap_last_cap r,
# For hostdev access. The actual devices will be added dynamically
--
2.11.0
5
15
19 Dec '16
I run a system dnsmasq to be able to forward specific DNS requests to
specific servers. And I have it configured for both forward and reverse
lookups. Another dnsmasq is started for a virtual network with domain
"virt". The system dnsmasq knows it needs to forward any requests for
the "virt" domain and corresponding PTR domain to the dnsmasq started by
libvirt. The problem is dnsmasq forwards queries for unknown names to
the upstream name server (which is the system instance in my case). One
can get nice endless loops of DNS requests pretty easily. Forward loops
can be avoided by specifying localOnly='yes', but there was no way to
avoid reverse lookup loops. And this is what I'm trying to address in
the following patches.
Version 3:
- <ptr> support dropped from this series, it will be implemented
separately
Patches 1 and 2 from version 2 were already pushed.
Version 2:
- RNG schema changes and tests
Jiri Denemark (3):
conf: Make virNetworkIPDefParseXML a little bit saner
util: Introduce virSocketAddrPTRDomain
network: Add support for local PTR domains
docs/formatnetwork.html.in | 21 ++++--
docs/news.html.in | 2 +
docs/schemas/network.rng | 3 +
src/conf/network_conf.c | 55 +++++++++-------
src/conf/network_conf.h | 2 +
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 41 ++++++++++++
src/util/virsocketaddr.c | 85 +++++++++++++++++++++++++
src/util/virsocketaddr.h | 9 +++
tests/networkxml2confdata/ptr-domains-auto.conf | 20 ++++++
tests/networkxml2confdata/ptr-domains-auto.xml | 21 ++++++
tests/networkxml2conftest.c | 1 +
12 files changed, 232 insertions(+), 29 deletions(-)
create mode 100644 tests/networkxml2confdata/ptr-domains-auto.conf
create mode 100644 tests/networkxml2confdata/ptr-domains-auto.xml
--
2.11.0
2
7
[libvirt] [PATCH] perf: Consider all perf events mentioned in commandline
by Nitesh Konkar 19 Dec '16
by Nitesh Konkar 19 Dec '16
19 Dec '16
Currently 'virsh perf domainName --enable a,b' command
fails to enable/disable perf event b if perf event a has
failed to get enabled/disabled. This patch fixes this
issue.
Signed-off-by: Nitesh Konkar <nitkon12(a)linux.vnet.ibm.com>
---
src/qemu/qemu_driver.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0bf1856..365af37 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9884,9 +9884,9 @@ qemuDomainSetPerfEvents(virDomainPtr dom,
type = virPerfEventTypeFromString(param->field);
if (!enabled && virPerfEventDisable(priv->perf, type) < 0)
- goto endjob;
+ continue;
if (enabled && virPerfEventEnable(priv->perf, type, vm->pid) < 0)
- goto endjob;
+ continue;
def->perf.events[type] = enabled ?
VIR_TRISTATE_BOOL_YES : VIR_TRISTATE_BOOL_NO;
--
1.9.3
2
1
Hi,
I wanted to use libvirt to connect to KVM in Windows-64bit,but I was failed。In fact,when I tryed that in Windows-32bit,it can be right。
Please teach me,how can I make it right in Windows-64bit?After all, the Windows-32bit is outdated。
Thank you very much。forgive my pool English。
Looking forward to your reply!
a new Java developer
2
1
Changes v2 -> v3:
* Implemented a "slot set" structure, where multiple slots can be
reported by using integer ranges or lists for possible
values for each property. Added a ValueSet struct, that
can represent a set of values using either a simple list of
values, or integer ranges. (Its JSON representation is very
verbose, though. See comments below).
* Removed the *Properties structs, and replaced them with
a simple list of SlotOption structs.
* DeviceSlotInfo is not an union anymore, removed the 'type'
field only because there are no slot-type-specific fields in
the current implementation, but we may add it back if necessary
* The implementation is very quick and dirty, the main purpose of
this RFC is to evaluate the schema and returned data.
Changes v1 -> v2:
* Don't show sysbus unless has_dynamic_sysbus is set for the
machine type
* Removed max-devices and devices properties
* Introduced "non-slot" slot type, to explicitly indicate
we are returning info on a bus that doesn't implement slot
enumeration yet.
* Return bus name instead of full QOM path on "bus" field
* PCI: Replaced "addr" property (string parsed by property
setter) with "device-number" uint32 property
* PCI: return only one slot for PCIe ports
This adds a new command to QMP: query-device-slots. It will allow
management software to query possible slots where devices can be
plugged.
This implementation of the command will return:
* Multiple PCI slots per bus, in the case of PCI buses;
* One slot per bus for the other buses (that don't
implement slot enumeration yet);
* One slot for each entry from query-hotpluggable-cpus.
Representation of slot sets in JSON
-----------------------------------
Slot sets are represented by a list of option names and sets of
possible values for each of those options. See the SlotOption
struct below for details.
The representation of those sets is very verbose in this version
(see below). e.g. the following set of 5 PCI functions:
bus: pcie.0
device-number: 31
function: 1,4-7
Is represented in the JSON data as:
"props": [
{
"values": {
"data": {
"ranges": [
{ "max": 1, "min": 1 },
{ "max": 7, "min": 4 }
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [ { "max": 31, "min": 31 } ]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [ "pcie.0" ],
"type": "list"
},
"option": "bus"
}
]
We could have used something more compact like:
function: 1,4-7
device-number: 31
bus: pcie.0
"props": {
"function": [ 1, { 'min': 4, 'max': 7 } ],
"device-number": 31,
"bus": "pcie.0"
}
But this would probably cost us the ability of describing and
validating the exact representation using the QAPI schema. I
don't know which way we should go.
QAPI schema
-----------
The following structures were added to the QAPI schema:
{ 'struct': 'IntegerSet',
'data': { 'ranges': [ 'IntegerRange' ] } }
{ 'struct': 'IntegerRange',
'data': { 'min': 'int', 'max': 'int' } }
{ 'union': 'ValueSet',
'data': { 'list': [ 'any' ], 'int-set': 'IntegerSet' } }
{ 'struct': 'SlotOption',
'data': { 'option': 'str', 'values': 'ValueSet' } }
{ 'struct': 'DeviceSlotInfo',
'data': { 'accepted-device-types': [ 'str' ],
'available': 'bool', 'hotpluggable': 'bool',
'*count': 'int', 'incomplete': 'bool',
'props': [ 'SlotOption' ] } }
{ 'command': 'query-device-slots',
'returns': [ 'DeviceSlotInfo' ] }
Git tree
--------
This patch needs the previous query-machines series I am working
on. The full tree can be found on the git tree at:
git://github.com/ehabkost/qemu-hacks.git work/query-machines-bus-info
Example output
--------------
The following output was returned by QEMU when running it as:
$ qemu-system-x86_64 -machine q35 \
-readconfig docs/q35-chipset.cfg \
-smp 4,maxcpus=8,sockets=2,cores=2,threads=2
As the JSON output is now quite verbose, I am including the
output of a script that translates the JSON data to a more
human-friendly format:
Slot set for: i2c-slave
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: i2c
Slot set for: ide-device
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: ide.4
Slot set for: ide-device
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: ide.5
Slot set for: ide-device
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: ide.0
Slot set for: ide-device
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: ide.1
Slot set for: ide-device
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: ide.2
Slot set for: ide-device
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: ide.3
Slot set for: sys-bus-device
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: main-system-bus
Slot set for: isa-device
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: isa.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 0
device-number: 0
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 7
available: yes
hotpluggable: no
valid device_add arguments:
function: 1-7
device-number: 0
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 0
device-number: 1
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 7
available: yes
hotpluggable: no
valid device_add arguments:
function: 1-7
device-number: 1
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 0
device-number: 2
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 7
available: yes
hotpluggable: no
valid device_add arguments:
function: 1-7
device-number: 2
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 0
device-number: 26
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 1
device-number: 26
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 2
device-number: 26
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 7
device-number: 26
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 4
available: yes
hotpluggable: no
valid device_add arguments:
function: 3-6
device-number: 26
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 0
device-number: 27
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 7
available: yes
hotpluggable: no
valid device_add arguments:
function: 1-7
device-number: 27
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 0
device-number: 28
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 1
device-number: 28
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 2
device-number: 28
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 3
device-number: 28
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 4
available: yes
hotpluggable: no
valid device_add arguments:
function: 4-7
device-number: 28
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 0
device-number: 29
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 1
device-number: 29
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 2
device-number: 29
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 7
device-number: 29
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 4
available: yes
hotpluggable: no
valid device_add arguments:
function: 3-6
device-number: 29
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 0
device-number: 30
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 7
available: yes
hotpluggable: no
valid device_add arguments:
function: 1-7
device-number: 30
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 0
device-number: 31
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 2
device-number: 31
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 1
available: no
hotpluggable: no
valid device_add arguments:
function: 3
device-number: 31
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 5
available: yes
hotpluggable: no
valid device_add arguments:
function: 1,4-7
device-number: 31
bus: pcie.0
Slot set for: legacy-pci-device, pci-express-device
Slot count: 184
available: yes
hotpluggable: no
valid device_add arguments:
function: 0-7
device-number: 3-25
bus: pcie.0
Slot set for: pci-express-device
Slot count: 8
available: yes
hotpluggable: yes
valid device_add arguments:
function: 0-7
device-number: 0
bus: ich9-pcie-port-1
Slot set for: pci-express-device
Slot count: 8
available: yes
hotpluggable: yes
valid device_add arguments:
function: 0-7
device-number: 0
bus: ich9-pcie-port-2
Slot set for: pci-express-device
Slot count: 8
available: yes
hotpluggable: yes
valid device_add arguments:
function: 0-7
device-number: 0
bus: ich9-pcie-port-3
Slot set for: pci-express-device
Slot count: 8
available: yes
hotpluggable: yes
valid device_add arguments:
function: 0-7
device-number: 0
bus: ich9-pcie-port-4
Slot set for: legacy-pci-device
Slot count: 256
available: yes
hotpluggable: no
valid device_add arguments:
function: 0-7
device-number: 0-31
bus: ich9-pci-bridge
Slot set for: usb-device
Incomplete set
available: yes
hotpluggable: yes
valid device_add arguments:
bus: ich9-ehci-1.0
Slot set for: usb-device
Incomplete set
available: yes
hotpluggable: yes
valid device_add arguments:
bus: ich9-ehci-2.0
Slot set for: hda-codec
Incomplete set
available: no
hotpluggable: no
valid device_add arguments:
bus: ich9-hda-audio.0
Slot set for: qemu64-x86_64-cpu
Slot count: 1
available: yes
hotpluggable: yes
valid device_add arguments:
socket-id: 1
thread-id: 1
core-id: 1
Slot set for: qemu64-x86_64-cpu
Slot count: 1
available: yes
hotpluggable: yes
valid device_add arguments:
socket-id: 1
thread-id: 0
core-id: 1
Slot set for: qemu64-x86_64-cpu
Slot count: 1
available: yes
hotpluggable: yes
valid device_add arguments:
socket-id: 1
thread-id: 1
core-id: 0
Slot set for: qemu64-x86_64-cpu
Slot count: 1
available: yes
hotpluggable: yes
valid device_add arguments:
socket-id: 1
thread-id: 0
core-id: 0
Slot set for: qemu64-x86_64-cpu
Slot count: 1
available: no
hotpluggable: yes
valid device_add arguments:
socket-id: 0
thread-id: 1
core-id: 1
Slot set for: qemu64-x86_64-cpu
Slot count: 1
available: no
hotpluggable: yes
valid device_add arguments:
socket-id: 0
thread-id: 0
core-id: 1
Slot set for: qemu64-x86_64-cpu
Slot count: 1
available: no
hotpluggable: yes
valid device_add arguments:
socket-id: 0
thread-id: 1
core-id: 0
Slot set for: qemu64-x86_64-cpu
Slot count: 1
available: no
hotpluggable: yes
valid device_add arguments:
socket-id: 0
thread-id: 0
core-id: 0
Raw JSON data for the above:
{
"return": [
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"i2c"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"i2c-slave"
]
},
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"ide.4"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"ide.5"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"ide.0"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"ide.1"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"ide.2"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"ide.3"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"main-system-bus"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"sys-bus-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"isa.0"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"isa-device"
]
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 7,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 1
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 1,
"min": 1
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 7,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 1
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 1,
"min": 1
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 2,
"min": 2
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 7,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 1
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 2,
"min": 2
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 26,
"min": 26
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 1,
"min": 1
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 26,
"min": 26
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 2,
"min": 2
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 26,
"min": 26
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 7
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 26,
"min": 26
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 4,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 6,
"min": 3
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 26,
"min": 26
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 27,
"min": 27
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 7,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 1
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 27,
"min": 27
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 28,
"min": 28
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 1,
"min": 1
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 28,
"min": 28
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 2,
"min": 2
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 28,
"min": 28
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 3,
"min": 3
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 28,
"min": 28
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 4,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 4
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 28,
"min": 28
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 29,
"min": 29
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 1,
"min": 1
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 29,
"min": 29
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 2,
"min": 2
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 29,
"min": 29
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 7
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 29,
"min": 29
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 4,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 6,
"min": 3
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 29,
"min": 29
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 30,
"min": 30
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 7,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 1
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 30,
"min": 30
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 31,
"min": 31
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 2,
"min": 2
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 31,
"min": 31
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 3,
"min": 3
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 31,
"min": 31
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 5,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 1,
"min": 1
},
{
"max": 7,
"min": 4
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 31,
"min": 31
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 184,
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 25,
"min": 3
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"pcie.0"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"count": 8,
"accepted-device-types": [
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"ich9-pcie-port-1"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": true,
"count": 8,
"accepted-device-types": [
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"ich9-pcie-port-2"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": true,
"count": 8,
"accepted-device-types": [
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"ich9-pcie-port-3"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": true,
"count": 8,
"accepted-device-types": [
"pci-express-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 0,
"min": 0
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"ich9-pcie-port-4"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": true,
"count": 256,
"accepted-device-types": [
"legacy-pci-device"
],
"props": [
{
"values": {
"data": {
"ranges": [
{
"max": 7,
"min": 0
}
]
},
"type": "int-set"
},
"option": "function"
},
{
"values": {
"data": {
"ranges": [
{
"max": 31,
"min": 0
}
]
},
"type": "int-set"
},
"option": "device-number"
},
{
"values": {
"data": [
"ich9-pci-bridge"
],
"type": "list"
},
"option": "bus"
}
],
"hotpluggable": false,
"incomplete": false
},
{
"available": true,
"hotpluggable": true,
"props": [
{
"values": {
"data": [
"ich9-ehci-1.0"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"usb-device"
]
},
{
"available": true,
"hotpluggable": true,
"props": [
{
"values": {
"data": [
"ich9-ehci-2.0"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"usb-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": [
{
"values": {
"data": [
"ich9-hda-audio.0"
],
"type": "list"
},
"option": "bus"
}
],
"incomplete": true,
"accepted-device-types": [
"hda-codec"
]
},
{
"available": true,
"count": 1,
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": [
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "socket-id"
},
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "thread-id"
},
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "core-id"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": true,
"count": 1,
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": [
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "socket-id"
},
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "thread-id"
},
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "core-id"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": true,
"count": 1,
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": [
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "socket-id"
},
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "thread-id"
},
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "core-id"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": true,
"count": 1,
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": [
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "socket-id"
},
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "thread-id"
},
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "core-id"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": [
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "socket-id"
},
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "thread-id"
},
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "core-id"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": [
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "socket-id"
},
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "thread-id"
},
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "core-id"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": [
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "socket-id"
},
{
"values": {
"data": [
1
],
"type": "list"
},
"option": "thread-id"
},
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "core-id"
}
],
"hotpluggable": true,
"incomplete": false
},
{
"available": false,
"count": 1,
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": [
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "socket-id"
},
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "thread-id"
},
{
"values": {
"data": [
0
],
"type": "list"
},
"option": "core-id"
}
],
"hotpluggable": true,
"incomplete": false
}
]
}
Cc: Marcel Apfelbaum <marcel(a)redhat.com>
Cc: Markus Armbruster <armbru(a)redhat.com>
Cc: libvir-list(a)redhat.com,
Cc: Igor Mammedov <imammedo(a)redhat.com>
Cc: Laine Stump <laine(a)redhat.com>
Cc: "Michael S. Tsirkin" <mst(a)redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost(a)redhat.com>
---
---
qapi-schema.json | 109 ++++++++++
scripts/qmp/query-slots.py | 50 +++++
include/hw/qdev-core.h | 6 +
include/qapi/qobject-output-visitor.h | 9 +
hw/core/bus.c | 45 +++++
hw/pci/pci.c | 363 +++++++++++++++++++++++++++++++---
qapi/qobject-output-visitor.c | 14 ++
qdev-monitor.c | 128 +++++++++++-
tests/qmp-machine-info.py | 72 +++++--
9 files changed, 746 insertions(+), 50 deletions(-)
create mode 100755 scripts/qmp/query-slots.py
diff --git a/qapi-schema.json b/qapi-schema.json
index d48ff3f..3d597b5 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3165,6 +3165,115 @@
##
{ 'command': 'closefd', 'data': {'fdname': 'str'} }
+
+##
+# @IntegerSet:
+#
+# A set of integers.
+##
+{ 'struct': 'IntegerSet',
+ 'data': { 'ranges': [ 'IntegerRange' ] } }
+
+##
+# @IntegerRange:
+#
+# A contiguous range of integers.
+#
+# @min: The first value in the range
+# @max: The last value in the range
+##
+{ 'struct': 'IntegerRange',
+ 'data': { 'min': 'int', 'max': 'int' } }
+
+##
+# @ValueSet:
+#
+# A set of values.
+#
+# @list: A set of elements in a list.
+#
+# @int-set: A set represented by an IntegerSet.
+##
+{ 'union': 'ValueSet',
+ 'data': { 'list': [ 'any' ], 'int-set': 'IntegerSet' } }
+
+##
+# @SlotOption:
+#
+# A option to be used when plugging a device to a slot.
+#
+# @option: Option name.
+#
+# @values: Set of valid option values.
+##
+{ 'struct': 'SlotOption',
+ 'data': { 'option': 'str', 'values': 'ValueSet' } }
+
+##
+# @DeviceSlotInfo:
+#
+# Information on a set of slots where devices can be plugged.
+#
+# @type: type of device slot.
+#
+# @accepted-device-types: List of device types accepted by the slots.
+# Any device plugged to the slot should implement
+# one of the accepted device types.
+#
+# @available: If false, the slot is not available for plugging any device.
+# This value can change at runtime if condition changes
+# (e.g. if the slot becomes full, or if the machine
+# was already initialized and the slot doesn't support
+# hotplug).
+#
+# @hotpluggable: If true, the slot accepts hotplugged devices.
+#
+# @count: #optional Number of slots represented by this slot set.
+# Will always be present if @incomplete=false.
+#
+# @incomplete: Slot information is incomplete. Slot count is not
+# available, and additional arguments are missing
+# on @props.
+#
+# @props: Information on the arguments that should be given to
+# @device_add if plugging a device to this slot.
+#
+# How to interpret @props
+# -----------------------
+#
+# Each key/value pair in @props represent an option that should
+# be set when using @device_add to plug a new device.
+#
+# Each value in @props represent a single value that should be
+# provided to @device_add, or a set of possible values for the option.
+#
+# Incomplete Slot Sets
+# --------------------
+#
+# Slot sets with @incomplete=true represent a bus that doesn't
+# support slot enumeration yet. Slots of this type should be replaced
+# by more detailed slot sets in future QEMU versions.
+#
+# Slots of this type may or may not support multiple devices.
+#
+# Slots in incomplete slot sets might require extra arguments to
+# be set to specify the device address.
+##
+{ 'struct': 'DeviceSlotInfo',
+ 'data': { 'accepted-device-types': [ 'str' ],
+ 'available': 'bool', 'hotpluggable': 'bool',
+ '*count': 'int', 'incomplete': 'bool',
+ 'props': [ 'SlotOption' ] } }
+
+##
+# @query-device-slots:
+#
+# Return the list of possible slots for plugging devices using
+# @device_add.
+##
+{ 'command': 'query-device-slots',
+ 'returns': [ 'DeviceSlotInfo' ] }
+
##
# @MachineBusInfo
#
diff --git a/scripts/qmp/query-slots.py b/scripts/qmp/query-slots.py
new file mode 100755
index 0000000..02c60b7
--- /dev/null
+++ b/scripts/qmp/query-slots.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+# test script to dump slot info in a more human-friendly way
+
+import qmp
+import sys
+
+q = qmp.QEMUMonitorProtocol(sys.argv[1])
+q.connect()
+slots = q.command('query-device-slots')
+for slot in slots:
+ types = slot.pop('accepted-device-types')
+ print 'Slot set for: %s' % (', '.join(types))
+ inc = slot.pop('incomplete')
+ if inc:
+ print ' Incomplete set'
+ else:
+ count = slot.pop('count')
+ print ' Slot count: %d' % (count)
+ props = slot.pop('props')
+ for k,v in slot.items():
+ if type(v) == bool:
+ if v:
+ v = 'yes'
+ else:
+ v = 'no'
+ elif type(v) == unicode:
+ v = str(v)
+ else:
+ v = repr(v)
+ print ' %s: %s' % (k, v)
+
+ print ' valid device_add arguments:'
+ for p in props:
+ option = p.pop('option')
+ values = p.pop('values')
+ assert not p # no other field
+ valuestr = repr(values)
+ if values['type'] == 'list':
+ valuestr = ', '.join(str(v) for v in values['data'])
+ elif values['type'] == 'int-set':
+ ranges = []
+ for r in values['data']['ranges']:
+ if r['max'] == r['min']:
+ ranges.append('%d' % (r['max']))
+ else:
+ ranges.append('%d-%d' % (r['min'], r['max']))
+ valuestr = ','.join(ranges)
+ else:
+ assert False
+ print ' %s: %s' % (option, valuestr)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index a7f9ac4..2cb043a 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -214,6 +214,10 @@ struct BusClass {
* but on some cases bus instances may override it.
*/
const char *device_type;
+
+ /*TODO: write doc */
+ DeviceSlotInfoList *(*enumerate_slots)(BusState *bus, Error **errp);
+
};
typedef struct BusChild {
@@ -412,4 +416,6 @@ static inline bool qbus_is_hotpluggable(BusState *bus)
void device_listener_register(DeviceListener *listener);
void device_listener_unregister(DeviceListener *listener);
+bool qbus_is_full(BusState *bus);
+
#endif
diff --git a/include/qapi/qobject-output-visitor.h b/include/qapi/qobject-output-visitor.h
index 8241877..319985e 100644
--- a/include/qapi/qobject-output-visitor.h
+++ b/include/qapi/qobject-output-visitor.h
@@ -16,6 +16,7 @@
#include "qapi/visitor.h"
#include "qapi/qmp/qobject.h"
+#include "qapi/error.h"
typedef struct QObjectOutputVisitor QObjectOutputVisitor;
@@ -27,4 +28,12 @@ typedef struct QObjectOutputVisitor QObjectOutputVisitor;
*/
Visitor *qobject_output_visitor_new(QObject **result);
+QObject *qapi_to_qobject(const void *src,
+ void (*visit_fn)(Visitor *, const char *,
+ void**, Error **));
+
+#define QAPI_TO_QOBJ(type, src) \
+ (qapi_to_qobject((src), (void (*)(Visitor *, const char *, void**, \
+ Error **))visit_type_ ## type))
+
#endif
diff --git a/hw/core/bus.c b/hw/core/bus.c
index d2bf717..2f47fe1 100644
--- a/hw/core/bus.c
+++ b/hw/core/bus.c
@@ -21,7 +21,9 @@
#include "qemu-common.h"
#include "hw/qdev.h"
#include "qapi/error.h"
+#include "qapi/clone-visitor.h"
#include "qapi-visit.h"
+#include "qapi/qmp/qstring.h"
static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
Error **errp)
@@ -225,12 +227,55 @@ static void bus_get_device_type(Object *obj, Visitor *v,
visit_type_strList(v, NULL, &bus->accepted_device_types, errp);
}
+bool qbus_is_full(BusState *bus)
+{
+ BusClass *bus_class = BUS_GET_CLASS(bus);
+ return bus_class->max_dev && bus->max_index >= bus_class->max_dev;
+}
+
+/* Generic slot enumeration function that will return a generic-slot slot type.
+ */
+static DeviceSlotInfoList *bus_generic_enumerate_slots(BusState *bus, Error **errp)
+{
+ Error *local_err = NULL;
+ DeviceSlotInfoList *r = g_new0(DeviceSlotInfoList, 1);
+
+ r->value = g_new0(DeviceSlotInfo, 1);
+ r->value->accepted_device_types = QAPI_CLONE(strList, bus->accepted_device_types);
+
+ r->value->hotpluggable = qbus_is_hotpluggable(bus);
+
+ r->value->incomplete = true;
+
+ /* Conditions that make a bus unavailable:
+ * - Bus already full
+ * - Hotplug when the bus is not hotpluggable
+ */
+ r->value->available =
+ !(qbus_is_full(bus) ||
+ (qdev_hotplug && !qbus_is_hotpluggable(bus)));
+
+
+ /* r->value->props = { 'bus': bus->name } */
+ r->value->props = g_new0(SlotOptionList, 1);
+ r->value->props->value = g_new0(SlotOption, 1);
+ r->value->props->value->option = g_strdup("bus");
+ r->value->props->value->values = g_new0(ValueSet, 1);
+ r->value->props->value->values->type = VALUE_SET_KIND_LIST;;
+ r->value->props->value->values->u.list.data = g_new0(anyList, 1);
+ r->value->props->value->values->u.list.data->value = QOBJECT(qstring_from_str(bus->name));
+
+ error_propagate(errp, local_err);
+ return r;
+}
+
static void bus_class_init(ObjectClass *class, void *data)
{
BusClass *bc = BUS_CLASS(class);
class->unparent = bus_unparent;
bc->get_fw_dev_path = default_bus_get_fw_dev_path;
+ bc->enumerate_slots = bus_generic_enumerate_slots;
object_class_property_add(class, "accepted-device-types", "strList",
bus_get_device_type, NULL, NULL, NULL,
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 2eac71a..26721a6 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -41,6 +41,8 @@
#include "hw/hotplug.h"
#include "hw/boards.h"
#include "qemu/cutils.h"
+#include "qapi/clone-visitor.h"
+#include "qapi/qmp/qstring.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
@@ -141,6 +143,8 @@ static uint16_t pcibus_numa_node(PCIBus *bus)
return NUMA_NODE_UNASSIGNED;
}
+static DeviceSlotInfoList *pci_bus_enumerate_slots(BusState *bus, Error **errp);
+
static void pci_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *k = BUS_CLASS(klass);
@@ -156,6 +160,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
* but overrides BusClass::device_type to INTERFACE_PCIE_DEVICE
*/
k->device_type = INTERFACE_LEGACY_PCI_DEVICE;
+ k->enumerate_slots = pci_bus_enumerate_slots;
pbc->is_root = pcibus_is_root;
pbc->bus_num = pcibus_num;
@@ -967,6 +972,274 @@ uint16_t pci_requester_id(PCIDevice *dev)
return pci_req_id_cache_extract(&dev->requester_id_cache);
}
+static bool pci_bus_has_pcie_upstream_port(PCIBus *bus)
+{
+ PCIDevice *parent_dev = pci_bridge_get_device(bus);
+
+ /* Device associated with an upstream port.
+ * As there are several types of these, it's easier to check the
+ * parent device: upstream ports are always connected to
+ * root or downstream ports.
+ */
+ return parent_dev &&
+ pci_is_express(parent_dev) &&
+ parent_dev->exp.exp_cap &&
+ (pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_ROOT_PORT ||
+ pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_DOWNSTREAM);
+}
+
+static PCIDevice *pci_bus_get_function_0(PCIBus *bus, int devfn)
+{
+ if(pci_bus_has_pcie_upstream_port(bus)) {
+ /* With an upstream PCIe port, we only support 1 device at slot 0 */
+ return bus->devices[0];
+ } else {
+ /* Other bus types might support multiple devices at slots 0-31 */
+ return bus->devices[PCI_DEVFN(PCI_SLOT(devfn), 0)];
+ }
+}
+
+PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
+{
+ return pci_bus_get_function_0(pci_dev->bus, pci_dev->devfn);
+}
+
+static bool int_set_empty(IntegerSet *set)
+{
+ return !set->ranges;
+}
+
+static int int_range_size(IntegerRange *range)
+{
+ return range->max - range->min + 1;
+}
+
+static int int_set_size(IntegerSet *set)
+{
+ int r = 0;
+ IntegerRangeList *rl;
+ for (rl = set->ranges; rl; rl = rl->next) {
+ r += int_range_size(rl->value);
+ }
+ return r;
+}
+
+static void int_set_add(IntegerSet *set, int min, int max)
+{
+ IntegerRangeList *rl;
+ IntegerRangeList **pnext = &set->ranges;
+ IntegerRangeList *prev = NULL;
+
+ for (rl = set->ranges; rl; rl = rl->next) {
+ IntegerRange *r = rl->value;
+ if (max < r->min - 1) {
+ goto insert;
+ } else if (max <= r->max) {
+ r->min = min;
+ goto try_merge_back;
+ } else if (min == r->max + 1) {
+ r->max = max;
+ goto try_merge_front;
+ } else {
+ pnext = &rl->next;
+ prev = rl;
+ }
+ }
+
+insert:
+ rl = g_new0(IntegerRangeList, 1);
+ rl->value = g_new0(IntegerRange, 1);
+ rl->value->min = min;
+ rl->value->max = max;
+ rl->next = *pnext;
+ *pnext = rl;
+
+try_merge_back:
+ /*TODO: can't merge more than 1 range */
+ if (prev && prev->value->max == rl->value->min - 1) {
+ prev->value->max = rl->value->max;
+ prev->next = rl->next;
+ g_free(rl);
+ }
+
+try_merge_front:
+ while (rl->next && rl->value->max + 1 == rl->next->value->min) {
+ IntegerRangeList *old = rl->next;
+ rl->next = old->next;
+ g_free(old);
+ }
+}
+
+static ValueSet *new_slot_prop(DeviceSlotInfo *slot, const char *option, ValueSetKind type)
+{
+ SlotOptionList *l = g_new0(SlotOptionList, 1);
+ SlotOption *opt = g_new0(SlotOption, 1);
+ ValueSet *vs = g_new0(ValueSet, 1);
+
+ vs->type = type;
+ opt->option = g_strdup(option);
+ opt->values = vs;
+ l->value = opt;
+ l->next = slot->props;
+ slot->props = l;
+ return vs;
+}
+
+static void value_set_list_append(ValueSet *vs, QObject *value)
+{
+ anyList *new = g_new0(anyList, 1);
+
+ assert(vs->type == VALUE_SET_KIND_LIST);
+ new->value = value;
+ new->next = vs->u.list.data;
+ vs->u.list.data = new;
+}
+
+static DeviceSlotInfoList *pci_bus_enumerate_slots(BusState *bus, Error **errp)
+{
+ PCIBus *pb = PCI_BUS(bus);
+ int devnr, devnrs;
+ DeviceSlotInfoList *r = NULL;
+ DeviceSlotInfoList **next = &r;
+ IntegerSet *empty_slots = g_new0(IntegerSet, 1);
+
+ if (pci_bus_has_pcie_upstream_port(pb)) {
+ devnrs = 1;
+ } else {
+ devnrs = PCI_SLOT_MAX;
+ }
+
+ /* Each PCI devfn (device number + function) is a separate slot,
+ * because we implement multi-function PCI devices as separate
+ * device objects.
+ *
+ * As an experiment, return a slot set for each device number.
+ */
+ for(devnr = PCI_SLOT(pb->devfn_min); devnr < devnrs; devnr++) {
+ IntegerSet *empty_funcs = g_new0(IntegerSet, 1);
+
+ int func;
+ for (func = 0; func < PCI_FUNC_MAX; func++) {
+ if (pb->devices[PCI_DEVFN(devnr, func)]) {
+ break;
+ }
+ }
+ if (func == PCI_FUNC_MAX) {
+ /* All functions are empty, we can return the whole slot in the "empty" slot set */
+ int_set_add(empty_slots, devnr, devnr);
+ continue;
+ }
+
+ /* Not all functions are empty, so return one entry for each function */
+ for (func = 0; func < PCI_FUNC_MAX; func++) {
+ /* Empty functions will be reported as a single slot set later: */
+ if (!pb->devices[PCI_DEVFN(devnr, func)]) {
+ int_set_add(empty_funcs, func, func);
+ continue;
+ }
+
+ DeviceSlotInfoList *i = g_new0(DeviceSlotInfoList, 1);
+ i->value = g_new0(DeviceSlotInfo, 1);
+ /*TODO: add info about accepting only bridges on extra PCI root buses */
+ i->value->accepted_device_types = QAPI_CLONE(strList, bus->accepted_device_types);
+
+ i->value->hotpluggable = qbus_is_hotpluggable(bus);
+
+ /* Conditions that make a devnr unavailable:
+ * - function already occupied
+ * - function 0 already occupied by a device
+ * - Hotplug when the bus is not hotpluggable
+ */
+ i->value->available =
+ !((pb->devices[PCI_DEVFN(devnr, func)]) ||
+ (pb->devices[PCI_DEVFN(devnr, 0)]) ||
+ (0 && qdev_hotplug && !qbus_is_hotpluggable(bus)));
+
+ ValueSet *bus_values = new_slot_prop(i->value, "bus", VALUE_SET_KIND_LIST);
+ value_set_list_append(bus_values, QOBJECT(qstring_from_str(bus->name)));
+
+ ValueSet *dev_values = new_slot_prop(i->value, "device-number", VALUE_SET_KIND_INT_SET);
+ dev_values->u.int_set.data = g_new0(IntegerSet, 1);
+ int_set_add(dev_values->u.int_set.data, devnr, devnr);
+
+ ValueSet *func_values = new_slot_prop(i->value, "function", VALUE_SET_KIND_INT_SET);
+ func_values->u.int_set.data = g_new0(IntegerSet, 1);
+ int_set_add(func_values->u.int_set.data, func, func);
+
+ i->value->has_count = true;
+ i->value->count = 1;
+
+ *next = i;
+ next = &i->next;
+ }
+
+ if (!int_set_empty(empty_funcs)) {
+ DeviceSlotInfoList *i = g_new0(DeviceSlotInfoList, 1);
+ i->value = g_new0(DeviceSlotInfo, 1);
+ /*TODO: add info about accepting only bridges on extra PCI root buses */
+ i->value->accepted_device_types = QAPI_CLONE(strList, bus->accepted_device_types);
+
+ i->value->hotpluggable = qbus_is_hotpluggable(bus);
+
+ i->value->available =
+ !(0 && qdev_hotplug && !qbus_is_hotpluggable(bus));
+
+ ValueSet *bus_values = new_slot_prop(i->value, "bus", VALUE_SET_KIND_LIST);
+ value_set_list_append(bus_values, QOBJECT(qstring_from_str(bus->name)));
+
+ ValueSet *dev_values = new_slot_prop(i->value, "device-number", VALUE_SET_KIND_INT_SET);
+ dev_values->u.int_set.data = g_new0(IntegerSet, 1);
+ int_set_add(dev_values->u.int_set.data, devnr, devnr);
+
+ ValueSet *func_values = new_slot_prop(i->value, "function", VALUE_SET_KIND_INT_SET);
+ func_values->u.int_set.data = empty_funcs;
+
+ i->value->has_count = true;
+ i->value->count = int_set_size(empty_funcs);
+
+ *next = i;
+ next = &i->next;
+ } else {
+ qapi_free_IntegerSet(empty_slots);
+ }
+ }
+
+ /* Return a single slot set for the empty slots */
+ if (!int_set_empty(empty_slots)) {
+ DeviceSlotInfoList *i = g_new0(DeviceSlotInfoList, 1);
+ i->value = g_new0(DeviceSlotInfo, 1);
+ /*TODO: add info about accepting only bridges on extra PCI root buses */
+ i->value->accepted_device_types = QAPI_CLONE(strList, bus->accepted_device_types);
+
+ i->value->hotpluggable = qbus_is_hotpluggable(bus);
+
+ /* Conditions that make a devnr unavailable:
+ * - function 0 already occupied by a device
+ * - Hotplug when the bus is not hotpluggable
+ */
+ i->value->available = !(0 && qdev_hotplug && !qbus_is_hotpluggable(bus));
+
+ ValueSet *bus_values = new_slot_prop(i->value, "bus", VALUE_SET_KIND_LIST);
+ value_set_list_append(bus_values, QOBJECT(qstring_from_str(bus->name)));
+
+ ValueSet *dev_values = new_slot_prop(i->value, "device-number", VALUE_SET_KIND_INT_SET);
+ dev_values->u.int_set.data = empty_slots;
+
+ ValueSet *func_values = new_slot_prop(i->value, "function", VALUE_SET_KIND_INT_SET);
+ func_values->u.int_set.data = g_new0(IntegerSet, 1);
+ int_set_add(func_values->u.int_set.data, 0, PCI_FUNC_MAX - 1);
+
+ i->value->has_count = true;
+ i->value->count = PCI_FUNC_MAX * int_set_size(empty_slots);
+
+ *next = i;
+ next = &i->next;
+ } else {
+ qapi_free_IntegerSet(empty_slots);
+ }
+ return r;
+}
+
/* -1 for devfn means auto assign */
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
const char *name, int devfn,
@@ -2509,6 +2782,56 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev)
return dev->bus->address_space_io;
}
+static void pci_device_get_devnr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t devnr = PCI_SLOT(dev->devfn);
+
+ visit_type_uint32(v, "device-number", &devnr, errp);
+}
+
+static void pci_device_set_devnr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t devnr;
+ Error *local_err = NULL;
+
+ visit_type_uint32(v, "device-number", &devnr, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ dev->devfn = PCI_DEVFN(devnr, PCI_FUNC(dev->devfn));
+out:
+ error_propagate(errp, local_err);
+}
+
+static void pci_device_get_function(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t function = PCI_FUNC(dev->devfn);
+
+ visit_type_uint32(v, "function", &function, errp);
+}
+
+static void pci_device_set_function(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t function;
+ Error *local_err = NULL;
+
+ visit_type_uint32(v, "function", &function, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ dev->devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), function);
+out:
+ error_propagate(errp, local_err);
+}
+
static void pci_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
@@ -2519,6 +2842,19 @@ static void pci_device_class_init(ObjectClass *klass, void *data)
k->bus_type = TYPE_PCI_BUS;
k->props = pci_props;
pc->realize = pci_default_realize;
+
+ /* Internally, bits 3:8 of devfn are called "slots", but:
+ * - they can be confused with physical slot numbers;
+ * - TYPE_PCIE_SLOT objects already have a "slot" property.
+ * So we use the terminology used in the PCI specifiction:
+ * "device number".
+ */
+ object_class_property_add(klass, "device-number", "uint32",
+ pci_device_get_devnr, pci_device_set_devnr,
+ NULL, NULL, &error_abort);
+ object_class_property_add(klass, "function", "uint32",
+ pci_device_get_function, pci_device_set_function,
+ NULL, NULL, &error_abort);
}
static void pci_device_class_base_init(ObjectClass *klass, void *data)
@@ -2607,33 +2943,6 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range)
pci_for_each_device_under_bus(bus, pci_dev_get_w64, range);
}
-static bool pcie_has_upstream_port(PCIDevice *dev)
-{
- PCIDevice *parent_dev = pci_bridge_get_device(dev->bus);
-
- /* Device associated with an upstream port.
- * As there are several types of these, it's easier to check the
- * parent device: upstream ports are always connected to
- * root or downstream ports.
- */
- return parent_dev &&
- pci_is_express(parent_dev) &&
- parent_dev->exp.exp_cap &&
- (pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_ROOT_PORT ||
- pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_DOWNSTREAM);
-}
-
-PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
-{
- if(pcie_has_upstream_port(pci_dev)) {
- /* With an upstream PCIe port, we only support 1 device at slot 0 */
- return pci_dev->bus->devices[0];
- } else {
- /* Other bus types might support multiple devices at slots 0-31 */
- return pci_dev->bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
- }
-}
-
MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
{
MSIMessage msg;
diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
index 8711270..86c3e1b 100644
--- a/qapi/qobject-output-visitor.c
+++ b/qapi/qobject-output-visitor.c
@@ -252,3 +252,17 @@ Visitor *qobject_output_visitor_new(QObject **result)
return &v->visitor;
}
+
+QObject *qapi_to_qobject(const void *src,
+ void (*visit_fn)(Visitor *, const char *,
+ void**, Error **))
+{
+ QObject *qobj = NULL;
+ void *obj = (void *) src;
+ Visitor *v = qobject_output_visitor_new(&qobj);
+
+ visit_fn(v, "unused", &obj, &error_abort);
+ visit_complete(v, &qobj);
+ visit_free(v);
+ return qobj;
+}
diff --git a/qdev-monitor.c b/qdev-monitor.c
index c73410c..4df29c4 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -29,6 +29,9 @@
#include "qemu/error-report.h"
#include "qemu/help_option.h"
#include "sysemu/block-backend.h"
+#include "qapi/clone-visitor.h"
+#include "qapi/qobject-output-visitor.h"
+#include "hw/boards.h"
/*
* Aliases were a bad idea from the start. Let's keep them
@@ -399,12 +402,6 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
return NULL;
}
-static inline bool qbus_is_full(BusState *bus)
-{
- BusClass *bus_class = BUS_GET_CLASS(bus);
- return bus_class->max_dev && bus->max_index >= bus_class->max_dev;
-}
-
/*
* Search the tree rooted at @bus for a bus.
* If @name, search for a bus with that name. Note that bus names
@@ -631,6 +628,125 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
return dev;
}
+typedef struct SlotListState {
+ MachineState *machine;
+ DeviceSlotInfoList *result;
+ DeviceSlotInfoList **next;
+ Error *err;
+} SlotListState;
+
+static int walk_bus(Object *obj, void *opaque)
+{
+ SlotListState *s = opaque;
+
+ /* sysbus is special: never return it unless the machine
+ * supports dynamic sysbus devices.
+ */
+ if (object_dynamic_cast(obj, TYPE_BUS) &&
+ (!object_dynamic_cast(obj, TYPE_SYSTEM_BUS) ||
+ MACHINE_GET_CLASS(s->machine)->has_dynamic_sysbus)) {
+ BusState *bus = BUS(obj);
+ BusClass *bc = BUS_GET_CLASS(bus);
+ DeviceSlotInfoList *l = bc->enumerate_slots(bus, &s->err);
+ *s->next = l;
+ for (; l; l = l->next) {
+ s->next = &l->next;
+ }
+ if (s->err) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void add_option(const char *key, QObject *obj, void *opaque)
+{
+ SlotOptionList **l = opaque;
+ SlotOption *opt = g_new0(SlotOption, 1);
+ SlotOptionList *new = g_new0(SlotOptionList, 1);
+
+ opt->option = g_strdup(key);
+ opt->values = g_new0(ValueSet, 1);
+ opt->values->type = VALUE_SET_KIND_LIST;
+ opt->values->u.list.data = g_new0(anyList, 1);
+ opt->values->u.list.data->value = obj;
+ qobject_incref(obj);
+
+ new->next = *l;
+ new->value = opt;
+ *l = new;
+}
+
+/* Convert a simple QDict to a list of single-value slot properties */
+static void qdict_to_slot_props(QDict *d, SlotOptionList **l)
+{
+ qdict_iter(d, add_option, l);
+}
+
+static QObject *cpu_instance_props_to_qobj(CpuInstanceProperties *src, Error **errp)
+{
+ QObject *qobj = NULL;
+ Visitor *v = qobject_output_visitor_new(&qobj);
+
+ visit_type_CpuInstanceProperties(v, "unused", &src, &error_abort);
+ visit_complete(v, &qobj);
+ visit_free(v);
+ return qobj;
+}
+
+DeviceSlotInfoList *qmp_query_device_slots(Error **errp)
+{
+ SlotListState s = { };
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+
+ s.machine = ms;
+ s.next = &s.result;
+
+ /* We build the device slot list from two sources:
+ * 1) Calling the BusClass::enumerate_slots() method on all buses;
+ * 2) The return value of MachineClass::query_hotpluggable_cpus()
+ */
+
+
+ object_child_foreach_recursive(qdev_get_machine(), walk_bus, &s);
+ if (s.err) {
+ goto out;
+ }
+
+ if (mc->query_hotpluggable_cpus) {
+ HotpluggableCPUList *hcl = mc->query_hotpluggable_cpus(ms);
+ HotpluggableCPUList *i;
+
+ for (i = hcl; i; i = i->next) {
+ DeviceSlotInfoList *r = g_new0(DeviceSlotInfoList, 1);
+ HotpluggableCPU *hc = i->value;
+ QObject *props;
+
+ r->value = g_new0(DeviceSlotInfo, 1);
+ r->value->accepted_device_types = g_new0(strList, 1);
+ r->value->accepted_device_types->value = g_strdup(hc->type);
+ r->value->available = !hc->has_qom_path;
+ /*TODO: should it be always true? */
+ r->value->hotpluggable = true;
+ r->value->has_count = true;
+ r->value->count = 1;
+
+ props = cpu_instance_props_to_qobj(hc->props, &s.err);
+ qdict_to_slot_props(qobject_to_qdict(props), &r->value->props);
+
+ *s.next = r;
+ s.next = & r->next;
+ }
+
+ qapi_free_HotpluggableCPUList(hcl);
+ }
+
+out:
+ error_propagate(errp, s.err);
+ return s.result;
+}
+
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
static void qbus_print(Monitor *mon, BusState *bus, int indent);
diff --git a/tests/qmp-machine-info.py b/tests/qmp-machine-info.py
index 7905afb..850e89a 100755
--- a/tests/qmp-machine-info.py
+++ b/tests/qmp-machine-info.py
@@ -6,6 +6,8 @@ import qtest
import unittest
import logging
import argparse
+import itertools
+import operator
logger = logging.getLogger('qemu.tests.machineinfo')
@@ -35,6 +37,34 @@ NODEFAULTS_BLACKLIST = set([
'z2', # "qemu: missing SecureDigital device"
])
+# iterators for QAPI ValueSets:
+# all of the iterators below should support iter() and len()
+
+def int_range(d):
+ """Iterator for IntegerRange"""
+ return xrange(d['min'], d['max'] + 1)
+
+class IntegerSet:
+ """Iterator for IntegerSet"""
+ def __init__(self, d):
+ self._ranges = d['ranges']
+
+ def __iter__(self):
+ iters = [int_range(r) for r in self._ranges]
+ return itertools.chain(*iters)
+
+ def __len__(self):
+ return sum([len(int_range(r)) for r in self._ranges])
+
+def value_set(d):
+ """Iterator for ValueSet"""
+ if d['type'] == 'list':
+ return d['data']
+ elif d['type'] == 'int-set':
+ return IntegerSet(d['data'])
+ else:
+ raise NotImplementedError
+
class QueryMachinesTest(unittest.TestCase):
def setUp(self):
self.vm = None
@@ -154,9 +184,12 @@ class QueryMachinesTest(unittest.TestCase):
types_to_check = {}
buses_to_check = {}
for slot in slots:
- if slot['props'].has_key('bus'):
- bus = slot['props']['bus']
- buses_to_check.setdefault(bus, []).append(slot)
+ for prop in slot['props']:
+ if prop['option'] == 'bus':
+ values = value_set(bus['values'])
+ self.assertEquals(len(values), 1)
+ bus = values[0]
+ buses_to_check.setdefault(v, []).append(slot)
for t in slot['accepted-device-types']:
types_to_check.setdefault(t, set()).update(slot['props'].keys())
@@ -185,27 +218,32 @@ class QueryMachinesTest(unittest.TestCase):
self.assertFalse(slot['available'])
def checkSlotInfo(self, args):
- #TODO:
- # * check if -device works with at least one device type
- # * check if query-hotpluggable-cpus matches what's in query-device-slots
- # * check if accepted-device-types match the property on the bus
- # * check if available=false if len(devices) >= max-devices
- # * check if all plugged devices are really in the QOM tree
+ #TODO: check if:
+ # * -device works with at least one device type
+ # * query-hotpluggable-cpus matches what's in query-device-slots
+ # * accepted-device-types match the property on the bus
+ # * available=false if hotpluggable=false
+ # * 'count' is always set if not incomplete
+ # * slot count is <= set of possible values for @props
self.vm = qtest.QEMUQtestMachine(args=args, logging=False)
self.vm.launch()
slots = self.vm.command('query-device-slots')
- self.checkSlotProps(slots)
+ #self.checkSlotProps(slots)
#self.checkSlotDevices(slots)
- self.checkAvailableField(slots)
+ #self.checkAvailableField(slots)
+
+ for slot in slots:
+ logging.debug('slot: %r', slot)
+ if not slot['incomplete']:
+ self.assertTrue(slot.has_key('count'))
+
+ all_counts = [len(value_set(p['values'])) for p in slot['props']]
+ total_count = reduce(operator.mul, all_counts, 1)
+ logging.debug('%d possible values', total_count)
+ self.assertEquals(total_count, slot['count'])
def machineTestSlotInfo(self, machine):
- #TODO:
- # * check if -device works with at least one device type
- # * check if query-hotpluggable-cpus matches what's in query-device-slots
- # * check if accepted-device-types match the property on the bus
- # * check if available=false if len(devices) >= max-devices
- # * check if all plugged devices are really in the QOM tree
if machine['name'] in BLACKLIST:
self.skipTest("machine %s on BLACKLIST" % (machine['name']))
--
2.7.4
1
0
16 Dec '16
Similarly to 29bb066915 forbid paths used with blockjobs to be relative.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1300177
---
src/conf/snapshot_conf.c | 4 +---
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 6 ++++++
src/util/virstoragefile.c | 31 +++++++++++++++++++++++++++++++
src/util/virstoragefile.h | 2 ++
5 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index 862c2ec00..5daa8d11a 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -170,9 +170,7 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
}
/* validate that the passed path is absolute */
- if (virStorageSourceIsLocalStorage(def->src) &&
- def->src->path &&
- def->src->path[0] != '/') {
+ if (virStorageSourceIsRelative(def->src)) {
virReportError(VIR_ERR_XML_ERROR,
_("disk snapshot image path '%s' must be absolute"),
def->src->path);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7beebbf27..5c82e4a0e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2455,6 +2455,7 @@ virStorageSourceInitChainElement;
virStorageSourceIsBlockLocal;
virStorageSourceIsEmpty;
virStorageSourceIsLocalStorage;
+virStorageSourceIsRelative;
virStorageSourceNewFromBacking;
virStorageSourceNewFromBackingAbsolute;
virStorageSourceParseRBDColonString;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0bf185644..1a464337e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -16665,6 +16665,12 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
priv = vm->privateData;
cfg = virQEMUDriverGetConfig(driver);
+ if (virStorageSourceIsRelative(mirror)) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("absolute path must be used as block copy target"));
+ goto cleanup;
+ }
+
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 9ec005d50..ce6d21388 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -3672,3 +3672,34 @@ virStorageFileCheckCompat(const char *compat)
virStringListFree(version);
return ret;
}
+
+
+/**
+ * virStorageSourceIsRelative:
+ * @src: storage source to check
+ *
+ * Returns true if given storage source definition is a relative path.
+ */
+bool
+virStorageSourceIsRelative(virStorageSourcePtr src)
+{
+ virStorageType actual_type = virStorageSourceGetActualType(src);
+
+ if (!src->path)
+ return false;
+
+ switch (actual_type) {
+ case VIR_STORAGE_TYPE_FILE:
+ case VIR_STORAGE_TYPE_BLOCK:
+ case VIR_STORAGE_TYPE_DIR:
+ return src->path[0] != '/';
+
+ case VIR_STORAGE_TYPE_NETWORK:
+ case VIR_STORAGE_TYPE_VOLUME:
+ case VIR_STORAGE_TYPE_NONE:
+ case VIR_STORAGE_TYPE_LAST:
+ return false;
+ }
+
+ return false;
+}
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 6d1aac78d..1f62244db 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -388,4 +388,6 @@ int virStorageFileCheckCompat(const char *compat);
virStorageSourcePtr virStorageSourceNewFromBackingAbsolute(const char *path);
+bool virStorageSourceIsRelative(virStorageSourcePtr src);
+
#endif /* __VIR_STORAGE_FILE_H__ */
--
2.11.0
2
1
16 Dec '16
I run a system dnsmasq to be able to forward specific DNS requests to
specific servers. And I have it configured for both forward and reverse
lookups. Another dnsmasq is started for a virtual network with domain
"virt". The system dnsmasq knows it needs to forward any requests for
the "virt" domain and corresponding PTR domain to the dnsmasq started by
libvirt. The problem is dnsmasq forwards queries for unknown names to
the upstream name server (which is the system instance in my case). One
can get nice endless loops of DNS requests pretty easily. Forward loops
can be avoided by specifying localOnly='yes', but there was no way to
avoid reverse lookup loops. And this is what I'm trying to address in
the following patches.
Version 2:
- RNG schema changes and tests
Jiri Denemark (5):
tests: Check more network XMLs for schema compliance
schema: Let elements in /network/ip be specified in any order
conf: Make virNetworkIPDefParseXML a little bit saner
util: Introduce virSocketAddrPTRDomain
network: Add support for local PTR domains
docs/formatnetwork.html.in | 37 ++++++--
docs/schemas/basictypes.rng | 6 ++
docs/schemas/network.rng | 92 ++++++++++++--------
src/conf/network_conf.c | 108 +++++++++++++++++++-----
src/conf/network_conf.h | 4 +
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 47 +++++++++++
src/util/virsocketaddr.c | 85 +++++++++++++++++++
src/util/virsocketaddr.h | 9 ++
tests/networkxml2confdata/dhcp6-nat-network.xml | 2 +-
tests/networkxml2confdata/netboot-network.xml | 2 +-
tests/networkxml2confdata/ptr-domains-auto.conf | 20 +++++
tests/networkxml2confdata/ptr-domains-auto.xml | 21 +++++
tests/networkxml2confdata/ptr-domains.conf | 24 ++++++
tests/networkxml2confdata/ptr-domains.xml | 24 ++++++
tests/networkxml2conftest.c | 2 +
tests/virschematest.c | 2 +-
17 files changed, 418 insertions(+), 68 deletions(-)
create mode 100644 tests/networkxml2confdata/ptr-domains-auto.conf
create mode 100644 tests/networkxml2confdata/ptr-domains-auto.xml
create mode 100644 tests/networkxml2confdata/ptr-domains.conf
create mode 100644 tests/networkxml2confdata/ptr-domains.xml
--
2.11.0
2
12
This patch set enables cpu model support for s390. The user can now set exact
cpu models, query supported models via virsh domcapabilities, and use host-model
and host-passthrough modes. The end result is that migration is safer because
Qemu will perform runnability checking on the destination host and quit with an
error if the guest's cpu model is not supported.
Note: Some test data has been separated from corresponding test case updates for
ease of review.
Changelog
---------
[v2]
* Added s390x cpu and capabilities tests
* Added cpu feature syntax tests
* Dropped patch: Warn when migrating host-passthrough
* Added patch: Document migrating host-passthrough is dangerous
s390: Cpu driver support for update and compare
- Compare: Added comment explaining why s390 bypasses the cpuCompare operation
- Update: Added error message explaining minimum match mode is not supported
- Update: Ensure user is not using unsupported optional feature policy
- Update: Use virCPUDefUpdateFeature to update/create user requested features
- Other minor fixes
s390-cpu: Remove nodeData and decode
- Completely remove nodeData and decode functions
qemu: qmp query-cpu-model-expansion command
- Cleaned up debug print
- Restructured qemuMonitorJSONGetCPUModelExpansion
- Added more JSON parsing error handling
- CPU model features now parsed via an iterator
- qemuMonitorJSONGetCPUModelExpansion: Fixed double free of model ptr
- Restructure qemuMonitorCPUModelInfoFree
- Other minor fixes
qemu-caps: Get host model directly from Qemu when available
- virQEMUCapsProbeQMPHostCPU: indentation fix
- Fixed rebase error involving a missing 'goto cleanup;'.
- Fix indentation in virQEMUCapsProbeQMPHostCPU
- virQEMUCapsInitHostCPUModel now routes to virQEMUCapsCopyModelFromQEMU or
virQEMUCapsCopyModelFromHost, depending on architecture.
- Restructure hostCpu data in qemu caps cache xml
- Other minor fixes
Collin L. Walling (6):
qemu: qmp query-cpu-model-expansion command
qemu-caps: Get host model directly from Qemu when available
qemu: command: Support new cpu feature argument syntax
test-data: Qemu caps replies and xml for s390x qemu 2.7 and 2.8
tests: qemu capabilites: qemu 2.7 and 2.8 on s390x
tests: domain capabilities: qemu 2.8 on s390x
Jason J. Herne (5):
s390: Cpu driver support for update and compare
s390-cpu: Remove nodeData and decode
docs: document cpu host-passthrough migration issue
tests: qemuxml2argv s390x cpu model
tests: qemuxml2argv cpu feature syntax
docs/formatdomain.html.in | 6 +-
po/POTFILES.in | 1 +
src/cpu/cpu_s390.c | 103 +-
src/qemu/qemu_capabilities.c | 180 +-
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 10 +-
src/qemu/qemu_monitor.c | 62 +
src/qemu/qemu_monitor.h | 22 +
src/qemu/qemu_monitor_json.c | 121 +
src/qemu/qemu_monitor_json.h | 12 +
tests/domaincapsschemadata/qemu_2.8.0.s390x.xml | 159 +
tests/domaincapstest.c | 14 +
.../qemucapabilitiesdata/caps_2.7.0.s390x.replies | 11999 +++++++++++++++++
tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 140 +
.../qemucapabilitiesdata/caps_2.8.0.s390x.replies | 13380 +++++++++++++++++++
tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 286 +
tests/qemucapabilitiestest.c | 4 +
.../qemuxml2argv-cpu-features-post-qcme.args | 19 +
.../qemuxml2argv-cpu-features-post-qcme.xml | 23 +
.../qemuxml2argv-cpu-features-pre-qcme.args | 19 +
.../qemuxml2argv-cpu-features-pre-qcme.xml | 23 +
.../qemuxml2argv-cpu-s390-zEC12.args | 19 +
.../qemuxml2argv-cpu-s390-zEC12.xml | 21 +
tests/qemuxml2argvtest.c | 19 +
tests/testutilsqemu.c | 39 +-
tests/testutilsqemu.h | 1 +
26 files changed, 26642 insertions(+), 41 deletions(-)
create mode 100644 tests/domaincapsschemadata/qemu_2.8.0.s390x.xml
create mode 100644 tests/qemucapabilitiesdata/caps_2.7.0.s390x.replies
create mode 100644 tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml
create mode 100644 tests/qemucapabilitiesdata/caps_2.8.0.s390x.replies
create mode 100644 tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-features-post-qcme.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-features-post-qcme.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-features-pre-qcme.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-features-pre-qcme.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-s390-zEC12.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-s390-zEC12.xml
--
2.7.4
3
29
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
Changes | 4 ++++
Virt.xs | 4 ++++
lib/Sys/Virt/Domain.pm | 26 ++++++++++++++++++++++++++
3 files changed, 34 insertions(+)
diff --git a/Changes b/Changes
index ffb1911..48ac221 100644
--- a/Changes
+++ b/Changes
@@ -5,6 +5,10 @@ Revision history for perl module Sys::Virt
- Add group_name for block iotune
- Add new branch instructions perf event
- Add PERF_PARAM_BRANCH_MISSES constant
+ - Add PERF_PARAM_BUS_CYCLES constant
+ - Add PERF_PARAM_STALLED_CYCLES_FRONTEND constant
+ - Add PERF_PARAM_STALLED_CYCLES_BACKEND constant
+ - Add PERF_PARAM_REF_CPU_CYCLES constant
2.5.0 2016-12-05
diff --git a/Virt.xs b/Virt.xs
index 65f4975..d694eff 100644
--- a/Virt.xs
+++ b/Virt.xs
@@ -8303,6 +8303,10 @@ BOOT:
REGISTER_CONSTANT_STR(VIR_PERF_PARAM_INSTRUCTIONS, PERF_PARAM_INSTRUCTIONS);
REGISTER_CONSTANT_STR(VIR_PERF_PARAM_BRANCH_INSTRUCTIONS, PERF_PARAM_BRANCH_INSTRUCTIONS);
REGISTER_CONSTANT_STR(VIR_PERF_PARAM_BRANCH_MISSES, PERF_PARAM_BRANCH_MISSES);
+ REGISTER_CONSTANT_STR(VIR_PERF_PARAM_BUS_CYCLES, PERF_PARAM_BUS_CYCLES);
+ REGISTER_CONSTANT_STR(VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND, PERF_PARAM_STALLED_CYCLES_FRONTEND);
+ REGISTER_CONSTANT_STR(VIR_PERF_PARAM_STALLED_CYCLES_BACKEND, PERF_PARAM_STALLED_CYCLES_BACKEND);
+ REGISTER_CONSTANT_STR(VIR_PERF_PARAM_REF_CPU_CYCLES, PERF_PARAM_REF_CPU_CYCLES);
REGISTER_CONSTANT_STR(VIR_DOMAIN_BANDWIDTH_IN_AVERAGE, BANDWIDTH_IN_AVERAGE);
REGISTER_CONSTANT_STR(VIR_DOMAIN_BANDWIDTH_IN_PEAK, BANDWIDTH_IN_PEAK);
diff --git a/lib/Sys/Virt/Domain.pm b/lib/Sys/Virt/Domain.pm
index 3d9b106..bd59139 100644
--- a/lib/Sys/Virt/Domain.pm
+++ b/lib/Sys/Virt/Domain.pm
@@ -2783,6 +2783,32 @@ count of branch misses by applications running on the platform.
It corresponds to the "perf.branch_misses" field in the *Stats
APIs.
+=item Sys::Virt::Domain::PERF_PARAM_BUS_CYCLES
+The bus_cycles perf event counter which can be used to measure
+the count of bus cycles by applications running on the platform.
+It corresponds to the "perf.bus_cycles" field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_STALLED_CYCLES_FRONTEND
+The stalled_cycles_frontend perf event counter which can be used
+to measure the count of stalled cpu cycles in the frontend of the
+instruction processor pipeline by applications running on the
+platform. It corresponds to the "perf.stalled_cycles_frontend"
+field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_STALLED_CYCLES_BACKEND
+The stalled_cycles_backend perf event counter which can be used
+to measure the count of stalled cpu cycles in the backend of the
+instruction processor pipeline by application running on the
+platform. It corresponds to the "perf.stalled_cycles_backend"
+field in the *Stats APIs.
+
+=item Sys::Virt::Domain::PERF_PARAM_REF_CPU_CYCLES
+The ref_cpu_cycles perf event counter which can be used to
+measure the count of total cpu cycles not affected by CPU
+frequency scaling by applications running on the platform.
+It corresponds to the "perf.ref_cpu_cycles" field in the
+*Stats APIs.
+
=back
=head2 VCPU FLAGS
--
2.7.4
2
1
This adds a new command to QMP: query-device-slots. It will allow
management software to query possible slots where devices can be
plugged.
This implementation of the command will return:
* Multiple PCI slots per bus, in the case of PCI buses;
* One slot per bus in the case of the other buses;
* One slot for each entry from query-hotpluggable-cpus.
In the example below, I am not sure if the PCIe ports are all
supposed to report all slots, but I didn't find any existing
field in PCIBus that would help me figure out the actual number
of slots in a given PCI bus.
Git tree
--------
This patch needs the previous query-machines series I am working
on. The full tree can be found on the git tree at:
git://github.com/ehabkost/qemu-hacks.git work/query-machines-bus-info
Example output
--------------
The following output was returned by QEMU when running it as:
$ qemu-system-x86_64 -machine q35 \
-readconfig docs/q35-chipset.cfg \
-smp 4,maxcpus=8,sockets=2,cores=2,threads=2
{
"return": [
{
"available": false,
"devices": [
"/machine/unattached/device[30]",
"/machine/unattached/device[29]",
"/machine/unattached/device[28]",
"/machine/unattached/device[27]",
"/machine/unattached/device[26]",
"/machine/unattached/device[25]",
"/machine/unattached/device[24]",
"/machine/unattached/device[23]"
],
"accepted-device-types": [
"i2c-slave"
],
"props": {
"bus": "/machine/unattached/device[22]/i2c"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"ide-device"
],
"props": {
"bus": "/machine/unattached/device[20]/ide.4"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"ide-device"
],
"props": {
"bus": "/machine/unattached/device[20]/ide.5"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"ide-device"
],
"props": {
"bus": "/machine/unattached/device[20]/ide.0"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"ide-device"
],
"props": {
"bus": "/machine/unattached/device[20]/ide.1"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": false,
"devices": [
"/machine/unattached/device[21]"
],
"accepted-device-types": [
"ide-device"
],
"props": {
"bus": "/machine/unattached/device[20]/ide.2"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"ide-device"
],
"props": {
"bus": "/machine/unattached/device[20]/ide.3"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": false,
"devices": [
"/machine/unattached/device[8]",
"/machine/q35/ioapic",
"/machine/q35",
"/machine/fw_cfg",
"/machine/unattached/device[1]"
],
"accepted-device-types": [
"sys-bus-device"
],
"props": {
"bus": "/machine/unattached/sysbus"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": false,
"devices": [
"/machine/unattached/device[19]",
"/machine/unattached/device[18]",
"/machine/unattached/device[17]",
"/machine/unattached/device[16]",
"/machine/unattached/device[15]",
"/machine/unattached/device[14]",
"/machine/unattached/device[13]",
"/machine/unattached/device[12]",
"/machine/unattached/device[11]",
"/machine/unattached/device[10]",
"/machine/unattached/device[9]",
"/machine/unattached/device[7]",
"/machine/unattached/device[6]"
],
"accepted-device-types": [
"isa-device"
],
"props": {
"bus": "/machine/unattached/device[5]/isa.0"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": false,
"devices": [
"/machine/q35/mch"
],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 0
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/unattached/device[31]"
],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 8
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/unattached/device[32]"
],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 16
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 24
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 32
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 40
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 48
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 56
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 64
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 72
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 80
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 88
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 96
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 104
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 112
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 120
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 128
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 136
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 144
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 152
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 160
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 168
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 176
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 184
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 192
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 200
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/peripheral/ich9-uhci-4"
],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 208
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/peripheral/ich9-hda-audio"
],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 216
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/peripheral/ich9-pcie-port-1"
],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 224
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/peripheral/ich9-uhci-1"
],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 232
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/peripheral/ich9-pci-bridge"
],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 240
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/unattached/device[5]"
],
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
],
"props": {
"bus": "/machine/q35/pcie.0",
"addr": 248
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 0
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 8
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 16
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 24
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 32
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 40
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 48
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 56
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 64
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 72
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 80
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 88
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 96
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 104
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 112
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 120
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 128
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 136
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 144
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 152
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 160
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 168
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 176
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 184
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 192
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 200
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 208
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 216
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 224
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 232
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 240
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-1/ich9-pcie-port-1",
"addr": 248
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 0
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 8
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 16
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 24
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 32
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 40
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 48
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 56
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 64
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 72
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 80
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 88
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 96
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 104
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 112
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 120
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 128
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 136
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 144
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 152
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 160
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 168
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 176
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 184
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 192
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 200
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 208
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 216
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 224
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 232
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 240
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-2/ich9-pcie-port-2",
"addr": 248
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 0
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 8
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 16
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 24
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 32
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 40
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 48
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 56
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 64
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 72
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 80
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 88
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 96
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 104
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 112
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 120
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 128
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 136
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 144
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 152
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 160
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 168
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 176
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 184
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 192
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 200
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 208
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 216
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 224
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 232
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 240
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-3/ich9-pcie-port-3",
"addr": 248
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 0
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 8
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 16
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 24
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 32
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 40
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 48
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 56
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 64
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 72
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 80
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 88
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 96
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 104
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 112
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 120
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 128
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 136
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 144
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 152
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 160
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 168
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 176
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 184
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 192
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 200
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 208
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 216
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 224
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 232
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 240
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"pci-express-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pcie-port-4/ich9-pcie-port-4",
"addr": 248
},
"hotpluggable": true,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 0
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 8
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 16
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 24
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 32
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 40
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 48
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 56
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 64
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 72
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 80
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 88
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 96
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 104
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 112
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 120
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 128
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 136
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 144
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 152
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 160
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 168
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 176
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 184
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 192
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 200
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 208
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 216
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 224
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 232
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 240
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"legacy-pci-device"
],
"props": {
"bus": "/machine/peripheral/ich9-pci-bridge/ich9-pci-bridge",
"addr": 248
},
"hotpluggable": false,
"type": "pci",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"usb-device"
],
"props": {
"bus": "/machine/peripheral/ich9-ehci-1/ich9-ehci-1.0"
},
"hotpluggable": true,
"type": "generic"
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"usb-device"
],
"props": {
"bus": "/machine/peripheral/ich9-ehci-2/ich9-ehci-2.0"
},
"hotpluggable": true,
"type": "generic"
},
{
"available": false,
"devices": [],
"accepted-device-types": [
"hda-codec"
],
"props": {
"bus": "/machine/peripheral/ich9-hda-audio/ich9-hda-audio.0"
},
"hotpluggable": false,
"type": "generic"
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": {
"socket-id": 1,
"core-id": 1,
"thread-id": 1
},
"hotpluggable": true,
"type": "cpu",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": {
"socket-id": 1,
"core-id": 1,
"thread-id": 0
},
"hotpluggable": true,
"type": "cpu",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": {
"socket-id": 1,
"core-id": 0,
"thread-id": 1
},
"hotpluggable": true,
"type": "cpu",
"max-devices": 1
},
{
"available": true,
"devices": [],
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": {
"socket-id": 1,
"core-id": 0,
"thread-id": 0
},
"hotpluggable": true,
"type": "cpu",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/unattached/device[4]"
],
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": {
"socket-id": 0,
"core-id": 1,
"thread-id": 1
},
"hotpluggable": true,
"type": "cpu",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/unattached/device[3]"
],
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": {
"socket-id": 0,
"core-id": 1,
"thread-id": 0
},
"hotpluggable": true,
"type": "cpu",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/unattached/device[2]"
],
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": {
"socket-id": 0,
"core-id": 0,
"thread-id": 1
},
"hotpluggable": true,
"type": "cpu",
"max-devices": 1
},
{
"available": false,
"devices": [
"/machine/unattached/device[0]"
],
"accepted-device-types": [
"qemu64-x86_64-cpu"
],
"props": {
"socket-id": 0,
"core-id": 0,
"thread-id": 0
},
"hotpluggable": true,
"type": "cpu",
"max-devices": 1
}
]
}
Signed-off-by: Eduardo Habkost <ehabkost(a)redhat.com>
---
qapi-schema.json | 114 +++++++++++++++++++++++++++++++++++++++++++++++++
include/hw/qdev-core.h | 6 +++
hw/core/bus.c | 49 +++++++++++++++++++++
hw/pci/pci.c | 106 +++++++++++++++++++++++++++++++++------------
qdev-monitor.c | 86 ++++++++++++++++++++++++++++++++++---
5 files changed, 328 insertions(+), 33 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index d48ff3f..484d91e 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3166,6 +3166,120 @@
{ 'command': 'closefd', 'data': {'fdname': 'str'} }
##
+# @DeviceSlotType:
+#
+# Type of device slot
+#
+# @generic: Generic device slot, with no bus-specific information
+# @pci: PCI device slot
+# @cpu: CPU device slot
+##
+{ 'enum': 'DeviceSlotType',
+ 'data': ['generic', 'pci', 'cpu'] }
+
+##
+# @DeviceSlotInfo:
+#
+# Information on a slot where devices can be plugged. Some buses
+# are represented as a single slot that can support multiple devices,
+# and some buses have multiple slots that are identified by arguments
+# to @device_add.
+#
+# @bus: ID of the bus object where the device can be plugged. Optional,
+# as some devices don't need a bus to be plugged (e.g. CPUs).
+# Can be copied to the "bus" argument to @device_add.
+#
+# @type: type of device slot.
+#
+# @accepted-device-types: List of device types accepted by the slot.
+# Any device plugged to the slot should implement
+# one of the accepted device types.
+#
+# @max-devices: #optional maximum number of devices that can be plugged
+# to the slot.
+#
+# @devices: List of QOM paths for devices that are already plugged.
+#
+# @available: If false, the slot is not available for plugging any device.
+# This value can change at runtime if condition changes
+# (e.g. if the device becomes full, or if the machine
+# was already initialized and the slot doesn't support
+# hotplug).
+#
+# @hotpluggable: If true, the slot accepts hotplugged devices.
+#
+# DeviceSlotInfo structs always have a @props member, whose members
+# can be directly copied to the arguments to @device_add.
+##
+{ 'union': 'DeviceSlotInfo',
+ 'base': { 'type': 'DeviceSlotType',
+ 'accepted-device-types': [ 'str' ],
+ '*max-devices': 'int', 'devices': [ 'str' ],
+ 'available': 'bool', 'hotpluggable': 'bool' },
+ 'discriminator': 'type',
+ 'data': { 'generic': 'GenericSlotInfo',
+ 'pci': 'PCISlotInfo',
+ 'cpu': 'CPUSlotInfo' } }
+
+##
+# @GenericSlotProperties:
+##
+{ 'struct': 'GenericSlotProperties',
+ 'data': { 'bus': 'str' } }
+
+
+##
+# @GenericSlotInfo:
+#
+# Generic slot information, with no bus-specific information
+##
+{ 'struct': 'GenericSlotInfo',
+ 'data': { 'props': 'GenericSlotProperties' } }
+
+##
+# @PCIDeviceSlotProperties:
+#
+# Properties that can be set when plugging a PCI device.
+#
+# @addr: "addr" argument to @device_add.
+#
+#FIXME: replace @addr with slot and function properties.
+##
+{ 'struct': 'PCIDeviceSlotProperties',
+ 'data': { 'bus': 'str', 'addr': 'int' } }
+
+##
+# @PCISlotInfo:
+#
+# Information on a PCI device slot.
+#
+# @props: The @device_add arguments that can be used when plugging
+# the device.
+##
+{ 'struct': 'PCISlotInfo',
+ 'data': { 'props': 'PCIDeviceSlotProperties' } }
+
+##
+# @CPUSlotInfo:
+#
+# Information on a CPU device slot.
+#
+# @props: The @device_add arguments that can be used when plugging
+# the device.
+##
+{ 'struct': 'CPUSlotInfo',
+ 'data': { 'props': 'CpuInstanceProperties' } }
+
+##
+# @query-device-slots:
+#
+# Return the list of possible slots for plugging devices using
+# @device_add.
+##
+{ 'command': 'query-device-slots',
+ 'returns': [ 'DeviceSlotInfo' ] }
+
+##
# @MachineBusInfo
#
# Information about a bus present on a machine.
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index a7f9ac4..7a87234 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -214,6 +214,10 @@ struct BusClass {
* but on some cases bus instances may override it.
*/
const char *device_type;
+
+ /*TOD: write doc */
+ DeviceSlotInfoList *(*enumerate_slots)(BusState *bus, Error **errp);
+
};
typedef struct BusChild {
@@ -412,4 +416,6 @@ static inline bool qbus_is_hotpluggable(BusState *bus)
void device_listener_register(DeviceListener *listener);
void device_listener_unregister(DeviceListener *listener);
+bool qbus_is_full(BusState *bus);
+
#endif
diff --git a/hw/core/bus.c b/hw/core/bus.c
index d2bf717..58b5c3d 100644
--- a/hw/core/bus.c
+++ b/hw/core/bus.c
@@ -21,6 +21,7 @@
#include "qemu-common.h"
#include "hw/qdev.h"
#include "qapi/error.h"
+#include "qapi/clone-visitor.h"
#include "qapi-visit.h"
static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
@@ -225,12 +226,60 @@ static void bus_get_device_type(Object *obj, Visitor *v,
visit_type_strList(v, NULL, &bus->accepted_device_types, errp);
}
+bool qbus_is_full(BusState *bus)
+{
+ BusClass *bus_class = BUS_GET_CLASS(bus);
+ return bus_class->max_dev && bus->max_index >= bus_class->max_dev;
+}
+
+/* Generic slot enumeration function: will return a single slot
+ * for the bus, with max_devices set to BusClass::max_dev, if set.
+ */
+static DeviceSlotInfoList *bus_generic_enumerate_slots(BusState *bus, Error **errp)
+{
+ Error *local_err = NULL;
+ BusClass *bc = BUS_GET_CLASS(bus);
+ strList **devlist;
+ BusChild *kid;
+ DeviceSlotInfoList *r = g_new0(DeviceSlotInfoList, 1);
+
+ r->value = g_new0(DeviceSlotInfo, 1);
+ r->value->type = DEVICE_SLOT_TYPE_GENERIC;
+ r->value->has_max_devices = bc->max_dev > 0;
+ r->value->max_devices = bc->max_dev;
+ r->value->accepted_device_types = QAPI_CLONE(strList, bus->accepted_device_types);
+ r->value->u.generic.props = g_new0(GenericSlotProperties, 1);
+ r->value->u.generic.props->bus = object_get_canonical_path(OBJECT(bus));
+
+ devlist = &r->value->devices;
+ QTAILQ_FOREACH(kid, &bus->children, sibling) {
+ DeviceState *dev = kid->child;
+ strList *item = g_new0(strList, 1);
+ item->value = object_get_canonical_path(OBJECT(dev));
+ *devlist = item;
+ devlist = &item->next;
+ }
+ r->value->hotpluggable = qbus_is_hotpluggable(bus);
+
+ /* Conditions that make a bus unavailable:
+ * - Bus already full
+ * - Hotplug when the bus is not hotpluggable
+ */
+ r->value->available =
+ !(qbus_is_full(bus) ||
+ (qdev_hotplug && !qbus_is_hotpluggable(bus)));
+
+ error_propagate(errp, local_err);
+ return r;
+}
+
static void bus_class_init(ObjectClass *class, void *data)
{
BusClass *bc = BUS_CLASS(class);
class->unparent = bus_unparent;
bc->get_fw_dev_path = default_bus_get_fw_dev_path;
+ bc->enumerate_slots = bus_generic_enumerate_slots;
object_class_property_add(class, "accepted-device-types", "strList",
bus_get_device_type, NULL, NULL, NULL,
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 2eac71a..9bcc116 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -41,6 +41,7 @@
#include "hw/hotplug.h"
#include "hw/boards.h"
#include "qemu/cutils.h"
+#include "qapi/clone-visitor.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
@@ -141,6 +142,8 @@ static uint16_t pcibus_numa_node(PCIBus *bus)
return NUMA_NODE_UNASSIGNED;
}
+static DeviceSlotInfoList *pci_bus_enumerate_slots(BusState *bus, Error **errp);
+
static void pci_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *k = BUS_CLASS(klass);
@@ -156,6 +159,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
* but overrides BusClass::device_type to INTERFACE_PCIE_DEVICE
*/
k->device_type = INTERFACE_LEGACY_PCI_DEVICE;
+ k->enumerate_slots = pci_bus_enumerate_slots;
pbc->is_root = pcibus_is_root;
pbc->bus_num = pcibus_num;
@@ -967,6 +971,81 @@ uint16_t pci_requester_id(PCIDevice *dev)
return pci_req_id_cache_extract(&dev->requester_id_cache);
}
+static bool pci_bus_has_pcie_upstream_port(PCIBus *bus)
+{
+ PCIDevice *parent_dev = pci_bridge_get_device(bus);
+
+ /* Device associated with an upstream port.
+ * As there are several types of these, it's easier to check the
+ * parent device: upstream ports are always connected to
+ * root or downstream ports.
+ */
+ return parent_dev &&
+ pci_is_express(parent_dev) &&
+ parent_dev->exp.exp_cap &&
+ (pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_ROOT_PORT ||
+ pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_DOWNSTREAM);
+}
+
+static PCIDevice *pci_bus_get_function_0(PCIBus *bus, int devfn)
+{
+ if(pci_bus_has_pcie_upstream_port(bus)) {
+ /* With an upstream PCIe port, we only support 1 device at slot 0 */
+ return bus->devices[0];
+ } else {
+ /* Other bus types might support multiple devices at slots 0-31 */
+ return bus->devices[PCI_DEVFN(PCI_SLOT(devfn), 0)];
+ }
+}
+
+PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
+{
+ return pci_bus_get_function_0(pci_dev->bus, pci_dev->devfn);
+}
+
+static DeviceSlotInfoList *pci_bus_enumerate_slots(BusState *bus, Error **errp)
+{
+ PCIBus *pb = PCI_BUS(bus);
+ int devfn;
+ DeviceSlotInfoList *r = NULL;
+ DeviceSlotInfoList **next = &r;
+
+ for(devfn = pb->devfn_min; devfn < ARRAY_SIZE(pb->devices);
+ devfn += PCI_FUNC_MAX) {
+ DeviceSlotInfoList *i = g_new0(DeviceSlotInfoList, 1);
+ i->value = g_new0(DeviceSlotInfo, 1);
+ i->value->type = DEVICE_SLOT_TYPE_PCI;
+ i->value->has_max_devices = true;
+ i->value->max_devices = 1;
+ i->value->u.pci.props = g_new0(PCIDeviceSlotProperties, 1);
+ i->value->u.pci.props->bus = object_get_canonical_path(OBJECT(bus));
+ i->value->u.pci.props->addr = devfn;
+ /*TODO: add info about accepting only bridges on extra PCI root buses */
+ i->value->accepted_device_types = QAPI_CLONE(strList, bus->accepted_device_types);
+ if (pb->devices[devfn]) {
+ i->value->devices = g_new0(strList, 1);
+ i->value->devices->value =
+ object_get_canonical_path(OBJECT(pb->devices[devfn]));
+ }
+
+ i->value->hotpluggable = qbus_is_hotpluggable(bus);
+ /* Conditions that make a devfn unavailable:
+ * - Hotplug when function 0 is already occupied
+ * - devfn already occupied by a device
+ * - Hotplug when the bus is not hotpluggable
+ */
+ i->value->available =
+ !((qdev_hotplug && pci_bus_get_function_0(pb, devfn)) ||
+ (pb->devices[devfn]) ||
+ (qdev_hotplug && !qbus_is_hotpluggable(bus)));
+
+ *next = i;
+ next = &i->next;
+ }
+
+ return r;
+}
+
/* -1 for devfn means auto assign */
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
const char *name, int devfn,
@@ -2607,33 +2686,6 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range)
pci_for_each_device_under_bus(bus, pci_dev_get_w64, range);
}
-static bool pcie_has_upstream_port(PCIDevice *dev)
-{
- PCIDevice *parent_dev = pci_bridge_get_device(dev->bus);
-
- /* Device associated with an upstream port.
- * As there are several types of these, it's easier to check the
- * parent device: upstream ports are always connected to
- * root or downstream ports.
- */
- return parent_dev &&
- pci_is_express(parent_dev) &&
- parent_dev->exp.exp_cap &&
- (pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_ROOT_PORT ||
- pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_DOWNSTREAM);
-}
-
-PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
-{
- if(pcie_has_upstream_port(pci_dev)) {
- /* With an upstream PCIe port, we only support 1 device at slot 0 */
- return pci_dev->bus->devices[0];
- } else {
- /* Other bus types might support multiple devices at slots 0-31 */
- return pci_dev->bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
- }
-}
-
MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
{
MSIMessage msg;
diff --git a/qdev-monitor.c b/qdev-monitor.c
index c73410c..b4071c4 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -29,6 +29,8 @@
#include "qemu/error-report.h"
#include "qemu/help_option.h"
#include "sysemu/block-backend.h"
+#include "qapi/clone-visitor.h"
+#include "hw/boards.h"
/*
* Aliases were a bad idea from the start. Let's keep them
@@ -399,12 +401,6 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
return NULL;
}
-static inline bool qbus_is_full(BusState *bus)
-{
- BusClass *bus_class = BUS_GET_CLASS(bus);
- return bus_class->max_dev && bus->max_index >= bus_class->max_dev;
-}
-
/*
* Search the tree rooted at @bus for a bus.
* If @name, search for a bus with that name. Note that bus names
@@ -631,6 +627,84 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
return dev;
}
+typedef struct SlotListState {
+ DeviceSlotInfoList *result;
+ DeviceSlotInfoList **next;
+ Error *err;
+} SlotListState;
+
+static int walk_bus(Object *obj, void *opaque)
+{
+ SlotListState *s = opaque;
+ if (object_dynamic_cast(obj, TYPE_BUS)) {
+ BusState *bus = BUS(obj);
+ BusClass *bc = BUS_GET_CLASS(bus);
+ DeviceSlotInfoList *l = bc->enumerate_slots(bus, &s->err);
+ *s->next = l;
+ for (; l; l = l->next) {
+ s->next = &l->next;
+ }
+ if (s->err) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+DeviceSlotInfoList *qmp_query_device_slots(Error **errp)
+{
+ SlotListState s = { };
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+
+ s.next = &s.result;
+
+ /* We build the device slot list from two sources:
+ * 1) Calling the BusClass::enumerate_slots() method on all buses;
+ * 2) The return value of MachineClass::query_hotpluggable_cpus()
+ */
+
+
+ object_child_foreach_recursive(qdev_get_machine(), walk_bus, &s);
+ if (s.err) {
+ goto out;
+ }
+
+ if (mc->query_hotpluggable_cpus) {
+ HotpluggableCPUList *hcl = mc->query_hotpluggable_cpus(ms);
+ HotpluggableCPUList *i;
+
+ for (i = hcl; i; i = i->next) {
+ DeviceSlotInfoList *r = g_new0(DeviceSlotInfoList, 1);
+ HotpluggableCPU *hc = i->value;
+ r->value = g_new0(DeviceSlotInfo, 1);
+ r->value->type = DEVICE_SLOT_TYPE_CPU;
+ r->value->accepted_device_types = g_new0(strList, 1);
+ r->value->accepted_device_types->value = g_strdup(hc->type);
+ r->value->has_max_devices = true;
+ r->value->max_devices = 1;
+ r->value->available = !hc->has_qom_path;
+ /*TODO: should it be always true? */
+ r->value->hotpluggable = true;
+
+ if (hc->has_qom_path) {
+ r->value->devices = g_new0(strList, 1);
+ r->value->devices->value = g_strdup(hc->qom_path);
+ }
+ r->value->u.cpu.props = QAPI_CLONE(CpuInstanceProperties,
+ hc->props);
+ *s.next = r;
+ s.next = & r->next;
+ }
+
+ qapi_free_HotpluggableCPUList(hcl);
+ }
+
+out:
+ error_propagate(errp, s.err);
+ return s.result;
+}
+
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
static void qbus_print(Monitor *mon, BusState *bus, int indent);
--
2.7.4
--
Eduardo
4
18
16 Dec '16
This does two simplifications to the perf events code.
Daniel P. Berrange (2):
perf: get rid of pointless virPerfGetEventAttr() method
perf: get rid of pointless virPerfGetEvent() method
src/util/virperf.c | 162 +++++++++++++++++++++--------------------------------
1 file changed, 65 insertions(+), 97 deletions(-)
--
2.9.3
2
3
Obviously my latest patch set broke some stuff on FreeBSD.
Michal Privoznik (3):
configure: Link witch -lacl only on linux
qemu: Mark more namespace code linux-only
virfile: Support bind mount only on linux
configure.ac | 2 +-
src/qemu/qemu_domain.c | 372 +++++++++++++++++++++++++------------------------
src/util/virfile.c | 6 +-
3 files changed, 195 insertions(+), 185 deletions(-)
--
2.11.0
2
7
Add support and documentation for generic
perf events like bus_cycles, stalled_cycles_frontend,
stalled_cycles_backend and ref_cpu_cycles.
Nitesh Konkar (4):
perf: add bus_cycles perf event support
perf: add stalled_cycles_frontend perf event support
perf: add stalled_cycles_backend perf event support
perf: add ref_cpu_cycles perf event support
docs/formatdomain.html.in | 24 +++++++++++++++++
docs/news.html.in | 6 +++--
docs/schemas/domaincommon.rng | 4 +++
include/libvirt/libvirt-domain.h | 40 +++++++++++++++++++++++++++++
src/libvirt-domain.c | 11 ++++++++
src/qemu/qemu_driver.c | 4 +++
src/util/virperf.c | 16 +++++++++++-
src/util/virperf.h | 4 +++
tests/genericxml2xmlindata/generic-perf.xml | 4 +++
tools/virsh.pod | 16 +++++++++++-
10 files changed, 125 insertions(+), 4 deletions(-)
--
1.9.3
3
14
This adds a new command to QMP: query-device-slots. It will allow
management software to query possible slots where devices can be
plugged.
This implementation of the command will return:
* Multiple PCI slots per bus, in the case of PCI buses;
* One slot per bus for the other buses (that don't
implement slot enumeration yet);
* One slot for each entry from query-hotpluggable-cpus.
Git tree
--------
This patch needs the previous query-machines series I am working
on. The full tree can be found on the git tree at:
git://github.com/ehabkost/qemu-hacks.git work/query-machines-bus-info
Example output
--------------
The following output was returned by QEMU when running it as:
$ qemu-system-x86_64 -machine q35 \
-readconfig docs/q35-chipset.cfg \
-smp 4,maxcpus=8,sockets=2,cores=2,threads=2
{
"return": [
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "i2c"
},
"type": "non-slot",
"accepted-device-types": [
"i2c-slave"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ide.4"
},
"type": "non-slot",
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ide.5"
},
"type": "non-slot",
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ide.0"
},
"type": "non-slot",
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ide.1"
},
"type": "non-slot",
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ide.2"
},
"type": "non-slot",
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ide.3"
},
"type": "non-slot",
"accepted-device-types": [
"ide-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "main-system-bus"
},
"type": "non-slot",
"accepted-device-types": [
"sys-bus-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "isa.0"
},
"type": "non-slot",
"accepted-device-types": [
"isa-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 0
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 1
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 2
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 3
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 4
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 5
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 6
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 7
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 8
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 9
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 10
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 11
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 12
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 13
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 14
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 15
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 16
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 17
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 18
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 19
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 20
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 21
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 22
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 23
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 24
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 25
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 26
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 27
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 28
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 29
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 30
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "pcie.0",
"device-number": 31
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device",
"pci-express-device"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"bus": "ich9-pcie-port-1",
"device-number": 0
},
"type": "pci",
"accepted-device-types": [
"pci-express-device"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"bus": "ich9-pcie-port-2",
"device-number": 0
},
"type": "pci",
"accepted-device-types": [
"pci-express-device"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"bus": "ich9-pcie-port-3",
"device-number": 0
},
"type": "pci",
"accepted-device-types": [
"pci-express-device"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"bus": "ich9-pcie-port-4",
"device-number": 0
},
"type": "pci",
"accepted-device-types": [
"pci-express-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 0
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 1
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 2
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 3
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 4
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 5
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 6
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 7
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 8
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 9
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 10
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 11
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 12
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 13
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 14
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 15
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 16
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 17
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 18
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 19
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 20
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 21
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 22
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 23
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 24
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 25
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 26
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 27
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 28
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 29
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 30
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-pci-bridge",
"device-number": 31
},
"type": "pci",
"accepted-device-types": [
"legacy-pci-device"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"bus": "ich9-ehci-1.0"
},
"type": "non-slot",
"accepted-device-types": [
"usb-device"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"bus": "ich9-ehci-2.0"
},
"type": "non-slot",
"accepted-device-types": [
"usb-device"
]
},
{
"available": false,
"hotpluggable": false,
"props": {
"bus": "ich9-hda-audio.0"
},
"type": "non-slot",
"accepted-device-types": [
"hda-codec"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"socket-id": 1,
"core-id": 1,
"thread-id": 1
},
"type": "cpu",
"accepted-device-types": [
"qemu64-x86_64-cpu"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"socket-id": 1,
"core-id": 1,
"thread-id": 0
},
"type": "cpu",
"accepted-device-types": [
"qemu64-x86_64-cpu"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"socket-id": 1,
"core-id": 0,
"thread-id": 1
},
"type": "cpu",
"accepted-device-types": [
"qemu64-x86_64-cpu"
]
},
{
"available": true,
"hotpluggable": true,
"props": {
"socket-id": 1,
"core-id": 0,
"thread-id": 0
},
"type": "cpu",
"accepted-device-types": [
"qemu64-x86_64-cpu"
]
},
{
"available": false,
"hotpluggable": true,
"props": {
"socket-id": 0,
"core-id": 1,
"thread-id": 1
},
"type": "cpu",
"accepted-device-types": [
"qemu64-x86_64-cpu"
]
},
{
"available": false,
"hotpluggable": true,
"props": {
"socket-id": 0,
"core-id": 1,
"thread-id": 0
},
"type": "cpu",
"accepted-device-types": [
"qemu64-x86_64-cpu"
]
},
{
"available": false,
"hotpluggable": true,
"props": {
"socket-id": 0,
"core-id": 0,
"thread-id": 1
},
"type": "cpu",
"accepted-device-types": [
"qemu64-x86_64-cpu"
]
},
{
"available": false,
"hotpluggable": true,
"props": {
"socket-id": 0,
"core-id": 0,
"thread-id": 0
},
"type": "cpu",
"accepted-device-types": [
"qemu64-x86_64-cpu"
]
}
]
}
Cc: Marcel Apfelbaum <marcel(a)redhat.com>
Cc: Markus Armbruster <armbru(a)redhat.com>
Cc: libvir-list(a)redhat.com,
Cc: Igor Mammedov <imammedo(a)redhat.com>
Cc: Laine Stump <laine(a)redhat.com>
Cc: "Michael S. Tsirkin" <mst(a)redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost(a)redhat.com>
---
Changes v1 -> v2:
* Don't show sysbus unless has_dynamic_sysbus is set for the
machine type
* Removed max-devices and devices properties
* Introduced "non-slot" slot type, to explicitly indicate
we are returning info on a bus that doesn't implement slot
enumeration yet.
* Return bus name instead of full QOM path on "bus" field
* PCI: Replaced "addr" property (string parsed by property
setter) with "device-number" uint32 property
* PCI: return only one slot for PCIe ports
---
qapi-schema.json | 131 +++++++++++++++++++++++++++++++++++++++
include/hw/qdev-core.h | 6 ++
hw/core/bus.c | 35 +++++++++++
hw/pci/pci.c | 165 +++++++++++++++++++++++++++++++++++++++++--------
qdev-monitor.c | 88 ++++++++++++++++++++++++--
5 files changed, 392 insertions(+), 33 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index d48ff3f..50e09f5 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3166,6 +3166,137 @@
{ 'command': 'closefd', 'data': {'fdname': 'str'} }
##
+# @DeviceSlotType:
+#
+# Type of device slot
+#
+# @non-slot: Slot type representing a bus that doesn't return any
+# specific slot information yet.
+# @pci: PCI device slot
+# @cpu: CPU device slot
+#
+#TODO: try to find a better name for non-slot. "generic-bus", maybe?
+##
+{ 'enum': 'DeviceSlotType',
+ 'data': ['non-slot', 'pci', 'cpu'] }
+
+##
+# @DeviceSlotInfo:
+#
+# Information on a slot where devices can be plugged.
+#
+# @type: type of device slot.
+#
+# @accepted-device-types: List of device types accepted by the slot.
+# Any device plugged to the slot should implement
+# one of the accepted device types.
+#
+# @available: If false, the slot is not available for plugging any device.
+# This value can change at runtime if condition changes
+# (e.g. if the slot becomes full, or if the machine
+# was already initialized and the slot doesn't support
+# hotplug).
+#
+# @hotpluggable: If true, the slot accepts hotplugged devices.
+#
+# @props: The arguments that should be given to @device_add if plugging
+# a device to this slot.
+#
+# For specific rules about what can be plugged on each type of slot,
+# see the type-specific structs (@NonSlotInfo, @PCISlotInfo,
+# @CPUSlotInfo).
+##
+{ 'union': 'DeviceSlotInfo',
+ 'base': { 'type': 'DeviceSlotType',
+ 'accepted-device-types': [ 'str' ],
+ 'available': 'bool', 'hotpluggable': 'bool' },
+ 'discriminator': 'type',
+ 'data': { 'non-slot': 'NonSlotInfo',
+ 'pci': 'PCISlotInfo',
+ 'cpu': 'CPUSlotInfo' } }
+
+##
+# @NonSlotProperties:
+#
+# Arguments to @device_add when plugging a device to a bus that
+# doesn't return specific slot info yet.
+#
+# @bus: "bus" argument to @device_add.
+#
+# Slots returned as type=non-slot might require extra arguments to
+# be set to specify the device address, but they are not covered by
+# NonSlotInfoProperties.
+##
+{ 'struct': 'NonSlotProperties',
+ 'data': { 'bus': 'str' } }
+
+
+##
+# @NonSlotInfo:
+#
+# Generic entry representing a bus that doesn't support slot enumeration
+# yet. Slots of this type should be replaced by more specific slot types
+# in future QEMU versions.
+#
+# Slots of this type may or may not support multiple devices.
+#
+# @props: The arguments that should be given to @device_add if plugging
+# a device to this slot. The list of properties might be incomplete
+# in case the bus requires additional parameters to be provided.
+##
+{ 'struct': 'NonSlotInfo',
+ 'data': { 'props': 'NonSlotProperties' } }
+
+##
+# @PCIDeviceSlotProperties:
+#
+# Arguments to @device_add when plugging a device to a PCI slot.
+#
+# @bus: "bus" argument to @device_add.
+# @slot: "device-number" argument to @device_add. PCI device
+# number (sometimes called "slot").
+#
+##
+{ 'struct': 'PCIDeviceSlotProperties',
+ 'data': { 'bus': 'str', 'device-number': 'int' } }
+
+##
+# @PCISlotInfo:
+#
+# Information on a PCI device slot.
+#
+# @props: The arguments that should be given to @device_add if plugging
+# a device to this slot.
+#
+# PCI device slots become unavailable after a device is plugged to
+# function 0.
+##
+{ 'struct': 'PCISlotInfo',
+ 'data': { 'props': 'PCIDeviceSlotProperties' } }
+
+##
+# @CPUSlotInfo:
+#
+# Information on a CPU device slot.
+#
+# @props: The arguments that should be given to @device_add if plugging
+# a device to this slot.
+#
+# CPU slots become unavailable after one device is plugged to them.
+##
+{ 'struct': 'CPUSlotInfo',
+ 'data': { 'props': 'CpuInstanceProperties' } }
+
+##
+# @query-device-slots:
+#
+# Return the list of possible slots for plugging devices using
+# @device_add.
+##
+{ 'command': 'query-device-slots',
+ 'returns': [ 'DeviceSlotInfo' ] }
+
+##
# @MachineBusInfo
#
# Information about a bus present on a machine.
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index a7f9ac4..2cb043a 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -214,6 +214,10 @@ struct BusClass {
* but on some cases bus instances may override it.
*/
const char *device_type;
+
+ /*TODO: write doc */
+ DeviceSlotInfoList *(*enumerate_slots)(BusState *bus, Error **errp);
+
};
typedef struct BusChild {
@@ -412,4 +416,6 @@ static inline bool qbus_is_hotpluggable(BusState *bus)
void device_listener_register(DeviceListener *listener);
void device_listener_unregister(DeviceListener *listener);
+bool qbus_is_full(BusState *bus);
+
#endif
diff --git a/hw/core/bus.c b/hw/core/bus.c
index d2bf717..451fa46 100644
--- a/hw/core/bus.c
+++ b/hw/core/bus.c
@@ -21,6 +21,7 @@
#include "qemu-common.h"
#include "hw/qdev.h"
#include "qapi/error.h"
+#include "qapi/clone-visitor.h"
#include "qapi-visit.h"
static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
@@ -225,12 +226,46 @@ static void bus_get_device_type(Object *obj, Visitor *v,
visit_type_strList(v, NULL, &bus->accepted_device_types, errp);
}
+bool qbus_is_full(BusState *bus)
+{
+ BusClass *bus_class = BUS_GET_CLASS(bus);
+ return bus_class->max_dev && bus->max_index >= bus_class->max_dev;
+}
+
+/* Generic slot enumeration function that will return a generic-slot slot type.
+ */
+static DeviceSlotInfoList *bus_generic_enumerate_slots(BusState *bus, Error **errp)
+{
+ Error *local_err = NULL;
+ DeviceSlotInfoList *r = g_new0(DeviceSlotInfoList, 1);
+
+ r->value = g_new0(DeviceSlotInfo, 1);
+ r->value->type = DEVICE_SLOT_TYPE_NON_SLOT;
+ r->value->accepted_device_types = QAPI_CLONE(strList, bus->accepted_device_types);
+ r->value->u.non_slot.props = g_new0(NonSlotProperties, 1);
+ r->value->u.non_slot.props->bus = g_strdup(bus->name);
+
+ r->value->hotpluggable = qbus_is_hotpluggable(bus);
+
+ /* Conditions that make a bus unavailable:
+ * - Bus already full
+ * - Hotplug when the bus is not hotpluggable
+ */
+ r->value->available =
+ !(qbus_is_full(bus) ||
+ (qdev_hotplug && !qbus_is_hotpluggable(bus)));
+
+ error_propagate(errp, local_err);
+ return r;
+}
+
static void bus_class_init(ObjectClass *class, void *data)
{
BusClass *bc = BUS_CLASS(class);
class->unparent = bus_unparent;
bc->get_fw_dev_path = default_bus_get_fw_dev_path;
+ bc->enumerate_slots = bus_generic_enumerate_slots;
object_class_property_add(class, "accepted-device-types", "strList",
bus_get_device_type, NULL, NULL, NULL,
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 2eac71a..7870af9 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -41,6 +41,7 @@
#include "hw/hotplug.h"
#include "hw/boards.h"
#include "qemu/cutils.h"
+#include "qapi/clone-visitor.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
@@ -141,6 +142,8 @@ static uint16_t pcibus_numa_node(PCIBus *bus)
return NUMA_NODE_UNASSIGNED;
}
+static DeviceSlotInfoList *pci_bus_enumerate_slots(BusState *bus, Error **errp);
+
static void pci_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *k = BUS_CLASS(klass);
@@ -156,6 +159,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
* but overrides BusClass::device_type to INTERFACE_PCIE_DEVICE
*/
k->device_type = INTERFACE_LEGACY_PCI_DEVICE;
+ k->enumerate_slots = pci_bus_enumerate_slots;
pbc->is_root = pcibus_is_root;
pbc->bus_num = pcibus_num;
@@ -967,6 +971,77 @@ uint16_t pci_requester_id(PCIDevice *dev)
return pci_req_id_cache_extract(&dev->requester_id_cache);
}
+static bool pci_bus_has_pcie_upstream_port(PCIBus *bus)
+{
+ PCIDevice *parent_dev = pci_bridge_get_device(bus);
+
+ /* Device associated with an upstream port.
+ * As there are several types of these, it's easier to check the
+ * parent device: upstream ports are always connected to
+ * root or downstream ports.
+ */
+ return parent_dev &&
+ pci_is_express(parent_dev) &&
+ parent_dev->exp.exp_cap &&
+ (pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_ROOT_PORT ||
+ pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_DOWNSTREAM);
+}
+
+static PCIDevice *pci_bus_get_function_0(PCIBus *bus, int devfn)
+{
+ if(pci_bus_has_pcie_upstream_port(bus)) {
+ /* With an upstream PCIe port, we only support 1 device at slot 0 */
+ return bus->devices[0];
+ } else {
+ /* Other bus types might support multiple devices at slots 0-31 */
+ return bus->devices[PCI_DEVFN(PCI_SLOT(devfn), 0)];
+ }
+}
+
+PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
+{
+ return pci_bus_get_function_0(pci_dev->bus, pci_dev->devfn);
+}
+
+static DeviceSlotInfoList *pci_bus_enumerate_slots(BusState *bus, Error **errp)
+{
+ PCIBus *pb = PCI_BUS(bus);
+ int slot, slots;
+ DeviceSlotInfoList *r = NULL;
+ DeviceSlotInfoList **next = &r;
+
+ if (pci_bus_has_pcie_upstream_port(pb)) {
+ slots = 1;
+ } else {
+ slots = PCI_SLOT_MAX;
+ }
+
+ for(slot = PCI_SLOT(pb->devfn_min); slot < slots; slot++) {
+ DeviceSlotInfoList *i = g_new0(DeviceSlotInfoList, 1);
+ i->value = g_new0(DeviceSlotInfo, 1);
+ i->value->type = DEVICE_SLOT_TYPE_PCI;
+ i->value->u.pci.props = g_new0(PCIDeviceSlotProperties, 1);
+ i->value->u.pci.props->bus = g_strdup(bus->name);
+ i->value->u.pci.props->device_number = slot;
+ /*TODO: add info about accepting only bridges on extra PCI root buses */
+ i->value->accepted_device_types = QAPI_CLONE(strList, bus->accepted_device_types);
+
+ i->value->hotpluggable = qbus_is_hotpluggable(bus);
+ /* Conditions that make a slot unavailable:
+ * - function 0 already occupied by a device
+ * - Hotplug when the bus is not hotpluggable
+ */
+ i->value->available =
+ !((pb->devices[PCI_DEVFN(slot, 0)]) ||
+ (qdev_hotplug && !qbus_is_hotpluggable(bus)));
+
+ *next = i;
+ next = &i->next;
+ }
+
+ return r;
+}
+
/* -1 for devfn means auto assign */
static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
const char *name, int devfn,
@@ -2509,6 +2584,56 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev)
return dev->bus->address_space_io;
}
+static void pci_device_get_devnr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t devnr = PCI_SLOT(dev->devfn);
+
+ visit_type_uint32(v, "device-number", &devnr, errp);
+}
+
+static void pci_device_set_devnr(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t devnr;
+ Error *local_err = NULL;
+
+ visit_type_uint32(v, "device-number", &devnr, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ dev->devfn = PCI_DEVFN(devnr, PCI_FUNC(dev->devfn));
+out:
+ error_propagate(errp, local_err);
+}
+
+static void pci_device_get_function(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t function = PCI_FUNC(dev->devfn);
+
+ visit_type_uint32(v, "function", &function, errp);
+}
+
+static void pci_device_set_function(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ PCIDevice *dev = PCI_DEVICE(obj);
+ uint32_t function;
+ Error *local_err = NULL;
+
+ visit_type_uint32(v, "function", &function, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ dev->devfn = PCI_DEVFN(PCI_SLOT(dev->devfn), function);
+out:
+ error_propagate(errp, local_err);
+}
+
static void pci_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
@@ -2519,6 +2644,19 @@ static void pci_device_class_init(ObjectClass *klass, void *data)
k->bus_type = TYPE_PCI_BUS;
k->props = pci_props;
pc->realize = pci_default_realize;
+
+ /* Internally, bits 3:8 of devfn are called "slots", but:
+ * - they can be confused with physical slot numbers;
+ * - TYPE_PCIE_SLOT objects already have a "slot" property.
+ * So we use the terminology used in the PCI specifiction:
+ * "device number".
+ */
+ object_class_property_add(klass, "device-number", "uint32",
+ pci_device_get_devnr, pci_device_set_devnr,
+ NULL, NULL, &error_abort);
+ object_class_property_add(klass, "function", "uint32",
+ pci_device_get_function, pci_device_set_function,
+ NULL, NULL, &error_abort);
}
static void pci_device_class_base_init(ObjectClass *klass, void *data)
@@ -2607,33 +2745,6 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range)
pci_for_each_device_under_bus(bus, pci_dev_get_w64, range);
}
-static bool pcie_has_upstream_port(PCIDevice *dev)
-{
- PCIDevice *parent_dev = pci_bridge_get_device(dev->bus);
-
- /* Device associated with an upstream port.
- * As there are several types of these, it's easier to check the
- * parent device: upstream ports are always connected to
- * root or downstream ports.
- */
- return parent_dev &&
- pci_is_express(parent_dev) &&
- parent_dev->exp.exp_cap &&
- (pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_ROOT_PORT ||
- pcie_cap_get_type(parent_dev) == PCI_EXP_TYPE_DOWNSTREAM);
-}
-
-PCIDevice *pci_get_function_0(PCIDevice *pci_dev)
-{
- if(pcie_has_upstream_port(pci_dev)) {
- /* With an upstream PCIe port, we only support 1 device at slot 0 */
- return pci_dev->bus->devices[0];
- } else {
- /* Other bus types might support multiple devices at slots 0-31 */
- return pci_dev->bus->devices[PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 0)];
- }
-}
-
MSIMessage pci_get_msi_message(PCIDevice *dev, int vector)
{
MSIMessage msg;
diff --git a/qdev-monitor.c b/qdev-monitor.c
index c73410c..44f8b5c 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -29,6 +29,8 @@
#include "qemu/error-report.h"
#include "qemu/help_option.h"
#include "sysemu/block-backend.h"
+#include "qapi/clone-visitor.h"
+#include "hw/boards.h"
/*
* Aliases were a bad idea from the start. Let's keep them
@@ -399,12 +401,6 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
return NULL;
}
-static inline bool qbus_is_full(BusState *bus)
-{
- BusClass *bus_class = BUS_GET_CLASS(bus);
- return bus_class->max_dev && bus->max_index >= bus_class->max_dev;
-}
-
/*
* Search the tree rooted at @bus for a bus.
* If @name, search for a bus with that name. Note that bus names
@@ -631,6 +627,86 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
return dev;
}
+typedef struct SlotListState {
+ MachineState *machine;
+ DeviceSlotInfoList *result;
+ DeviceSlotInfoList **next;
+ Error *err;
+} SlotListState;
+
+static int walk_bus(Object *obj, void *opaque)
+{
+ SlotListState *s = opaque;
+
+ /* sysbus is special: never return it unless the machine
+ * supports dynamic sysbus devices.
+ */
+ if (object_dynamic_cast(obj, TYPE_BUS) &&
+ (!object_dynamic_cast(obj, TYPE_SYSTEM_BUS) ||
+ MACHINE_GET_CLASS(s->machine)->has_dynamic_sysbus)) {
+ BusState *bus = BUS(obj);
+ BusClass *bc = BUS_GET_CLASS(bus);
+ DeviceSlotInfoList *l = bc->enumerate_slots(bus, &s->err);
+ *s->next = l;
+ for (; l; l = l->next) {
+ s->next = &l->next;
+ }
+ if (s->err) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+DeviceSlotInfoList *qmp_query_device_slots(Error **errp)
+{
+ SlotListState s = { };
+ MachineState *ms = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
+
+ s.machine = ms;
+ s.next = &s.result;
+
+ /* We build the device slot list from two sources:
+ * 1) Calling the BusClass::enumerate_slots() method on all buses;
+ * 2) The return value of MachineClass::query_hotpluggable_cpus()
+ */
+
+
+ object_child_foreach_recursive(qdev_get_machine(), walk_bus, &s);
+ if (s.err) {
+ goto out;
+ }
+
+ if (mc->query_hotpluggable_cpus) {
+ HotpluggableCPUList *hcl = mc->query_hotpluggable_cpus(ms);
+ HotpluggableCPUList *i;
+
+ for (i = hcl; i; i = i->next) {
+ DeviceSlotInfoList *r = g_new0(DeviceSlotInfoList, 1);
+ HotpluggableCPU *hc = i->value;
+ r->value = g_new0(DeviceSlotInfo, 1);
+ r->value->type = DEVICE_SLOT_TYPE_CPU;
+ r->value->accepted_device_types = g_new0(strList, 1);
+ r->value->accepted_device_types->value = g_strdup(hc->type);
+ r->value->available = !hc->has_qom_path;
+ /*TODO: should it be always true? */
+ r->value->hotpluggable = true;
+
+ r->value->u.cpu.props = QAPI_CLONE(CpuInstanceProperties,
+ hc->props);
+ *s.next = r;
+ s.next = & r->next;
+ }
+
+ qapi_free_HotpluggableCPUList(hcl);
+ }
+
+out:
+ error_propagate(errp, s.err);
+ return s.result;
+}
+
#define qdev_printf(fmt, ...) monitor_printf(mon, "%*s" fmt, indent, "", ## __VA_ARGS__)
static void qbus_print(Monitor *mon, BusState *bus, int indent);
--
2.7.4
3
4
[libvirt] [PATCH v2] [libvirt-ci] Add builders for Fedora 25 and remove builders for Fedora 23
by Yash Mankad 15 Dec '16
by Yash Mankad 15 Dec '16
15 Dec '16
Add builders for Fedora 25 and remove builders for Fedora 23
for ci.centos.org
Signed-off-by: Yash Mankad <ymankad(a)redhat.com>
---
projects/libosinfo.yaml | 2 +-
projects/libvirt-cim.yaml | 2 +-
projects/libvirt-glib.yaml | 2 +-
projects/libvirt-perl.yaml | 2 +-
projects/libvirt-python.yaml | 2 +-
projects/libvirt-sandbox.yaml | 2 +-
projects/libvirt-tck.yaml | 2 +-
projects/libvirt.yaml | 6 +++---
projects/osinfo-db-tools.yaml | 2 +-
projects/osinfo-db.yaml | 2 +-
projects/virt-manager.yaml | 2 +-
projects/virt-viewer.yaml | 2 +-
12 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/projects/libosinfo.yaml b/projects/libosinfo.yaml
index 49639f3..6562fa8 100644
--- a/projects/libosinfo.yaml
+++ b/projects/libosinfo.yaml
@@ -3,8 +3,8 @@
name: libosinfo
machines:
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: libosinfo
make_env: |
diff --git a/projects/libvirt-cim.yaml b/projects/libvirt-cim.yaml
index d1705af..a2b1086 100644
--- a/projects/libvirt-cim.yaml
+++ b/projects/libvirt-cim.yaml
@@ -4,8 +4,8 @@
machines:
- libvirt-centos-6
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: libvirt CIM
jobs:
diff --git a/projects/libvirt-glib.yaml b/projects/libvirt-glib.yaml
index 38bcded..c3f60db 100644
--- a/projects/libvirt-glib.yaml
+++ b/projects/libvirt-glib.yaml
@@ -3,8 +3,8 @@
name: libvirt-glib
machines:
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: Libvirt GLib
jobs:
diff --git a/projects/libvirt-perl.yaml b/projects/libvirt-perl.yaml
index 2bad51d..668de7d 100644
--- a/projects/libvirt-perl.yaml
+++ b/projects/libvirt-perl.yaml
@@ -3,8 +3,8 @@
name: libvirt-perl
machines:
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: Libvirt Perl
jobs:
diff --git a/projects/libvirt-python.yaml b/projects/libvirt-python.yaml
index baca308..1df43bf 100644
--- a/projects/libvirt-python.yaml
+++ b/projects/libvirt-python.yaml
@@ -4,8 +4,8 @@
machines:
- libvirt-centos-6
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: Libvirt Python
jobs:
diff --git a/projects/libvirt-sandbox.yaml b/projects/libvirt-sandbox.yaml
index eee249c..97abbe9 100644
--- a/projects/libvirt-sandbox.yaml
+++ b/projects/libvirt-sandbox.yaml
@@ -2,8 +2,8 @@
- project:
name: libvirt-sandbox
machines:
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: Libvirt Sandbox
jobs:
diff --git a/projects/libvirt-tck.yaml b/projects/libvirt-tck.yaml
index 571f3ce..0c3515b 100644
--- a/projects/libvirt-tck.yaml
+++ b/projects/libvirt-tck.yaml
@@ -2,8 +2,8 @@
- project:
name: libvirt-tck
machines:
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: Libvirt TCK
jobs:
diff --git a/projects/libvirt.yaml b/projects/libvirt.yaml
index 20de27c..a75d2a7 100644
--- a/projects/libvirt.yaml
+++ b/projects/libvirt.yaml
@@ -4,8 +4,8 @@
machines:
- libvirt-centos-6
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: Libvirt
archive_format: xz
@@ -16,8 +16,8 @@
- libvirt-centos-6
- libvirt-centos-7
- libvirt-debian
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
- libvirt-freebsd
- autotools-syntax-check-job:
@@ -26,8 +26,8 @@
- libvirt-centos-6
- libvirt-centos-7
- libvirt-debian
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
check_env: |
export VIR_TEST_EXPENSIVE=1
diff --git a/projects/osinfo-db-tools.yaml b/projects/osinfo-db-tools.yaml
index bcb63da..5aff41b 100644
--- a/projects/osinfo-db-tools.yaml
+++ b/projects/osinfo-db-tools.yaml
@@ -3,8 +3,8 @@
name: osinfo-db-tools
machines:
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: osinfo database tools
jobs:
diff --git a/projects/osinfo-db.yaml b/projects/osinfo-db.yaml
index f48aa3f..c8b60b5 100644
--- a/projects/osinfo-db.yaml
+++ b/projects/osinfo-db.yaml
@@ -3,8 +3,8 @@
name: osinfo-db
machines:
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: osinfo database
jobs:
diff --git a/projects/virt-manager.yaml b/projects/virt-manager.yaml
index 737e37d..5268085 100644
--- a/projects/virt-manager.yaml
+++ b/projects/virt-manager.yaml
@@ -3,8 +3,8 @@
name: virt-manager
machines:
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: Virtual Machine Manager
jobs:
diff --git a/projects/virt-viewer.yaml b/projects/virt-viewer.yaml
index d7b7108..5076f1b 100644
--- a/projects/virt-viewer.yaml
+++ b/projects/virt-viewer.yaml
@@ -3,8 +3,8 @@
name: virt-viewer
machines:
- libvirt-centos-7
- - libvirt-fedora-23
- libvirt-fedora-24
+ - libvirt-fedora-25
- libvirt-fedora-rawhide
title: Virt Viewer
jobs:
--
2.7.4
1
0