linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] kernfs: implement custom llseek method to fix userspace regression
@ 2023-08-14 19:08 Valentine Sinitsyn
  2023-08-14 20:01 ` Dan Williams
  0 siblings, 1 reply; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-08-14 19:08 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"),
mmapable sysfs binary attributes have started receiving their
f_mapping from the iomem pseudo filesystem, so that
CONFIG_IO_STRICT_DEVMEM is honored in sysfs (and procfs) as well
as in /dev/[k]mem.

This resulted in a userspace-visible regression: lseek(fd, 0, SEEK_END)
now returns zero regardless the real sysfs attribute size which stat()
reports. The reason is that kernfs files use generic_file_llseek()
implementation, which relies on f_mapping->host inode to get the file
size. As f_mapping is now redefined, f_mapping->host points to an
anonymous zero-sized iomem inode which has nothing to do with sysfs
attribute or kernfs file representing it. This being said, f_inode
remains valid, so stat() which uses it works correctly.

Fixes the regression by implementing a custom llseek fop for kernfs,
which uses an attribute's file inode to get the file size,
just as stat() does.

Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
---
 fs/kernfs/file.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 180906c36f51..6d81e0c981f3 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -903,6 +903,21 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
 	return ret;
 }
 
+static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
+{
+	/*
+	 * This is almost identical to generic_file_llseek() except it uses
+	 * cached inode value instead of f_mapping->host.
+	 * The reason is that, for PCI resources in sysfs the latter points to
+	 * iomem_inode whose size has nothing to do with the attribute's size.
+	 */
+	struct inode *inode = file_inode(file);
+
+	return generic_file_llseek_size(file, offset, whence,
+					inode->i_sb->s_maxbytes,
+					i_size_read(inode));
+}
+
 static void kernfs_notify_workfn(struct work_struct *work)
 {
 	struct kernfs_node *kn;
@@ -1005,7 +1020,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
 const struct file_operations kernfs_file_fops = {
 	.read_iter	= kernfs_fop_read_iter,
 	.write_iter	= kernfs_fop_write_iter,
-	.llseek		= generic_file_llseek,
+	.llseek		= kernfs_fop_llseek,
 	.mmap		= kernfs_fop_mmap,
 	.open		= kernfs_fop_open,
 	.release	= kernfs_fop_release,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* RE: [PATCH] kernfs: implement custom llseek method to fix userspace regression
  2023-08-14 19:08 [PATCH] kernfs: implement custom llseek method to fix userspace regression Valentine Sinitsyn
@ 2023-08-14 20:01 ` Dan Williams
  2023-08-15  8:25   ` Valentin Sinitsyn
  0 siblings, 1 reply; 31+ messages in thread
From: Dan Williams @ 2023-08-14 20:01 UTC (permalink / raw)
  To: Valentine Sinitsyn, Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

Valentine Sinitsyn wrote:
> Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"),
> mmapable sysfs binary attributes have started receiving their
> f_mapping from the iomem pseudo filesystem, so that
> CONFIG_IO_STRICT_DEVMEM is honored in sysfs (and procfs) as well
> as in /dev/[k]mem.
> 
> This resulted in a userspace-visible regression: lseek(fd, 0, SEEK_END)
> now returns zero regardless the real sysfs attribute size which stat()
> reports. The reason is that kernfs files use generic_file_llseek()
> implementation, which relies on f_mapping->host inode to get the file
> size. As f_mapping is now redefined, f_mapping->host points to an
> anonymous zero-sized iomem inode which has nothing to do with sysfs
> attribute or kernfs file representing it. This being said, f_inode
> remains valid, so stat() which uses it works correctly.

Can you say a bit more about what userspace scenario regressed so that
others doing backports can make a judgement call on the severity?

> 
> Fixes the regression by implementing a custom llseek fop for kernfs,
> which uses an attribute's file inode to get the file size,
> just as stat() does.
> 
> Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
> Cc: stable@vger.kernel.org
> Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
> ---
>  fs/kernfs/file.c | 17 ++++++++++++++++-
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
> index 180906c36f51..6d81e0c981f3 100644
> --- a/fs/kernfs/file.c
> +++ b/fs/kernfs/file.c
> @@ -903,6 +903,21 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
>  	return ret;
>  }
>  
> +static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
> +{
> +	/*
> +	 * This is almost identical to generic_file_llseek() except it uses
> +	 * cached inode value instead of f_mapping->host.
> +	 * The reason is that, for PCI resources in sysfs the latter points to
> +	 * iomem_inode whose size has nothing to do with the attribute's size.
> +	 */
> +	struct inode *inode = file_inode(file);

My only concern is whether there are any scenarios where this is not
appropriate. I.e. do a bit more work to define a kernfs_ops instance
specifically for overriding lseek() in this scenario.

> +
> +	return generic_file_llseek_size(file, offset, whence,
> +					inode->i_sb->s_maxbytes,
> +					i_size_read(inode));
> +}
> +
>  static void kernfs_notify_workfn(struct work_struct *work)
>  {
>  	struct kernfs_node *kn;
> @@ -1005,7 +1020,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
>  const struct file_operations kernfs_file_fops = {
>  	.read_iter	= kernfs_fop_read_iter,
>  	.write_iter	= kernfs_fop_write_iter,
> -	.llseek		= generic_file_llseek,
> +	.llseek		= kernfs_fop_llseek,
>  	.mmap		= kernfs_fop_mmap,
>  	.open		= kernfs_fop_open,
>  	.release	= kernfs_fop_release,
> -- 
> 2.34.1
> 



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] kernfs: implement custom llseek method to fix userspace regression
  2023-08-14 20:01 ` Dan Williams
@ 2023-08-15  8:25   ` Valentin Sinitsyn
  2023-08-15 15:48     ` Dan Williams
  0 siblings, 1 reply; 31+ messages in thread
From: Valentin Sinitsyn @ 2023-08-15  8:25 UTC (permalink / raw)
  To: Dan Williams, Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, linux-kernel

On 15.08.2023 01:01, Dan Williams wrote:
> Valentine Sinitsyn wrote:
>> Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"),
>> mmapable sysfs binary attributes have started receiving their
>> f_mapping from the iomem pseudo filesystem, so that
>> CONFIG_IO_STRICT_DEVMEM is honored in sysfs (and procfs) as well
>> as in /dev/[k]mem.
>>
>> This resulted in a userspace-visible regression: lseek(fd, 0, SEEK_END)
>> now returns zero regardless the real sysfs attribute size which stat()
>> reports. The reason is that kernfs files use generic_file_llseek()
>> implementation, which relies on f_mapping->host inode to get the file
>> size. As f_mapping is now redefined, f_mapping->host points to an
>> anonymous zero-sized iomem inode which has nothing to do with sysfs
>> attribute or kernfs file representing it. This being said, f_inode
>> remains valid, so stat() which uses it works correctly.
> 
> Can you say a bit more about what userspace scenario regressed so that
> others doing backports can make a judgement call on the severity?

We've encountered this regression in the code which used lseek() to 
determine the size of PCI region. It was roughly equivalent to:

#define SYSFS_DEVICE_DIR "/sys/bus/pci/devices/<some id>/"

int fd = open(SYSFS_DEVICE_DIR "/resource0", O_RDWR);
off_t size = lseek(fd, 0, SEEK_END);
assert(size != 0)

Calling lseek() with whence argument other than SEEK_END and non-zero 
offset on this fd returns an error as the kernel considers it as seeking 
past EOF.

I'll add this explanation to v2 commit message.

> 
>>
>> Fixes the regression by implementing a custom llseek fop for kernfs,
>> which uses an attribute's file inode to get the file size,
>> just as stat() does.
>>
>> Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
>> ---
>>   fs/kernfs/file.c | 17 ++++++++++++++++-
>>   1 file changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
>> index 180906c36f51..6d81e0c981f3 100644
>> --- a/fs/kernfs/file.c
>> +++ b/fs/kernfs/file.c
>> @@ -903,6 +903,21 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
>>   	return ret;
>>   }
>>   
>> +static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
>> +{
>> +	/*
>> +	 * This is almost identical to generic_file_llseek() except it uses
>> +	 * cached inode value instead of f_mapping->host.
>> +	 * The reason is that, for PCI resources in sysfs the latter points to
>> +	 * iomem_inode whose size has nothing to do with the attribute's size.
>> +	 */
>> +	struct inode *inode = file_inode(file);
> 
> My only concern is whether there are any scenarios where this is not
> appropriate. I.e. do a bit more work to define a kernfs_ops instance
> specifically for overriding lseek() in this scenario.

Not sure I'm getting you here: do you mean something like this?

struct inode *inode = is_f_mapping_redefined(file) ? file_inode(file) : 
file->f_mapping->host;

My understanding is file->f_inode should always be non-NULL and point to 
the inode corresponding the path of the opened file, so it should be 
safe to call regardless what f_mapping->host is. Do I miss anything?

Best,
Valentin

> 
>> +
>> +	return generic_file_llseek_size(file, offset, whence,
>> +					inode->i_sb->s_maxbytes,
>> +					i_size_read(inode));
>> +}
>> +
>>   static void kernfs_notify_workfn(struct work_struct *work)
>>   {
>>   	struct kernfs_node *kn;
>> @@ -1005,7 +1020,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
>>   const struct file_operations kernfs_file_fops = {
>>   	.read_iter	= kernfs_fop_read_iter,
>>   	.write_iter	= kernfs_fop_write_iter,
>> -	.llseek		= generic_file_llseek,
>> +	.llseek		= kernfs_fop_llseek,
>>   	.mmap		= kernfs_fop_mmap,
>>   	.open		= kernfs_fop_open,
>>   	.release	= kernfs_fop_release,
>> -- 
>> 2.34.1
>>
> 
> 


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH] kernfs: implement custom llseek method to fix userspace regression
  2023-08-15  8:25   ` Valentin Sinitsyn
@ 2023-08-15 15:48     ` Dan Williams
  2023-08-17 18:53       ` Valentin Sinitsyn
  0 siblings, 1 reply; 31+ messages in thread
From: Dan Williams @ 2023-08-15 15:48 UTC (permalink / raw)
  To: Valentin Sinitsyn, Dan Williams, Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, linux-kernel

Valentin Sinitsyn wrote:
[..]
> > My only concern is whether there are any scenarios where this is not
> > appropriate. I.e. do a bit more work to define a kernfs_ops instance
> > specifically for overriding lseek() in this scenario.
> 
> Not sure I'm getting you here: do you mean something like this?
> 
> struct inode *inode = is_f_mapping_redefined(file) ? file_inode(file) : 
> file->f_mapping->host;

I meant something like the patch below (incomplete, but shows the idea).

> My understanding is file->f_inode should always be non-NULL and point to 
> the inode corresponding the path of the opened file, so it should be 
> safe to call regardless what f_mapping->host is. Do I miss anything?

That matches my understanding and I do not think you missed anything. At
the same time a comment about "PCI resources" is out of place in
fs/kernfs/file.c.

On the rare chance that someone down the line cares about the
difference, a more localized change like this lets this override be done
in generic terms (f_mapping override) without reference to PCI resource
specifics:

diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a12ac0356c69..748804cd889f 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -167,6 +167,23 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
 	return battr->mmap(of->file, kobj, battr, vma);
 }
 
+static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset,
+				  int whence)
+{
+	struct bin_attribute *battr = of->kn->priv;
+	struct kobject *kobj = of->kn->parent->priv;
+
+	/* when mapping is overridden do not use it to lookup the inode */
+	if (battr->f_mapping) {
+		struct inode *file_inode(of->file);
+
+		return generic_file_llseek_size(of->file, offset, whence,
+						inode->i_sb->s_maxbytes,
+						i_size_read(inode));
+	}
+	return generic_file_llseek(of->file, offset, whence);
+}
+
 static int sysfs_kf_bin_open(struct kernfs_open_file *of)
 {
 	struct bin_attribute *battr = of->kn->priv;
@@ -249,6 +266,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 	.write		= sysfs_kf_bin_write,
 	.mmap		= sysfs_kf_bin_mmap,
 	.open		= sysfs_kf_bin_open,
+	.llseek		= sysfs_kf_bin_llseek,
 };
 
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 73f5c120def8..9ed535930259 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -316,6 +316,7 @@ struct kernfs_ops {
 			 struct poll_table_struct *pt);
 
 	int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
+	loff_t (*llseek)(struct kernfs_open_file *of, loff_t offset, int whence);
 };
 
 /*

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH] kernfs: implement custom llseek method to fix userspace regression
  2023-08-15 15:48     ` Dan Williams
@ 2023-08-17 18:53       ` Valentin Sinitsyn
  2023-08-21  7:29         ` [RESEND PATCH v2 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
  2023-08-21  7:29         ` [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs Valentine Sinitsyn
  0 siblings, 2 replies; 31+ messages in thread
From: Valentin Sinitsyn @ 2023-08-17 18:53 UTC (permalink / raw)
  To: Dan Williams, Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, linux-kernel

On 15.08.2023 20:48, Dan Williams wrote:
> Valentin Sinitsyn wrote:
> [..]
>>> My only concern is whether there are any scenarios where this is not
>>> appropriate. I.e. do a bit more work to define a kernfs_ops instance
>>> specifically for overriding lseek() in this scenario.
>>
>> Not sure I'm getting you here: do you mean something like this?
>>
>> struct inode *inode = is_f_mapping_redefined(file) ? file_inode(file) :
>> file->f_mapping->host;
> 
> I meant something like the patch below (incomplete, but shows the idea).
Understood, thanks. I believe the change can be localized even further, 
up to the point where battr->f_mapping is initialized with 
iomem_get_mapping, as it is the only override known to break 
generic_file_llseek().

I'll send the updated patch in a few days.

Best,
Valentin

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [RESEND PATCH v2 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-08-17 18:53       ` Valentin Sinitsyn
@ 2023-08-21  7:29         ` Valentine Sinitsyn
  2023-08-21  7:29         ` [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs Valentine Sinitsyn
  1 sibling, 0 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-08-21  7:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo, Dan Williams
  Cc: Daniel Vetter, Bjorn Helgaas, linux-kernel

As of now, seeking in sysfs files is handled by generic_file_llseek().
There are situations where one may want to customize seeking logic:

- Many sysfs entries are fixed files while generic_file_llseek() accepts
  past-the-end positions. Not only being useless by itself, this
  also means a bug in userspace code will trigger not at lseek(), but at
  some later point making debugging harder.
- generic_file_llseek() relies on f_mapping->host to get the file size
  which might not be correct for all sysfs entries.
  See commit 636b21b50152 ("PCI: Revoke mappings like devmem") as an example.

Implement llseek method to override this behavior at sysfs attribute
level. The method is optional, and if it is absent,
generic_file_llseek() is called to preserve backwards compatibility.

Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
---
Looks like the patch didn't get to lkml, resending

 fs/kernfs/file.c       | 14 +++++++++++++-
 fs/sysfs/file.c        | 13 +++++++++++++
 include/linux/kernfs.h |  1 +
 include/linux/sysfs.h  |  2 ++
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 180906c36f51..6166bf74d5b8 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -903,6 +903,18 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
 	return ret;
 }

+static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
+{
+	struct kernfs_open_file *of = kernfs_of(file);
+	const struct kernfs_ops *ops;
+
+	ops = kernfs_ops(of->kn);
+	if (ops->llseek)
+		return ops->llseek(of, offset, whence);
+	else
+		return generic_file_llseek(file, offset, whence);
+}
+
 static void kernfs_notify_workfn(struct work_struct *work)
 {
 	struct kernfs_node *kn;
@@ -1005,7 +1017,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
 const struct file_operations kernfs_file_fops = {
 	.read_iter	= kernfs_fop_read_iter,
 	.write_iter	= kernfs_fop_write_iter,
-	.llseek		= generic_file_llseek,
+	.llseek		= kernfs_fop_llseek,
 	.mmap		= kernfs_fop_mmap,
 	.open		= kernfs_fop_open,
 	.release	= kernfs_fop_release,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a12ac0356c69..6b7652fb8050 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -167,6 +167,18 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
 	return battr->mmap(of->file, kobj, battr, vma);
 }
 
+static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset,
+				  int whence)
+{
+	struct bin_attribute *battr = of->kn->priv;
+	struct kobject *kobj = of->kn->parent->priv;
+
+	if (battr->llseek)
+		return battr->llseek(of->file, kobj, battr, offset, whence);
+	else
+		return generic_file_llseek(of->file, offset, whence);
+}
+
 static int sysfs_kf_bin_open(struct kernfs_open_file *of)
 {
 	struct bin_attribute *battr = of->kn->priv;
@@ -249,6 +261,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 	.write		= sysfs_kf_bin_write,
 	.mmap		= sysfs_kf_bin_mmap,
 	.open		= sysfs_kf_bin_open,
+	.llseek		= sysfs_kf_bin_llseek,
 };
 
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 73f5c120def8..9ed535930259 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -316,6 +316,7 @@ struct kernfs_ops {
 			 struct poll_table_struct *pt);
 
 	int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
+	loff_t (*llseek)(struct kernfs_open_file *of, loff_t offset, int whence);
 };
 
 /*
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index fd3fe5c8c17f..b717a70219f6 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -181,6 +181,8 @@ struct bin_attribute {
 			char *, loff_t, size_t);
 	ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
 			 char *, loff_t, size_t);
+	loff_t (*llseek)(struct file *, struct kobject *, struct bin_attribute *,
+			 loff_t, int);
 	int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
 		    struct vm_area_struct *vma);
 };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs
  2023-08-17 18:53       ` Valentin Sinitsyn
  2023-08-21  7:29         ` [RESEND PATCH v2 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
@ 2023-08-21  7:29         ` Valentine Sinitsyn
  2023-08-21 19:55           ` Bjorn Helgaas
  2023-08-21 23:15           ` [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs kernel test robot
  1 sibling, 2 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-08-21  7:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo, Dan Williams
  Cc: Daniel Vetter, Bjorn Helgaas, linux-kernel

Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"), mmapable
sysfs entries have started to receive their f_mapping from the iomem
pseudo filesystem, so that CONFIG_IO_STRICT_DEVMEM is honored in sysfs
(and procfs) as well as in /dev/[k]mem.

This resulted in a userspace-visible regression:

1. Open a sysfs PCI resource file (eg. /sys/bus/pci/devices/*/resource0)
2. Use lseek(fd, 0, SEEK_END) to determine its size

