[libvirt] [PATCH go 0/3] Add bindings for new (and missing!) events
by Daniel P. Berrange
Daniel P. Berrange (3):
Add support for domain metadata change event
Add missing binding for storage pool refresh event
Add binding for secret event APIs
api_test.go | 6 ++
domain_compat.h | 3 +
domain_events.go | 46 +++++++++++++
domain_events_cfuncs.go | 10 +++
domain_events_cfuncs.h | 5 ++
secret.go | 14 ++++
secret_compat.go | 47 +++++++++++++
secret_compat.h | 30 ++++++++
secret_events.go | 157 ++++++++++++++++++++++++++++++++++++++++++
secret_events_cfuncs.go | 65 +++++++++++++++++
secret_events_cfuncs.h | 40 +++++++++++
storage_pool_events.go | 40 +++++++++++
storage_pool_events_cfuncs.go | 7 ++
storage_pool_events_cfuncs.h | 2 +
14 files changed, 472 insertions(+)
create mode 100644 secret_compat.go
create mode 100644 secret_events.go
create mode 100644 secret_events_cfuncs.go
create mode 100644 secret_events_cfuncs.h
--
2.9.3
7 years, 10 months
[libvirt] [PATCH perl 0/2] Add bindings for new events
by Daniel P. Berrange
Daniel P. Berrange (2):
Add domain metadata change event
Add support for secret event APIs
Changes | 2 +
Virt.xs | 184 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/Sys/Virt.pm | 36 ++++++++++
lib/Sys/Virt/Domain.pm | 4 ++
lib/Sys/Virt/Secret.pm | 33 +++++++++
t/030-api-coverage.t | 4 ++
6 files changed, 263 insertions(+)
--
2.9.3
7 years, 10 months
[libvirt] [PATCH v2 0/2] Detect misconfiguration between disk bus and disk address
by Marc Hartmayer
This patch series adds the functionality to detect a misconfiguration
between disk bus type and disk address type for disks that are using
the address type virDomainDeviceDriveAddress. It also adds a test for
it.
A check for other bus types may be needed. This may require a driver
specific function, as it is already implemented in
virDomainDeviceDefPostParse(), for example.
Changelog:
- v1 -> v2:
+ Use full enumeration of the bus types
+ Add warning for unexpected bus type
Marc Hartmayer (2):
conf: Detect misconfiguration between disk bus and disk address
tests: Add tests for disk configuration validation
src/conf/domain_conf.c | 56 ++++++++++++++++++++++
.../qemuxml2argv-disk-fdc-incompatible-address.xml | 22 +++++++++
.../qemuxml2argv-disk-ide-incompatible-address.xml | 23 +++++++++
...qemuxml2argv-disk-sata-incompatible-address.xml | 23 +++++++++
...qemuxml2argv-disk-scsi-incompatible-address.xml | 24 ++++++++++
tests/qemuxml2argvtest.c | 8 ++++
6 files changed, 156 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-fdc-incompatible-address.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-ide-incompatible-address.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-sata-incompatible-address.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-scsi-incompatible-address.xml
--
2.5.5
7 years, 10 months
[libvirt] [PATCH] qemu: setvcpus: Properly coldplug vcpus when hotpluggable vcpus are present
by Peter Krempa
When coldplugging vcpus to a VM that already has a few hotpluggable
vcpus the code might generate a invalid configuration as
non-hotpluggable cpus need to be clustered starting from vcpu 0.
This fix forces the added vcpus to be hotpluggable in such case.
Fixes a corner case described in:
https://bugzilla.redhat.com/show_bug.cgi?id=1370357
---
src/qemu/qemu_driver.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 675a4d0e7..30edb6cde 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4943,9 +4943,20 @@ qemuDomainSetVcpusConfig(virDomainDefPtr def,
for (i = 0; i < maxvcpus; i++) {
vcpu = virDomainDefGetVcpu(def, i);
- if (!vcpu || vcpu->online)
+ if (!vcpu)
continue;
+ if (vcpu->online) {
+ /* non-hotpluggable vcpus need to be clustered at the beggining,
+ * thus we need to force vcpus to be hotpluggable when we find
+ * vcpus that are hotpluggable and online prior to the ones
+ * we are going to add */
+ if (vcpu->hotpluggable == VIR_TRISTATE_BOOL_YES)
+ hotpluggable = true;
+
+ continue;
+ }
+
vcpu->online = true;
if (hotpluggable) {
vcpu->hotpluggable = VIR_TRISTATE_BOOL_YES;
--
2.11.0
7 years, 10 months
[libvirt] [PATCH] cgroup: add virCgroupAddMachineTask stub for win32
by Daniel P. Berrange
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
Pushed as a win32 build fix
src/util/vircgroup.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index ddf19e9..5aa1db5 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -4289,6 +4289,16 @@ virCgroupAddTask(virCgroupPtr group ATTRIBUTE_UNUSED,
int
+virCgroupAddMachineTask(virCgroupPtr group ATTRIBUTE_UNUSED,
+ pid_t pid ATTRIBUTE_UNUSED)
+{
+ virReportSystemError(ENXIO, "%s",
+ _("Control groups not supported on this platform"));
+ return -1;
+}
+
+
+int
virCgroupAddTaskController(virCgroupPtr group ATTRIBUTE_UNUSED,
pid_t pid ATTRIBUTE_UNUSED,
int controller ATTRIBUTE_UNUSED)
--
2.9.3
7 years, 10 months
[libvirt] Plans for next release 3.0.0
by Daniel Veillard
Since we had planned a release mid January, it's time to plan
the next release, I suggest to shoot for a release next Monday, the
16th. In which case we should enter freeze this Wednesday, then
have RC2 on Friday, and then if everything is fine, push the release
next Monday.
Hope this works for everybody,
thanks,
Daniel
--
Daniel Veillard | Open Source and Standards, Red Hat
veillard(a)redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | virtualization library http://libvirt.org/
7 years, 10 months
[libvirt] RFC for support Intel RDT/CAT in libvirt
by Qiao, Liyong
Hi folks
I would like to start a discussion about how to support a new cpu feature in libvirt. CAT support is not fully merged into linux kernel yet, the target release is 4.10, and all patches has been merged into linux tip branch. So there won’t be interface/design changes.
## Background
Intel RDT is a toolkit to do resource Qos for cpu such as llc(l3) cache, memory bandwidth usage, these fine granularity resource control features are very useful in a cloud environment which will run logs of noisy instances.
Currently, Libvirt has supported CAT/MBMT/MBML already, they are only for resource usage monitor, propose to supporting CAT to control VM’s l3 cache quota.
## CAT interface in kernel
In kernel, a new resource interface has been introduced under /sys/fs/resctrl, it’s used for resource control, for more information, refer
Intel_rdt_ui [ https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/tree/Documentati... ]
Kernel requires to provide schemata for l3 cache before add a task to a new partition, these interface is too much detail for a virtual machine user, so propose to let Libvirt manage schemata on the host.
## What will libvirt do?
### Questions:
To enable CAT support in libvirt, we need to think about follow questions
1. Only set CAT when an VM has CPU pin, which is to say, l3 cache is per cpu socket resources. On a host which has 2 cpu sockets, each cpu socket has it own cache, and can not be shared..
2. What the cache allocation policy should be used, this will be looks like:
a. VM has it’s own dedicated l3 cache and also can share other l3 cache.
b. VM can only use the caches which allocated to it.
c. Has some pre-defined policies and priority for a VM
Like COB [1]
1. Should reserve some l3 cache for host’s system usage (related to 2)
2. What’s the unit for l3 cache allocation? (related to 2)
### Propose Changes
XML domain user interface changes:
Option 1: explicit specify cache allocation for a VM
1 work with numa node
Some cloud orchestration software use numa + vcpu pin together, so we can enable cat supporting with numa infra.
Expose how many l3 cache a VM want to reserved and we require that the l3 cache should be bind on some specify cpu socket, just like what we did for numa node.
This is an domain xml example which is generated by OpenStack Nova for allocate llc(l3 cache) when booting a new VM
<domain>
…
<cputune>
<vcpupin vcpu='0' cpuset='19'/>
<vcpupin vcpu='1' cpuset='63'/>
<vcpupin vcpu='2' cpuset='83'/>
<vcpupin vcpu='3' cpuset='39'/>
<vcpupin vcpu='4' cpuset='40'/>
<vcpupin vcpu='5' cpuset='84'/>
<emulatorpin cpuset='19,39-40,63,83-84'/>
</cputune>
...
<cpu mode='host-model'>
<model fallback='allow'/>
<topology sockets='3' cores='1' threads='2'/>
<numa>
<cell id='0' cpus='0-1' memory='2097152' l3cache='1408' unit='KiB'/>
<cell id='1' cpus='2-5' memory='4194304' l3cache='5632' unit='KiB'/>
</numa>
</cpu>
...
</domain>
Refer to [http://libvirt.org/formatdomain.html#elementsCPUTuning]
So finally we can calculate on which CPU socket(cell) we need to allocate how may l3cache for a VM.
2. work with vcpu pin
Forget numa part, CAT setting should have relationship with cpu core setting, we can apply CAT policy if VM has set cpu pin setting (only VM won’t be schedule to another CPU sockets)
Cache allocation on which CPU socket can be calculate as just as 1.
We may need to enable both 1 and 2.
There are several policy for cache allocation:
Let’ take some examples:
For intel e5 v4 2699(Signal socket), there are 55M l3 cache on the chip , the default of L3 schemata is L3:0=ffffff , it represents to use 20 bit to control l3 cache, each bit will represent 2.75M, which will be the minimal unit on this host.
The allocation policy could be 3 policies :
1. One priority VM:
A priority import VM can be allocated a dedicated amount l3 cache (let’s say 2.75 * 4 = 11M) and it can also reach the left 44 M cache which will be shared with other process and VM on the same host.
So that we need to create a new ‘Partition’ n-20371
root@s2600wt:/sys/fs/resctrl# ls
cpus info n-20371 schemata tasks
Inside of n-20371 directory:
root@s2600wt:/sys/fs/resctrl# ls n-20371/
cpus schemata tasks
The schemata content will be L3:0=fffff
The tasks content will be the pids of that VM
Along we need to change the default schemata of system:
root@s2600wt:/sys/fs/resctrl# cat schemata
L3:0=ffff # which can not use the highest 4 bits, only tasks in n-20371 can reach that.
In this design , we can only get 1 priority VM.
Let’s change it a bit to have 2 VMs
The schemata of the 2 VMs could be:
1. L3:0=ffff0 # could not use the 4 low bits 11M l3 cache
2. L3:0=0ffff # could not use the 4 high bits 11M l3 cache
Default schemata changes to
L3:0=0fff0 # default system process could only use the middle 33M l3 cache
2. Isolated l3 cache dedicated allocation for each VM(if required)
A VM can only use the cache allocated to it.
For example
VM 1 requires to allocate 11 M
It’s schemata will be L3:0=f0000 #
VM 2 requires to allocate 11M
It’s schemata will be L3:0=f000
And default schemata will be L3:0=fff
In this case, we can create multiple VMs which each of them can have dedicated l3 cache.
The disadvantage is that we the allocated cache could be not be shared efficiently.
3. Isolated l3 cache shared allocation for each VM(if required by user)
In this case, we will put some VMs (which consider as noisy neighbors) to a ‘Partition’, restrict them to use the only caches allocated to them, by do this, other much more priority VM can be ensure to have enough l3 cache
Then we should decide how much cache the noisy group should have, and put all of their pids in that tasks file.
Option 2: set cache priority and apply policies
Don’t specify cache amount at all, only define cache usage priority when define a VM domain XML.
Cache priority will decide how much the VM can use l3 cache on a host, it’s not a quantized. So user don’t need to think about how much cache it should have when define a domain XML.
Libvirt will decide cache allocation by the priority of VM defined and policies using.
Disadvantage is that caches ability on different host may be different. Same VM domain XML on different host may have vary caches allocation amount.
# Support CAT in libvirt itself or leverage other software
COB
COB is Intel Cache Orchestrator Balancer (COB). please refer http://clrgitlab.intel.com/rdt/cob/tree/master
COB supports some pre-defined policies, it will monitor cpu/cache/cache missing and do cache allocation based on policy using.
If COB support monitor some specified process (VM process) and accept priority defined, it will be good to reuse.
At last the question came out:
* Support a fine-grained llc cache control , let user specify cache allocation
* Support pre-defined policies and user specify llc allocation priority.
Reference
[1] COB http://clrgitlab.intel.com/rdt/cob/tree/master
[2] CAT intro: https://software.intel.com/en-us/articles/software-enabling-for-cache-all...
[3] kernel Intel_rdt_ui [ https://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/tree/Documentati... ]
Best Regards
Eli Qiao(乔立勇)OpenStack Core team OTC Intel.
--
7 years, 10 months
[libvirt] [PATCH 0/6] Don't run whole sec driver in namespace
by Michal Privoznik
In eadaa97548 I've tried to solve the issue of setting seclabels
on private /dev/* entries. While my approach works, it has tiny
flaw - anything that happens in the namespace stays in the
namespace. I mean, if there's a internal state change occurring
on relabel operation (it should not, and it doesn't nowadays, but
it's no guarantee), this change is not reflected in the daemon.
This is because when entering the namespace, the daemon forks,
enters the namespace and then executes the RelabelAll() function.
This imperfection is:
a) very easy to forget
b) very hard to debug
Therefore, we may have transaction APIs as suggested here [1]. On
transactionBegin() the sec driver will record [path. seclabel]
somewhere instead of applying the label. Then on
transactionCommit() new process is forked, enters the namespace
and perform previously recorded changes. This way it is only the
minimal code that runs in the namespace. Moreover, it runs over
constant data thus there can be no internal state transition.
1: https://www.redhat.com/archives/libvir-list/2016-December/msg00254.html
Michal Privoznik (6):
security_selinux: s/virSecuritySELinuxSecurity/virSecuritySELinux/
security_dac: Resolve virSecurityDACSetOwnershipInternal const
correctness
security driver: Introduce transaction APIs
security_dac: Implement transaction APIs
security_selinux: Implement transaction APIs
qemu: Use transactions from security driver
src/libvirt_private.syms | 3 +
src/qemu/qemu_driver.c | 28 +++--
src/qemu/qemu_security.c | 98 +++++----------
src/security/security_dac.c | 197 +++++++++++++++++++++++++++++-
src/security/security_driver.h | 9 ++
src/security/security_manager.c | 38 ++++++
src/security/security_manager.h | 7 +-
src/security/security_selinux.c | 219 +++++++++++++++++++++++++++++++---
src/security/security_stack.c | 49 ++++++++
src/storage/storage_backend.h | 2 +-
src/storage/storage_backend_fs.c | 2 +-
src/storage/storage_backend_gluster.c | 2 +-
src/storage/storage_driver.c | 6 +-
src/storage/storage_driver.h | 4 +-
src/util/virstoragefile.c | 2 +-
src/util/virstoragefile.h | 2 +-
16 files changed, 561 insertions(+), 107 deletions(-)
--
2.11.0
7 years, 10 months
Re: [libvirt] libvirt support for mediated devices
by Laine Stump
VFIO's new mediated device interface "is used for allowing
software-defined devices to be exposed through VFIO while the host
driver manages access to the interface" (quoted from
http://www.phoronix.com/scan.php?page=news_item&px=VFIO-Linux-4.10-Mediated
). Now that the support for mediated devices has been added to the
upstream Linux kernel, there is a stable API that libvirt can use to
support assigning mediated devices (e.g. virtual GPUs) to Qemu/KVM
guests (or presumably any other hypervisor that support device
assignment via VFIO.
We've had a few private discussions about what should be added to
libvirt, and now have enough rough ideas to start discussing it on the list.
The major requirements we've come up with so far (in what I think is a
reasonable order of implementation) are:
1) The ability to assign an already-created mediated device to a guest
(think of "<hostdev ... managed='no'>" mode for assigning regular PCI
devices).
2) reporting of the capabilities of a mediated device "parent"
(including, for example, the supported types and maximum number of child
devices that are supported, and the names of all existing child devices)
and of existing child devices (via the node device APIs, e.g. virsh
nodedev-list and virsh nodedev-dumpxml)
3) The ability to create and destroy mediated devices via the NodeDevice
API. (similar in function to the "virsh detach-device and virsh
attach-device commands - i.e. they make a device ready to be assigned to
a guest using <hostdev>, but have no persistent config and no
"auto-start" capability).
4) Support for "managed" mediated devices - libvirt will create a new
child device as required, and destroy it when it's no longer needed
(similar to the way that standard PCI hostdevs are (when managed="yes")
detached from their host driver and attached to vfio-pci as needed) (I
think this is less useful than item (5), but is simpler and may be a
good way to test all the preceding additions (as well as being useful in
some simpler configurations).
5) The ability to create and manage "pools" of mediated devices, with
persistent config and an auto-start capability so that the device pools
are automatically created when the host is booted (this will require
either some form of persistent config and lifecycle management to be
added to the nodedevice driver, or a new libvirt driver type with
functionality similar to storage pools, but used to manage pools of mdev
child devices).
=========
Going back to the beginning, with slightly more detail:
1) "Unmanaged" mediated device assignment - assigning an existing device
to a virtual machine
This will assume that the desired child device has already been created,
and can be found in /sys/bus/mdev/devices/$UUID. Here's a first attempt
at what the XML would look like:
<hostdev mode='subsystem' type='pci' /managed='no'>/
<source> <!-- (maybe add "type='mdev'" ???) -->
<mdev uuid='$uuid'/>
</source>
<address type='pci' blah blah blah/> <!-- PCI address in the
guest -->
</hostdev>
In the past, the "type" attribute of hostdev described the type on both
the host and the guest. With mediated devices, the device isn't visible
on the host as a PCI device, but just as a software device. So the type
attribute in <hostdev> now gives the type of the device on the guest,
and the device type on the host is determined from the contents of <source>.
Erik had a different suggestion for this (which I think he's already
working on patches for) - that the type attribute in <hostdev> should be
the type of the device in the *host*, and the type in the guest would be
that given in the <address>. Something like this I think:
<hostdev mode='subsystem' type='mdev' /managed='no'/>
<source>
<mdev uuid='$uuid'/>
</source>
<address type='pci' blah blah blah/>
</hostdev>
(Is this correct, Erik?)
(I arrived at my suggestion by the thinking that, in other places where
there are similar attributes for the host and guest side, e.g. the IP
addresses and routes that can be added on both the host and guest side
of an <interface>, everything related to the host side is in the
<source> subelement, while things related to the guest are directly
under the toplevel of the device element. On the other hand, the
"managed" attribute isn't something related to the guest, but to the
host, and his idea has less redundancy, so maybe he's onto something...)
(NB: a mediated device could be exposed to the guest as a PCI device, a
CCW device, or anything else supported by vfio. The type of device that
the guest will see can be determined from the contents of
mdev_supported_types/<type-id>/device_api under the parent device's
directory in sysfs (it will be, e.g., "vfio-pci" or "vfio-ccw"). But
libvirt assigns guest-side addresses at the time a domain is defined,
and it's possible that the mdev child device won't be created yet at
define time (and therefore we won't know which parent device it's
associated with, and so we won't be able to look at device_api). In such
situations, it will be up to management to know something about the
device it will be creating and assume a type. Fortunately this is a
reasonably safe thing to do - on x86 platforms we can be fairly certain
that the device will be a PCI device. (And, because this also makes a
difference for some machinetypes, that it will be a PCI Express device).
We will want to check device_api at runtime though, to validate that the
guest-side device really is a PCI device.
==
2) Reporting parent and child mediated devices and their capabilities in
the node device API.
There are 3 stages to this:
a) add mediated child devices to the list of devices provided by "virsh
nodedev-list". These will be called "mdev_$UUID", and will show up as
descendents of their respective parent devices in "virsh nodedev-list
--tree". The list of all these devices can easily be retrieved by
enumerating the links in /sys/bus/mdev/devices/$UUID.
b) report the capabilities of parent devices in their dumpxml output.
This will included supported child device types and a list of current
children.
I don't have any experience with nodedev reporting for SCSI devices, but
recently noticed that nodedev-list can report lists of devices with
certain capabilities, e.g. "virsh nodedev-list --cap=scsi_host". Based
on this, I guess it would be useful for the parent devices to show
something like this (using the sample mtty driver as an example):
<device>
<name>pci_0000_02_00_0</name>
<parent>pci_0000_00_04_0</parent>
<driver>
<name>mtty</name>
</driver>
<capability type='mdev_parent'>
[list of supported types, each with number allowed]
[list of current child devices (just giving uuid or device
name ("mdev_$uuid"?)]
[other info about parent/children?]
</capability>
...
Likewise, a nodedev-dumpxml of a child device should contain a pointer
to the parent device.
c) respond to dumpxml requests for mediated child devices. This should
include at least the uuid/type of the child device, and a link back to
the parent device (and I suppose somehow include <capability
type='mdev_child'> so that it can be filtered with virsh modedev-list?)
==
(3), (4), and (5) need more thought that I haven't gotten to yet. TBD
(if anyone else has thoughts on those, please share!)
7 years, 10 months
[libvirt] [PATCH] conf: Parse virtio-crypto in the domain XML
by Longpeng(Mike)
As virtio-crypto has been supported in QEMU 2.9 and
the frontend driver has been merged in linux 4.10,
so it's necessary to support virtio-crypto in domain
XML.
This patch parse the domain XML with virtio-crypto
support, the virtio-crypto XML looks like this:
<crypto model='virtio'>
<backend type='builtin' queues='2'/>
</crypto>
Signed-off-by: Longpeng(Mike) <longpeng2(a)huawei.com>
---
src/conf/domain_conf.c | 212 +++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 32 +++++++
src/qemu/qemu_alias.c | 20 ++++
src/qemu/qemu_alias.h | 4 +
src/qemu/qemu_capabilities.c | 4 +
src/qemu/qemu_capabilities.h | 2 +
src/qemu/qemu_command.c | 129 +++++++++++++++++++++++++
src/qemu/qemu_command.h | 4 +
src/qemu/qemu_domain_address.c | 17 ++++
src/qemu/qemu_driver.c | 6 ++
src/qemu/qemu_hotplug.c | 1 +
11 files changed, 431 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9f7b906..fcfccd5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -237,6 +237,7 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
"memballoon",
"nvram",
"rng",
+ "crypto",
"shmem",
"tpm",
"panic",
@@ -797,6 +798,14 @@ VIR_ENUM_IMPL(virDomainRNGBackend,
"random",
"egd");
+VIR_ENUM_IMPL(virDomainCryptoModel,
+ VIR_DOMAIN_CRYPTO_MODEL_LAST,
+ "virtio");
+
+VIR_ENUM_IMPL(virDomainCryptoBackend,
+ VIR_DOMAIN_CRYPTO_BACKEND_LAST,
+ "builtin");
+
VIR_ENUM_IMPL(virDomainTPMModel, VIR_DOMAIN_TPM_MODEL_LAST,
"tpm-tis")
@@ -2337,6 +2346,9 @@ void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
case VIR_DOMAIN_DEVICE_RNG:
virDomainRNGDefFree(def->data.rng);
break;
+ case VIR_DOMAIN_DEVICE_CRYPTO:
+ virDomainCryptoDefFree(def->data.crypto);
+ break;
case VIR_DOMAIN_DEVICE_CHR:
virDomainChrDefFree(def->data.chr);
break;
@@ -2600,6 +2612,10 @@ void virDomainDefFree(virDomainDefPtr def)
virDomainRNGDefFree(def->rngs[i]);
VIR_FREE(def->rngs);
+ for (i = 0; i < def->ncryptos; i++)
+ virDomainCryptoDefFree(def->cryptos[i]);
+ VIR_FREE(def->cryptos);
+
for (i = 0; i < def->nmems; i++)
virDomainMemoryDefFree(def->mems[i]);
VIR_FREE(def->mems);
@@ -3169,6 +3185,8 @@ virDomainDeviceGetInfo(virDomainDeviceDefPtr device)
return &device->data.shmem->info;
case VIR_DOMAIN_DEVICE_RNG:
return &device->data.rng->info;
+ case VIR_DOMAIN_DEVICE_CRYPTO:
+ return &device->data.crypto->info;
case VIR_DOMAIN_DEVICE_TPM:
return &device->data.tpm->info;
case VIR_DOMAIN_DEVICE_PANIC:
@@ -3464,6 +3482,12 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
if (cb(def, &device, &def->rngs[i]->info, opaque) < 0)
return -1;
}
+ device.type = VIR_DOMAIN_DEVICE_CRYPTO;
+ for (i = 0; i < def->ncryptos; i++) {
+ device.data.crypto = def->cryptos[i];
+ if (cb(def, &device, &def->cryptos[i]->info, opaque) < 0)
+ return -1;
+ }
if (def->nvram) {
device.type = VIR_DOMAIN_DEVICE_NVRAM;
device.data.nvram = def->nvram;
@@ -3541,6 +3565,7 @@ virDomainDeviceInfoIterateInternal(virDomainDefPtr def,
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_LAST:
case VIR_DOMAIN_DEVICE_RNG:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_MEMORY:
break;
}
@@ -4599,6 +4624,7 @@ virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev,
case VIR_DOMAIN_DEVICE_MEMBALLOON:
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_RNG:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_SHMEM:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
@@ -12022,6 +12048,88 @@ virDomainRNGDefParseXML(xmlNodePtr node,
}
+static virDomainCryptoDefPtr
+virDomainCryptoDefParseXML(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ unsigned int flags)
+{
+ char *model = NULL;
+ char *backend = NULL;
+ char *queues = NULL;
+ virDomainCryptoDefPtr def;
+ xmlNodePtr save = ctxt->node;
+ xmlNodePtr *backends = NULL;
+ int nbackends;
+
+ if (VIR_ALLOC(def) < 0)
+ return NULL;
+
+ if (!(model = virXMLPropString(node, "model"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing Crypto device model"));
+ goto error;
+ }
+
+ if ((def->model = virDomainCryptoModelTypeFromString(model)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown Crypto model '%s'"), model);
+ goto error;
+ }
+
+ ctxt->node = node;
+
+ if ((nbackends = virXPathNodeSet("./backend", ctxt, &backends)) < 0)
+ goto error;
+
+ if (nbackends != 1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("only one Crypto backend is supported"));
+ goto error;
+ }
+
+ if (!(backend = virXMLPropString(backends[0], "type"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing Crypto device backend type"));
+ goto error;
+ }
+
+ if ((def->backend = virDomainCryptoBackendTypeFromString(backend)) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown Crypto backend model '%s'"), backend);
+ goto error;
+ }
+
+ switch ((virDomainCryptoBackend) def->backend) {
+ case VIR_DOMAIN_CRYPTO_BACKEND_BUILTIN:
+ queues = virXMLPropString(backends[0], "queues");
+ if (queues && virStrToLong_ui(queues, NULL, 10, &def->queues) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Malformed 'queues' value '%s'"), queues);
+ }
+ break;
+
+ case VIR_DOMAIN_CRYPTO_BACKEND_LAST:
+ break;
+ }
+
+ if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0)
+ goto error;
+
+cleanup:
+ VIR_FREE(model);
+ VIR_FREE(backend);
+ VIR_FREE(queues);
+ VIR_FREE(backends);
+ ctxt->node = save;
+ return def;
+
+error:
+ virDomainCryptoDefFree(def);
+ def = NULL;
+ goto cleanup;
+}
+
+
static virDomainMemballoonDefPtr
virDomainMemballoonDefParseXML(xmlNodePtr node,
xmlXPathContextPtr ctxt,
@@ -13368,6 +13476,10 @@ virDomainDeviceDefParse(const char *xmlStr,
if (!(dev->data.rng = virDomainRNGDefParseXML(node, ctxt, flags)))
goto error;
break;
+ case VIR_DOMAIN_DEVICE_CRYPTO:
+ if (!(dev->data.crypto = virDomainCryptoDefParseXML(node, ctxt, flags)))
+ goto error;
+ break;
case VIR_DOMAIN_DEVICE_CHR:
if (!(dev->data.chr = virDomainChrDefParseXML(ctxt,
node,
@@ -17073,6 +17185,22 @@ virDomainDefParseXML(xmlDocPtr xml,
}
VIR_FREE(nodes);
+ /* Parse the crypto devices */
+ if ((n = virXPathNodeSet("./devices/crypto", ctxt, &nodes)) < 0)
+ goto error;
+ if (n && VIR_ALLOC_N(def->cryptos, n) < 0)
+ goto error;
+ for (i = 0; i < n; i++) {
+ virDomainCryptoDefPtr crypto = virDomainCryptoDefParseXML(nodes[i],
+ ctxt,
+ flags);
+ if (!crypto)
+ goto error;
+
+ def->cryptos[def->ncryptos++] = crypto;
+ }
+ VIR_FREE(nodes);
+
/* Parse the TPM devices */
if ((n = virXPathNodeSet("./devices/tpm", ctxt, &nodes)) < 0)
goto error;
@@ -18199,6 +18327,25 @@ virDomainRNGDefCheckABIStability(virDomainRNGDefPtr src,
static bool
+virDomainCryptoDefCheckABIStability(virDomainCryptoDefPtr src,
+ virDomainCryptoDefPtr dst)
+{
+ if (src->model != dst->model) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target Crypto model '%s' does not match source '%s'"),
+ virDomainCryptoModelTypeToString(dst->model),
+ virDomainCryptoModelTypeToString(src->model));
+ return false;
+ }
+
+ if (!virDomainDeviceInfoCheckABIStability(&src->info, &dst->info))
+ return false;
+
+ return true;
+}
+
+
+static bool
virDomainHubDefCheckABIStability(virDomainHubDefPtr src,
virDomainHubDefPtr dst)
{
@@ -18933,6 +19080,17 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
if (!virDomainRNGDefCheckABIStability(src->rngs[i], dst->rngs[i]))
goto error;
+ if (src->ncryptos != dst->ncryptos) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Target domain crypto device count %zu "
+ "does not match source %zu"), dst->ncryptos, src->ncryptos);
+ goto error;
+ }
+
+ for (i = 0; i < src->ncryptos; i++)
+ if (!virDomainCryptoDefCheckABIStability(src->cryptos[i], dst->cryptos[i]))
+ goto error;
+
if (src->npanics != dst->npanics) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Target domain panic device count %zu "
@@ -19007,6 +19165,7 @@ virDomainDefCheckABIStability(virDomainDefPtr src,
case VIR_DOMAIN_DEVICE_NVRAM:
case VIR_DOMAIN_DEVICE_LAST:
case VIR_DOMAIN_DEVICE_RNG:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_SHMEM:
@@ -21590,6 +21749,51 @@ virDomainRNGDefFree(virDomainRNGDefPtr def)
static int
+virDomainCryptoDefFormat(virBufferPtr buf,
+ virDomainCryptoDefPtr def,
+ unsigned int flags)
+{
+ const char *model = virDomainCryptoModelTypeToString(def->model);
+ const char *backend = virDomainCryptoBackendTypeToString(def->backend);
+
+ virBufferAsprintf(buf, "<crypto model='%s'>\n", model);
+ virBufferAdjustIndent(buf, 2);
+ virBufferAsprintf(buf, "<backend type='%s'", backend);
+
+ switch ((virDomainCryptoBackend) def->backend) {
+ case VIR_DOMAIN_CRYPTO_BACKEND_BUILTIN:
+ if (def->queues)
+ virBufferAsprintf(buf, " queues='%u'", def->queues);
+
+ virBufferAddLit(buf, "/>\n");
+ break;
+
+ case VIR_DOMAIN_CRYPTO_BACKEND_LAST:
+ break;
+ }
+
+ if (virDomainDeviceInfoNeedsFormat(&def->info, flags)) {
+ if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+ return -1;
+ }
+
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</crypto>\n");
+ return 0;
+}
+
+void
+virDomainCryptoDefFree(virDomainCryptoDefPtr def)
+{
+ if (!def)
+ return;
+
+ virDomainDeviceInfoClear(&def->info);
+ VIR_FREE(def);
+}
+
+
+static int
virDomainMemorySourceDefFormat(virBufferPtr buf,
virDomainMemoryDefPtr def)
{
@@ -23539,6 +23743,11 @@ virDomainDefFormatInternal(virDomainDefPtr def,
goto error;
}
+ for (n = 0; n < def->ncryptos; n++) {
+ if (virDomainCryptoDefFormat(buf, def->cryptos[n], flags))
+ goto error;
+ }
+
if (def->nvram)
virDomainNVRAMDefFormat(buf, def->nvram, flags);
@@ -24657,6 +24866,9 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
case VIR_DOMAIN_DEVICE_RNG:
rc = virDomainRNGDefFormat(&buf, src->data.rng, flags);
break;
+ case VIR_DOMAIN_DEVICE_CRYPTO:
+ rc = virDomainCryptoDefFormat(&buf, src->data.crypto, flags);
+ break;
case VIR_DOMAIN_DEVICE_CHR:
rc = virDomainChrDefFormat(&buf, src->data.chr, flags);
break;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ba0ad5f..995ce8f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -127,6 +127,9 @@ typedef virDomainSnapshotObjList *virDomainSnapshotObjListPtr;
typedef struct _virDomainRNGDef virDomainRNGDef;
typedef virDomainRNGDef *virDomainRNGDefPtr;
+typedef struct _virDomainCryptoDef virDomainCryptoDef;
+typedef virDomainCryptoDef *virDomainCryptoDefPtr;
+
typedef struct _virDomainIdMapEntry virDomainIdMapEntry;
typedef virDomainIdMapEntry *virDomainIdMapEntryPtr;
@@ -172,6 +175,7 @@ typedef enum {
VIR_DOMAIN_DEVICE_MEMBALLOON,
VIR_DOMAIN_DEVICE_NVRAM,
VIR_DOMAIN_DEVICE_RNG,
+ VIR_DOMAIN_DEVICE_CRYPTO,
VIR_DOMAIN_DEVICE_SHMEM,
VIR_DOMAIN_DEVICE_TPM,
VIR_DOMAIN_DEVICE_PANIC,
@@ -203,6 +207,7 @@ struct _virDomainDeviceDef {
virDomainMemballoonDefPtr memballoon;
virDomainNVRAMDefPtr nvram;
virDomainRNGDefPtr rng;
+ virDomainCryptoDefPtr crypto;
virDomainShmemDefPtr shmem;
virDomainTPMDefPtr tpm;
virDomainPanicDefPtr panic;
@@ -1927,6 +1932,26 @@ struct _virDomainRNGDef {
};
typedef enum {
+ VIR_DOMAIN_CRYPTO_MODEL_VIRTIO,
+
+ VIR_DOMAIN_CRYPTO_MODEL_LAST
+} virDomainCryptoModel;
+
+typedef enum {
+ VIR_DOMAIN_CRYPTO_BACKEND_BUILTIN,
+
+ VIR_DOMAIN_CRYPTO_BACKEND_LAST
+} virDomainCryptoBackend;
+
+struct _virDomainCryptoDef {
+ int model;
+ int backend;
+ unsigned int queues; /* Multiqueue virtio-crypto */
+
+ virDomainDeviceInfo info;
+};
+
+typedef enum {
VIR_DOMAIN_MEMORY_MODEL_NONE,
VIR_DOMAIN_MEMORY_MODEL_DIMM, /* dimm hotpluggable memory device */
@@ -2218,6 +2243,9 @@ struct _virDomainDef {
size_t nrngs;
virDomainRNGDefPtr *rngs;
+ size_t ncryptos;
+ virDomainCryptoDefPtr *cryptos;
+
size_t nshmems;
virDomainShmemDefPtr *shmems;
@@ -2696,6 +2724,8 @@ int virDomainDefCompatibleDevice(virDomainDefPtr def,
void virDomainRNGDefFree(virDomainRNGDefPtr def);
+void virDomainCryptoDefFree(virDomainCryptoDefPtr def);
+
int virDomainDiskIndexByAddress(virDomainDefPtr def,
virPCIDeviceAddressPtr pci_controller,
unsigned int bus, unsigned int target,
@@ -2996,6 +3026,8 @@ VIR_ENUM_DECL(virDomainHyperv)
VIR_ENUM_DECL(virDomainKVM)
VIR_ENUM_DECL(virDomainRNGModel)
VIR_ENUM_DECL(virDomainRNGBackend)
+VIR_ENUM_DECL(virDomainCryptoModel)
+VIR_ENUM_DECL(virDomainCryptoBackend)
VIR_ENUM_DECL(virDomainTPMModel)
VIR_ENUM_DECL(virDomainTPMBackend)
VIR_ENUM_DECL(virDomainMemoryModel)
diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c
index d624071..25b87d2 100644
--- a/src/qemu/qemu_alias.c
+++ b/src/qemu/qemu_alias.c
@@ -331,6 +331,26 @@ qemuAssignDeviceRNGAlias(virDomainDefPtr def,
int
+qemuAssignDeviceCryptoAlias(const virDomainDef *def,
+ virDomainCryptoDefPtr crypto)
+{
+ size_t i;
+ int maxidx = 0;
+ int idx;
+
+ for (i = 0; i < def->ncryptos; i++) {
+ if ((idx = qemuDomainDeviceAliasIndex(&def->cryptos[i]->info, "crypto")) >= maxidx)
+ maxidx = idx + 1;
+ }
+
+ if (virAsprintf(&crypto->info.alias, "crypto%d", maxidx) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+int
qemuAssignDeviceMemoryAlias(virDomainDefPtr def,
virDomainMemoryDefPtr mem)
{
diff --git a/src/qemu/qemu_alias.h b/src/qemu/qemu_alias.h
index e328a9b..4ae1c92 100644
--- a/src/qemu/qemu_alias.h
+++ b/src/qemu/qemu_alias.h
@@ -57,6 +57,10 @@ int qemuAssignDeviceRedirdevAlias(virDomainDefPtr def,
int qemuAssignDeviceRNGAlias(virDomainDefPtr def,
virDomainRNGDefPtr rng);
+int
+qemuAssignDeviceCryptoAlias(const virDomainDef *def,
+ virDomainCryptoDefPtr crypto);
+
int qemuAssignDeviceMemoryAlias(virDomainDefPtr def,
virDomainMemoryDefPtr mems);
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 2c0b29d..b1b718b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -337,6 +337,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"drive-detect-zeroes",
"tls-creds-x509", /* 230 */
+ "cryptodev-backend-builtin",
+ "virtio-crypto",
);
@@ -1565,6 +1567,8 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
{ "pxb", QEMU_CAPS_DEVICE_PXB },
{ "pxb-pcie", QEMU_CAPS_DEVICE_PXB_PCIE },
{ "tls-creds-x509", QEMU_CAPS_OBJECT_TLS_CREDS_X509 },
+ { "cryptodev-backend-builtin", QEMU_CAPS_OBJECT_CRYPTO_BUILTIN },
+ { "virtio-crypto-device", QEMU_CAPS_DEVICE_VIRTIO_CRYPTO },
};
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBalloon[] = {
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index affb639..98cb817 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -370,6 +370,8 @@ typedef enum {
/* 230 */
QEMU_CAPS_OBJECT_TLS_CREDS_X509, /* -object tls-creds-x509 */
+ QEMU_CAPS_OBJECT_CRYPTO_BUILTIN,
+ QEMU_CAPS_DEVICE_VIRTIO_CRYPTO,
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3898ed7..8cf1258 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5451,6 +5451,132 @@ qemuBuildRNGCommandLine(virLogManagerPtr logManager,
}
+static char *
+qemuBuildCryptoBackendStr(virDomainCryptoDefPtr crypto,
+ virQEMUCapsPtr qemuCaps)
+{
+ const char *type = NULL;
+ char *alias = NULL;
+ char *queue = NULL;
+ char *ret = NULL;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ if (virAsprintf(&alias, "obj%s", crypto->info.alias) < 0)
+ goto cleanup;
+
+ if (crypto->queues > 1) {
+ if (virAsprintf(&queue, ",queues=%u", crypto->queues) < 0)
+ goto cleanup;
+ }
+
+ switch ((virDomainCryptoBackend)crypto->backend) {
+ case VIR_DOMAIN_CRYPTO_BACKEND_BUILTIN:
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_CRYPTO_BUILTIN)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("this qemu doesn't support the crypto-backend"
+ "-builtin"));
+ goto cleanup;
+ }
+
+ type = "cryptodev-backend-builtin";
+ break;
+
+ case VIR_DOMAIN_CRYPTO_BACKEND_LAST:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("unknown crypto backend"));
+ goto cleanup;
+ }
+
+ virBufferAsprintf(&buf, "%s,id=%s%s", type, alias, queue);
+
+ ret = virBufferContentAndReset(&buf);
+
+cleanup:
+ VIR_FREE(alias);
+ return ret;
+}
+
+
+char *
+qemuBuildCryptoDevStr(const virDomainDef *def,
+ virDomainCryptoDefPtr dev,
+ virQEMUCapsPtr qemuCaps)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ if (dev->model != VIR_DOMAIN_CRYPTO_MODEL_VIRTIO ||
+ !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_CRYPTO)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("this qemu doesn't support crypto device model '%s'"),
+ virDomainRNGModelTypeToString(dev->model));
+ goto error;
+ }
+
+ if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("this qemu only support crypto device PCI address type"));
+ goto error;
+ }
+
+ virBufferAsprintf(&buf, "virtio-crypto-pci,cryptodev=obj%s,id=%s",
+ dev->info.alias, dev->info.alias);
+
+ if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0)
+ goto error;
+
+ if (virBufferCheckError(&buf) < 0)
+ goto error;
+
+ return virBufferContentAndReset(&buf);
+
+error:
+ virBufferFreeAndReset(&buf);
+ return NULL;
+}
+
+
+static int
+qemuBuildCryptoCommandLine(virCommandPtr cmd,
+ const virDomainDef *def,
+ virQEMUCapsPtr qemuCaps)
+{
+ size_t i;
+
+ for (i = 0; i < def->ncryptos; i++) {
+ virDomainCryptoDefPtr crypto = def->cryptos[i];
+ char *tmp;
+
+ if (qemuAssignDeviceCryptoAlias(def, crypto)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("crypto device assign alias faile"));
+ return -1;
+ }
+
+ if (!crypto->info.alias) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("crypto device is missing alias"));
+ return -1;
+ }
+
+ /* add the Crypto backend */
+ if (!(tmp = qemuBuildCryptoBackendStr(crypto, qemuCaps)))
+ return -1;
+
+ virCommandAddArgList(cmd, "-object", tmp, NULL);
+ VIR_FREE(tmp);
+
+ /* add the device */
+ if (!(tmp = qemuBuildCryptoDevStr(def, crypto, qemuCaps)))
+ return -1;
+
+ virCommandAddArgList(cmd, "-device", tmp, NULL);
+ VIR_FREE(tmp);
+ }
+
+ return 0;
+}
+
+
static char *qemuBuildSmbiosBiosStr(virSysinfoBIOSDefPtr def)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -9312,6 +9438,9 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
if (qemuBuildRNGCommandLine(logManager, cmd, cfg, def, qemuCaps) < 0)
goto error;
+ if (qemuBuildCryptoCommandLine(cmd, def, qemuCaps) < 0)
+ goto error;
+
if (qemuBuildNVRAMCommandLine(cmd, def, qemuCaps) < 0)
goto error;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index c4d0567..ec9b3ac 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -143,6 +143,10 @@ int qemuBuildRNGBackendProps(virDomainRNGDefPtr rng,
const char **type,
virJSONValuePtr *props);
+char *qemuBuildCryptoDevStr(const virDomainDef *def,
+ virDomainCryptoDefPtr dev,
+ virQEMUCapsPtr qemuCaps);
+
char *qemuBuildShmemDevStr(virDomainDefPtr def,
virDomainShmemDefPtr shmem,
virQEMUCapsPtr qemuCaps);
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index ee44d45..26e6caa 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -328,6 +328,12 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def,
def->rngs[i]->info.type = type;
}
+ for (i = 0; i < def->ncryptos; i++) {
+ if (def->cryptos[i]->model == VIR_DOMAIN_CRYPTO_MODEL_VIRTIO &&
+ def->cryptos[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
+ def->cryptos[i]->info.type = type;
+ }
+
if (type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
for (i = 0; i < def->nfss; i++) {
if (def->fss[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
@@ -1236,6 +1242,17 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def,
goto error;
}
+ /* VirtIO CRYPTO */
+ for (i = 0; i < def->ncryptos; i++) {
+ if (def->cryptos[i]->model != VIR_DOMAIN_CRYPTO_MODEL_VIRTIO ||
+ !virDeviceInfoPCIAddressWanted(&def->cryptos[i]->info))
+ continue;
+
+ if (virDomainPCIAddressReserveNextSlot(addrs,
+ &def->cryptos[i]->info, flags) < 0)
+ goto error;
+ }
+
/* A watchdog - check if it is a PCI device */
if (def->watchdog &&
def->watchdog->model == VIR_DOMAIN_WATCHDOG_MODEL_I6300ESB &&
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 2089359..a28a3c2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7431,6 +7431,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
case VIR_DOMAIN_DEVICE_SHMEM:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("live attach of device '%s' is not supported"),
@@ -7522,6 +7523,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("live detach of device '%s' is not supported"),
@@ -7637,6 +7639,7 @@ qemuDomainUpdateDeviceLive(virConnectPtr conn,
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("live update of device '%s' is not supported"),
@@ -7800,6 +7803,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("persistent attach of device '%s' is not supported"),
@@ -7954,6 +7958,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("persistent detach of device '%s' is not supported"),
@@ -8052,6 +8057,7 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
case VIR_DOMAIN_DEVICE_NONE:
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
case VIR_DOMAIN_DEVICE_LAST:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("persistent update of device '%s' is not supported"),
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 093aaf9..c1cfb76 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3301,6 +3301,7 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver,
case VIR_DOMAIN_DEVICE_TPM:
case VIR_DOMAIN_DEVICE_PANIC:
case VIR_DOMAIN_DEVICE_LAST:
+ case VIR_DOMAIN_DEVICE_CRYPTO:
virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("don't know how to remove a %s device"),
virDomainDeviceTypeToString(dev->type));
--
1.8.3.1
7 years, 10 months