Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

virtio changes 5/2016 #55

Closed
wants to merge 8 commits into from
Closed

virtio changes 5/2016 #55

wants to merge 8 commits into from

Conversation

ladipro
Copy link
Contributor

@ladipro ladipro commented Jun 2, 2016

ff1ab8b touches common PCI code but only the virtio-net driver is affected. Please let me know if there are any questions or concerns.

Thank you,
Ladi

This commit adds two new functions. pci_enable_device gives drivers
finer control over how the PCI device is initialized and
pci_restore_device is the shutdown path counterpart.

adjust_pci_device is now implemented in terms of pci_enable_device
and its functionality hasn't changed, i.e. it still unconditionally
enables both memory and I/O space access, and makes sure that the PCI
latency timer is set to a minimum value of 32.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Some of the regions may end up being unmapped, either because
they are optional or because the attempt to map them has failed.
Region types starting at 0 didn't make it easy to test for this
condition.

This commit bumps all valid region types up by 1 with 0 having
the implicit 'unmapped' meaning.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
The driver enabled both memory and I/O access even if they were
not usable, e.g. BAR not mapped by BIOS. This commit fixes it by
enabling only the BAR types actually used. The device is also
restored to the original state (in terms of the command PCI
register) on removal.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
iPXE debug logging doesn't support %u. This commit replaces it with %d
in virtio-pci debug format strings.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
@ladipro
Copy link
Contributor Author

ladipro commented Jun 9, 2016

Friendly ping.

@ipxe-devel
Copy link

On 09/06/16 07:41, Ladi Prosek wrote:

Friendly ping.

ACK. In the post-ARM64-work queue. Thanks for putting this into a git
tree; that's easier for me to handle than e-mails, at least until github
next decides to break their API.

Michael

@ipxe-devel
Copy link

On 09/06/16 07:41, Ladi Prosek wrote:

Friendly ping.

I've cherry-picked the two commits that seemed obviously correct to me:

[virtio] Renumber virtio_pci_region flags
[virtio] Fix virtio-pci logging

I don't understand the motivation for the remaining two:

[pci] Add pci_enable_device and pci_restore_device
[virtio] Enable and restore PCI device correctly

If a PCI device has no I/O BAR, then it can simply implement
PCI_COMMAND_IO as hardwired to zero. Similarly for PCI_COMMAND_MEM.

Do virtio devices treat PCI_COMMAND in some special way which requires
this additional (mild) complexity?

Thanks,

Michael

@ladipro
Copy link
Contributor Author

ladipro commented Jun 20, 2016

Thanks - virtio devices may be configured to expose both I/O and memory BARs, with either type being enough to drive the device. It is basically a back-compat setup where older drivers can still use I/O ports and newer may choose to use the so called "modern" interface.

We would like to avoid enabling PCI_COMMAND_IO / PCI_COMMAND_MEM if the driver is not going to use it.

@ipxe-devel
Copy link

On 20/06/16 15:37, Ladi Prosek wrote:

Thanks - virtio devices may be configured to expose both I/O and memory
BARs, with either type being enough to drive the device. It is basically
a back-compat setup where older drivers can still use I/O ports and
newer may choose to use the so called "modern" interface.

We would like to avoid enabling PCI_COMMAND_IO / PCI_COMMAND_MEM if the
driver is not going to use it.

Why? What goes wrong if iPXE just enables both? Does this prevent iPXE
from using the modern interface?

Michael

@ipxe-devel
Copy link

On Mo, 2016-06-20 at 15:44 +0100, Michael Brown wrote:

On 20/06/16 15:37, Ladi Prosek wrote:

Thanks - virtio devices may be configured to expose both I/O and memory
BARs, with either type being enough to drive the device. It is basically
a back-compat setup where older drivers can still use I/O ports and
newer may choose to use the so called "modern" interface.

We would like to avoid enabling PCI_COMMAND_IO / PCI_COMMAND_MEM if the
driver is not going to use it.

Why?

It is nice to have. It will make sure the driver will only use the
interface it intends to use and doesn't mix IO-based legacy device
access and MMIO-based modern device access by accident.

What goes wrong if iPXE just enables both?

Nothing (in theory).

cheers,
Gerd

@ipxe-devel
Copy link

On 20/06/16 16:30, Gerd Hoffmann wrote:

On Mo, 2016-06-20 at 15:44 +0100, Michael Brown wrote:

On 20/06/16 15:37, Ladi Prosek wrote:

Thanks - virtio devices may be configured to expose both I/O and memory
BARs, with either type being enough to drive the device. It is basically
a back-compat setup where older drivers can still use I/O ports and
newer may choose to use the so called "modern" interface.

