aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libvfio-user.c40
-rw-r--r--lib/pci_caps.c2
-rw-r--r--lib/private.h4
-rw-r--r--test/py/libvfio_user.py10
-rw-r--r--test/py/test_pci_caps.py19
-rw-r--r--test/py/test_quiesce.py22
6 files changed, 64 insertions, 33 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index be4be95..5a6269a 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -887,19 +887,32 @@ out:
return ret;
}
+int
+call_reset_cb(vfu_ctx_t *vfu_ctx, vfu_reset_type_t reason)
+{
+ int ret;
+
+ if (vfu_ctx->reset == NULL) {
+ return 0;
+ }
+
+ vfu_ctx->in_cb = CB_RESET;
+ ret = vfu_ctx->reset(vfu_ctx, reason);
+ vfu_ctx->in_cb = CB_NONE;
+
+ return ret;
+}
+
static int
-do_device_reset(vfu_ctx_t *vfu_ctx, vfu_reset_type_t reason)
+device_reset(vfu_ctx_t *vfu_ctx, vfu_reset_type_t reason)
{
int ret;
- if (vfu_ctx->reset != NULL) {
- vfu_ctx->in_cb = CB_RESET;
- ret = vfu_ctx->reset(vfu_ctx, reason);
- vfu_ctx->in_cb = CB_NONE;
- if (ret < 0) {
- return ret;
- }
+ ret = call_reset_cb(vfu_ctx, reason);
+ if (ret < 0) {
+ return ret;
}
+
if (vfu_ctx->migration != NULL) {
return handle_device_state(vfu_ctx, vfu_ctx->migration,
VFIO_DEVICE_STATE_V1_RUNNING, false);
@@ -907,12 +920,6 @@ do_device_reset(vfu_ctx_t *vfu_ctx, vfu_reset_type_t reason)
return 0;
}
-int
-handle_device_reset(vfu_ctx_t *vfu_ctx, vfu_reset_type_t reason)
-{
- return do_device_reset(vfu_ctx, reason);
-}
-
static int
handle_dirty_pages_get(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
{
@@ -1189,7 +1196,7 @@ handle_request(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
case VFIO_USER_DEVICE_RESET:
vfu_log(vfu_ctx, LOG_INFO, "device reset by client");
- ret = handle_device_reset(vfu_ctx, VFU_RESET_DEVICE);
+ ret = device_reset(vfu_ctx, VFU_RESET_DEVICE);
break;
case VFIO_USER_DIRTY_PAGES:
@@ -1495,6 +1502,7 @@ vfu_run_ctx(vfu_ctx_t *vfu_ctx)
* be called at all.
*/
if (vfu_ctx->quiesced) {
+ // FIXME?
vfu_log(vfu_ctx, LOG_DEBUG, "device unquiesced");
vfu_ctx->quiesced = false;
}
@@ -1614,7 +1622,7 @@ vfu_reset_ctx_quiesced(vfu_ctx_t *vfu_ctx)
}
/* FIXME what happens if the device reset callback fails? */
- do_device_reset(vfu_ctx, VFU_RESET_LOST_CONN);
+ device_reset(vfu_ctx, VFU_RESET_LOST_CONN);
if (vfu_ctx->irqs != NULL) {
irqs_reset(vfu_ctx);
diff --git a/lib/pci_caps.c b/lib/pci_caps.c
index 50eb29b..73e2645 100644
--- a/lib/pci_caps.c
+++ b/lib/pci_caps.c
@@ -270,7 +270,7 @@ handle_px_pxdc_write(vfu_ctx_t *vfu_ctx, struct pxcap *px,
}
if (vfu_ctx->reset != NULL) {
vfu_log(vfu_ctx, LOG_DEBUG, "initiate function level reset");
- return vfu_ctx->reset(vfu_ctx, VFU_RESET_PCI_FLR);
+ return call_reset_cb(vfu_ctx, VFU_RESET_PCI_FLR);
} else {
vfu_log(vfu_ctx, LOG_ERR, "FLR callback is not implemented");
}
diff --git a/lib/private.h b/lib/private.h
index 346cfed..fdd804f 100644
--- a/lib/private.h
+++ b/lib/private.h
@@ -221,10 +221,10 @@ handle_dma_unmap(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg,
struct vfio_user_dma_unmap *dma_unmap);
int
-handle_device_get_region_info(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg);
+call_reset_cb(vfu_ctx_t *vfu_ctx, vfu_reset_type_t reason);
int
-handle_device_reset(vfu_ctx_t *vfu_ctx, vfu_reset_type_t reason);
+handle_device_get_region_info(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg);
MOCK_DECLARE(bool, cmd_allowed_when_stopped_and_copying, uint16_t cmd);
diff --git a/test/py/libvfio_user.py b/test/py/libvfio_user.py
index 5f0872a..73fad5a 100644
--- a/test/py/libvfio_user.py
+++ b/test/py/libvfio_user.py
@@ -869,6 +869,16 @@ def __dma_unregister(ctx, info):
dma_unregister(ctx, copy.copy(info.contents))
+def setup_flrc(ctx):
+ # flrc
+ cap = struct.pack("ccHHcc52c", to_byte(PCI_CAP_ID_EXP), b'\0', 0, 0, b'\0',
+ b'\x10', *[b'\0' for _ in range(52)])
+ # FIXME adding capability after we've realized the device only works
+ # because of bug #618.
+ pos = vfu_pci_add_capability(ctx, pos=0, flags=0, data=cap)
+ assert pos == PCI_STD_HEADER_SIZEOF
+
+
def quiesce_cb(ctx):
return 0
diff --git a/test/py/test_pci_caps.py b/test/py/test_pci_caps.py
index 24e992f..edd1683 100644
--- a/test/py/test_pci_caps.py
+++ b/test/py/test_pci_caps.py
@@ -314,16 +314,6 @@ def __test_pci_cap_write_pmcs(sock):
count=len(data), data=data, expect=errno.ENOTSUP)
-def _setup_flrc(ctx):
- # flrc
- cap = struct.pack("ccHHcc52c", to_byte(PCI_CAP_ID_EXP), b'\0', 0, 0, b'\0',
- b'\x10', *[b'\0' for _ in range(52)])
- # FIXME adding capability after we've realized the device only works
- # because of bug #618.
- pos = vfu_pci_add_capability(ctx, pos=0, flags=0, data=cap)
- assert pos == PCI_STD_HEADER_SIZEOF
-
-
@patch("libvfio_user.reset_cb", return_value=0)
@patch('libvfio_user.quiesce_cb')
def test_pci_cap_write_px(mock_quiesce, mock_reset):
@@ -333,7 +323,7 @@ def test_pci_cap_write_px(mock_quiesce, mock_reset):
setup_pci_dev(realize=True)
sock = connect_client(ctx)
- _setup_flrc(ctx)
+ setup_flrc(ctx)
# iflr
offset = PCI_STD_HEADER_SIZEOF + 8
@@ -421,7 +411,7 @@ def test_pci_cap_write_pxdc2():
setup_pci_dev(realize=True)
sock = connect_client(ctx)
- _setup_flrc(ctx)
+ setup_flrc(ctx)
offset = (vfu_pci_find_capability(ctx, False, PCI_CAP_ID_EXP) +
PCI_EXP_DEVCTL2)
@@ -436,9 +426,10 @@ def test_pci_cap_write_pxdc2():
def test_pci_cap_write_pxlc2():
setup_pci_dev(realize=True)
- _setup_flrc(ctx)
-
sock = connect_client(ctx)
+
+ setup_flrc(ctx)
+
offset = (vfu_pci_find_capability(ctx, False, PCI_CAP_ID_EXP) +
PCI_EXP_LNKCTL2)
data = b'\xbe\xef'
diff --git a/test/py/test_quiesce.py b/test/py/test_quiesce.py
index 0e2a980..b1fb2fd 100644
--- a/test/py/test_quiesce.py
+++ b/test/py/test_quiesce.py
@@ -247,4 +247,26 @@ def test_allowed_funcs_in_quiesced_reset_busy(mock_quiesce, mock_reset):
mock_reset.assert_called_once_with(ctx, VFU_RESET_DEVICE)
+@patch('libvfio_user.reset_cb', side_effect=_side_effect)
+@patch('libvfio_user.quiesce_cb')
+def test_flr(mock_quiesce, mock_reset):
+ """Test that an FLR reset callback is still able to call functions not
+ allowed in quiescent state."""
+
+ global ctx, sock
+
+ _map_dma_region(ctx, sock)
+
+ setup_flrc(ctx)
+
+ # iflr
+ offset = PCI_STD_HEADER_SIZEOF + 8
+ data = b'\x00\x80'
+ write_region(ctx, sock, VFU_PCI_DEV_CFG_REGION_IDX, offset=offset,
+ count=len(data), data=data)
+
+ mock_quiesce.assert_called_with(ctx)
+ mock_reset.assert_called_once_with(ctx, VFU_RESET_PCI_FLR)
+
+
# ex: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: #