Expected result: a PCI region size is returned.
Actual result: 0 is returned.

The reason is that PCI resource files residing in sysfs use
generic_file_llseek(), which relies on f_mapping->host inode to get the
file size. As f_mapping is now redefined, f_mapping->host points to an
anonymous zero-sized iomem_inode which has nothing to do with sysfs file
in question.

Implement a custom llseek method for sysfs PCI resources, which is
almost the same as proc_bus_pci_lseek() used for procfs entries.

This makes sysfs and procfs entries consistent with regards to seeking,
but also introduces userspace-visible changes to seeking PCI resources
in sysfs:

- SEEK_DATA and SEEK_HOLE are no longer supported;
- Seeking past the end of the file is prohibited while previously
  offsets up to MAX_NON_LFS were accepted (reading from these offsets
  was always invalid).

Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
---
Looks like the patch didn't get to lkml, resending

 drivers/pci/pci-sysfs.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index ab32a91f287b..42eaeb8d4a4f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -967,6 +967,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_io->attr.mode = 0600;
 	b->legacy_io->read = pci_read_legacy_io;
 	b->legacy_io->write = pci_write_legacy_io;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_io->mmap = pci_mmap_legacy_io;
 	b->legacy_io->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_io);
@@ -981,6 +983,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_mem->size = 1024*1024;
 	b->legacy_mem->attr.mode = 0600;
 	b->legacy_mem->mmap = pci_mmap_legacy_mem;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_mem->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_mem);
 	error = device_create_bin_file(&b->dev, b->legacy_mem);
@@ -1138,6 +1142,14 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
 }
 
+static loff_t pci_llseek_resource(struct file *filep,
+				  struct kobject *kobj __always_unused,
+				  struct bin_attribute *attr,
+				  loff_t offset, int whence)
+{
+	return fixed_size_llseek(filep, offset, whence, attr->size);
+}
+
 /**
  * pci_remove_resource_files - cleanup resource files
  * @pdev: dev to cleanup
@@ -1195,8 +1207,15 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
 			res_attr->mmap = pci_mmap_resource_uc;
 		}
 	}
-	if (res_attr->mmap)
+	if (res_attr->mmap) {
 		res_attr->f_mapping = iomem_get_mapping;
+		/*
+		 * generic_file_llseek() consults f_mapping->host to determine
+		 * the file size. As iomem_inode knows nothing about the
+		 * attribute, it's not going to work, so override it as well.
+		 */
+		res_attr->llseek = pci_llseek_resource;
+	}
 	res_attr->attr.name = res_attr_name;
 	res_attr->attr.mode = 0600;
 	res_attr->size = pci_resource_len(pdev, num);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs
  2023-08-21  7:29         ` [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs Valentine Sinitsyn
@ 2023-08-21 19:55           ` Bjorn Helgaas
  2023-08-22  7:51             ` [PATCH v3 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
  2023-08-22  7:51             ` [PATCH v3 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
  2023-08-21 23:15           ` [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs kernel test robot
  1 sibling, 2 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2023-08-21 19:55 UTC (permalink / raw)
  To: Valentine Sinitsyn
  Cc: Greg Kroah-Hartman, Tejun Heo, Dan Williams, Daniel Vetter,
	Bjorn Helgaas, linux-kernel

In subject, to match history:

  PCI: Implement custom llseek for sysfs resource entries

On Mon, Aug 21, 2023 at 12:29:56PM +0500, Valentine Sinitsyn wrote:
> Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"), mmapable
> sysfs entries have started to receive their f_mapping from the iomem
> pseudo filesystem, so that CONFIG_IO_STRICT_DEVMEM is honored in sysfs
> (and procfs) as well as in /dev/[k]mem.

s/mmapable/mmappable/ (there's precedent for both, but by analogy with
"mappable", I think "mmappable" makes more sense)

> This resulted in a userspace-visible regression:
> 
> 1. Open a sysfs PCI resource file (eg. /sys/bus/pci/devices/*/resource0)
> 2. Use lseek(fd, 0, SEEK_END) to determine its size
> 
> Expected result: a PCI region size is returned.
> Actual result: 0 is returned.
> 
> The reason is that PCI resource files residing in sysfs use
> generic_file_llseek(), which relies on f_mapping->host inode to get the
> file size. As f_mapping is now redefined, f_mapping->host points to an
> anonymous zero-sized iomem_inode which has nothing to do with sysfs file
> in question.
> 
> Implement a custom llseek method for sysfs PCI resources, which is
> almost the same as proc_bus_pci_lseek() used for procfs entries.
> 
> This makes sysfs and procfs entries consistent with regards to seeking,
> but also introduces userspace-visible changes to seeking PCI resources
> in sysfs:
> 
> - SEEK_DATA and SEEK_HOLE are no longer supported;
> - Seeking past the end of the file is prohibited while previously
>   offsets up to MAX_NON_LFS were accepted (reading from these offsets
>   was always invalid).
> 
> Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
> Cc: stable@vger.kernel.org
> Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>

It'd be nice but not essential to tweak commit log as above.

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
> Looks like the patch didn't get to lkml, resending
> 
>  drivers/pci/pci-sysfs.c | 21 ++++++++++++++++++++-
>  1 file changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index ab32a91f287b..42eaeb8d4a4f 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -967,6 +967,8 @@ void pci_create_legacy_files(struct pci_bus *b)
>  	b->legacy_io->attr.mode = 0600;
>  	b->legacy_io->read = pci_read_legacy_io;
>  	b->legacy_io->write = pci_write_legacy_io;
> +	/* See pci_create_attr() for motivation */
> +	b->legacy_io->llseek = pci_llseek_resource;
>  	b->legacy_io->mmap = pci_mmap_legacy_io;
>  	b->legacy_io->f_mapping = iomem_get_mapping;
>  	pci_adjust_legacy_attr(b, pci_mmap_io);
> @@ -981,6 +983,8 @@ void pci_create_legacy_files(struct pci_bus *b)
>  	b->legacy_mem->size = 1024*1024;
>  	b->legacy_mem->attr.mode = 0600;
>  	b->legacy_mem->mmap = pci_mmap_legacy_mem;
> +	/* See pci_create_attr() for motivation */
> +	b->legacy_io->llseek = pci_llseek_resource;
>  	b->legacy_mem->f_mapping = iomem_get_mapping;
>  	pci_adjust_legacy_attr(b, pci_mmap_mem);
>  	error = device_create_bin_file(&b->dev, b->legacy_mem);
> @@ -1138,6 +1142,14 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
>  	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
>  }
>  
> +static loff_t pci_llseek_resource(struct file *filep,
> +				  struct kobject *kobj __always_unused,
> +				  struct bin_attribute *attr,
> +				  loff_t offset, int whence)
> +{
> +	return fixed_size_llseek(filep, offset, whence, attr->size);
> +}
> +
>  /**
>   * pci_remove_resource_files - cleanup resource files
>   * @pdev: dev to cleanup
> @@ -1195,8 +1207,15 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
>  			res_attr->mmap = pci_mmap_resource_uc;
>  		}
>  	}
> -	if (res_attr->mmap)
> +	if (res_attr->mmap) {
>  		res_attr->f_mapping = iomem_get_mapping;
> +		/*
> +		 * generic_file_llseek() consults f_mapping->host to determine
> +		 * the file size. As iomem_inode knows nothing about the
> +		 * attribute, it's not going to work, so override it as well.
> +		 */
> +		res_attr->llseek = pci_llseek_resource;
> +	}
>  	res_attr->attr.name = res_attr_name;
>  	res_attr->attr.mode = 0600;
>  	res_attr->size = pci_resource_len(pdev, num);
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs
  2023-08-21  7:29         ` [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs Valentine Sinitsyn
  2023-08-21 19:55           ` Bjorn Helgaas
@ 2023-08-21 23:15           ` kernel test robot
  2023-08-22  8:09             ` Valentin Sinitsyn
  1 sibling, 1 reply; 31+ messages in thread
From: kernel test robot @ 2023-08-21 23:15 UTC (permalink / raw)
  To: Valentine Sinitsyn, Greg Kroah-Hartman, Tejun Heo, Dan Williams
  Cc: oe-kbuild-all, Daniel Vetter, Bjorn Helgaas, linux-kernel

Hi Valentine,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.5-rc7 next-20230821]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Valentine-Sinitsyn/PCI-implement-custom-llseek-method-for-PCI-resource-entries-in-sysfs/20230821-163118
base:   linus/master
patch link:    https://lore.kernel.org/r/20230821072956.114193-2-valesini%40yandex-team.ru
patch subject: [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs
config: powerpc-randconfig-r024-20230821 (https://download.01.org/0day-ci/archive/20230822/202308220648.wcmc5jWq-lkp@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 12.3.0
reproduce: (https://download.01.org/0day-ci/archive/20230822/202308220648.wcmc5jWq-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308220648.wcmc5jWq-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/pci/pci-sysfs.c:936:13: warning: no previous prototype for 'pci_adjust_legacy_attr' [-Wmissing-prototypes]
     936 | void __weak pci_adjust_legacy_attr(struct pci_bus *b,
         |             ^~~~~~~~~~~~~~~~~~~~~~
   drivers/pci/pci-sysfs.c: In function 'pci_create_legacy_files':
>> drivers/pci/pci-sysfs.c:971:32: error: 'pci_llseek_resource' undeclared (first use in this function); did you mean 'pci_claim_resource'?
     971 |         b->legacy_io->llseek = pci_llseek_resource;
         |                                ^~~~~~~~~~~~~~~~~~~
         |                                pci_claim_resource
   drivers/pci/pci-sysfs.c:971:32: note: each undeclared identifier is reported only once for each function it appears in


vim +971 drivers/pci/pci-sysfs.c

   940	
   941	/**
   942	 * pci_create_legacy_files - create legacy I/O port and memory files
   943	 * @b: bus to create files under
   944	 *
   945	 * Some platforms allow access to legacy I/O port and ISA memory space on
   946	 * a per-bus basis.  This routine creates the files and ties them into
   947	 * their associated read, write and mmap files from pci-sysfs.c
   948	 *
   949	 * On error unwind, but don't propagate the error to the caller
   950	 * as it is ok to set up the PCI bus without these files.
   951	 */
   952	void pci_create_legacy_files(struct pci_bus *b)
   953	{
   954		int error;
   955	
   956		if (!sysfs_initialized)
   957			return;
   958	
   959		b->legacy_io = kcalloc(2, sizeof(struct bin_attribute),
   960				       GFP_ATOMIC);
   961		if (!b->legacy_io)
   962			goto kzalloc_err;
   963	
   964		sysfs_bin_attr_init(b->legacy_io);
   965		b->legacy_io->attr.name = "legacy_io";
   966		b->legacy_io->size = 0xffff;
   967		b->legacy_io->attr.mode = 0600;
   968		b->legacy_io->read = pci_read_legacy_io;
   969		b->legacy_io->write = pci_write_legacy_io;
   970		/* See pci_create_attr() for motivation */
 > 971		b->legacy_io->llseek = pci_llseek_resource;
   972		b->legacy_io->mmap = pci_mmap_legacy_io;
   973		b->legacy_io->f_mapping = iomem_get_mapping;
   974		pci_adjust_legacy_attr(b, pci_mmap_io);
   975		error = device_create_bin_file(&b->dev, b->legacy_io);
   976		if (error)
   977			goto legacy_io_err;
   978	
   979		/* Allocated above after the legacy_io struct */
   980		b->legacy_mem = b->legacy_io + 1;
   981		sysfs_bin_attr_init(b->legacy_mem);
   982		b->legacy_mem->attr.name = "legacy_mem";
   983		b->legacy_mem->size = 1024*1024;
   984		b->legacy_mem->attr.mode = 0600;
   985		b->legacy_mem->mmap = pci_mmap_legacy_mem;
   986		/* See pci_create_attr() for motivation */
   987		b->legacy_io->llseek = pci_llseek_resource;
   988		b->legacy_mem->f_mapping = iomem_get_mapping;
   989		pci_adjust_legacy_attr(b, pci_mmap_mem);
   990		error = device_create_bin_file(&b->dev, b->legacy_mem);
   991		if (error)
   992			goto legacy_mem_err;
   993	
   994		return;
   995	
   996	legacy_mem_err:
   997		device_remove_bin_file(&b->dev, b->legacy_io);
   998	legacy_io_err:
   999		kfree(b->legacy_io);
  1000		b->legacy_io = NULL;
  1001	kzalloc_err:
  1002		dev_warn(&b->dev, "could not create legacy I/O port and ISA memory resources in sysfs\n");
  1003	}
  1004	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v3 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-08-21 19:55           ` Bjorn Helgaas
@ 2023-08-22  7:51             ` Valentine Sinitsyn
  2023-08-22  7:51             ` [PATCH v3 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
  1 sibling, 0 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-08-22  7:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo, Bjorn Helgaas
  Cc: Daniel Vetter, Dan Williams, linux-kernel

As of now, seeking in sysfs files is handled by generic_file_llseek().
There are situations where one may want to customize seeking logic:

- Many sysfs entries are fixed files while generic_file_llseek() accepts
  past-the-end positions. Not only being useless by itself, this
  also means a bug in userspace code will trigger not at lseek(), but at
  some later point making debugging harder.
- generic_file_llseek() relies on f_mapping->host to get the file size
  which might not be correct for all sysfs entries.
  See commit 636b21b50152 ("PCI: Revoke mappings like devmem") as an example.

Implement llseek method to override this behavior at sysfs attribute
level. The method is optional, and if it is absent,
generic_file_llseek() is called to preserve backwards compatibility.

Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
---
v3:
        - Grammar fixes
        - Add base-patch: and prerequisite-patch-id: to make kernel test
          robot happy
v2:
        - Add infrastructure to customize llseek per sysfs entry type
        - Override llseek for PCI sysfs entries with fixed_file_llseek()

 fs/kernfs/file.c       | 14 +++++++++++++-
 fs/sysfs/file.c        | 13 +++++++++++++
 include/linux/kernfs.h |  1 +
 include/linux/sysfs.h  |  2 ++
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 180906c36f51..6166bf74d5b8 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -903,6 +903,18 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
 	return ret;
 }
 
+static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
+{
+	struct kernfs_open_file *of = kernfs_of(file);
+	const struct kernfs_ops *ops;
+
+	ops = kernfs_ops(of->kn);
+	if (ops->llseek)
+		return ops->llseek(of, offset, whence);
+	else
+		return generic_file_llseek(file, offset, whence);
+}
+
 static void kernfs_notify_workfn(struct work_struct *work)
 {
 	struct kernfs_node *kn;
@@ -1005,7 +1017,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
 const struct file_operations kernfs_file_fops = {
 	.read_iter	= kernfs_fop_read_iter,
 	.write_iter	= kernfs_fop_write_iter,
-	.llseek		= generic_file_llseek,
+	.llseek		= kernfs_fop_llseek,
 	.mmap		= kernfs_fop_mmap,
 	.open		= kernfs_fop_open,
 	.release	= kernfs_fop_release,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a12ac0356c69..6b7652fb8050 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -167,6 +167,18 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
 	return battr->mmap(of->file, kobj, battr, vma);
 }
 
+static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset,
+				  int whence)
+{
+	struct bin_attribute *battr = of->kn->priv;
+	struct kobject *kobj = of->kn->parent->priv;
+
+	if (battr->llseek)
+		return battr->llseek(of->file, kobj, battr, offset, whence);
+	else
+		return generic_file_llseek(of->file, offset, whence);
+}
+
 static int sysfs_kf_bin_open(struct kernfs_open_file *of)
 {
 	struct bin_attribute *battr = of->kn->priv;
@@ -249,6 +261,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 	.write		= sysfs_kf_bin_write,
 	.mmap		= sysfs_kf_bin_mmap,
 	.open		= sysfs_kf_bin_open,
+	.llseek		= sysfs_kf_bin_llseek,
 };
 
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 73f5c120def8..9ed535930259 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -316,6 +316,7 @@ struct kernfs_ops {
 			 struct poll_table_struct *pt);
 
 	int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
+	loff_t (*llseek)(struct kernfs_open_file *of, loff_t offset, int whence);
 };
 
 /*
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index fd3fe5c8c17f..b717a70219f6 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -181,6 +181,8 @@ struct bin_attribute {
 			char *, loff_t, size_t);
 	ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
 			 char *, loff_t, size_t);
+	loff_t (*llseek)(struct file *, struct kobject *, struct bin_attribute *,
+			 loff_t, int);
 	int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
 		    struct vm_area_struct *vma);
 };

base-commit: f7757129e3dea336c407551c98f50057c22bb266
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v3 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-08-21 19:55           ` Bjorn Helgaas
  2023-08-22  7:51             ` [PATCH v3 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
@ 2023-08-22  7:51             ` Valentine Sinitsyn
  2023-08-22 11:54               ` [PATCH v4 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
  2023-08-22 11:54               ` [PATCH v4 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
  1 sibling, 2 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-08-22  7:51 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo, Bjorn Helgaas
  Cc: Daniel Vetter, Dan Williams, linux-kernel

Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"), mmappable
sysfs entries have started to receive their f_mapping from the iomem
pseudo filesystem, so that CONFIG_IO_STRICT_DEVMEM is honored in sysfs
(and procfs) as well as in /dev/[k]mem.

This resulted in a userspace-visible regression:

1. Open a sysfs PCI resource file (eg. /sys/bus/pci/devices/*/resource0)
2. Use lseek(fd, 0, SEEK_END) to determine its size