We would like to avoid enabling PCI_COMMAND_IO / PCI_COMMAND_MEM if the
driver is not going to use it.

Why?

It is nice to have. It will make sure the driver will only use the
interface it intends to use and doesn't mix IO-based legacy device
access and MMIO-based modern device access by accident.

OK. If that kind of safety check is wanted, it should probably be
ensured at compile time, e.g. by having some kind of operations table
instead of scattered "if (is_modern) {}" tests.

I don't think this "nice to have" justifies the code size increase, but
I'll merge it if both you and Ladi disagree with me.

Michael

@ladipro
Copy link
Contributor Author

ladipro commented Jun 20, 2016

I'm fine with dropping this if @marcel-apf doesn't object.

@marcel-apf
Copy link

Hi,
We can't hard-wire the PCI_COMMAND_IO to 0 since virtio are(may be) transitional devices that support both IO and MEM. Since the device supports both modes is up to firmware/OS to choose a working mode. Once the mode is chosen it is expected to update the command register accordingly. This is why PCI spec has separate bits for IO/MEM . If we dig into virtio implementation we may find that we don't care if both bits are on and we may also be able to fix any potential problems.

If every byte is important for ipxe you may leave the patches out, consciously creating an "unfriendly" driver (QEMU will create an io-region for that and will have some 'if' statements with politically correct comments: "Some drivers enable IO even if .." :) )

Bottom line, I would add the patches but definitely there are not a must.
I hope I helped,
Marcel

@ipxe-devel
Copy link

On 21/06/16 09:49, Marcel Apfelbaum wrote:

We can't hard-wire the PCI_COMMAND_IO to 0 since virtio are(may be)
transitional devices that support both IO and MEM. Since the device
supports both modes is up to firmware/OS to choose a working mode. Once
the mode is chosen it is expected to update the command register
accordingly. This is why PCI spec has separate bits for IO/MEM . If we
dig into virtio implementation we may find that we don't care if both
bits are on and we may also be able to fix any potential problems.

If every byte is important for ipxe you may leave the patches out,
consciously creating an "unfriendly" driver (QEMU will create an
io-region for that and will have some 'if' statements with politically
correct comments: "Some drivers enable IO even if .." :) )

Bottom line, I would add the patches but definitely there are not a must.
I hope I helped,

Thanks for the input!

If the current code would potentially cause problems for the virtio host
side (in current or older implementations), then we should definitely
add the patches to iPXE.

Looking at the current hw/virtio/virtio-pci.c in qemu: it seems to react
to only the PCI_COMMAND_MASTER bit of PCI_COMMAND anyway. Does it
actually make any difference to qemu if we set both the IO and MEM bits?

Thanks,

Michael

@ipxe-devel
Copy link

Hi,

Looking at the current hw/virtio/virtio-pci.c in qemu: it seems to react
to only the PCI_COMMAND_MASTER bit of PCI_COMMAND anyway. Does it
actually make any difference to qemu if we set both the IO and MEM bits?

It does, but that happens in the generic pci code as it is the same for
all pci devices. With IO not set the io region for the pci io bar is
not enabled, and qemu can skip the region when searching for a io
handler after trapping an io instruction.

So, in general it is a good idea to leave stuff disabled if you don't
need it as this saves resources. Some cpu cycles in emulation code in
case of qemu, and possibly it reduces power consumption a bit on
physical hardware.

But not doing so should not cause big problems either, especially in
case the software runs for a short amount of time only like ipxe does.

For reference: seabios recently started doing that too with this commit:

https://code.coreboot.org/p/seabios/source/commit/f1b1d76159a8e7091e783bbc296b928226ccf153/

... and switching all drivers over to use the new pci_enable_{io,mem}bar
functions in subsequent patches.

cheers,
Gerd

This commit adds two new functions. pci_enable_device gives drivers
finer control over how the PCI device is initialized and
pci_restore_device is the shutdown path counterpart.

adjust_pci_device is now implemented in terms of pci_enable_device
and its functionality hasn't changed, i.e. it still unconditionally
enables both memory and I/O space access, and makes sure that the PCI
latency timer is set to a minimum value of 32.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
The driver enabled both memory and I/O access even if they were
not usable, e.g. BAR not mapped by BIOS. This commit fixes it by
enabling only the BAR types actually used. The device is also
restored to the original state (in terms of the command PCI
register) on removal.

Signed-off-by: Ladi Prosek <lprosek@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
@ladipro ladipro closed this Dec 21, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants