Skip to content

Commit 6af47f2

Browse files
ZideChen0lijinxia
authored andcommitted
hv: vpci: add callback functions to struct vpci
Add 'struct vpci_ops *ops' to 'struct vpci' so we have clearer structure: - struct vpci: include struct vpci_ops pointing to different callback functions for partition or sharing mode repsectively. - struct pci_vdev: includes struct pci_vdev_ops to handle different vpci functionalities: hostbridge emulation passthrough device BAR emulation msi/msi-x remapping This patch moves the code around but doesn't change the underlying logic in terms of PCI spec handling. More detailed implementation: - create new file partition_mode.c to house the implementation of partition mode regarding the vpci layer. - vpci.c: only keeps the abstract code which calls vpci->ops to functions in partition_mode.c, and potentially to sharing_mode.c. - the following functions are moved to partition_mode.c and renamed with partition_mode prefix. - vpci_init() -> partition_mode_vpci_init() - vpci_cleanup() -> partition_mode_vpci_deinit() - pci_cfg_io_write() -> partition_mode_cfgread() - pci_cfg_io_read() -> partition_mode_cfgwrite() Track-On: #1568 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com> Signed-off-by: Zide Chen <zide.chen@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com> Reviewed-by: Li, Fei1 <fei1.li@intel.com>
1 parent 3e54c70 commit 6af47f2

File tree

4 files changed

+96
-67
lines changed

4 files changed

+96
-67
lines changed

hypervisor/dm/vpci/pci_vdev.c renamed to hypervisor/dm/vpci/partition_mode.c

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@
3232
#include <hypervisor.h>
3333
#include "pci_priv.h"
3434

35-
36-
static struct pci_vdev *pci_vdev_find(struct vpci *vpci, union pci_bdf vbdf)
35+
static struct pci_vdev *partition_mode_find_vdev(struct vpci *vpci, union pci_bdf vbdf)
3736
{
3837
struct vpci_vdev_array *vdev_array;
3938
struct pci_vdev *vdev;
@@ -50,31 +49,71 @@ static struct pci_vdev *pci_vdev_find(struct vpci *vpci, union pci_bdf vbdf)
5049
return NULL;
5150
}
5251

