mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Farhan Ali <alifm@linux.ibm.com>
To: Alex Williamson <alex@shazbot.org>
Cc: linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-pci@vger.kernel.org, helgaas@kernel.org, lukas@wunner.de,
	clg@redhat.com, kbusch@kernel.org, schnelle@linux.ibm.com,
	mjrosato@linux.ibm.com
Subject: Re: [PATCH v13 5/7] vfio-pci/zdev: Add a device feature for error information
Date: Tue, 14 Apr 2026 10:13:22 -0700	[thread overview]
Message-ID: <5f26af4c-9584-4c70-9702-0a3bcd0c4ad1@linux.ibm.com> (raw)
In-Reply-To: <20260414081238.23e2cecc@shazbot.org>


On 4/14/2026 7:12 AM, Alex Williamson wrote:
> On Mon, 13 Apr 2026 16:40:49 -0700
> Farhan Ali <alifm@linux.ibm.com> wrote:
>
>> On 4/13/2026 3:57 PM, Alex Williamson wrote:
>>> On Mon, 13 Apr 2026 14:06:06 -0700
>>> Farhan Ali <alifm@linux.ibm.com> wrote:
>>>   
>>>> For zPCI devices, we have platform specific error information. The platform
>>>> firmware provides this error information to the operating system in an
>>>> architecture specific mechanism. To enable recovery from userspace for
>>>> these devices, we want to expose this error information to userspace. Add a
>>>> new device feature to expose this information.
>>>>
>>>> Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
>>>> Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
>>>> ---
>>>>    arch/s390/include/asm/pci.h      |  3 +++
>>>>    arch/s390/pci/pci_event.c        | 19 +++++++++++++++++++
>>>>    drivers/vfio/pci/vfio_pci_core.c |  2 ++
>>>>    drivers/vfio/pci/vfio_pci_priv.h |  9 +++++++++
>>>>    drivers/vfio/pci/vfio_pci_zdev.c | 31 +++++++++++++++++++++++++++++++
>>>>    include/uapi/linux/vfio.h        | 20 ++++++++++++++++++++
>>>>    6 files changed, 84 insertions(+)
>>>>
>>>> diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
>>>> index 9a6a4eb9d7c1..9c8ee97d7e8a 100644
>>>> --- a/arch/s390/include/asm/pci.h
>>>> +++ b/arch/s390/include/asm/pci.h
>>>> @@ -360,6 +360,9 @@ int zpci_clear_error_state(struct zpci_dev *zdev);
>>>>    int zpci_reset_load_store_blocked(struct zpci_dev *zdev);
>>>>    void zpci_start_mediated_recovery(struct zpci_dev *zdev);
>>>>    void zpci_stop_mediated_recovery(struct zpci_dev *zdev);
>>>> +void zpci_get_pending_error_and_count(struct zpci_dev *zdev,
>>>> +				      struct zpci_ccdf_err *ccdf,
>>>> +				      int *count);
>>>>    
>>>>    #ifdef CONFIG_NUMA
>>>>    
>>>> diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
>>>> index c279a9f50a64..c8714d4a32fa 100644
>>>> --- a/arch/s390/pci/pci_event.c
>>>> +++ b/arch/s390/pci/pci_event.c
>>>> @@ -74,6 +74,25 @@ static void zpci_store_pci_error(struct pci_dev *pdev,
>>>>    	zdev->pending_errs.count++;
>>>>    }
>>>>    
>>>> +void zpci_get_pending_error_and_count(struct zpci_dev *zdev,
>>>> +				      struct zpci_ccdf_err *ccdf,
>>>> +				      int *count)
>>>> +{
>>>> +	int head = 0;
>>> Unnecessary.  Should also be a blank line between variable declaration
>>> and code.
>>>   
>>>> +	*count = 0;
>>> But why do we zero this and not ccdf?
>> I had thought of memsetting ccdf to 0, but the only caller right already
>> initializes to 0. So didn't think it was needed.
> The caller initializes count as well.
>
>>>> +
>>>> +	guard(mutex)(&zdev->pending_errs_lock);
>>>> +	if (zdev->pending_errs.count) {
>>>> +		head = zdev->pending_errs.head % ZPCI_ERR_PENDING_MAX;
>>>> +		memcpy(ccdf, &zdev->pending_errs.err[head],
>>>> +		       sizeof(struct zpci_ccdf_err));
>>>> +		zdev->pending_errs.head++;
>>>> +		zdev->pending_errs.count--;
>>>> +		*count = zdev->pending_errs.count;
>>>> +	}
>>>> +}
>>> You've describe in the uAPI now how pec = 0 means no error, but why not
>>> remove that ambiguity altogether and return -ENOMSG in that case.  We
>>> could start here and pass it through:
>>>
>>> {
>>> 	int head;
>>>
>>> 	guard(mutex)(&zdev->pending_errs_lock);
>>>
>>> 	if (!zdev->pending_errs.count)
>>> 		return -ENOMSG;
>>>
>>> 	head = zdev->pending_errs.head % ZPCI_ERR_PENDING_MAX;
>>> 	memcpy(ccdf, &zdev->pending_errs.err[head],
>>> 	       sizeof(struct zpci_ccdf_err));
>>> 	zdev->pending_errs.head++;
>>> 	zdev->pending_errs.count--;
>>> 	*count = zdev->pending_errs.count;
>>>
>>> 	return 0;
>>> }
>> I had thought of returning an error (ENOENT was what I was going with),
>> but perhaps I misunderstood your comment from v12 about specifying pec =
>> 0 and pending error = 0 as not being an error. My assumption was as this
>> is not an error we shouldn't return an error to userspace.
> I think I was trying to get clarity on how 0/0 is interpreted because
> it seems like a weak point of the uAPI.  We could make a more intuitive
> uAPI if we make the "I have no message of desired type" response an
> explicit, unique errno, rather than a reserved pec value.
>
>>>> +EXPORT_SYMBOL_GPL(zpci_get_pending_error_and_count);
>>>> +
>>>>    void zpci_start_mediated_recovery(struct zpci_dev *zdev)
>>>>    {
>>>>    	guard(mutex)(&zdev->pending_errs_lock);
>>>> diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c
>>>> index ad52abc46c04..5403730786a1 100644
>>>> --- a/drivers/vfio/pci/vfio_pci_core.c
>>>> +++ b/drivers/vfio/pci/vfio_pci_core.c
>>>> @@ -1534,6 +1534,8 @@ int vfio_pci_core_ioctl_feature(struct vfio_device *device, u32 flags,
>>>>    		return vfio_pci_core_feature_token(vdev, flags, arg, argsz);
>>>>    	case VFIO_DEVICE_FEATURE_DMA_BUF:
>>>>    		return vfio_pci_core_feature_dma_buf(vdev, flags, arg, argsz);
>>>> +	case VFIO_DEVICE_FEATURE_ZPCI_ERROR:
>>>> +		return vfio_pci_zdev_feature_err(device, flags, arg, argsz);
>>>>    	default:
>>>>    		return -ENOTTY;
>>>>    	}
>>>> diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h
>>>> index fca9d0dfac90..4e7162234a2e 100644
>>>> --- a/drivers/vfio/pci/vfio_pci_priv.h
>>>> +++ b/drivers/vfio/pci/vfio_pci_priv.h
>>>> @@ -93,6 +93,8 @@ int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,
>>>>    				struct vfio_info_cap *caps);
>>>>    int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev);
>>>>    void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev);
>>>> +int vfio_pci_zdev_feature_err(struct vfio_device *device, u32 flags,
>>>> +			      void __user *arg, size_t argsz);
>>>>    #else
>>>>    static inline int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,
>>>>    					      struct vfio_info_cap *caps)
>>>> @@ -107,6 +109,13 @@ static inline int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev)
>>>>    
>>>>    static inline void vfio_pci_zdev_close_device(struct vfio_pci_core_device *vdev)
>>>>    {}
>>>> +
>>>> +static inline int vfio_pci_zdev_feature_err(struct vfio_device *device,
>>>> +					    u32 flags, void __user *arg,
>>>> +					    size_t argsz)
>>>> +{
>>>> +	return -ENOTTY;
>>>> +}
>>>>    #endif
>>>>    
>>>>    static inline bool vfio_pci_is_vga(struct pci_dev *pdev)
>>>> diff --git a/drivers/vfio/pci/vfio_pci_zdev.c b/drivers/vfio/pci/vfio_pci_zdev.c
>>>> index 0658095ac5b1..ee1647f0ffe6 100644
>>>> --- a/drivers/vfio/pci/vfio_pci_zdev.c
>>>> +++ b/drivers/vfio/pci/vfio_pci_zdev.c
>>>> @@ -141,6 +141,37 @@ int vfio_pci_info_zdev_add_caps(struct vfio_pci_core_device *vdev,
>>>>    	return ret;
>>>>    }
>>>>    
>>>> +int vfio_pci_zdev_feature_err(struct vfio_device *device, u32 flags,
>>>> +			      void __user *arg, size_t argsz)
>>>> +{
>>>> +	struct vfio_device_feature_zpci_err err = {};
>>>> +	struct vfio_pci_core_device *vdev;
>>>> +	struct zpci_ccdf_err ccdf = {};
>>>> +	struct zpci_dev *zdev;
>>>> +	int pending_errors = 0;
>>>> +	int ret;
>>>> +
>>>> +	vdev = container_of(device, struct vfio_pci_core_device, vdev);
>>>> +	zdev = to_zpci(vdev->pdev);
>>>> +	if (!zdev)
>>>> +		return -ENODEV;
>>>> +
>>>> +	ret = vfio_check_feature(flags, argsz, VFIO_DEVICE_FEATURE_GET,
>>>> +				 sizeof(err));
>>>> +	if (ret != 1)
>>>> +		return ret;
>>>> +
>>>> +	zpci_get_pending_error_and_count(zdev, &ccdf, &pending_errors);
>>>> +
>>>> +	err.version = 1;
>>>> +	err.pec = ccdf.pec;
>>>> +	err.pending_errors = pending_errors;
>>>> +	if (copy_to_user(arg, &err, sizeof(err)))
>>>> +		return -EFAULT;
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>>    int vfio_pci_zdev_open_device(struct vfio_pci_core_device *vdev)
>>>>    {
>>>>    	struct zpci_dev *zdev = to_zpci(vdev->pdev);
>>>> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
>>>> index 5de618a3a5ee..2980ca39dd38 100644
>>>> --- a/include/uapi/linux/vfio.h
>>>> +++ b/include/uapi/linux/vfio.h
>>>> @@ -1534,6 +1534,26 @@ struct vfio_device_feature_dma_buf {
>>>>     */
>>>>    #define VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2  12
>>>>    
>>>> +/**
>>>> + * VFIO_DEVICE_FEATURE_ZPCI_ERROR feature provides PCI error information to
>>>> + * userspace for vfio-pci devices on s390x. On s390x, PCI error recovery
>>>> + * involves platform firmware and notification to operating system is done
>>>> + * by architecture specific mechanism. Exposing this information to
>>>> + * userspace allows it to take appropriate actions to handle an
>>>> + * error on the device. The pending_errors provide any additional errors
>>>> + * pending for the device, and userspace should read until zero. A value of
>>>> + * 0 for pending_errors and pec would indicate no pending errors that need
>>>> + * to be handled.
>>>> + */
>>>> +
>>>> +struct vfio_device_feature_zpci_err {
>>>> +	__u8 version;
>>>> +	__u8 pending_errors;
>>>> +	__u16 pec;
>>>> +};
>>> I assume .version is for compatibility, but we don't define a strategy
>>> for using it or specify what the version should be for this table.  It
>>> doesn't seem like there's actually an value-add to having it.
>> Its possible we may need to extend this structure in the future if we
>> want to report more information to userspace. I at least want the
>> flexibility to do so. We had some discussion around this [1] in an
>> earlier version. I was trying to follow similar versioning pattern we
>> had around vfio-pci/zdev structures.
> IMHO, the version field is a dead end towards achieving this,
> especially if we don't specify from the onset the expected version
> value or the compatibility semantics.  All that's going to happen is
> that some userspace will hard code that it understands version 1
> because that's what's currently reported and matches the struct defined
> here, and you can never ever report anything other than version 1
> without breaking that user.  At that point you need to come up with
> some other means for the user to opt-in to a new version, whether it's
> triggered by another feature (as we did with the PRECOPY_INFOv2 above
> this), or we reimplement the whole v2 feature.

My understanding was based on how we version some of the capability 
structures for zdev (in include/uapi/linux/vfio_zdev.h). If we wanted to 
provide more information to userspace in the future, what would be 
preferred approach? Do we need to explicitly define a v2 feature? I am 
open to suggestions on this.

If we need to define v2 explicitly in the future, then yes I agree we 
can simplify it to return only the PEC code (or an error code otherwise).

Thanks

Farhan


  reply	other threads:[~2026-04-14 17:13 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-13 21:06 [PATCH v13 0/7] Error recovery for vfio-pci devices on s390x Farhan Ali
2026-04-13 21:06 ` [PATCH v13 1/7] PCI: Allow per function PCI slots to fix slot reset on s390 Farhan Ali
2026-04-13 21:06 ` [PATCH v13 2/7] PCI: Avoid saving config space state if inaccessible Farhan Ali
2026-04-13 21:06 ` [PATCH v13 3/7] PCI: Fail FLR when config space is inaccessible Farhan Ali
2026-04-13 21:06 ` [PATCH v13 4/7] s390/pci: Store PCI error information for passthrough devices Farhan Ali
2026-04-13 21:06 ` [PATCH v13 5/7] vfio-pci/zdev: Add a device feature for error information Farhan Ali
2026-04-13 22:57   ` Alex Williamson
2026-04-13 23:40     ` Farhan Ali
2026-04-14 14:12       ` Alex Williamson
2026-04-14 17:13         ` Farhan Ali [this message]
2026-04-14 17:41           ` Alex Williamson
2026-04-14 18:45             ` Farhan Ali
2026-04-14 19:43               ` Niklas Schnelle
2026-04-14 21:06                 ` Farhan Ali
2026-04-15 19:17                   ` Niklas Schnelle
2026-04-13 21:06 ` [PATCH v13 6/7] vfio/pci: Add a reset_done callback for vfio-pci driver Farhan Ali
2026-04-13 21:06 ` [PATCH v13 7/7] vfio/pci: Remove the pcie check for VFIO_PCI_ERR_IRQ_INDEX Farhan Ali

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5f26af4c-9584-4c70-9702-0a3bcd0c4ad1@linux.ibm.com \
    --to=alifm@linux.ibm.com \
    --cc=alex@shazbot.org \
    --cc=clg@redhat.com \
    --cc=helgaas@kernel.org \
    --cc=kbusch@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=mjrosato@linux.ibm.com \
    --cc=schnelle@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®