Expected result: a PCI region size is returned.
Actual result: 0 is returned.

The reason is that PCI resource files residing in sysfs use
generic_file_llseek(), which relies on f_mapping->host inode to get the
file size. As f_mapping is now redefined, f_mapping->host points to an
anonymous zero-sized iomem_inode which has nothing to do with sysfs file
in question.

Implement a custom llseek method for sysfs PCI resources, which is
almost the same as proc_bus_pci_lseek() used for procfs entries.

This makes sysfs and procfs entries consistent with regards to seeking,
but also introduces userspace-visible changes to seeking PCI resources
in sysfs:

- SEEK_DATA and SEEK_HOLE are no longer supported;
- Seeking past the end of the file is prohibited while previously
  offsets up to MAX_NON_LFS were accepted (reading from these offsets
  was always invalid).

Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/pci-sysfs.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index ab32a91f287b..42eaeb8d4a4f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -967,6 +967,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_io->attr.mode = 0600;
 	b->legacy_io->read = pci_read_legacy_io;
 	b->legacy_io->write = pci_write_legacy_io;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_io->mmap = pci_mmap_legacy_io;
 	b->legacy_io->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_io);
@@ -981,6 +983,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_mem->size = 1024*1024;
 	b->legacy_mem->attr.mode = 0600;
 	b->legacy_mem->mmap = pci_mmap_legacy_mem;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_mem->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_mem);
 	error = device_create_bin_file(&b->dev, b->legacy_mem);
@@ -1138,6 +1142,14 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
 }
 
+static loff_t pci_llseek_resource(struct file *filep,
+				  struct kobject *kobj __always_unused,
+				  struct bin_attribute *attr,
+				  loff_t offset, int whence)
+{
+	return fixed_size_llseek(filep, offset, whence, attr->size);
+}
+
 /**
  * pci_remove_resource_files - cleanup resource files
  * @pdev: dev to cleanup
@@ -1195,8 +1207,15 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
 			res_attr->mmap = pci_mmap_resource_uc;
 		}
 	}
-	if (res_attr->mmap)
+	if (res_attr->mmap) {
 		res_attr->f_mapping = iomem_get_mapping;
+		/*
+		 * generic_file_llseek() consults f_mapping->host to determine
+		 * the file size. As iomem_inode knows nothing about the
+		 * attribute, it's not going to work, so override it as well.
+		 */
+		res_attr->llseek = pci_llseek_resource;
+	}
 	res_attr->attr.name = res_attr_name;
 	res_attr->attr.mode = 0600;
 	res_attr->size = pci_resource_len(pdev, num);

prerequisite-patch-id: 955ac8520d17a30dc71166fa7f1d25c09cbab46e
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs
  2023-08-21 23:15           ` [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs kernel test robot
@ 2023-08-22  8:09             ` Valentin Sinitsyn
  0 siblings, 0 replies; 31+ messages in thread
From: Valentin Sinitsyn @ 2023-08-22  8:09 UTC (permalink / raw)
  To: kernel test robot, Greg Kroah-Hartman, Tejun Heo, Dan Williams
  Cc: oe-kbuild-all, Daniel Vetter, Bjorn Helgaas, linux-kernel

On 22.08.2023 04:15, kernel test robot wrote:
> Hi Valentine,
> 
> kernel test robot noticed the following build errors:
Just realized that v3 doesn't really address this, will send the updated 
patch shortly.

Best,
Valentin

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v4 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-08-22  7:51             ` [PATCH v3 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
@ 2023-08-22 11:54               ` Valentine Sinitsyn
  2023-08-22 11:54               ` [PATCH v4 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
  1 sibling, 0 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-08-22 11:54 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo, Bjorn Helgaas, Dan Williams
  Cc: Daniel Vetter, linux-kernel

As of now, seeking in sysfs files is handled by generic_file_llseek().
There are situations where one may want to customize seeking logic:

- Many sysfs entries are fixed files while generic_file_llseek() accepts
  past-the-end positions. Not only being useless by itself, this
  also means a bug in userspace code will trigger not at lseek(), but at
  some later point making debugging harder.
- generic_file_llseek() relies on f_mapping->host to get the file size
  which might not be correct for all sysfs entries.
  See commit 636b21b50152 ("PCI: Revoke mappings like devmem") as an example.

Implement llseek method to override this behavior at sysfs attribute
level. The method is optional, and if it is absent,
generic_file_llseek() is called to preserve backwards compatibility.

Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
---
v4:
        - Fix builds which #define HAVE_PCI_LEGACY (e.g. PowerPC)
v3:
        - Grammar fixes
        - Add base-patch: and prerequisite-patch-id: to make kernel test
          robot happy
v2:
        - Add infrastructure to customize llseek per sysfs entry type
        - Override llseek for PCI sysfs entries with fixed_file_llseek()

 fs/kernfs/file.c       | 14 +++++++++++++-
 fs/sysfs/file.c        | 13 +++++++++++++
 include/linux/kernfs.h |  1 +
 include/linux/sysfs.h  |  2 ++
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 180906c36f51..6166bf74d5b8 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -903,6 +903,18 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
 	return ret;
 }
 
+static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
+{
+	struct kernfs_open_file *of = kernfs_of(file);
+	const struct kernfs_ops *ops;
+
+	ops = kernfs_ops(of->kn);
+	if (ops->llseek)
+		return ops->llseek(of, offset, whence);
+	else
+		return generic_file_llseek(file, offset, whence);
+}
+
 static void kernfs_notify_workfn(struct work_struct *work)
 {
 	struct kernfs_node *kn;
@@ -1005,7 +1017,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
 const struct file_operations kernfs_file_fops = {
 	.read_iter	= kernfs_fop_read_iter,
 	.write_iter	= kernfs_fop_write_iter,
-	.llseek		= generic_file_llseek,
+	.llseek		= kernfs_fop_llseek,
 	.mmap		= kernfs_fop_mmap,
 	.open		= kernfs_fop_open,
 	.release	= kernfs_fop_release,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a12ac0356c69..6b7652fb8050 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -167,6 +167,18 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
 	return battr->mmap(of->file, kobj, battr, vma);
 }
 
+static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset,
+				  int whence)
+{
+	struct bin_attribute *battr = of->kn->priv;
+	struct kobject *kobj = of->kn->parent->priv;
+
+	if (battr->llseek)
+		return battr->llseek(of->file, kobj, battr, offset, whence);
+	else
+		return generic_file_llseek(of->file, offset, whence);
+}
+
 static int sysfs_kf_bin_open(struct kernfs_open_file *of)
 {
 	struct bin_attribute *battr = of->kn->priv;
@@ -249,6 +261,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 	.write		= sysfs_kf_bin_write,
 	.mmap		= sysfs_kf_bin_mmap,
 	.open		= sysfs_kf_bin_open,
+	.llseek		= sysfs_kf_bin_llseek,
 };
 
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 73f5c120def8..9ed535930259 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -316,6 +316,7 @@ struct kernfs_ops {
 			 struct poll_table_struct *pt);
 
 	int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
+	loff_t (*llseek)(struct kernfs_open_file *of, loff_t offset, int whence);
 };
 
 /*
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index fd3fe5c8c17f..b717a70219f6 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -181,6 +181,8 @@ struct bin_attribute {
 			char *, loff_t, size_t);
 	ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
 			 char *, loff_t, size_t);
+	loff_t (*llseek)(struct file *, struct kobject *, struct bin_attribute *,
+			 loff_t, int);
 	int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
 		    struct vm_area_struct *vma);
 };

base-commit: f7757129e3dea336c407551c98f50057c22bb266
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v4 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-08-22  7:51             ` [PATCH v3 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
  2023-08-22 11:54               ` [PATCH v4 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
@ 2023-08-22 11:54               ` Valentine Sinitsyn
  2023-08-22 17:43                 ` kernel test robot
  1 sibling, 1 reply; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-08-22 11:54 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo, Bjorn Helgaas, Dan Williams
  Cc: Daniel Vetter, linux-kernel

Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"), mmappable
sysfs entries have started to receive their f_mapping from the iomem
pseudo filesystem, so that CONFIG_IO_STRICT_DEVMEM is honored in sysfs
(and procfs) as well as in /dev/[k]mem.

This resulted in a userspace-visible regression:

1. Open a sysfs PCI resource file (eg. /sys/bus/pci/devices/*/resource0)
2. Use lseek(fd, 0, SEEK_END) to determine its size

Expected result: a PCI region size is returned.
Actual result: 0 is returned.

The reason is that PCI resource files residing in sysfs use
generic_file_llseek(), which relies on f_mapping->host inode to get the
file size. As f_mapping is now redefined, f_mapping->host points to an
anonymous zero-sized iomem_inode which has nothing to do with sysfs file
in question.

Implement a custom llseek method for sysfs PCI resources, which is
almost the same as proc_bus_pci_lseek() used for procfs entries.

This makes sysfs and procfs entries consistent with regards to seeking,
but also introduces userspace-visible changes to seeking PCI resources
in sysfs:

- SEEK_DATA and SEEK_HOLE are no longer supported;
- Seeking past the end of the file is prohibited while previously
  offsets up to MAX_NON_LFS were accepted (reading from these offsets
  was always invalid).

Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/pci-sysfs.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index ab32a91f287b..2b9d93f11dd1 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -836,6 +836,12 @@ static const struct attribute_group pci_dev_config_attr_group = {
 };
 
 #ifdef HAVE_PCI_LEGACY
+
+static loff_t pci_llseek_resource(struct file *filep,
+				  struct kobject *kobj,
+				  struct bin_attribute *attr,
+				  loff_t offset, int whence);
+
 /**
  * pci_read_legacy_io - read byte(s) from legacy I/O port space
  * @filp: open sysfs file
@@ -967,6 +973,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_io->attr.mode = 0600;
 	b->legacy_io->read = pci_read_legacy_io;
 	b->legacy_io->write = pci_write_legacy_io;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_io->mmap = pci_mmap_legacy_io;
 	b->legacy_io->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_io);
@@ -981,6 +989,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_mem->size = 1024*1024;
 	b->legacy_mem->attr.mode = 0600;
 	b->legacy_mem->mmap = pci_mmap_legacy_mem;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_mem->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_mem);
 	error = device_create_bin_file(&b->dev, b->legacy_mem);
@@ -1138,6 +1148,14 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
 }
 
+static loff_t pci_llseek_resource(struct file *filep,
+				  struct kobject *kobj __always_unused,
+				  struct bin_attribute *attr,
+				  loff_t offset, int whence)
+{
+	return fixed_size_llseek(filep, offset, whence, attr->size);
+}
+
 /**
  * pci_remove_resource_files - cleanup resource files
  * @pdev: dev to cleanup
@@ -1195,8 +1213,15 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
 			res_attr->mmap = pci_mmap_resource_uc;
 		}
 	}
-	if (res_attr->mmap)
+	if (res_attr->mmap) {
 		res_attr->f_mapping = iomem_get_mapping;
+		/*
+		 * generic_file_llseek() consults f_mapping->host to determine
+		 * the file size. As iomem_inode knows nothing about the
+		 * attribute, it's not going to work, so override it as well.
+		 */
+		res_attr->llseek = pci_llseek_resource;
+	}
 	res_attr->attr.name = res_attr_name;
 	res_attr->attr.mode = 0600;
 	res_attr->size = pci_resource_len(pdev, num);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH v4 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-08-22 11:54               ` [PATCH v4 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
@ 2023-08-22 17:43                 ` kernel test robot
  2023-08-23 12:58                   ` [PATCH v5 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
  2023-08-23 12:58                   ` [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
  0 siblings, 2 replies; 31+ messages in thread
From: kernel test robot @ 2023-08-22 17:43 UTC (permalink / raw)
  To: Valentine Sinitsyn, Greg Kroah-Hartman, Tejun Heo, Bjorn Helgaas,
	Dan Williams
  Cc: oe-kbuild-all, Daniel Vetter, linux-kernel

Hi Valentine,

kernel test robot noticed the following build warnings:

[auto build test WARNING on f7757129e3dea336c407551c98f50057c22bb266]

url:    https://github.com/intel-lab-lkp/linux/commits/Valentine-Sinitsyn/PCI-Implement-custom-llseek-for-sysfs-resource-entries/20230822-205513
base:   f7757129e3dea336c407551c98f50057c22bb266
patch link:    https://lore.kernel.org/r/20230822115455.310222-2-valesini%40yandex-team.ru
patch subject: [PATCH v4 2/2] PCI: Implement custom llseek for sysfs resource entries
config: alpha-allnoconfig (https://download.01.org/0day-ci/archive/20230823/202308230126.O8xXYkdt-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20230823/202308230126.O8xXYkdt-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308230126.O8xXYkdt-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/pci/pci-sysfs.c:840:15: warning: 'pci_llseek_resource' used but never defined
     840 | static loff_t pci_llseek_resource(struct file *filep,
         |               ^~~~~~~~~~~~~~~~~~~


vim +/pci_llseek_resource +840 drivers/pci/pci-sysfs.c

   839	
 > 840	static loff_t pci_llseek_resource(struct file *filep,
   841					  struct kobject *kobj,
   842					  struct bin_attribute *attr,
   843					  loff_t offset, int whence);
   844	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v5 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-08-22 17:43                 ` kernel test robot
@ 2023-08-23 12:58                   ` Valentine Sinitsyn
  2023-08-23 14:37                     ` Greg Kroah-Hartman
  2023-08-23 12:58                   ` [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
  1 sibling, 1 reply; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-08-23 12:58 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

As of now, seeking in sysfs files is handled by generic_file_llseek().
There are situations where one may want to customize seeking logic:

- Many sysfs entries are fixed files while generic_file_llseek() accepts
  past-the-end positions. Not only being useless by itself, this
  also means a bug in userspace code will trigger not at lseek(), but at
  some later point making debugging harder.
- generic_file_llseek() relies on f_mapping->host to get the file size
  which might not be correct for all sysfs entries.
  See commit 636b21b50152 ("PCI: Revoke mappings like devmem") as an example.

Implement llseek method to override this behavior at sysfs attribute
level. The method is optional, and if it is absent,
generic_file_llseek() is called to preserve backwards compatibility.

Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
---
v5:
        - Fix builds without PCI mmap support (e.g. Alpha)
v4:
        - Fix builds which #define HAVE_PCI_LEGACY (e.g. PowerPC)
v3:
        - Grammar fixes
        - Add base-patch: and prerequisite-patch-id: to make kernel test
          robot happy
v2:
        - Add infrastructure to customize llseek per sysfs entry type
        - Override llseek for PCI sysfs entries with fixed_file_llseek()
 fs/kernfs/file.c       | 14 +++++++++++++-
 fs/sysfs/file.c        | 13 +++++++++++++
 include/linux/kernfs.h |  1 +
 include/linux/sysfs.h  |  2 ++
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 180906c36f51..6166bf74d5b8 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -903,6 +903,18 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
 	return ret;
 }
 
+static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
+{
+	struct kernfs_open_file *of = kernfs_of(file);
+	const struct kernfs_ops *ops;
+
+	ops = kernfs_ops(of->kn);
+	if (ops->llseek)
+		return ops->llseek(of, offset, whence);
+	else
+		return generic_file_llseek(file, offset, whence);
+}
+
 static void kernfs_notify_workfn(struct work_struct *work)
 {
 	struct kernfs_node *kn;
@@ -1005,7 +1017,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
 const struct file_operations kernfs_file_fops = {
 	.read_iter	= kernfs_fop_read_iter,
 	.write_iter	= kernfs_fop_write_iter,
-	.llseek		= generic_file_llseek,
+	.llseek		= kernfs_fop_llseek,
 	.mmap		= kernfs_fop_mmap,
 	.open		= kernfs_fop_open,
 	.release	= kernfs_fop_release,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a12ac0356c69..6b7652fb8050 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -167,6 +167,18 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
 	return battr->mmap(of->file, kobj, battr, vma);
 }
 
+static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset,
+				  int whence)
+{
+	struct bin_attribute *battr = of->kn->priv;
+	struct kobject *kobj = of->kn->parent->priv;
+
+	if (battr->llseek)
+		return battr->llseek(of->file, kobj, battr, offset, whence);
+	else
+		return generic_file_llseek(of->file, offset, whence);
+}
+
 static int sysfs_kf_bin_open(struct kernfs_open_file *of)
 {
 	struct bin_attribute *battr = of->kn->priv;
@@ -249,6 +261,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 	.write		= sysfs_kf_bin_write,
 	.mmap		= sysfs_kf_bin_mmap,
 	.open		= sysfs_kf_bin_open,
+	.llseek		= sysfs_kf_bin_llseek,
 };
 
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 73f5c120def8..9ed535930259 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -316,6 +316,7 @@ struct kernfs_ops {
 			 struct poll_table_struct *pt);
 
 	int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
+	loff_t (*llseek)(struct kernfs_open_file *of, loff_t offset, int whence);
 };
 
 /*
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index fd3fe5c8c17f..b717a70219f6 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -181,6 +181,8 @@ struct bin_attribute {
 			char *, loff_t, size_t);
 	ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
 			 char *, loff_t, size_t);
+	loff_t (*llseek)(struct file *, struct kobject *, struct bin_attribute *,
+			 loff_t, int);
 	int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
 		    struct vm_area_struct *vma);
 };

base-commit: 89bf6209cad66214d3774dac86b6bbf2aec6a30d
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-08-22 17:43                 ` kernel test robot
  2023-08-23 12:58                   ` [PATCH v5 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
@ 2023-08-23 12:58                   ` Valentine Sinitsyn
  2023-08-25 14:10                     ` kernel test robot
  1 sibling, 1 reply; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-08-23 12:58 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"), mmappable
sysfs entries have started to receive their f_mapping from the iomem
pseudo filesystem, so that CONFIG_IO_STRICT_DEVMEM is honored in sysfs
(and procfs) as well as in /dev/[k]mem.

This resulted in a userspace-visible regression:

1. Open a sysfs PCI resource file (eg. /sys/bus/pci/devices/*/resource0)
2. Use lseek(fd, 0, SEEK_END) to determine its size

Expected result: a PCI region size is returned.
Actual result: 0 is returned.

The reason is that PCI resource files residing in sysfs use
generic_file_llseek(), which relies on f_mapping->host inode to get the
file size. As f_mapping is now redefined, f_mapping->host points to an
anonymous zero-sized iomem_inode which has nothing to do with sysfs file
in question.

Implement a custom llseek method for sysfs PCI resources, which is
almost the same as proc_bus_pci_lseek() used for procfs entries.

This makes sysfs and procfs entries consistent with regards to seeking,
but also introduces userspace-visible changes to seeking PCI resources
in sysfs:

- SEEK_DATA and SEEK_HOLE are no longer supported;
- Seeking past the end of the file is prohibited while previously
  offsets up to MAX_NON_LFS were accepted (reading from these offsets
  was always invalid).

Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/pci-sysfs.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index ab32a91f287b..03ac21eeb9bb 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -835,6 +835,14 @@ static const struct attribute_group pci_dev_config_attr_group = {
 	.is_bin_visible = pci_dev_config_attr_is_visible,
 };
 
+static loff_t pci_llseek_resource(struct file *filep,
+				  struct kobject *kobj __always_unused,
+				  struct bin_attribute *attr,
+				  loff_t offset, int whence)
+{
+	return fixed_size_llseek(filep, offset, whence, attr->size);
+}
+
 #ifdef HAVE_PCI_LEGACY
 /**
  * pci_read_legacy_io - read byte(s) from legacy I/O port space
@@ -967,6 +975,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_io->attr.mode = 0600;
 	b->legacy_io->read = pci_read_legacy_io;
 	b->legacy_io->write = pci_write_legacy_io;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_io->mmap = pci_mmap_legacy_io;
 	b->legacy_io->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_io);
@@ -981,6 +991,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_mem->size = 1024*1024;
 	b->legacy_mem->attr.mode = 0600;
 	b->legacy_mem->mmap = pci_mmap_legacy_mem;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_mem->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_mem);
 	error = device_create_bin_file(&b->dev, b->legacy_mem);
@@ -1195,8 +1207,15 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
 			res_attr->mmap = pci_mmap_resource_uc;
 		}
 	}
-	if (res_attr->mmap)
+	if (res_attr->mmap) {
 		res_attr->f_mapping = iomem_get_mapping;
+		/*
+		 * generic_file_llseek() consults f_mapping->host to determine
+		 * the file size. As iomem_inode knows nothing about the
+		 * attribute, it's not going to work, so override it as well.
+		 */
+		res_attr->llseek = pci_llseek_resource;
+	}
 	res_attr->attr.name = res_attr_name;
 	res_attr->attr.mode = 0600;
 	res_attr->size = pci_resource_len(pdev, num);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH v5 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-08-23 12:58                   ` [PATCH v5 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
@ 2023-08-23 14:37                     ` Greg Kroah-Hartman
  2023-08-23 14:39                       ` Greg Kroah-Hartman
  0 siblings, 1 reply; 31+ messages in thread
From: Greg Kroah-Hartman @ 2023-08-23 14:37 UTC (permalink / raw)
  To: Valentine Sinitsyn
  Cc: Tejun Heo, Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

On Wed, Aug 23, 2023 at 05:58:33PM +0500, Valentine Sinitsyn wrote:
> As of now, seeking in sysfs files is handled by generic_file_llseek().
> There are situations where one may want to customize seeking logic:
> 
> - Many sysfs entries are fixed files while generic_file_llseek() accepts
>   past-the-end positions. Not only being useless by itself, this
>   also means a bug in userspace code will trigger not at lseek(), but at
>   some later point making debugging harder.
> - generic_file_llseek() relies on f_mapping->host to get the file size
>   which might not be correct for all sysfs entries.
>   See commit 636b21b50152 ("PCI: Revoke mappings like devmem") as an example.
> 
> Implement llseek method to override this behavior at sysfs attribute
> level. The method is optional, and if it is absent,
> generic_file_llseek() is called to preserve backwards compatibility.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
> ---
> v5:
>         - Fix builds without PCI mmap support (e.g. Alpha)
> v4:
>         - Fix builds which #define HAVE_PCI_LEGACY (e.g. PowerPC)
> v3:
>         - Grammar fixes
>         - Add base-patch: and prerequisite-patch-id: to make kernel test
>           robot happy
> v2:
>         - Add infrastructure to customize llseek per sysfs entry type
>         - Override llseek for PCI sysfs entries with fixed_file_llseek()
>  fs/kernfs/file.c       | 14 +++++++++++++-
>  fs/sysfs/file.c        | 13 +++++++++++++
>  include/linux/kernfs.h |  1 +
>  include/linux/sysfs.h  |  2 ++
>  4 files changed, 29 insertions(+), 1 deletion(-)
> 

Due to the high rate of errors and respins of this, I'm going to wait
until after 5.7-rc1 is out before adding it to my tree so that things
can calm down a bit...

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v5 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-08-23 14:37                     ` Greg Kroah-Hartman
@ 2023-08-23 14:39                       ` Greg Kroah-Hartman
  2023-08-23 20:11                         ` Valentin Sinitsyn
  0 siblings, 1 reply; 31+ messages in thread
From: Greg Kroah-Hartman @ 2023-08-23 14:39 UTC (permalink / raw)
  To: Valentine Sinitsyn
  Cc: Tejun Heo, Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

On Wed, Aug 23, 2023 at 04:37:49PM +0200, Greg Kroah-Hartman wrote:
> On Wed, Aug 23, 2023 at 05:58:33PM +0500, Valentine Sinitsyn wrote:
> > As of now, seeking in sysfs files is handled by generic_file_llseek().
> > There are situations where one may want to customize seeking logic:
> > 
> > - Many sysfs entries are fixed files while generic_file_llseek() accepts
> >   past-the-end positions. Not only being useless by itself, this
> >   also means a bug in userspace code will trigger not at lseek(), but at
> >   some later point making debugging harder.
> > - generic_file_llseek() relies on f_mapping->host to get the file size
> >   which might not be correct for all sysfs entries.
> >   See commit 636b21b50152 ("PCI: Revoke mappings like devmem") as an example.
> > 
> > Implement llseek method to override this behavior at sysfs attribute
> > level. The method is optional, and if it is absent,
> > generic_file_llseek() is called to preserve backwards compatibility.
> > 
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
> > ---
> > v5:
> >         - Fix builds without PCI mmap support (e.g. Alpha)
> > v4:
> >         - Fix builds which #define HAVE_PCI_LEGACY (e.g. PowerPC)
> > v3:
> >         - Grammar fixes
> >         - Add base-patch: and prerequisite-patch-id: to make kernel test
> >           robot happy
> > v2:
> >         - Add infrastructure to customize llseek per sysfs entry type
> >         - Override llseek for PCI sysfs entries with fixed_file_llseek()
> >  fs/kernfs/file.c       | 14 +++++++++++++-
> >  fs/sysfs/file.c        | 13 +++++++++++++
> >  include/linux/kernfs.h |  1 +
> >  include/linux/sysfs.h  |  2 ++
> >  4 files changed, 29 insertions(+), 1 deletion(-)
> > 
> 
> Due to the high rate of errors and respins of this, I'm going to wait
> until after 5.7-rc1 is out before adding it to my tree so that things
> can calm down a bit...

{sigh}

I don't know what kernel version we are at anymore, it should be
"6.6-rc1".

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v5 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-08-23 14:39                       ` Greg Kroah-Hartman
@ 2023-08-23 20:11                         ` Valentin Sinitsyn
  0 siblings, 0 replies; 31+ messages in thread
From: Valentin Sinitsyn @ 2023-08-23 20:11 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Tejun Heo, Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

[...]

>> Due to the high rate of errors and respins of this, I'm going to wait
>> until after 5.7-rc1 is out before adding it to my tree so that things
>> can calm down a bit...
Ack. Sorry for the fuss, I believe v5 should be final, unless someone 
steps in with essential review comments.

Thanks,
Valentine

> 
> {sigh}
> 
> I don't know what kernel version we are at anymore, it should be
> "6.6-rc1".
> 
> thanks,
> 
> greg k-h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-08-23 12:58                   ` [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
@ 2023-08-25 14:10                     ` kernel test robot
  2023-08-28  7:22                       ` Valentin Sinitsyn
  0 siblings, 1 reply; 31+ messages in thread
From: kernel test robot @ 2023-08-25 14:10 UTC (permalink / raw)
  To: Valentine Sinitsyn, Greg Kroah-Hartman, Tejun Heo
  Cc: oe-kbuild-all, Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

Hi Valentine,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 89bf6209cad66214d3774dac86b6bbf2aec6a30d]

url:    https://github.com/intel-lab-lkp/linux/commits/Valentine-Sinitsyn/PCI-Implement-custom-llseek-for-sysfs-resource-entries/20230823-210101
base:   89bf6209cad66214d3774dac86b6bbf2aec6a30d
patch link:    https://lore.kernel.org/r/20230823125834.492298-2-valesini%40yandex-team.ru
patch subject: [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries
config: arc-randconfig-r023-20230824 (https://download.01.org/0day-ci/archive/20230825/202308252133.YO5zs5rv-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20230825/202308252133.YO5zs5rv-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202308252133.YO5zs5rv-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/pci/pci-sysfs.c:1268:12: warning: no previous prototype for 'pci_create_resource_files' [-Wmissing-prototypes]
    1268 | int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/pci/pci-sysfs.c:1269:13: warning: no previous prototype for 'pci_remove_resource_files' [-Wmissing-prototypes]
    1269 | void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
         |             ^~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/pci/pci-sysfs.c:838:15: warning: 'pci_llseek_resource' defined but not used [-Wunused-function]
     838 | static loff_t pci_llseek_resource(struct file *filep,
         |               ^~~~~~~~~~~~~~~~~~~


vim +/pci_llseek_resource +838 drivers/pci/pci-sysfs.c

   837	
 > 838	static loff_t pci_llseek_resource(struct file *filep,
   839					  struct kobject *kobj __always_unused,
   840					  struct bin_attribute *attr,
   841					  loff_t offset, int whence)
   842	{
   843		return fixed_size_llseek(filep, offset, whence, attr->size);
   844	}
   845	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-08-25 14:10                     ` kernel test robot
@ 2023-08-28  7:22                       ` Valentin Sinitsyn
  2023-08-29 20:02                         ` Bjorn Helgaas
  0 siblings, 1 reply; 31+ messages in thread
From: Valentin Sinitsyn @ 2023-08-28  7:22 UTC (permalink / raw)
  To: kernel test robot, Greg Kroah-Hartman, Tejun Heo
  Cc: oe-kbuild-all, Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

Hi all,

On 25.08.2023 19:10, kernel test robot wrote:
> Hi Valentine,
> 
> kernel test robot noticed the following build warnings:
> 
[..]
> All warnings (new ones prefixed by >>):
> 
>     drivers/pci/pci-sysfs.c:1268:12: warning: no previous prototype for 'pci_create_resource_files' [-Wmissing-prototypes]
>      1268 | int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
>           |            ^~~~~~~~~~~~~~~~~~~~~~~~~
>     drivers/pci/pci-sysfs.c:1269:13: warning: no previous prototype for 'pci_remove_resource_files' [-Wmissing-prototypes]
>      1269 | void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
>           |             ^~~~~~~~~~~~~~~~~~~~~~~~~
>>> drivers/pci/pci-sysfs.c:838:15: warning: 'pci_llseek_resource' defined but not used [-Wunused-function]
>       838 | static loff_t pci_llseek_resource(struct file *filep,
>           |               ^~~~~~~~~~~~~~~~~~~
I'm not sure if I should do anything about it: arc doesn't HAVE_* 
anything PCI-related, and pci-sysfs doesn't seem to be written with this 
case in mind. Guarding pci_llseek_resource() with an #ifdef 
HAVE_AT_LEAST_SOMETHING is trivial, but it feels more like a patch to 
silence a bot than a proper fix.

Any thoughts / objections on this?

Best,
Valentine

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-08-28  7:22                       ` Valentin Sinitsyn
@ 2023-08-29 20:02                         ` Bjorn Helgaas
  2023-08-29 20:26                           ` Bjorn Helgaas
                                             ` (2 more replies)
  0 siblings, 3 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2023-08-29 20:02 UTC (permalink / raw)
  To: Valentin Sinitsyn
  Cc: kernel test robot, Greg Kroah-Hartman, Tejun Heo, oe-kbuild-all,
	Daniel Vetter, Dan Williams, linux-kernel

On Mon, Aug 28, 2023 at 12:22:54PM +0500, Valentin Sinitsyn wrote:
> On 25.08.2023 19:10, kernel test robot wrote:
> > Hi Valentine,
> > 
> > kernel test robot noticed the following build warnings:
> > 
> [..]
> > All warnings (new ones prefixed by >>):
> > 
> >     drivers/pci/pci-sysfs.c:1268:12: warning: no previous prototype for 'pci_create_resource_files' [-Wmissing-prototypes]
> >      1268 | int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
> >           |            ^~~~~~~~~~~~~~~~~~~~~~~~~
> >     drivers/pci/pci-sysfs.c:1269:13: warning: no previous prototype for 'pci_remove_resource_files' [-Wmissing-prototypes]
> >      1269 | void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
> >           |             ^~~~~~~~~~~~~~~~~~~~~~~~~
> > > > drivers/pci/pci-sysfs.c:838:15: warning: 'pci_llseek_resource' defined but not used [-Wunused-function]
> >       838 | static loff_t pci_llseek_resource(struct file *filep,
> >           |               ^~~~~~~~~~~~~~~~~~~
> I'm not sure if I should do anything about it: arc doesn't HAVE_* anything
> PCI-related, and pci-sysfs doesn't seem to be written with this case in
> mind. Guarding pci_llseek_resource() with an #ifdef HAVE_AT_LEAST_SOMETHING
> is trivial, but it feels more like a patch to silence a bot than a proper
> fix.

Looks like it will require some untangling to figure out a nice fix,
but I think you *do* need to do something about it because I don't
want to add build errors on any arch.

Bjorn

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-08-29 20:02                         ` Bjorn Helgaas
@ 2023-08-29 20:26                           ` Bjorn Helgaas
  2023-09-02 15:50                           ` [PATCH v6 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
  2023-09-02 15:50                           ` [PATCH v6 " Valentine Sinitsyn
  2 siblings, 0 replies; 31+ messages in thread
From: Bjorn Helgaas @ 2023-08-29 20:26 UTC (permalink / raw)
  To: Valentin Sinitsyn
  Cc: kernel test robot, Greg Kroah-Hartman, Tejun Heo, oe-kbuild-all,
	Daniel Vetter, Dan Williams, linux-kernel

On Tue, Aug 29, 2023 at 03:02:29PM -0500, Bjorn Helgaas wrote:
> On Mon, Aug 28, 2023 at 12:22:54PM +0500, Valentin Sinitsyn wrote:
> > On 25.08.2023 19:10, kernel test robot wrote:
> > > Hi Valentine,
> > > 
> > > kernel test robot noticed the following build warnings:
> > > 
> > [..]
> > > All warnings (new ones prefixed by >>):
> > > 
> > >     drivers/pci/pci-sysfs.c:1268:12: warning: no previous prototype for 'pci_create_resource_files' [-Wmissing-prototypes]
> > >      1268 | int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
> > >           |            ^~~~~~~~~~~~~~~~~~~~~~~~~
> > >     drivers/pci/pci-sysfs.c:1269:13: warning: no previous prototype for 'pci_remove_resource_files' [-Wmissing-prototypes]
> > >      1269 | void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
> > >           |             ^~~~~~~~~~~~~~~~~~~~~~~~~
> > > > > drivers/pci/pci-sysfs.c:838:15: warning: 'pci_llseek_resource' defined but not used [-Wunused-function]
> > >       838 | static loff_t pci_llseek_resource(struct file *filep,
> > >           |               ^~~~~~~~~~~~~~~~~~~
> > I'm not sure if I should do anything about it: arc doesn't HAVE_* anything
> > PCI-related, and pci-sysfs doesn't seem to be written with this case in
> > mind. Guarding pci_llseek_resource() with an #ifdef HAVE_AT_LEAST_SOMETHING
> > is trivial, but it feels more like a patch to silence a bot than a proper
> > fix.
> 
> Looks like it will require some untangling to figure out a nice fix,
> but I think you *do* need to do something about it because I don't
> want to add build errors on any arch.

P.S. This patch:
https://lore.kernel.org/r/20230810141947.1236730-5-arnd@kernel.org is
queued up for v6.6-rc1 and should help with the first two warnings.

Bjorn

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v6 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-08-29 20:02                         ` Bjorn Helgaas
  2023-08-29 20:26                           ` Bjorn Helgaas
@ 2023-09-02 15:50                           ` Valentine Sinitsyn
  2023-09-05  7:02                             ` kernel test robot
  2023-09-02 15:50                           ` [PATCH v6 " Valentine Sinitsyn
  2 siblings, 1 reply; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-09-02 15:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo, Bjorn Helgaas
  Cc: Daniel Vetter, Dan Williams, linux-kernel

As of now, seeking in sysfs files is handled by generic_file_llseek().
There are situations where one may want to customize seeking logic:

- Many sysfs entries are fixed files while generic_file_llseek() accepts
  past-the-end positions. Not only being useless by itself, this
  also means a bug in userspace code will trigger not at lseek(), but at
  some later point making debugging harder.
- generic_file_llseek() relies on f_mapping->host to get the file size
  which might not be correct for all sysfs entries.
  See commit 636b21b50152 ("PCI: Revoke mappings like devmem") as an example.

Implement llseek method to override this behavior at sysfs attribute
level. The method is optional, and if it is absent,
generic_file_llseek() is called to preserve backwards compatibility.

Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
---
Looks like a mere __maybe_unused is the cleanest way to fix the issue.

v6:
        - Mark pci_llseek_resource() as __maybe_unused
        - Fix a typo in pci_create_legacy_files()
v5:
        - Fix builds without PCI mmap support (e.g. Alpha)
v4:
        - Fix builds which #define HAVE_PCI_LEGACY (e.g. PowerPC)
v3:
        - Grammar fixes
        - Add base-patch: and prerequisite-patch-id: to make kernel test
          robot happy
v2:
        - Add infrastructure to customize llseek per sysfs entry type
        - Override llseek for PCI sysfs entries with fixed_file_llseek()

 fs/kernfs/file.c       | 14 +++++++++++++-
 fs/sysfs/file.c        | 13 +++++++++++++
 include/linux/kernfs.h |  1 +
 include/linux/sysfs.h  |  2 ++
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 180906c36f51..6166bf74d5b8 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -903,6 +903,18 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
 	return ret;
 }
 
+static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
+{
+	struct kernfs_open_file *of = kernfs_of(file);
+	const struct kernfs_ops *ops;
+
+	ops = kernfs_ops(of->kn);
+	if (ops->llseek)
+		return ops->llseek(of, offset, whence);
+	else
+		return generic_file_llseek(file, offset, whence);
+}
+
 static void kernfs_notify_workfn(struct work_struct *work)
 {
 	struct kernfs_node *kn;
@@ -1005,7 +1017,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
 const struct file_operations kernfs_file_fops = {
 	.read_iter	= kernfs_fop_read_iter,
 	.write_iter	= kernfs_fop_write_iter,
-	.llseek		= generic_file_llseek,
+	.llseek		= kernfs_fop_llseek,
 	.mmap		= kernfs_fop_mmap,
 	.open		= kernfs_fop_open,
 	.release	= kernfs_fop_release,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a12ac0356c69..6b7652fb8050 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -167,6 +167,18 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
 	return battr->mmap(of->file, kobj, battr, vma);
 }
 
+static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset,
+				  int whence)
+{
+	struct bin_attribute *battr = of->kn->priv;
+	struct kobject *kobj = of->kn->parent->priv;
+
+	if (battr->llseek)
+		return battr->llseek(of->file, kobj, battr, offset, whence);
+	else
+		return generic_file_llseek(of->file, offset, whence);
+}
+
 static int sysfs_kf_bin_open(struct kernfs_open_file *of)
 {
 	struct bin_attribute *battr = of->kn->priv;
@@ -249,6 +261,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 	.write		= sysfs_kf_bin_write,
 	.mmap		= sysfs_kf_bin_mmap,
 	.open		= sysfs_kf_bin_open,
+	.llseek		= sysfs_kf_bin_llseek,
 };
 
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 2a36f3218b51..99aaa050ccb7 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -316,6 +316,7 @@ struct kernfs_ops {
 			 struct poll_table_struct *pt);
 
 	int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
+	loff_t (*llseek)(struct kernfs_open_file *of, loff_t offset, int whence);
 };
 
 /*
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index fd3fe5c8c17f..b717a70219f6 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -181,6 +181,8 @@ struct bin_attribute {
 			char *, loff_t, size_t);
 	ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
 			 char *, loff_t, size_t);
+	loff_t (*llseek)(struct file *, struct kobject *, struct bin_attribute *,
+			 loff_t, int);
 	int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
 		    struct vm_area_struct *vma);
 };

base-commit: 76be05d4fd6c91a3885298f1dc3efeef32846399
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v6 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-08-29 20:02                         ` Bjorn Helgaas
  2023-08-29 20:26                           ` Bjorn Helgaas
  2023-09-02 15:50                           ` [PATCH v6 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
@ 2023-09-02 15:50                           ` Valentine Sinitsyn
  2 siblings, 0 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-09-02 15:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo, Bjorn Helgaas
  Cc: Daniel Vetter, Dan Williams, linux-kernel

Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"), mmappable
sysfs entries have started to receive their f_mapping from the iomem
pseudo filesystem, so that CONFIG_IO_STRICT_DEVMEM is honored in sysfs
(and procfs) as well as in /dev/[k]mem.

This resulted in a userspace-visible regression:

1. Open a sysfs PCI resource file (eg. /sys/bus/pci/devices/*/resource0)
2. Use lseek(fd, 0, SEEK_END) to determine its size

Expected result: a PCI region size is returned.
Actual result: 0 is returned.

The reason is that PCI resource files residing in sysfs use
generic_file_llseek(), which relies on f_mapping->host inode to get the
file size. As f_mapping is now redefined, f_mapping->host points to an
anonymous zero-sized iomem_inode which has nothing to do with sysfs file
in question.

Implement a custom llseek method for sysfs PCI resources, which is
almost the same as proc_bus_pci_lseek() used for procfs entries.

This makes sysfs and procfs entries consistent with regards to seeking,
but also introduces userspace-visible changes to seeking PCI resources
in sysfs:

- SEEK_DATA and SEEK_HOLE are no longer supported;
- Seeking past the end of the file is prohibited while previously
  offsets up to MAX_NON_LFS were accepted (reading from these offsets
  was always invalid).

Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/pci-sysfs.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index d9eede2dbc0e..97c9c62d5e3e 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -835,6 +835,19 @@ static const struct attribute_group pci_dev_config_attr_group = {
 	.is_bin_visible = pci_dev_config_attr_is_visible,
 };
 
+/*
+ * llseek operation for mmappable PCI resources.
+ * May be left unused if the arch doesn't provide them.
+ */
+static __maybe_unused loff_t
+pci_llseek_resource(struct file *filep,
+		    struct kobject *kobj __always_unused,
+		    struct bin_attribute *attr,
+		    loff_t offset, int whence)
+{
+	return fixed_size_llseek(filep, offset, whence, attr->size);
+}
+
 #ifdef HAVE_PCI_LEGACY
 /**
  * pci_read_legacy_io - read byte(s) from legacy I/O port space
@@ -967,6 +980,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_io->attr.mode = 0600;
 	b->legacy_io->read = pci_read_legacy_io;
 	b->legacy_io->write = pci_write_legacy_io;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_io->mmap = pci_mmap_legacy_io;
 	b->legacy_io->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_io);
@@ -981,6 +996,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_mem->size = 1024*1024;
 	b->legacy_mem->attr.mode = 0600;
 	b->legacy_mem->mmap = pci_mmap_legacy_mem;
+	/* See pci_create_attr() for motivation */
+	b->legacy_mem->llseek = pci_llseek_resource;
 	b->legacy_mem->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_mem);
 	error = device_create_bin_file(&b->dev, b->legacy_mem);
@@ -1199,8 +1216,15 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
 			res_attr->mmap = pci_mmap_resource_uc;
 		}
 	}
-	if (res_attr->mmap)
+	if (res_attr->mmap) {
 		res_attr->f_mapping = iomem_get_mapping;
+		/*
+		 * generic_file_llseek() consults f_mapping->host to determine
+		 * the file size. As iomem_inode knows nothing about the
+		 * attribute, it's not going to work, so override it as well.
+		 */
+		res_attr->llseek = pci_llseek_resource;
+	}
 	res_attr->attr.name = res_attr_name;
 	res_attr->attr.mode = 0600;
 	res_attr->size = pci_resource_len(pdev, num);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH v6 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-09-02 15:50                           ` [PATCH v6 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
@ 2023-09-05  7:02                             ` kernel test robot
  2023-09-08 13:49                               ` [PATCH v7 " Valentine Sinitsyn
                                                 ` (3 more replies)
  0 siblings, 4 replies; 31+ messages in thread
From: kernel test robot @ 2023-09-05  7:02 UTC (permalink / raw)
  To: Valentine Sinitsyn
  Cc: oe-lkp, lkp, linux-fsdevel, linux-kernel, Greg Kroah-Hartman,
	Tejun Heo, Bjorn Helgaas, Daniel Vetter, Dan Williams,
	oliver.sang



Hello,

kernel test robot noticed "WARNING:at_fs/kernfs/file.c:#kernfs_ops" on:

commit: c6eefad61209dab3de7446cf8151d38e70440484 ("[PATCH v6 1/2] kernfs: sysfs: support custom llseek method for sysfs entries")
url: https://github.com/intel-lab-lkp/linux/commits/Valentine-Sinitsyn/PCI-Implement-custom-llseek-for-sysfs-resource-entries/20230902-235234
patch link: https://lore.kernel.org/all/20230902155038.1661970-1-valesini@yandex-team.ru/
patch subject: [PATCH v6 1/2] kernfs: sysfs: support custom llseek method for sysfs entries

in testcase: boot

compiler: clang-16
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G

(please refer to attached dmesg/kmsg for entire log/backtrace)



If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202309051442.bd6f9879-oliver.sang@intel.com


[   96.320907][  T252] ------------[ cut here ]------------
[ 96.321715][ T252] WARNING: CPU: 1 PID: 252 at fs/kernfs/file.c:109 kernfs_ops (fs/kernfs/file.c:109) 
[   96.322853][  T252] Modules linked in:
[   96.323438][  T252] CPU: 1 PID: 252 Comm: systemd-logind Not tainted 6.5.0-10888-gc6eefad61209 #1
[   96.324966][  T252] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[ 96.326330][ T252] RIP: 0010:kernfs_ops (fs/kernfs/file.c:109) 
[ 96.327026][ T252] Code: 48 83 c3 68 48 89 d8 48 c1 e8 03 42 80 3c 38 00 74 08 48 89 df e8 de f3 e2 ff 48 8b 03 5b 41 5e 41 5f 31 c9 31 ff 31 f6 c3 cc <0f> 0b eb d2 44 89 f1 80 e1 07 fe c1 38 c1 7c 91 4c 89 f7 e8 76 f3
All code
========
   0:	48 83 c3 68          	add    $0x68,%rbx
   4:	48 89 d8             	mov    %rbx,%rax
   7:	48 c1 e8 03          	shr    $0x3,%rax
   b:	42 80 3c 38 00       	cmpb   $0x0,(%rax,%r15,1)
  10:	74 08                	je     0x1a
  12:	48 89 df             	mov    %rbx,%rdi
  15:	e8 de f3 e2 ff       	call   0xffffffffffe2f3f8
  1a:	48 8b 03             	mov    (%rbx),%rax
  1d:	5b                   	pop    %rbx
  1e:	41 5e                	pop    %r14
  20:	41 5f                	pop    %r15
  22:	31 c9                	xor    %ecx,%ecx
  24:	31 ff                	xor    %edi,%edi
  26:	31 f6                	xor    %esi,%esi
  28:	c3                   	ret
  29:	cc                   	int3
  2a:*	0f 0b                	ud2		<-- trapping instruction
  2c:	eb d2                	jmp    0x0
  2e:	44 89 f1             	mov    %r14d,%ecx
  31:	80 e1 07             	and    $0x7,%cl
  34:	fe c1                	inc    %cl
  36:	38 c1                	cmp    %al,%cl
  38:	7c 91                	jl     0xffffffffffffffcb
  3a:	4c 89 f7             	mov    %r14,%rdi
  3d:	e8                   	.byte 0xe8
  3e:	76 f3                	jbe    0x33

Code starting with the faulting instruction
===========================================
   0:	0f 0b                	ud2
   2:	eb d2                	jmp    0xffffffffffffffd6
   4:	44 89 f1             	mov    %r14d,%ecx
   7:	80 e1 07             	and    $0x7,%cl
   a:	fe c1                	inc    %cl
   c:	38 c1                	cmp    %al,%cl
   e:	7c 91                	jl     0xffffffffffffffa1
  10:	4c 89 f7             	mov    %r14,%rdi
  13:	e8                   	.byte 0xe8
  14:	76 f3                	jbe    0x9
[   96.329439][  T252] RSP: 0018:ffff8881638e7ea0 EFLAGS: 00010246
[   96.330261][  T252] RAX: 0000000000000000 RBX: ffff888111e4a2b8 RCX: 0000000000000000
[   96.331346][  T252] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
[   96.332425][  T252] RBP: dffffc0000000000 R08: 0000000000000000 R09: 0000000000000000
[   96.333503][  T252] R10: 0000000000000000 R11: ffffffff8184fd65 R12: ffff8881538a5c00
[   96.334649][  T252] R13: ffff888161bc5ec0 R14: ffff888111e4a350 R15: dffffc0000000000
[   96.335717][  T252] FS:  00007f2d9c6a8980(0000) GS:ffff8883aeb00000(0000) knlGS:0000000000000000
[   96.336833][  T252] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   96.337593][  T252] CR2: 00005600c8ef1595 CR3: 0000000162f96000 CR4: 00000000000406a0
[   96.338544][  T252] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   96.339487][  T252] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[   96.340472][  T252] Call Trace:
[   96.340983][  T252]  <TASK>
[ 96.341447][ T252] ? __warn (kernel/panic.c:673) 
[ 96.342078][ T252] ? kernfs_ops (fs/kernfs/file.c:109) 
[ 96.342740][ T252] ? kernfs_ops (fs/kernfs/file.c:109) 
[ 96.343391][ T252] ? report_bug (lib/bug.c:?) 
[ 96.344046][ T252] ? find_held_lock (kernel/locking/lockdep.c:?) 
[ 96.344738][ T252] ? handle_bug (arch/x86/kernel/traps.c:237) 
[ 96.345314][ T252] ? exc_invalid_op (arch/x86/kernel/traps.c:258) 
[ 96.345963][ T252] ? asm_exc_invalid_op (arch/x86/include/asm/idtentry.h:568) 
[ 96.346694][ T252] ? __cfi_kernfs_fop_llseek (fs/kernfs/file.c:907) 
[ 96.347473][ T252] ? kernfs_ops (fs/kernfs/file.c:109) 
[ 96.348135][ T252] kernfs_fop_llseek (fs/kernfs/file.c:911) 
[ 96.348869][ T252] ksys_lseek (fs/read_write.c:289) 
[ 96.349497][ T252] do_syscall_64 (arch/x86/entry/common.c:?) 
[ 96.350141][ T252] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) 
[   96.350952][  T252] RIP: 0033:0x7f2d9cf82fc7
[ 96.351602][ T252] Code: c7 c0 ff ff ff ff c3 0f 1f 40 00 48 8b 15 c1 ee 0c 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb ba 0f 1f 00 b8 08 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 01 c3 48 8b 15 99 ee 0c 00 f7 d8 64 89 02 48
All code
========
   0:	c7 c0 ff ff ff ff    	mov    $0xffffffff,%eax
   6:	c3                   	ret
   7:	0f 1f 40 00          	nopl   0x0(%rax)
   b:	48 8b 15 c1 ee 0c 00 	mov    0xceec1(%rip),%rdx        # 0xceed3
  12:	f7 d8                	neg    %eax
  14:	64 89 02             	mov    %eax,%fs:(%rdx)
  17:	48 c7 c0 ff ff ff ff 	mov    $0xffffffffffffffff,%rax
  1e:	eb ba                	jmp    0xffffffffffffffda
  20:	0f 1f 00             	nopl   (%rax)
  23:	b8 08 00 00 00       	mov    $0x8,%eax
  28:	0f 05                	syscall
  2a:*	48 3d 00 f0 ff ff    	cmp    $0xfffffffffffff000,%rax		<-- trapping instruction
  30:	77 01                	ja     0x33
  32:	c3                   	ret
  33:	48 8b 15 99 ee 0c 00 	mov    0xcee99(%rip),%rdx        # 0xceed3
  3a:	f7 d8                	neg    %eax
  3c:	64 89 02             	mov    %eax,%fs:(%rdx)
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	48 3d 00 f0 ff ff    	cmp    $0xfffffffffffff000,%rax
   6:	77 01                	ja     0x9
   8:	c3                   	ret
   9:	48 8b 15 99 ee 0c 00 	mov    0xcee99(%rip),%rdx        # 0xceea9
  10:	f7 d8                	neg    %eax
  12:	64 89 02             	mov    %eax,%fs:(%rdx)
  15:	48                   	rex.W
[   96.357571][  T252] RSP: 002b:00007fff4e4c3fc8 EFLAGS: 00000246 ORIG_RAX: 0000000000000008
[   96.358740][  T252] RAX: ffffffffffffffda RBX: 0000563f1ffa0a80 RCX: 00007f2d9cf82fc7
[   96.359842][  T252] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000007
[   96.360873][  T252] RBP: 0000563f1ffa0a80 R08: 00007fff4e4c3fc0 R09: 0000000000000000
[   96.361934][  T252] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
[   96.363024][  T252] R13: 0000000000000000 R14: 00007fff4e4c4188 R15: 00007fff4e4c41a0
[   96.364155][  T252]  </TASK>
[   96.364719][  T252] irq event stamp: 64209
[ 96.365341][ T252] hardirqs last enabled at (64219): __up_console_sem (arch/x86/include/asm/irqflags.h:26 arch/x86/include/asm/irqflags.h:67 arch/x86/include/asm/irqflags.h:127 kernel/printk/printk.c:347) 
[ 96.366558][ T252] hardirqs last disabled at (64228): __up_console_sem (kernel/printk/printk.c:345) 
[ 96.367774][ T252] softirqs last enabled at (64128): __do_softirq (arch/x86/include/asm/preempt.h:27 kernel/softirq.c:400 kernel/softirq.c:582) 
[ 96.368971][ T252] softirqs last disabled at (64119): __irq_exit_rcu (kernel/softirq.c:612) 
[   96.370158][  T252] ---[ end trace 0000000000000000 ]---
Starting LKP bootstrap...
Starting /etc/rc.local Compatibility...
Starting OpenBSD Secure Shell server...
Starting Permit User Sessions...
[FAILED] Failed to start LSB: OpenIPMI Driver init script.
See 'systemctl status openipmi.service' for details.
[  OK  ] Started User Login Management.
[  OK  ] Started LKP bootstrap.
[  OK  ] Started LSB: Load kernel image with kexec.
LKP: ttyS0: 296: skip deploy intel ucode as no ucode is specified
[  OK  ] Finished Permit User Sessions.
[  OK  ] Started OpenBSD Secure Shell server.
LKP: ttyS0: 296: Kernel tests: Boot OK!
LKP: ttyS0: 296: HOSTNAME vm-snb, MAC 52:54:00:12:34:56, kernel 6.5.0-10888-gc6eefad61209 1
LKP: ttyS0: 296:  /lkp/lkp/src/bin/run-lkp /lkp/jobs/scheduled/vm-meta-300/boot-1-debian-11.1-x86_64-20220510.cgz-x86_64-randconfig-071-20230903-c6eefad61209-20230903-11038-o17p1l-0.yaml
[  104.602900][  T165] kmemleak: Automatic memory scanning thread ended
[  OK  ] Started System Logging Service.
[  106.970306][  T310] is_virt=true
[  106.970347][  T310]
[  108.079565][  T310] lkp: kernel tainted state: 512
[  108.079600][  T310]
[  108.704632][  T310] LKP: stdout: 296: Kernel tests: Boot OK!
[  108.704672][  T310]
[  112.730026][  T310] LKP: stdout: 296: HOSTNAME vm-snb, MAC 52:54:00:12:34:56, kernel 6.5.0-10888-gc6eefad61209 1
[  112.730070][  T310]
[  112.732401][  T310] NO_NETWORK=
[  112.732437][  T310]
[  118.521298][  T310] LKP: stdout: 296:  /lkp/lkp/src/bin/run-lkp /lkp/jobs/scheduled/vm-meta-300/boot-1-debian-11.1-x86_64-20220510.cgz-x86_64-randconfig-071-20230903-c6eefad61209-20230903-11038-o17p1l-0.yaml
[  118.521368][  T310]
[  118.537313][  T310] RESULT_ROOT=/result/boot/1/vm-snb/debian-11.1-x86_64-20220510.cgz/x86_64-randconfig-071-20230903/clang-16/c6eefad61209dab3de7446cf8151d38e70440484/0
[  118.537382][  T310]
[  118.542693][  T310] job=/lkp/jobs/scheduled/vm-meta-300/boot-1-debian-11.1-x86_64-20220510.cgz-x86_64-randconfig-071-20230903-c6eefad61209-20230903-11038-o17p1l-0.yaml


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20230905/202309051442.bd6f9879-oliver.sang@intel.com



