From: Yahui Cao <yahui.cao@intel.com>
To: intel-wired-lan@lists.osuosl.org
Cc: kvm@vger.kernel.org, netdev@vger.kernel.org,
lingyu.liu@intel.com, kevin.tian@intel.com,
madhu.chittim@intel.com, sridhar.samudrala@intel.com,
alex.williamson@redhat.com, jgg@nvidia.com, yishaih@nvidia.com,
shameerali.kolothum.thodi@huawei.com, brett.creeley@amd.com,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com
Subject: [PATCH iwl-next v4 07/12] ice: Fix VSI id in virtual channel message for migration
Date: Tue, 21 Nov 2023 02:51:06 +0000 [thread overview]
Message-ID: <20231121025111.257597-8-yahui.cao@intel.com> (raw)
In-Reply-To: <20231121025111.257597-1-yahui.cao@intel.com>
From: Lingyu Liu <lingyu.liu@intel.com>
VSI id is a resource id for each VF and it is an absolute hardware id
per PCI card. It is exposed to VF driver through virtual channel
messages at the VF-PF negotiation stage. It is constant during the whole
device lifecycle unless driver re-init.
Almost all of the virtual channel messages will contain the VSI id. Once
PF receives message, it will check if VSI id in the message is equal to
the VF's VSI id for security and other reason. If a VM backed by VF VSI
A is migrated to a VM backed by VF with VSI B, while in messages
replaying stage, all the messages will be rejected by PF due to the
invalid VSI id. Even after migration, VM runtime will get failure as
well.
Fix this gap by modifying the VSI id in the virtual channel message at
migration device resuming stage and VM runtime stage. In most cases the
VSI id will vary between migration source and destination side. And this
is a slow path anyway.
Signed-off-by: Lingyu Liu <lingyu.liu@intel.com>
Signed-off-by: Yahui Cao <yahui.cao@intel.com>
---
.../net/ethernet/intel/ice/ice_migration.c | 95 +++++++++++++++++++
.../intel/ice/ice_migration_private.h | 4 +
drivers/net/ethernet/intel/ice/ice_vf_lib.h | 1 +
drivers/net/ethernet/intel/ice/ice_virtchnl.c | 1 +
4 files changed, 101 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_migration.c b/drivers/net/ethernet/intel/ice/ice_migration.c
index 981aa92bbe86..780d2183011a 100644
--- a/drivers/net/ethernet/intel/ice/ice_migration.c
+++ b/drivers/net/ethernet/intel/ice/ice_migration.c
@@ -25,6 +25,7 @@ struct ice_migration_dev_state {
u16 num_txq;
u16 num_rxq;
+ u16 vsi_id;
u8 virtchnl_msgs[];
} __aligned(8);
@@ -50,6 +51,7 @@ void ice_migration_init_vf(struct ice_vf *vf)
INIT_LIST_HEAD(&vf->virtchnl_msg_list);
vf->virtchnl_msg_num = 0;
vf->virtchnl_msg_size = 0;
+ vf->vm_vsi_num = vf->lan_vsi_num;
}
/**
@@ -314,6 +316,7 @@ ice_migration_save_devstate(struct ice_pf *pf, int vf_id, u8 *buf, u64 buf_sz)
devstate->num_txq = vsi->num_txq;
devstate->num_rxq = vsi->num_rxq;
buf = devstate->virtchnl_msgs;
+ devstate->vsi_id = vf->vm_vsi_num;
list_for_each_entry(msg_listnode, &vf->virtchnl_msg_list, node) {
struct ice_migration_virtchnl_msg_slot *msg_slot;
@@ -441,6 +444,8 @@ int ice_migration_load_devstate(struct ice_pf *pf, int vf_id,
goto out_put_vf;
devstate = (struct ice_migration_dev_state *)buf;
+ vf->vm_vsi_num = devstate->vsi_id;
+ dev_dbg(dev, "VF %d vm vsi num is:%d\n", vf->vf_id, vf->vm_vsi_num);
msg_slot = (struct ice_migration_virtchnl_msg_slot *)
devstate->virtchnl_msgs;
set_bit(ICE_VF_STATE_REPLAYING_VC, vf->vf_states);
@@ -473,3 +478,93 @@ int ice_migration_load_devstate(struct ice_pf *pf, int vf_id,
return ret;
}
EXPORT_SYMBOL(ice_migration_load_devstate);
+
+/**
+ * ice_migration_fix_msg_vsi - change virtual channel msg VSI id
+ *
+ * @vf: pointer to the VF structure
+ * @v_opcode: virtchnl message operation code
+ * @msg: pointer to the virtual channel message
+ *
+ * After migration, the VSI id saved by VF driver may be different from VF
+ * VSI id. Some virtual channel commands will fail due to unmatch VSI id.
+ * Change virtual channel message payload VSI id to real VSI id.
+ */
+void ice_migration_fix_msg_vsi(struct ice_vf *vf, u32 v_opcode, u8 *msg)
+{
+ if (!vf->migration_enabled)
+ return;
+
+ switch (v_opcode) {
+ case VIRTCHNL_OP_ADD_ETH_ADDR:
+ case VIRTCHNL_OP_DEL_ETH_ADDR:
+ case VIRTCHNL_OP_ENABLE_QUEUES:
+ case VIRTCHNL_OP_DISABLE_QUEUES:
+ case VIRTCHNL_OP_CONFIG_RSS_KEY:
+ case VIRTCHNL_OP_CONFIG_RSS_LUT:
+ case VIRTCHNL_OP_GET_STATS:
+ case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
+ case VIRTCHNL_OP_ADD_FDIR_FILTER:
+ case VIRTCHNL_OP_DEL_FDIR_FILTER:
+ case VIRTCHNL_OP_ADD_VLAN:
+ case VIRTCHNL_OP_DEL_VLAN: {
+ /* Read the beginning two bytes of message for VSI id */
+ u16 *vsi_id = (u16 *)msg;
+
+ /* For VM runtime stage, vsi_id in the virtual channel message
+ * should be equal to the PF logged vsi_id and vsi_id is
+ * replaced by VF's VSI id to guarantee that messages are
+ * processed successfully. If vsi_id is not equal to the PF
+ * logged vsi_id, then this message must be sent by malicious
+ * VF and no replacement is needed. Just let virtual channel
+ * handler to fail this message.
+ *
+ * For virtual channel replaying stage, all of the PF logged
+ * virtual channel messages are trusted and vsi_id is replaced
+ * anyway to guarantee the messages are processed successfully.
+ */
+ if (*vsi_id == vf->vm_vsi_num ||
+ test_bit(ICE_VF_STATE_REPLAYING_VC, vf->vf_states))
+ *vsi_id = vf->lan_vsi_num;
+ break;
+ }
+ case VIRTCHNL_OP_CONFIG_IRQ_MAP: {
+ struct virtchnl_irq_map_info *irqmap_info;
+ u16 num_q_vectors_mapped;
+ int i;
+
+ irqmap_info = (struct virtchnl_irq_map_info *)msg;
+ num_q_vectors_mapped = irqmap_info->num_vectors;
+ for (i = 0; i < num_q_vectors_mapped; i++) {
+ struct virtchnl_vector_map *map;
+
+ map = &irqmap_info->vecmap[i];
+ if (map->vsi_id == vf->vm_vsi_num ||
+ test_bit(ICE_VF_STATE_REPLAYING_VC, vf->vf_states))
+ map->vsi_id = vf->lan_vsi_num;
+ }
+ break;
+ }
+ case VIRTCHNL_OP_CONFIG_VSI_QUEUES: {
+ struct virtchnl_vsi_queue_config_info *qci;
+
+ qci = (struct virtchnl_vsi_queue_config_info *)msg;
+ if (qci->vsi_id == vf->vm_vsi_num ||
+ test_bit(ICE_VF_STATE_REPLAYING_VC, vf->vf_states)) {
+ int i;
+
+ qci->vsi_id = vf->lan_vsi_num;
+ for (i = 0; i < qci->num_queue_pairs; i++) {
+ struct virtchnl_queue_pair_info *qpi;
+
+ qpi = &qci->qpair[i];
+ qpi->txq.vsi_id = vf->lan_vsi_num;
+ qpi->rxq.vsi_id = vf->lan_vsi_num;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
diff --git a/drivers/net/ethernet/intel/ice/ice_migration_private.h b/drivers/net/ethernet/intel/ice/ice_migration_private.h
index 676eb2d6c12e..f72a488d9002 100644
--- a/drivers/net/ethernet/intel/ice/ice_migration_private.h
+++ b/drivers/net/ethernet/intel/ice/ice_migration_private.h
@@ -17,6 +17,7 @@ int ice_migration_log_vf_msg(struct ice_vf *vf,
struct ice_rq_event_info *event);
void ice_migration_unlog_vf_msg(struct ice_vf *vf, u32 v_opcode);
u32 ice_migration_supported_caps(void);
+void ice_migration_fix_msg_vsi(struct ice_vf *vf, u32 v_opcode, u8 *msg);
#else
static inline void ice_migration_init_vf(struct ice_vf *vf) { }
static inline void ice_migration_uninit_vf(struct ice_vf *vf) { }
@@ -33,6 +34,9 @@ ice_migration_supported_caps(void)
{
return 0xFFFFFFFF;
}
+
+static inline void
+ice_migration_fix_msg_vsi(struct ice_vf *vf, u32 v_opcode, u8 *msg) { }
#endif /* CONFIG_ICE_VFIO_PCI */
#endif /* _ICE_MIGRATION_PRIVATE_H_ */
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.h b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
index 318b6dfc016d..49d99694e91f 100644
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.h
@@ -146,6 +146,7 @@ struct ice_vf {
u64 virtchnl_msg_num;
u64 virtchnl_msg_size;
u32 virtchnl_retval;
+ u16 vm_vsi_num;
};
/* Flags for controlling behavior of ice_reset_vf */
diff --git a/drivers/net/ethernet/intel/ice/ice_virtchnl.c b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
index 54f441daa87e..8dbe558790af 100644
--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
@@ -4060,6 +4060,7 @@ int ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event,
}
if (vf->migration_enabled) {
+ ice_migration_fix_msg_vsi(vf, v_opcode, msg);
if (ice_migration_log_vf_msg(vf, event)) {
u32 status_code = VIRTCHNL_STATUS_ERR_NO_MEMORY;
--
2.34.1
next prev parent reply other threads:[~2023-11-21 2:50 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-21 2:50 [PATCH iwl-next v4 00/12] Add E800 live migration driver Yahui Cao
2023-11-21 2:51 ` [PATCH iwl-next v4 01/12] ice: Add function to get RX queue context Yahui Cao
2023-12-08 22:01 ` Brett Creeley
2023-11-21 2:51 ` [PATCH iwl-next v4 02/12] ice: Add function to get and set TX " Yahui Cao
2023-12-08 22:14 ` Brett Creeley
2023-11-21 2:51 ` [PATCH iwl-next v4 03/12] ice: Introduce VF state ICE_VF_STATE_REPLAYING_VC for migration Yahui Cao
2023-12-08 22:28 ` Brett Creeley
2024-02-12 23:07 ` [Intel-wired-lan] " Jacob Keller
2023-11-21 2:51 ` [PATCH iwl-next v4 04/12] ice: Add fundamental migration init and exit function Yahui Cao
2023-11-21 2:51 ` [PATCH iwl-next v4 05/12] ice: Log virtual channel messages in PF Yahui Cao
2023-11-29 17:12 ` Simon Horman
2023-12-01 8:27 ` Cao, Yahui
2023-12-07 7:33 ` Tian, Kevin
2023-12-08 1:53 ` Brett Creeley
2023-11-21 2:51 ` [PATCH iwl-next v4 06/12] ice: Add device state save/load function for migration Yahui Cao
2023-12-07 7:39 ` Tian, Kevin
2023-11-21 2:51 ` Yahui Cao [this message]
2023-12-07 7:42 ` [PATCH iwl-next v4 07/12] ice: Fix VSI id in virtual channel message " Tian, Kevin
2023-11-21 2:51 ` [PATCH iwl-next v4 08/12] ice: Save and load RX Queue head Yahui Cao
2023-12-07 7:55 ` Tian, Kevin
2023-12-07 14:46 ` Jason Gunthorpe
2023-12-08 2:53 ` Tian, Kevin
2023-11-21 2:51 ` [PATCH iwl-next v4 09/12] ice: Save and load TX " Yahui Cao
2023-12-07 8:22 ` Tian, Kevin
2023-12-07 14:48 ` Jason Gunthorpe
2023-11-21 2:51 ` [PATCH iwl-next v4 10/12] ice: Add device suspend function for migration Yahui Cao
2023-11-21 2:51 ` [PATCH iwl-next v4 11/12] ice: Save and load mmio registers Yahui Cao
2023-11-21 2:51 ` [PATCH iwl-next v4 12/12] vfio/ice: Implement vfio_pci driver for E800 devices Yahui Cao
2023-12-07 22:43 ` Alex Williamson
2023-12-08 3:42 ` Tian, Kevin
2023-12-08 3:42 ` Tian, Kevin
2023-12-04 11:18 ` [PATCH iwl-next v4 00/12] Add E800 live migration driver Cao, Yahui
2024-01-18 22:09 ` Jacob Keller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231121025111.257597-8-yahui.cao@intel.com \
--to=yahui.cao@intel.com \
--cc=alex.williamson@redhat.com \
--cc=brett.creeley@amd.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=intel-wired-lan@lists.osuosl.org \
--cc=jgg@nvidia.com \
--cc=kevin.tian@intel.com \
--cc=kuba@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=lingyu.liu@intel.com \
--cc=madhu.chittim@intel.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shameerali.kolothum.thodi@huawei.com \
--cc=sridhar.samudrala@intel.com \
--cc=yishaih@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).