Skip to content

pci: fail FLR when reset callback is missing#866

Open
zp78256pxd-ux wants to merge 5 commits into
nutanix:masterfrom
zp78256pxd-ux:fix/flr-no-reset-callback-clean
Open

pci: fail FLR when reset callback is missing#866
zp78256pxd-ux wants to merge 5 commits into
nutanix:masterfrom
zp78256pxd-ux:fix/flr-no-reset-callback-clean

Conversation

@zp78256pxd-ux

Copy link
Copy Markdown
Contributor

What this PR does

Return EINVAL when a guest triggers PCI Function Level Reset (FLR) but no reset callback is registered.

Previously the library logged:
"FLR callback is not implemented"
but returned success to the client.

This caused FLR requests to appear successful even though no reset occurred.

Changes

  • Return ERROR_INT(EINVAL) in handle_px_pxdc_write()
    when FLR is requested and reset callback is missing.
  • Add regression test covering FLR with FLRC enabled and
    no registered reset callback.

Testing

pytest test/py/test_pci_caps.py -k "write_px" -vv

@tmakatos tmakatos left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break virtual NVMe in SPDK, see #461 (comment)

Comment thread lib/pci_caps.c Outdated
return call_reset_cb(vfu_ctx, VFU_RESET_PCI_FLR);
} else {
vfu_log(vfu_ctx, LOG_ERR, "FLR callback is not implemented");
return ERROR_INT(EINVAL);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea was that the device might not have anything to do for FLR, but maybe that's unlikely.

I think we need to document this somewhere if we make this change?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jlevon IIUC you're in favour of getting this merged? If we're not planning to work on proper support on SPDK then we should at least add a callback and make it a no-op?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do have one, right?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we do have one, right?

we do, got confused that this callback is specific to FLR but it isn't, we pass the reason

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea was that the device might not have anything to do for FLR, but maybe that's unlikely.

I think we need to document this somewhere if we make this change?

If the device advertises FLR then it should provide a reset callback, so I think the correct fix should be to fail adding the Device Control capability (pxdc) if a reset callback hasn't been provided. This means we'll have to document that the reset callback must be configured before adding capabilities.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure myself, but perhaps this should be a failure at realize time - so setup can still be in any order.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's better yes.

@tmakatos

Copy link
Copy Markdown
Collaborator

This will break virtual NVMe in SPDK, see #461 (comment)

Wrong, NVMe does provide a reset callback.

@zp78256pxd-ux

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback — that makes sense to me. Catching this when the capability is added rather than when FLR is actually triggered does seem like the more correct place to enforce it, since it surfaces the misconfiguration at device setup time instead of waiting for a guest to hit it at runtime.

I’m fairly new to this codebase, so I don’t have much visibility into how existing consumers structure their setup calls. A couple of things I wanted to check before attempting a rework:

  1. Would you want this approach folded into this PR, or is it more involved than fits here? It looks like it would mean checking the flrc bit inside vfu_pci_add_capability() rather than just in the FLR write path, so I wasn’t sure whether that’s something you’d prefer to handle separately or whether you’d like me to take a pass at it.
  2. From the SPDK discussion earlier in the thread, is there any known consumer that currently registers the reset callback after adding the capability? If so, enforcing the ordering requirement could break that setup, so I wanted to flag it in case that affects the preferred approach.

Happy to take a shot at whichever direction makes sense — I just didn’t want to make assumptions given I don’t have the full picture of downstream usage yet.

@tmakatos

Copy link
Copy Markdown
Collaborator

Thanks for the feedback — that makes sense to me. Catching this when the capability is added rather than when FLR is actually triggered does seem like the more correct place to enforce it, since it surfaces the misconfiguration at device setup time instead of waiting for a guest to hit it at runtime.

I’m fairly new to this codebase, so I don’t have much visibility into how existing consumers structure their setup calls. A couple of things I wanted to check before attempting a rework:

  1. Would you want this approach folded into this PR, or is it more involved than fits here? It looks like it would mean checking the flrc bit inside vfu_pci_add_capability() rather than just in the FLR write path, so I wasn’t sure whether that’s something you’d prefer to handle separately or whether you’d like me to take a pass at it.

Yes it can be folded in this PR.

  1. From the SPDK discussion earlier in the thread, is there any known consumer that currently registers the reset callback after adding the capability? If so, enforcing the ordering requirement could break that setup, so I wanted to flag it in case that affects the preferred approach.

Our API is technically unstable so it's acceptable to break it in this way.

Happy to take a shot at whichever direction makes sense — I just didn’t want to make assumptions given I don’t have the full picture of downstream usage yet.

@zp78256pxd-ux zp78256pxd-ux force-pushed the fix/flr-no-reset-callback-clean branch from 13f4f7c to dfbd202 Compare June 30, 2026 17:56
Devices advertising PCIe Function Level Reset (FLR) support must
provide a reset callback.

Validate this requirement during device realization rather than
when the guest first triggers an FLR request, ensuring invalid
device configurations fail early.

Add a regression test verifying that vfu_realize_ctx() fails with
EINVAL when an FLR-capable device does not register a reset
callback.

Signed-off-by: Siddharth C <siddharthcibi@icloud.com>
@zp78256pxd-ux zp78256pxd-ux force-pushed the fix/flr-no-reset-callback-clean branch from dfbd202 to f2f038d Compare June 30, 2026 18:02
@zp78256pxd-ux

Copy link
Copy Markdown
Contributor Author

Updated per review feedback: moved the validation to vfu_realize_ctx() so the check happens during realization rather than when FLR is triggered, and added a regression test for the EINVAL case.

@tmakatos tmakatos left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just one nit

Comment thread lib/libvfio-user.c Outdated
struct pxcap *px;

px = (struct pxcap *)pci_config_space_ptr(vfu_ctx,
vfu_ctx->pci_cap_exp_off);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

identation

@tmakatos

tmakatos commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

@zp78256pxd-ux checks are failing

@zp78256pxd-ux

Copy link
Copy Markdown
Contributor Author

My current implementation validates this in vfu_realize_ctx(), which causes the samples/lspci example to fail because it advertises FLR support but does not register a reset callback.

Would you prefer:

  1. keeping the validation in vfu_realize_ctx() and updating samples/lspci to provide a reset callback (or disable FLR), or
  2. moving the validation to capability creation time as previously suggested?

@tmakatos

tmakatos commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

My current implementation validates this in vfu_realize_ctx(), which causes the samples/lspci example to fail because it advertises FLR support but does not register a reset callback.

Would you prefer:

  1. keeping the validation in vfu_realize_ctx() and updating samples/lspci to provide a reset callback (or disable FLR), or

this

@zp78256pxd-ux

Copy link
Copy Markdown
Contributor Author

Updated samples/lspci to register a trivial reset callback when advertising FLR support. This keeps the sample compatible with validation in vfu_realize_ctx() requiring a reset callback when FLR is enabled.

Verified locally that samples/lspci builds and runs successfully with the change.

My local make pre-push currently fails due to cmocka 2.0.2 deprecation warnings in existing unit tests (expect_check() with -Werror), which appears unrelated to this change

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.

4 participants