-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v7 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-09-05  7:02                             ` kernel test robot
@ 2023-09-08 13:49                               ` Valentine Sinitsyn
  2023-09-08 13:49                               ` [PATCH v7 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
                                                 ` (2 subsequent siblings)
  3 siblings, 0 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-09-08 13:49 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

As of now, seeking in sysfs files is handled by generic_file_llseek().
There are situations where one may want to customize seeking logic:

- Many sysfs entries are fixed files while generic_file_llseek() accepts
  past-the-end positions. Not only being useless by itself, this
  also means a bug in userspace code will trigger not at lseek(), but at
  some later point making debugging harder.
- generic_file_llseek() relies on f_mapping->host to get the file size
  which might not be correct for all sysfs entries.
  See commit 636b21b50152 ("PCI: Revoke mappings like devmem") as an example.

Implement llseek method to override this behavior at sysfs attribute
level. The method is optional, and if it is absent,
generic_file_llseek() is called to preserve backwards compatibility.

Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
---
v7:
        - Use proper locking in kernfs_fop_llseek()
v6:
        - Mark pci_llseek_resource() as __maybe_unused
        - Fix a typo in pci_create_legacy_files()
v5:
        - Fix builds without PCI mmap support (e.g. Alpha)
v4:
        - Fix builds which #define HAVE_PCI_LEGACY (e.g. PowerPC)
