Re: [PATCH 2/7] firmware: add offset to request_firmware_into_buf

From: Scott Branden
Date: Fri Feb 21 2020 - 18:37:55 EST


Hi Arnd,

On 2020-02-21 12:44 a.m., Arnd Bergmann wrote:
On Fri, Feb 21, 2020 at 1:11 AM Scott Branden
<scott.branden@xxxxxxxxxxxx> wrote:
On 2019-10-11 6:31 a.m., Luis Chamberlain wrote:
On Tue, Aug 27, 2019 at 12:40:02PM +0200, Takashi Iwai wrote:
On Mon, 26 Aug 2019 19:24:22 +0200,
Scott Branden wrote:
I will admit I am not familiar with every subtlety of PCI
accesses. Any comments to the Valkyrie driver in this patch series are
appreciated.
But not all drivers need to work on all architectures. I can add a
depends on x86 64bit architectures to the driver to limit it to such.
But it's an individual board on PCIe, and should work no matter which
architecture is? Or is this really exclusive to x86?
Poke Scott.
Yes, this is exclusive to x86.
In particular, 64-bit x86 server class machines with PCIe gen3 support.
There is no reason for these PCIe boards to run in other lower end
machines or architectures.
It doesn't really matter that much what you expect your customers to
do with your product, or what works a particular machine today, drivers
should generally be written in a portable manner anyway and use
the documented APIs. memcpy() into an __iomem pointer is not
portable and while it probably works on any x86 machine today, please
just don't do it. If you use 'sparse' to check your code, that would normally
result in an address space warning, unless you add __force and a
long comment explaining why you cannot just use memcpy_to_io()
instead. At that point, you are already better off usingn memcpy_to_io() ;-)

Arnd
I am a not performing a memcpy at all right now.
I am calling a request_firmware_into_buf call and do not need to make a copy.
This function eventually calls kernel_read_file, which then makes at indirect call in __vfs_read to perform the read to memory.
From there I am lost as to what operation happens to achieve this.
The read function would need to detect the buf is in io space and perform the necessary operation.
Anyone with any knowledge on how to make this read to io space would be appreciated?

ssize_t __vfs_read(struct file *file, char __user *buf, size_t count,
ÂÂÂ ÂÂÂ ÂÂ loff_t *pos)
{
ÂÂÂ if (file->f_op->read)
ÂÂÂ ÂÂÂ return file->f_op->read(file, buf, count, pos);
ÂÂÂ else if (file->f_op->read_iter)
ÂÂÂ ÂÂÂ return new_sync_read(file, buf, count, pos);
ÂÂÂ else
ÂÂÂ ÂÂÂ return -EINVAL;
}

ssize_t kernel_read(struct file *file, void *buf, size_t count, loff_t *pos)
{
ÂÂÂ mm_segment_t old_fs;
ÂÂÂ ssize_t result;

ÂÂÂ old_fs = get_fs();
ÂÂÂ set_fs(KERNEL_DS);
ÂÂÂ /* The cast to a user pointer is valid due to the set_fs() */
ÂÂÂ result = vfs_read(file, (void __user *)buf, count, pos);
ÂÂÂ set_fs(old_fs);
ÂÂÂ return result;
}