Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "linux2",
"zone_id": 1,
"cpus": [2, 3],
"memory_regions": [
{
"type": "ram",
"physical_start": "0x50000000",
"virtual_start": "0x50000000",
"size": "0x30000000"
},
{
"type": "virtio",
"physical_start": "0xa000000",
"virtual_start": "0xa000000",
"size": "0x4000"
}
],
"interrupts": [76, 78],
"ivc_configs": [],
"kernel_filepath": "./Image",
"dtb_filepath": "./linux2.dtb",
"kernel_load_paddr": "0x50400000",
"dtb_load_paddr": "0x50000000",
"entry_point": "0x50400000",
"arch_config": {
"gic_version": "v3",
"gicd_base": "0x8000000",
"gicd_size": "0x10000",
"gicr_base": "0x80a0000",
"gicr_size": "0xf60000",
"gits_base": "0x8080000",
"gits_size": "0x20000",
"is_aarch32": false
},
"pci_config": [{
"ecam_base": "0x4010000000",
"ecam_size": "0x10000000",
"io_base": "0x3eff0000",
"io_size": "0x10000",
"pci_io_base": "0x0",
"mem32_base": "0x10000000",
"mem32_size": "0x2eff0000",
"pci_mem32_base": "0x10000000",
"mem64_base": "0x8000000000",
"mem64_size": "0x8000000000",
"pci_mem64_base": "0x8000000000"
}],
"num_pci_devs": 2,
"alloc_pci_devs": [
{
"bdf": "0x0",
"vbdf": "0x0"
},
{
"bdf": "0x18",
"vbdf": "0x18"
}
]
}
15 changes: 12 additions & 3 deletions include/zone_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define CONFIG_MAX_ZONES 32
#define CONFIG_NAME_MAXLEN 32
#define CONFIG_MAX_PCI_DEV 32
#define CONFIG_PCI_BUS_MAXNUM 4

#define IVC_PROTOCOL_USER 0x0
#define IVC_PROTOCOL_HVISOR 0x01
Expand All @@ -35,6 +36,13 @@ struct memory_region {

typedef struct memory_region memory_region_t;

struct hv_pci_dev_config {
__u64 bdf;
__u64 vbdf;

Choose a reason for hiding this comment

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

There are no corresponding items in the new_pcie branch of hvisor:
https://github.com/syswonder/hvisor/tree/new_pcie

Perhaps this config needs to be updated.

See the following link for reference:
https://github.com/syswonder/hvisor/blob/new_pcie/src/config.rs#L212

};

typedef struct hv_pci_dev_config hv_pci_dev_config_t;

struct pci_config {

Choose a reason for hiding this comment

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

Since we added bus_range_begin and bus_range_end to the pci_config of hvisor,
we should probably add the same fields to the pci_config of hvisor-tools as well.
It would also be better to implement the corresponding JSON parsing logic.
Or the hvisor would panic at https://github.com/syswonder/hvisor/blob/new_pcie/src/hypercall/mod.rs#L200
See the following link for reference: https://github.com/syswonder/hvisor/blob/new_pcie/src/config.rs#L58

__u64 ecam_base;
__u64 ecam_size;
Expand Down Expand Up @@ -123,7 +131,7 @@ struct ivc_config {
};
typedef struct ivc_config ivc_config_t;

#define CONFIG_MAGIC_VERSION 0x03
#define CONFIG_MAGIC_VERSION 0x04

// Every time you change the struct, you should also change the
// `CONFIG_MAGIC_VERSION`
Expand All @@ -145,9 +153,10 @@ struct zone_config {
char name[CONFIG_NAME_MAXLEN];

arch_zone_config_t arch_config;
pci_config_t pci_config;
__u64 num_pci_bus;
pci_config_t pci_config[CONFIG_PCI_BUS_MAXNUM];
__u64 num_pci_devs;
__u64 alloc_pci_devs[CONFIG_MAX_PCI_DEV];
hv_pci_dev_config_t alloc_pci_devs[CONFIG_MAX_PCI_DEV];
};

typedef struct zone_config zone_config_t;
Expand Down
146 changes: 82 additions & 64 deletions tools/hvisor.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,80 +285,98 @@ static int parse_arch_config(cJSON *root, zone_config_t *config) {
}

static int parse_pci_config(cJSON *root, zone_config_t *config) {
cJSON *pci_config_json = SAFE_CJSON_GET_OBJECT_ITEM(root, "pci_config");
if (pci_config_json == NULL) {
log_warn("No pci_config field found.");
return -1;
} else {
printf("pci_config field found.\n");
}
cJSON *pci_configs_json = SAFE_CJSON_GET_OBJECT_ITEM(root, "pci_config");
CHECK_JSON_NULL_ERR_OUT(pci_configs_json, "pci_configs")
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

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

The error message says "pci_configs" but the actual JSON field being checked is "pci_config" (singular). This inconsistency could confuse users debugging missing configuration. The error message should match the actual field name.

Suggested change
CHECK_JSON_NULL_ERR_OUT(pci_configs_json, "pci_configs")
CHECK_JSON_NULL_ERR_OUT(pci_configs_json, "pci_config")

Copilot uses AI. Check for mistakes.

#if defined(ARM64) || defined(LOONGARCH64)
cJSON *ecam_base_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "ecam_base");
cJSON *io_base_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "io_base");
cJSON *pci_io_base_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_io_base");
cJSON *mem32_base_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem32_base");
cJSON *pci_mem32_base_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_mem32_base");
cJSON *mem64_base_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem64_base");
cJSON *pci_mem64_base_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_mem64_base");
cJSON *ecam_size_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "ecam_size");
cJSON *io_size_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "io_size");
cJSON *mem32_size_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem32_size");
cJSON *mem64_size_json =
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem64_size");

CHECK_JSON_NULL(ecam_base_json, "ecam_base")
CHECK_JSON_NULL(io_base_json, "io_base")
CHECK_JSON_NULL(mem32_base_json, "mem32_base")
CHECK_JSON_NULL(mem64_base_json, "mem64_base")
CHECK_JSON_NULL(ecam_size_json, "ecam_size")
CHECK_JSON_NULL(io_size_json, "io_size")
CHECK_JSON_NULL(mem32_size_json, "mem32_size")
CHECK_JSON_NULL(mem64_size_json, "mem64_size")
CHECK_JSON_NULL(pci_io_base_json, "pci_io_base")
CHECK_JSON_NULL(pci_mem32_base_json, "pci_mem32_base")
CHECK_JSON_NULL(pci_mem64_base_json, "pci_mem64_base")

config->pci_config.ecam_base =
strtoull(ecam_base_json->valuestring, NULL, 16);
config->pci_config.io_base = strtoull(io_base_json->valuestring, NULL, 16);
config->pci_config.mem32_base =
strtoull(mem32_base_json->valuestring, NULL, 16);
config->pci_config.mem64_base =
strtoull(mem64_base_json->valuestring, NULL, 16);
config->pci_config.pci_io_base =
strtoull(pci_io_base_json->valuestring, NULL, 16);
config->pci_config.pci_mem32_base =
strtoull(pci_mem32_base_json->valuestring, NULL, 16);
config->pci_config.pci_mem64_base =
strtoull(pci_mem64_base_json->valuestring, NULL, 16);
config->pci_config.ecam_size =
strtoull(ecam_size_json->valuestring, NULL, 16);
config->pci_config.io_size = strtoull(io_size_json->valuestring, NULL, 16);
config->pci_config.mem32_size =
strtoull(mem32_size_json->valuestring, NULL, 16);
config->pci_config.mem64_size =
strtoull(mem64_size_json->valuestring, NULL, 16);
int num_pci_bus = SAFE_CJSON_GET_ARRAY_SIZE(pci_configs_json);
if (num_pci_bus > CONFIG_PCI_BUS_MAXNUM) {
log_error("Exceeded maximum allowed pci configs.");
goto err_out;
}

config->num_pci_bus = num_pci_bus;
log_info("num pci bus %llx", num_pci_bus);
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

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

The format specifier %llx is used for num_pci_bus which is of type int. This is incorrect and should use %d instead. Using %llx for an int can lead to undefined behavior and incorrect output.

Suggested change
log_info("num pci bus %llx", num_pci_bus);
log_info("num pci bus %d", num_pci_bus);

Copilot uses AI. Check for mistakes.

for (int i = 0; i < num_pci_bus; i++) {
cJSON *pci_config_json = SAFE_CJSON_GET_ARRAY_ITEM(pci_configs_json, i);
pci_config_t *pci_config = &config->pci_config[i];

pci_config->ecam_base =
strtoull(SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "ecam_base")
->valuestring,
NULL, 16);
pci_config->ecam_size =
strtoull(SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "ecam_size")
->valuestring,
NULL, 16);
pci_config->io_base = strtoull(
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "io_base")->valuestring,
NULL, 16);
pci_config->io_size = strtoull(
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "io_size")->valuestring,
NULL, 16);
pci_config->pci_io_base =
strtoull(SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_io_base")
->valuestring,
NULL, 16);
pci_config->mem32_base =
strtoull(SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem32_base")
->valuestring,
NULL, 16);
pci_config->mem32_size =
strtoull(SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem32_size")
->valuestring,
NULL, 16);
pci_config->pci_mem32_base = strtoull(
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_mem32_base")
->valuestring,
NULL, 16);
pci_config->mem64_base =
strtoull(SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem64_base")
->valuestring,
NULL, 16);
pci_config->mem64_size =
strtoull(SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "mem64_size")
->valuestring,
NULL, 16);
pci_config->pci_mem64_base = strtoull(
SAFE_CJSON_GET_OBJECT_ITEM(pci_config_json, "pci_mem64_base")
->valuestring,
NULL, 16);

// log_info("pci_config %d: ecam_base=0x%llx, ecam_size=0x%llx, "
// "io_base=0x%llx, io_size=0x%llx, "
// "pci_io_base=0x%llx, mem32_base=0x%llx, mem32_size=0x%llx, "
// "pci_mem32_base=0x%llx, mem64_base=0x%llx,
// mem64_size=0x%llx, " "pci_mem64_base=0x%llx", i,
// pci_config->ecam_base, pci_config->ecam_size,
// pci_config->io_base, pci_config->io_size,
// pci_config->pci_io_base, pci_config->mem32_base,
// pci_config->mem32_size, pci_config->pci_mem32_base,
// pci_config->mem64_base, pci_config->mem64_size,
// pci_config->pci_mem64_base);
}

cJSON *alloc_pci_devs_json =
SAFE_CJSON_GET_OBJECT_ITEM(root, "alloc_pci_devs");
int num_pci_devs = SAFE_CJSON_GET_ARRAY_SIZE(alloc_pci_devs_json);
config->num_pci_devs = num_pci_devs;
for (int i = 0; i < num_pci_devs; i++) {
config->alloc_pci_devs[i] =
SAFE_CJSON_GET_ARRAY_ITEM(alloc_pci_devs_json, i)->valueint;
cJSON *dev_config_json =
SAFE_CJSON_GET_ARRAY_ITEM(alloc_pci_devs_json, i);
hv_pci_dev_config_t *dev_config = &config->alloc_pci_devs[i];
dev_config->bdf = strtoull(
SAFE_CJSON_GET_OBJECT_ITEM(dev_config_json, "bdf")->valuestring,
NULL, 16);
dev_config->vbdf = strtoull(
SAFE_CJSON_GET_OBJECT_ITEM(dev_config_json, "vbdf")->valuestring,
NULL, 16);
}
#endif
return 0;
err_out:
return -1;
}

static int zone_start_from_json(const char *json_config_path,
Expand Down