v3:
        - Grammar fixes
        - Add base-patch: and prerequisite-patch-id: to make kernel test
          robot happy
v2:
        - Add infrastructure to customize llseek per sysfs entry type
        - Override llseek for PCI sysfs entries with fixed_file_llseek()

 fs/kernfs/file.c       | 29 ++++++++++++++++++++++++++++-
 fs/sysfs/file.c        | 13 +++++++++++++
 include/linux/kernfs.h |  1 +
 include/linux/sysfs.h  |  2 ++
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 180906c36f51..1a76fb8128ce 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -903,6 +903,33 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
 	return ret;
 }
 
+static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
+{
+	struct kernfs_open_file *of = kernfs_of(file);
+	const struct kernfs_ops *ops;
+	loff_t ret;
+
+	/*
+	 * @of->mutex nests outside active ref and is primarily to ensure that
+	 * the ops aren't called concurrently for the same open file.
+	 */
+	mutex_lock(&of->mutex);
+	if (!kernfs_get_active(of->kn)) {
+		mutex_unlock(&of->mutex);
+		return -ENODEV;
+	}
+
+	ops = kernfs_ops(of->kn);
+	if (ops->llseek)
+		ret = ops->llseek(of, offset, whence);
+	else
+		ret = generic_file_llseek(file, offset, whence);
+
+	mutex_unlock(&of->mutex);
+	kernfs_put_active(of->kn);
+	return ret;
+}
+
 static void kernfs_notify_workfn(struct work_struct *work)
 {
 	struct kernfs_node *kn;
@@ -1005,7 +1032,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
 const struct file_operations kernfs_file_fops = {
 	.read_iter	= kernfs_fop_read_iter,
 	.write_iter	= kernfs_fop_write_iter,
-	.llseek		= generic_file_llseek,
+	.llseek		= kernfs_fop_llseek,
 	.mmap		= kernfs_fop_mmap,
 	.open		= kernfs_fop_open,
 	.release	= kernfs_fop_release,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a12ac0356c69..6b7652fb8050 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -167,6 +167,18 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
 	return battr->mmap(of->file, kobj, battr, vma);
 }
 
+static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset,
+				  int whence)
+{
+	struct bin_attribute *battr = of->kn->priv;
+	struct kobject *kobj = of->kn->parent->priv;
+
+	if (battr->llseek)
+		return battr->llseek(of->file, kobj, battr, offset, whence);
+	else
+		return generic_file_llseek(of->file, offset, whence);
+}
+
 static int sysfs_kf_bin_open(struct kernfs_open_file *of)
 {
 	struct bin_attribute *battr = of->kn->priv;
@@ -249,6 +261,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 	.write		= sysfs_kf_bin_write,
 	.mmap		= sysfs_kf_bin_mmap,
 	.open		= sysfs_kf_bin_open,
+	.llseek		= sysfs_kf_bin_llseek,
 };
 
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 2a36f3218b51..99aaa050ccb7 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -316,6 +316,7 @@ struct kernfs_ops {
 			 struct poll_table_struct *pt);
 
 	int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
+	loff_t (*llseek)(struct kernfs_open_file *of, loff_t offset, int whence);
 };
 
 /*
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index fd3fe5c8c17f..b717a70219f6 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -181,6 +181,8 @@ struct bin_attribute {
 			char *, loff_t, size_t);
 	ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
 			 char *, loff_t, size_t);
+	loff_t (*llseek)(struct file *, struct kobject *, struct bin_attribute *,
+			 loff_t, int);
 	int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
 		    struct vm_area_struct *vma);
 };

base-commit: a48fa7efaf1161c1c898931fe4c7f0070964233a
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v7 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-09-05  7:02                             ` kernel test robot
  2023-09-08 13:49                               ` [PATCH v7 " Valentine Sinitsyn
@ 2023-09-08 13:49                               ` Valentine Sinitsyn
  2023-09-08 13:56                               ` [PATCH v8 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
  2023-09-08 13:56                               ` [PATCH v8 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
  3 siblings, 0 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-09-08 13:49 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"), mmappable
sysfs entries have started to receive their f_mapping from the iomem
pseudo filesystem, so that CONFIG_IO_STRICT_DEVMEM is honored in sysfs
(and procfs) as well as in /dev/[k]mem.

This resulted in a userspace-visible regression:

1. Open a sysfs PCI resource file (eg. /sys/bus/pci/devices/*/resource0)
2. Use lseek(fd, 0, SEEK_END) to determine its size

Expected result: a PCI region size is returned.
Actual result: 0 is returned.

The reason is that PCI resource files residing in sysfs use
generic_file_llseek(), which relies on f_mapping->host inode to get the
file size. As f_mapping is now redefined, f_mapping->host points to an
anonymous zero-sized iomem_inode which has nothing to do with sysfs file
in question.

Implement a custom llseek method for sysfs PCI resources, which is
almost the same as proc_bus_pci_lseek() used for procfs entries.

This makes sysfs and procfs entries consistent with regards to seeking,
but also introduces userspace-visible changes to seeking PCI resources
in sysfs:

- SEEK_DATA and SEEK_HOLE are no longer supported;
- Seeking past the end of the file is prohibited while previously
  offsets up to MAX_NON_LFS were accepted (reading from these offsets
  was always invalid).

Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/pci-sysfs.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index d9eede2dbc0e..97c9c62d5e3e 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -835,6 +835,19 @@ static const struct attribute_group pci_dev_config_attr_group = {
 	.is_bin_visible = pci_dev_config_attr_is_visible,
 };
 
