[libvirt] [PATCH v2] util: disallow assigning or resetting a pci-bridge device
Shivaprasad G Bhat
sbhat at linux.vnet.ibm.com
Mon Jan 23 13:40:23 UTC 2017
Hi Laine,
On 01/21/2017 01:50 AM, Laine Stump wrote:
> On 01/18/2017 11:10 AM, Martin Kletzander wrote:
>> On Wed, Jan 18, 2017 at 07:29:29PM +0530, Shivaprasad G Bhat wrote:
>>> It is destructive to attempt reset on a pci-bridge, the host can crash.
>>> The bridges won't contain any guest data and neither they can be
>>> passed through using vfio/stub. So, no point in allowing a reset on
>>> them.
>>>
>>
>> Wasn't resetting non-endpoint the only way in some cases when you needed
>> to passthrough 2 endpoint devices when none of them could be reset? I
>> might be very easily wrong, though.
>
> What you're thinking of is the code in virPCIDeviceReset() that
> attempts to do a "secondary bus reset" on the parent of an endpoint
> device if the reset of the endpoint device itself fails. This is never
> initiated directly by the user (or the top level of the libvirt API)
> though, but only done internally when attempts to reset an endpoint
> device fail (libvirt then tries doing a secondary bus reset of the
> endpoint's parent device).
>
> Of course *all* of the PCI reset stuff in libvirt is a moot point if
> you're using vfio anyway - vfio itself will handle any device resets
> that need to be done at the appropriate time. That's why
> virPCIDeviceReset() returns success almost immediately if the device
> is bound to vfio-pci. Since the only time the device would *not* be
> bound to vfio-pci would be 1) if a domain was using legacy KVM device
> assignment (which is deprecated, and I think may even be completely
> removed from new kernels) or 2) if a user manually requested a device
> reset with libvirt's virNodeDeviceReset() API (which realistically
> speaking nobody should ever need to do), there's really not much
> chance of this making an actual difference. (This makes me wonder
> where Shivaprasad encountered this in the real world...)
>
I encountered this with virsh nodedev-reset on a pci-bridge.
>>
>>> Signed-off-by: Shivaprasad G Bhat <sbhat at linux.vnet.ibm.com>
>>> ---
>>> src/util/virhostdev.c | 10 ++++++++++
>>> src/util/virpci.c | 11 +++++++++++
>>> 2 files changed, 21 insertions(+)
>>>
>>> diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
>>> index 0673afb..16b96f3 100644
>>> --- a/src/util/virhostdev.c
>>> +++ b/src/util/virhostdev.c
>>> @@ -532,6 +532,16 @@
>>> virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
>>> bool strict_acs_check = !!(flags &
>>> VIR_HOSTDEV_STRICT_ACS_CHECK);
>>> bool usesVFIO = (virPCIDeviceGetStubDriver(pci) ==
>>> VIR_PCI_STUB_DRIVER_VFIO);
>>> struct virHostdevIsPCINodeDeviceUsedData data = { mgr,
>>> dom_name, usesVFIO };
>>> + int hdrType = -1;
>>> +
>>> + if (virPCIGetHeaderType(pci, &hdrType) < 0)
>>> + goto cleanup;
>>> +
>>> + if (hdrType == VIR_PCI_HEADER_PCI_BRIDGE) {
>
> I verified with the VFIO author/maintainer (Alex Williamson) that vfio
> will assign only endpoint devices - cardbus bridge devices and PCI
> bridge devices are both not allowed. So I think that this check should
> also be for "hdrType != VIR_PCI_HEADER_ENDPOINT".
>
> Also, it's kind of nit-picking, but I think this chunk should be in a
> separate patch from the other. One is preventing attempts to assign a
> device that isn't an endpoint, and the otehr is preventing attemps to
> reset a device that isn't an endpoint.
>
>
>>> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("PCI bridge devices"
>>> + " cannot be assigned to guests"));
>
> When a string is split into multiple lines, the final character of
> each line's substring must be a space (this is in the contribution
> guidelines and is enforced by make syntax-check)
>
I don't see a make syntax-check failure on my system though. Moved the
space to the previous line.
>
>>> + goto cleanup;
>>> + }
>>>
>>> if (!usesVFIO && !virPCIDeviceIsAssignable(pci,
>>> strict_acs_check)) {
>>> virReportError(VIR_ERR_OPERATION_INVALID,
>>> diff --git a/src/util/virpci.c b/src/util/virpci.c
>>> index 0601f49..f205abf 100644
>>> --- a/src/util/virpci.c
>>> +++ b/src/util/virpci.c
>>> @@ -933,6 +933,17 @@ virPCIDeviceReset(virPCIDevicePtr dev,
>>> char *drvName = NULL;
>>> int ret = -1;
>>> int fd = -1;
>>> + int hdrType = -1;
>>> +
>>> + if (virPCIGetHeaderType(dev, &hdrType) < 0)
>>> + return -1;
>>> +
>>> + if (hdrType != VIR_PCI_HEADER_ENDPOINT) {
>>> + virReportError(VIR_ERR_INTERNAL_ERROR,
>>> + _("Invalid attempt to reset non-endpoint PCI
>>> device %s."
>>> + " Only PCI endpoint devices can be
>>> reset"), dev->name);
>
> Same problem. make syntax-check will catch it.
>
>
> If you split this in two, change the first check to be for != endpoint
> rather than == bridge, and fix the strings, then these can be pushed.
>
Posted the v2 as suggested.
Thanks,
Shivaprasad
More information about the libvir-list
mailing list