Skip to content

Commit abbdef4

Browse files
yliu80wenlingz
authored andcommitted
hv: implement SRIOV VF_BAR initialization
All SRIOV VF physical devices don't have bars in configuration space, they are from the VF associated PF's VF_BAR registers of SRIOV capability. Adding a vbars data structure in pci_cap_sriov data structure to store SRIOV VF_BAR information, so that each VF bars can be initialized directly through the vbars instead multiple accessing of the PF VF_BAR registers. Tracked-On: #4433 Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent 298ef2f commit abbdef4

File tree

6 files changed

+68
-20
lines changed

6 files changed

+68
-20
lines changed

hypervisor/dm/vpci/pci_pt.c

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -215,26 +215,46 @@ void vdev_pt_write_vbar(struct pci_vdev *vdev, uint32_t idx, uint32_t val)
215215
* Hypervisor traps guest changes to the mmio vbar (gpa) to establish ept mapping
216216
* between vbar(gpa) and pbar(hpa). pbar should always align on 4K boundary.
217217
*
218+
* @param vdev Pointer to a vdev structure
219+
* @param is_sriov_bar When the first parameter vdev is a SRIOV PF vdev, the function
220+
* init_bars is used to initialize normal PCIe BARs of PF vdev if the
221+
* parameter is_sriov_bar is false, the function init_bars is used to
222+
* initialize SRIOV VF BARs of PF vdev if parameter is_sriov_bar is true
223+
* Otherwise, the parameter is_sriov_bar should be false if the first
224+
* parameter vdev is not SRIOV PF vdev
225+
*
218226
* @pre vdev != NULL
219227
* @pre vdev->vpci != NULL
220228
* @pre vdev->vpci->vm != NULL
221229
* @pre vdev->pdev != NULL
230+
*
231+
* @return None
222232
*/
223-
static void init_bars(struct pci_vdev *vdev)
233+
static void init_bars(struct pci_vdev *vdev, bool is_sriov_bar)
224234
{
225235
enum pci_bar_type type;
226-
uint32_t idx;
236+
uint32_t idx, bar_cnt;
227237
struct pci_vbar *vbar;
228238
uint32_t size32, offset, lo, hi = 0U;
229239
union pci_bdf pbdf;
230240
uint64_t mask;
231241

232-
vdev->nr_bars = vdev->pdev->nr_bars;
242+
if (is_sriov_bar) {
243+
bar_cnt = PCI_BAR_COUNT;
244+
} else {
245+
vdev->nr_bars = vdev->pdev->nr_bars;
246+
bar_cnt = vdev->nr_bars;
247+
}
233248
pbdf.value = vdev->pdev->bdf.value;
234249

235-
for (idx = 0U; idx < vdev->nr_bars; idx++) {
236-
vbar = &vdev->vbars[idx];
237-
offset = pci_bar_offset(idx);
250+
for (idx = 0U; idx < bar_cnt; idx++) {
251+
if (is_sriov_bar) {
252+
vbar = &vdev->sriov.vbars[idx];
253+
offset = sriov_bar_offset(vdev, idx);
254+
} else {
255+
vbar = &vdev->vbars[idx];
256+
offset = pci_bar_offset(idx);
257+
}
238258
lo = pci_pdev_read_cfg(pbdf, offset, 4U);
239259

240260
type = pci_get_bar_type(lo);
@@ -265,7 +285,11 @@ static void init_bars(struct pci_vdev *vdev)
265285

266286
if (type == PCIBAR_MEM64) {
267287
idx++;
268-
offset = pci_bar_offset(idx);
288+
if (is_sriov_bar) {
289+
offset = sriov_bar_offset(vdev, idx);
290+
} else {
291+
offset = pci_bar_offset(idx);
292+
}
269293
pci_pdev_write_cfg(pbdf, offset, 4U, ~0U);
270294
size32 = pci_pdev_read_cfg(pbdf, offset, 4U);
271295
pci_pdev_write_cfg(pbdf, offset, 4U, hi);
@@ -274,21 +298,32 @@ static void init_bars(struct pci_vdev *vdev)
274298
vbar->size = vbar->size & ~(vbar->size - 1UL);
275299
vbar->size = round_page_up(vbar->size);
276300

277-
vbar = &vdev->vbars[idx];
301+
if (is_sriov_bar) {
302+
vbar = &vdev->sriov.vbars[idx];
303+
} else {
304+
vbar = &vdev->vbars[idx];
305+
}
306+
278307
vbar->mask = size32;
279308
vbar->type = PCIBAR_MEM64HI;
280309

281310
if (is_prelaunched_vm(vdev->vpci->vm)) {
282311
hi = (uint32_t)(vdev->pci_dev_config->vbar_base[idx - 1U] >> 32U);
283312
}
284-
pci_vdev_write_bar(vdev, idx - 1U, lo);
285-
pci_vdev_write_bar(vdev, idx, hi);
313+
/* if it is parsing SRIOV VF BARs, no need to write vdev bars */
314+
if (!is_sriov_bar) {
315+
pci_vdev_write_bar(vdev, idx - 1U, lo);
316+
pci_vdev_write_bar(vdev, idx, hi);
317+
}
286318
} else {
287319
vbar->size = vbar->size & ~(vbar->size - 1UL);
288320
if (type == PCIBAR_MEM32) {
289321
vbar->size = round_page_up(vbar->size);
290322
}
291-
pci_vdev_write_bar(vdev, idx, lo);
323+
/* if it is parsing SRIOV VF BARs, no need to write vdev bar */
324+
if (!is_sriov_bar) {
325+
pci_vdev_write_bar(vdev, idx, lo);
326+
}
292327
}
293328
}
294329
}
@@ -316,11 +351,8 @@ void init_vdev_pt(struct pci_vdev *vdev, bool is_pf_vdev)
316351
{
317352
uint16_t pci_command;
318353

319-
/* SRIOV capability initialization implementaion in next patch */
320-
(void) is_pf_vdev;
321-
322-
init_bars(vdev);
323-
if (is_prelaunched_vm(vdev->vpci->vm)) {
354+
init_bars(vdev, is_pf_vdev);
355+
if (is_prelaunched_vm(vdev->vpci->vm) && (!is_pf_vdev)) {
324356
pci_command = (uint16_t)pci_pdev_read_cfg(vdev->pdev->bdf, PCIR_COMMAND, 2U);
325357

326358
/* Disable INTX */

hypervisor/dm/vpci/vpci_priv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ void deinit_vmsix(const struct pci_vdev *vdev);
159159
void init_vsriov(struct pci_vdev *vdev);
160160
void read_sriov_cap_reg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val);
161161
void write_sriov_cap_reg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val);
162+
uint32_t sriov_bar_offset(const struct pci_vdev *vdev, uint32_t bar_idx);
162163

163164
uint32_t pci_vdev_read_cfg(const struct pci_vdev *vdev, uint32_t offset, uint32_t bytes);
164165
void pci_vdev_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val);

hypervisor/dm/vpci/vsriov.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ static bool is_vf_enabled(const struct pci_vdev *pf_vdev)
7474
*/
7575
static void init_sriov_vf_bar(struct pci_vdev *pf_vdev)
7676
{
77-
/* Implementation in next patch */
78-
(void)pf_vdev;
77+
init_vdev_pt(pf_vdev, true);
7978
}
8079

8180
/**
@@ -234,3 +233,12 @@ void write_sriov_cap_reg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes,
234233
pci_pdev_write_cfg(vdev->pdev->bdf, offset, bytes, val);
235234
}
236235
}
236+
237+
238+
/**
239+
* @pre vdev != NULL
240+
*/
241+
uint32_t sriov_bar_offset(const struct pci_vdev *vdev, uint32_t bar_idx)
242+
{
243+
return (vdev->sriov.capoff + PCIR_SRIOV_VF_BAR_OFF + (bar_idx << 2U));
244+
}

hypervisor/hw/pci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ static bool is_hv_owned_pdev(union pci_bdf pbdf)
252252
static void pci_init_pdev(union pci_bdf pbdf, uint32_t drhd_index)
253253
{
254254
if (!is_hv_owned_pdev(pbdf)) {
255-
init_pdev(pbdf.value, drhd_index);
255+
(void)init_pdev(pbdf.value, drhd_index);
256256
}
257257
}
258258

@@ -469,7 +469,7 @@ static void init_all_dev_config(void)
469469
total += cnt;
470470
}
471471
}
472-
init_one_dev_config(pdev);
472+
(void)init_one_dev_config(pdev);
473473
}
474474
}
475475

hypervisor/include/dm/vpci.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,12 @@ struct pci_msix {
7373
struct pci_cap_sriov {
7474
uint32_t capoff;
7575
uint32_t caplen;
76+
77+
/*
78+
* If the vdev is a SRIOV PF vdev, the vbars is used to store
79+
* the bar information that is using to initialize SRIOV VF vdev bar.
80+
*/
81+
struct pci_vbar vbars[PCI_BAR_COUNT];
7682
};
7783

7884
union pci_cfgdata {

hypervisor/include/hw/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120
#define PCIR_SRIOV_NUMVFS 0x10U
121121
#define PCIR_SRIOV_FST_VF_OFF 0x14U
122122
#define PCIR_SRIOV_VF_STRIDE 0x16U
123+
#define PCIR_SRIOV_VF_BAR_OFF 0x24U
123124
#define PCIM_SRIOV_VF_ENABLE 0x1U
124125

125126
/* PCI Message Signalled Interrupts (MSI) */

0 commit comments

Comments
 (0)