+/*
+ * llseek operation for mmappable PCI resources.
+ * May be left unused if the arch doesn't provide them.
+ */
+static __maybe_unused loff_t
+pci_llseek_resource(struct file *filep,
+		    struct kobject *kobj __always_unused,
+		    struct bin_attribute *attr,
+		    loff_t offset, int whence)
+{
+	return fixed_size_llseek(filep, offset, whence, attr->size);
+}
+
 #ifdef HAVE_PCI_LEGACY
 /**
  * pci_read_legacy_io - read byte(s) from legacy I/O port space
@@ -967,6 +980,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_io->attr.mode = 0600;
 	b->legacy_io->read = pci_read_legacy_io;
 	b->legacy_io->write = pci_write_legacy_io;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_io->mmap = pci_mmap_legacy_io;
 	b->legacy_io->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_io);
@@ -981,6 +996,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_mem->size = 1024*1024;
 	b->legacy_mem->attr.mode = 0600;
 	b->legacy_mem->mmap = pci_mmap_legacy_mem;
+	/* See pci_create_attr() for motivation */
+	b->legacy_mem->llseek = pci_llseek_resource;
 	b->legacy_mem->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_mem);
 	error = device_create_bin_file(&b->dev, b->legacy_mem);
@@ -1199,8 +1216,15 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
 			res_attr->mmap = pci_mmap_resource_uc;
 		}
 	}
-	if (res_attr->mmap)
+	if (res_attr->mmap) {
 		res_attr->f_mapping = iomem_get_mapping;
+		/*
+		 * generic_file_llseek() consults f_mapping->host to determine
+		 * the file size. As iomem_inode knows nothing about the
+		 * attribute, it's not going to work, so override it as well.
+		 */
+		res_attr->llseek = pci_llseek_resource;
+	}
 	res_attr->attr.name = res_attr_name;
 	res_attr->attr.mode = 0600;
 	res_attr->size = pci_resource_len(pdev, num);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v8 1/2] kernfs: sysfs: support custom llseek method for sysfs entries
  2023-09-05  7:02                             ` kernel test robot
  2023-09-08 13:49                               ` [PATCH v7 " Valentine Sinitsyn
  2023-09-08 13:49                               ` [PATCH v7 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
@ 2023-09-08 13:56                               ` Valentine Sinitsyn
  2023-09-08 13:56                               ` [PATCH v8 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
  3 siblings, 0 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-09-08 13:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

As of now, seeking in sysfs files is handled by generic_file_llseek().
There are situations where one may want to customize seeking logic:

- Many sysfs entries are fixed files while generic_file_llseek() accepts
  past-the-end positions. Not only being useless by itself, this
  also means a bug in userspace code will trigger not at lseek(), but at
  some later point making debugging harder.
- generic_file_llseek() relies on f_mapping->host to get the file size
  which might not be correct for all sysfs entries.
  See commit 636b21b50152 ("PCI: Revoke mappings like devmem") as an example.

Implement llseek method to override this behavior at sysfs attribute
level. The method is optional, and if it is absent,
generic_file_llseek() is called to preserve backwards compatibility.

Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
----
v8:
        - This is real v7; previous v7 is a buggy earlier patch sent by
          mistake
v7:
        - Use proper locking in kernfs_fop_llseek()
v6:
        - Mark pci_llseek_resource() as __maybe_unused
        - Fix a typo in pci_create_legacy_files()
v5:
        - Fix builds without PCI mmap support (e.g. Alpha)
v4:
        - Fix builds which #define HAVE_PCI_LEGACY (e.g. PowerPC)
v3:
        - Grammar fixes
        - Add base-patch: and prerequisite-patch-id: to make kernel test
          robot happy
v2:
        - Add infrastructure to customize llseek per sysfs entry type
        - Override llseek for PCI sysfs entries with fixed_file_llseek()--

 fs/kernfs/file.c       | 29 ++++++++++++++++++++++++++++-
 fs/sysfs/file.c        | 13 +++++++++++++
 include/linux/kernfs.h |  1 +
 include/linux/sysfs.h  |  2 ++
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 180906c36f51..855e3f9d8dcc 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -903,6 +903,33 @@ static __poll_t kernfs_fop_poll(struct file *filp, poll_table *wait)
 	return ret;
 }
 
+static loff_t kernfs_fop_llseek(struct file *file, loff_t offset, int whence)
+{
+	struct kernfs_open_file *of = kernfs_of(file);
+	const struct kernfs_ops *ops;
+	loff_t ret;
+
+	/*
+	 * @of->mutex nests outside active ref and is primarily to ensure that
+	 * the ops aren't called concurrently for the same open file.
+	 */
+	mutex_lock(&of->mutex);
+	if (!kernfs_get_active(of->kn)) {
+		mutex_unlock(&of->mutex);
+		return -ENODEV;
+	}
+
+	ops = kernfs_ops(of->kn);
+	if (ops->llseek)
+		ret = ops->llseek(of, offset, whence);
+	else
+		ret = generic_file_llseek(file, offset, whence);
+
+	kernfs_put_active(of->kn);
+	mutex_unlock(&of->mutex);
+	return ret;
+}
+
 static void kernfs_notify_workfn(struct work_struct *work)
 {
 	struct kernfs_node *kn;
@@ -1005,7 +1032,7 @@ EXPORT_SYMBOL_GPL(kernfs_notify);
 const struct file_operations kernfs_file_fops = {
 	.read_iter	= kernfs_fop_read_iter,
 	.write_iter	= kernfs_fop_write_iter,
-	.llseek		= generic_file_llseek,
+	.llseek		= kernfs_fop_llseek,
 	.mmap		= kernfs_fop_mmap,
 	.open		= kernfs_fop_open,
 	.release	= kernfs_fop_release,
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index a12ac0356c69..6b7652fb8050 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -167,6 +167,18 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
 	return battr->mmap(of->file, kobj, battr, vma);
 }
 
+static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset,
+				  int whence)
+{
+	struct bin_attribute *battr = of->kn->priv;
+	struct kobject *kobj = of->kn->parent->priv;
+
+	if (battr->llseek)
+		return battr->llseek(of->file, kobj, battr, offset, whence);
+	else
+		return generic_file_llseek(of->file, offset, whence);
+}
+
 static int sysfs_kf_bin_open(struct kernfs_open_file *of)
 {
 	struct bin_attribute *battr = of->kn->priv;
@@ -249,6 +261,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
 	.write		= sysfs_kf_bin_write,
 	.mmap		= sysfs_kf_bin_mmap,
 	.open		= sysfs_kf_bin_open,
+	.llseek		= sysfs_kf_bin_llseek,
 };
 
 int sysfs_add_file_mode_ns(struct kernfs_node *parent,
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 2a36f3218b51..99aaa050ccb7 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -316,6 +316,7 @@ struct kernfs_ops {
 			 struct poll_table_struct *pt);
 
 	int (*mmap)(struct kernfs_open_file *of, struct vm_area_struct *vma);
+	loff_t (*llseek)(struct kernfs_open_file *of, loff_t offset, int whence);
 };
 
 /*
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index fd3fe5c8c17f..b717a70219f6 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -181,6 +181,8 @@ struct bin_attribute {
 			char *, loff_t, size_t);
 	ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,
 			 char *, loff_t, size_t);
+	loff_t (*llseek)(struct file *, struct kobject *, struct bin_attribute *,
+			 loff_t, int);
 	int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr,
 		    struct vm_area_struct *vma);
 };

base-commit: a48fa7efaf1161c1c898931fe4c7f0070964233a
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v8 2/2] PCI: Implement custom llseek for sysfs resource entries
  2023-09-05  7:02                             ` kernel test robot
                                                 ` (2 preceding siblings ...)
  2023-09-08 13:56                               ` [PATCH v8 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
@ 2023-09-08 13:56                               ` Valentine Sinitsyn
  3 siblings, 0 replies; 31+ messages in thread
From: Valentine Sinitsyn @ 2023-09-08 13:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Tejun Heo
  Cc: Daniel Vetter, Bjorn Helgaas, Dan Williams, linux-kernel

Since commit 636b21b50152 ("PCI: Revoke mappings like devmem"), mmappable
sysfs entries have started to receive their f_mapping from the iomem
pseudo filesystem, so that CONFIG_IO_STRICT_DEVMEM is honored in sysfs
(and procfs) as well as in /dev/[k]mem.

This resulted in a userspace-visible regression:

1. Open a sysfs PCI resource file (eg. /sys/bus/pci/devices/*/resource0)
2. Use lseek(fd, 0, SEEK_END) to determine its size

Expected result: a PCI region size is returned.
Actual result: 0 is returned.

The reason is that PCI resource files residing in sysfs use
generic_file_llseek(), which relies on f_mapping->host inode to get the
file size. As f_mapping is now redefined, f_mapping->host points to an
anonymous zero-sized iomem_inode which has nothing to do with sysfs file
in question.

Implement a custom llseek method for sysfs PCI resources, which is
almost the same as proc_bus_pci_lseek() used for procfs entries.

This makes sysfs and procfs entries consistent with regards to seeking,
but also introduces userspace-visible changes to seeking PCI resources
in sysfs:

- SEEK_DATA and SEEK_HOLE are no longer supported;
- Seeking past the end of the file is prohibited while previously
  offsets up to MAX_NON_LFS were accepted (reading from these offsets
  was always invalid).

Fixes: 636b21b50152 ("PCI: Revoke mappings like devmem")
Cc: stable@vger.kernel.org
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 drivers/pci/pci-sysfs.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index d9eede2dbc0e..97c9c62d5e3e 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -835,6 +835,19 @@ static const struct attribute_group pci_dev_config_attr_group = {
 	.is_bin_visible = pci_dev_config_attr_is_visible,
 };
 
+/*
+ * llseek operation for mmappable PCI resources.
+ * May be left unused if the arch doesn't provide them.
+ */
+static __maybe_unused loff_t
+pci_llseek_resource(struct file *filep,
+		    struct kobject *kobj __always_unused,
+		    struct bin_attribute *attr,
+		    loff_t offset, int whence)
+{
+	return fixed_size_llseek(filep, offset, whence, attr->size);
+}
+
 #ifdef HAVE_PCI_LEGACY
 /**
  * pci_read_legacy_io - read byte(s) from legacy I/O port space
@@ -967,6 +980,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_io->attr.mode = 0600;
 	b->legacy_io->read = pci_read_legacy_io;
 	b->legacy_io->write = pci_write_legacy_io;
+	/* See pci_create_attr() for motivation */
+	b->legacy_io->llseek = pci_llseek_resource;
 	b->legacy_io->mmap = pci_mmap_legacy_io;
 	b->legacy_io->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_io);
@@ -981,6 +996,8 @@ void pci_create_legacy_files(struct pci_bus *b)
 	b->legacy_mem->size = 1024*1024;
 	b->legacy_mem->attr.mode = 0600;
 	b->legacy_mem->mmap = pci_mmap_legacy_mem;
+	/* See pci_create_attr() for motivation */
+	b->legacy_mem->llseek = pci_llseek_resource;
 	b->legacy_mem->f_mapping = iomem_get_mapping;
 	pci_adjust_legacy_attr(b, pci_mmap_mem);
 	error = device_create_bin_file(&b->dev, b->legacy_mem);
@@ -1199,8 +1216,15 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
 			res_attr->mmap = pci_mmap_resource_uc;
 		}
 	}
-	if (res_attr->mmap)
+	if (res_attr->mmap) {
 		res_attr->f_mapping = iomem_get_mapping;
+		/*
+		 * generic_file_llseek() consults f_mapping->host to determine
+		 * the file size. As iomem_inode knows nothing about the
+		 * attribute, it's not going to work, so override it as well.
+		 */
+		res_attr->llseek = pci_llseek_resource;
+	}
 	res_attr->attr.name = res_attr_name;
 	res_attr->attr.mode = 0600;
 	res_attr->size = pci_resource_len(pdev, num);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2023-09-08 13:56 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-14 19:08 [PATCH] kernfs: implement custom llseek method to fix userspace regression Valentine Sinitsyn
2023-08-14 20:01 ` Dan Williams
2023-08-15  8:25   ` Valentin Sinitsyn
2023-08-15 15:48     ` Dan Williams
2023-08-17 18:53       ` Valentin Sinitsyn
2023-08-21  7:29         ` [RESEND PATCH v2 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
2023-08-21  7:29         ` [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs Valentine Sinitsyn
2023-08-21 19:55           ` Bjorn Helgaas
2023-08-22  7:51             ` [PATCH v3 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
2023-08-22  7:51             ` [PATCH v3 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
2023-08-22 11:54               ` [PATCH v4 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
2023-08-22 11:54               ` [PATCH v4 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
2023-08-22 17:43                 ` kernel test robot
2023-08-23 12:58                   ` [PATCH v5 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
2023-08-23 14:37                     ` Greg Kroah-Hartman
2023-08-23 14:39                       ` Greg Kroah-Hartman
2023-08-23 20:11                         ` Valentin Sinitsyn
2023-08-23 12:58                   ` [PATCH v5 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
2023-08-25 14:10                     ` kernel test robot
2023-08-28  7:22                       ` Valentin Sinitsyn
2023-08-29 20:02                         ` Bjorn Helgaas
2023-08-29 20:26                           ` Bjorn Helgaas
2023-09-02 15:50                           ` [PATCH v6 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
2023-09-05  7:02                             ` kernel test robot
2023-09-08 13:49                               ` [PATCH v7 " Valentine Sinitsyn
2023-09-08 13:49                               ` [PATCH v7 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
2023-09-08 13:56                               ` [PATCH v8 1/2] kernfs: sysfs: support custom llseek method for sysfs entries Valentine Sinitsyn
2023-09-08 13:56                               ` [PATCH v8 2/2] PCI: Implement custom llseek for sysfs resource entries Valentine Sinitsyn
2023-09-02 15:50                           ` [PATCH v6 " Valentine Sinitsyn
2023-08-21 23:15           ` [RESEND PATCH v2 2/2] PCI: implement custom llseek method for PCI resource entries in sysfs kernel test robot
2023-08-22  8:09             ` Valentin Sinitsyn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).