53-
/* PCI cfg vm-exit handler */
54-
void pci_vdev_cfg_handler(struct vpci *vpci, uint32_t in, union pci_bdf vbdf,
55-
uint32_t offset, uint32_t bytes, uint32_t *val)
52+
static int partition_mode_vpci_init(struct vm *vm)
5653
{
54+
struct vpci_vdev_array *vdev_array;
55+
struct vpci *vpci = &vm->vpci;
5756
struct pci_vdev *vdev;
58-
int ret;
57+
int i;
5958

60-
vdev = pci_vdev_find(vpci, vbdf);
61-
if (vdev == NULL) {
62-
return;
63-
}
59+
vdev_array = vm->vm_desc->vpci_vdev_array;
60+
61+
for (i = 0; i < vdev_array->num_pci_vdev; i++) {
62+
vdev = &vdev_array->vpci_vdev_list[i];
63+
vdev->vpci = vpci;
6464

65-
ret = -EINVAL;
66-
if (in == 1U) {
67-
if ((vdev->ops != NULL) && (vdev->ops->cfgread != NULL)) {
68-
ret = vdev->ops->cfgread(vdev, offset, bytes, val);
65+
if ((vdev->ops != NULL) && (vdev->ops->init != NULL)) {
66+
if (vdev->ops->init(vdev) != 0U) {
67+
pr_err("%s() failed at PCI device (bdf %x)!", __func__,
68+
vdev->vbdf);
69+
}
6970
}
70-
} else {
71-
if ((vdev->ops != NULL) && (vdev->ops->cfgwrite != NULL)) {
72-
ret = vdev->ops->cfgwrite(vdev, offset, bytes, *val);
71+
}
72+
73+
return 0;
74+
}
75+
76+
static void partition_mode_vpci_deinit(struct vm *vm)
77+
{
78+
struct vpci_vdev_array *vdev_array;
79+
struct pci_vdev *vdev;
80+
int i;
81+
82+
vdev_array = vm->vm_desc->vpci_vdev_array;
83+
84+
for (i = 0; i < vdev_array->num_pci_vdev; i++) {
85+
vdev = &vdev_array->vpci_vdev_list[i];
86+
if ((vdev->ops != NULL) && (vdev->ops->deinit != NULL)) {
87+
if (vdev->ops->deinit(vdev) != 0U) {
88+
pr_err("vdev->ops->deinit failed!");
89+
}
7390
}
7491
}
92+
}
7593

76-
if (ret != 0) {
77-
pr_dbg("pci_vdev_cfg_handler failed, ret=%d", ret);
94+
static void partition_mode_cfgread(struct vpci *vpci, union pci_bdf vbdf,
95+
uint32_t offset, uint32_t bytes, uint32_t *val)
96+
{
97+
struct pci_vdev *vdev = partition_mode_find_vdev(vpci, vbdf);
98+
if ((vdev != NULL) && (vdev->ops != NULL)
99+
&& (vdev->ops->cfgread != NULL)) {
100+
(void)vdev->ops->cfgread(vdev, offset, bytes, val);
101+
}
102+
}
103+
104+
static void partition_mode_cfgwrite(struct vpci *vpci, union pci_bdf vbdf,
105+
uint32_t offset, uint32_t bytes, uint32_t val)
106+
{
107+
struct pci_vdev *vdev = partition_mode_find_vdev(vpci, vbdf);
108+
if ((vdev != NULL) && (vdev->ops != NULL)
109+
&& (vdev->ops->cfgwrite != NULL)) {
110+
(void)vdev->ops->cfgwrite(vdev, offset, bytes, val);
78111
}
79112
}
80113

114+
struct vpci_ops partition_mode_vpci_ops = {
115+
.init = partition_mode_vpci_init,
116+
.deinit = partition_mode_vpci_deinit,
117+
.cfgread = partition_mode_cfgread,
118+
.cfgwrite = partition_mode_cfgwrite,
119+
};

hypervisor/dm/vpci/pci_priv.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,9 @@ pci_vdev_write_cfg_u32(struct pci_vdev *vdev, uint32_t offset, uint32_t val)
6868
*(uint32_t *)(vdev->cfgdata + offset) = val;
6969
}
7070

71+
extern struct vpci_ops partition_mode_vpci_ops;
72+
7173
uint32_t pci_vdev_read_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes);
7274
void pci_vdev_write_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val);
7375

74-
void pci_vdev_cfg_handler(struct vpci *vpci, uint32_t in, union pci_bdf vbdf, uint32_t offset,
75-
uint32_t bytes, uint32_t *val);
76-
7776
#endif /* PCI_PRIV_H_ */

hypervisor/dm/vpci/vpci.c

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,14 @@ static uint32_t pci_cfg_io_read(struct vm *vm, uint16_t addr, size_t bytes)
6868
if (pi->cached_enable) {
6969
uint16_t offset = addr - PCI_CONFIG_DATA;
7070

71-
pci_vdev_cfg_handler(vpci, 1U, pi->cached_bdf,
72-
pi->cached_reg + offset, bytes, &val);
71+
if ((vpci->ops != NULL) && (vpci->ops->cfgread != NULL)) {
72+
vpci->ops->cfgread(vpci, pi->cached_bdf,
73+
pi->cached_reg + offset, bytes, &val);
74+
}
7375

7476
pci_cfg_clear_cache(pi);
7577
}
76-
} else {
78+
} else {
7779
val = 0xFFFFFFFFU;
7880
}
7981

@@ -89,9 +91,9 @@ static void pci_cfg_io_write(struct vm *vm, uint16_t addr, size_t bytes,
8991
if (is_cfg_addr(addr)) {
9092
/* TODO: handling the non 4 bytes access */
9193
if (bytes == 4U) {
92-
pi->cached_bdf.bits.b = (val >> 16U) & PCI_BUSMAX;
93-
pi->cached_bdf.bits.d = (val >> 11U) & PCI_SLOTMAX;
94-
pi->cached_bdf.bits.f = (val >> 8U) & PCI_FUNCMAX;
94+
pi->cached_bdf.bits.b = (uint8_t)(val >> 16U) & PCI_BUSMAX;
95+
pi->cached_bdf.bits.d = (uint8_t)(val >> 11U) & PCI_SLOTMAX;
96+
pi->cached_bdf.bits.f = (uint8_t)(val >> 8U) & PCI_FUNCMAX;
9597

9698
pi->cached_reg = val & PCI_REGMAX;
9799
pi->cached_enable =
@@ -101,62 +103,40 @@ static void pci_cfg_io_write(struct vm *vm, uint16_t addr, size_t bytes,
101103
if (pi->cached_enable) {
102104
uint16_t offset = addr - PCI_CONFIG_DATA;
103105

104-
pci_vdev_cfg_handler(vpci, 0U, pi->cached_bdf,
105-
pi->cached_reg + offset, bytes, &val);
106-
106+
if ((vpci->ops != NULL) && (vpci->ops->cfgwrite != NULL)) {
107+
vpci->ops->cfgwrite(vpci, pi->cached_bdf,
108+
pi->cached_reg + offset, bytes, val);
109+
}
107110
pci_cfg_clear_cache(pi);
108111
}
109112
} else {
110113
pr_err("Not PCI cfg data/addr port access!");
111114
}
112-
113115
}
114116

115117
void vpci_init(struct vm *vm)
116118
{
117119
struct vpci *vpci = &vm->vpci;
118-
struct vpci_vdev_array *vdev_array;
119-
struct pci_vdev *vdev;
120-
int i;
121-
int ret;
122-
struct vm_io_range pci_cfg_range = {.flags = IO_ATTR_RW,
123-
.base = PCI_CONFIG_ADDR, .len = 8U};
120+
struct vm_io_range pci_cfg_range = {
121+
.flags = IO_ATTR_RW,
122+
.base = PCI_CONFIG_ADDR,
123+
.len = 8U
124+
};
124125

125126
vpci->vm = vm;
126-
vdev_array = vm->vm_desc->vpci_vdev_array;
127-
128-
for (i = 0; i < vdev_array->num_pci_vdev; i++) {
129-
vdev = &vdev_array->vpci_vdev_list[i];
130-
vdev->vpci = vpci;
127+
vpci->ops = &partition_mode_vpci_ops;
131128

132-
if ((vdev->ops != NULL) && (vdev->ops->init != NULL)) {
133-
ret = vdev->ops->init(vdev);
134-
if (ret != 0) {
135-
pr_err("vdev->ops->init failed!");
136-
}
137-
}
129+
if ((vpci->ops->init != NULL) && (vpci->ops->init(vm) == 0)) {
130+
register_io_emulation_handler(vm, &pci_cfg_range,
131+
&pci_cfg_io_read, &pci_cfg_io_write);
138132
}
139-
140-
register_io_emulation_handler(vm, &pci_cfg_range,
141-
&pci_cfg_io_read, &pci_cfg_io_write);
142133
}
143134

144135
void vpci_cleanup(struct vm *vm)
145136
{
146-
struct vpci_vdev_array *vdev_array;
147-
struct pci_vdev *vdev;
148-
int i;
149-
int ret;
150-
151-
vdev_array = vm->vm_desc->vpci_vdev_array;
152-
153-
for (i = 0; i < vdev_array->num_pci_vdev; i++) {
154-
vdev = &vdev_array->vpci_vdev_list[i];
155-
if ((vdev->ops != NULL) && (vdev->ops->deinit != NULL)) {
156-
ret = vdev->ops->deinit(vdev);
157-
if (ret != 0) {
158-
pr_err("vdev->ops->deinit failed!");
159-
}
160-
}
137+
struct vpci *vpci = &vm->vpci;
138+
139+
if ((vpci->ops != NULL) && (vpci->ops->deinit != NULL)) {
140+
vpci->ops->deinit(vm);
161141
}
162142
}

hypervisor/include/dm/vpci.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,20 @@ struct pci_addr_info {
7878
uint32_t cached_reg, cached_enable;
7979
};
8080

81+
struct vpci_ops {
82+
int (*init)(struct vm *vm);
83+
void (*deinit)(struct vm *vm);
84+
void (*cfgread)(struct vpci *vpci, union pci_bdf vbdf, uint32_t offset,
85+
uint32_t bytes, uint32_t *val);
86+
void (*cfgwrite)(struct vpci *vpci, union pci_bdf vbdf, uint32_t offset,
87+
uint32_t bytes, uint32_t val);
88+
};
89+
90+
8191
struct vpci {
8292
struct vm *vm;
8393
struct pci_addr_info addr_info;
94+
struct vpci_ops *ops;
8495
};
8596

8697
extern struct pci_vdev_ops pci_ops_vdev_hostbridge;

0 commit comments

Comments
 (0)