diff --git a/devicemodel/core/vmmapi.c b/devicemodel/core/vmmapi.c index 72f35e10a..72f1de6a1 100644 --- a/devicemodel/core/vmmapi.c +++ b/devicemodel/core/vmmapi.c @@ -672,13 +672,13 @@ vm_irqfd(struct vmctx *ctx, struct acrn_irqfd *args) } int -vm_get_config(struct vmctx *ctx, struct acrn_vm_config *vm_cfg, struct platform_info *plat_info) +vm_get_config(struct vmctx *ctx, struct acrn_vm_config_header *vm_cfg, struct acrn_platform_info *plat_info) { #define VM_CFG_BUFF_SIZE 0x8000 int i, err = 0; uint8_t *configs_buff; - struct acrn_vm_config *pcfg; - struct platform_info platform_info; + struct acrn_vm_config_header *pcfg; + struct acrn_platform_info platform_info; if ((ctx == NULL) || (vm_cfg == NULL)) return -1; @@ -690,31 +690,31 @@ vm_get_config(struct vmctx *ctx, struct acrn_vm_config *vm_cfg, struct platform_ } bzero(&platform_info, sizeof(platform_info)); - platform_info.vm_configs_addr = (uint64_t)configs_buff; - err = ioctl(ctx->fd, IC_GET_PLATFORM_INFO, &platform_info); + platform_info.sw.vm_configs_addr = configs_buff; + err = ioctl(ctx->fd, ACRN_IOCTL_GET_PLATFORM_INFO, &platform_info); if (err) { pr_err("%s, failed: get platform info.\n", __func__); goto exit; } - assert(VM_CFG_BUFF_SIZE > (platform_info.max_vms * platform_info.vm_config_entry_size)); + assert(VM_CFG_BUFF_SIZE > (platform_info.sw.max_vms * platform_info.sw.vm_config_size)); - for (i = 0; i < platform_info.max_vms; i++) { - pcfg = (struct acrn_vm_config *)(configs_buff + (i * platform_info.vm_config_entry_size)); + for (i = 0; i < platform_info.sw.max_vms; i++) { + pcfg = (struct acrn_vm_config_header *)(configs_buff + (i * platform_info.sw.vm_config_size)); if (!uuid_compare(ctx->vm_uuid, pcfg->uuid)) break; } - if (i == platform_info.max_vms) { + if (i == platform_info.sw.max_vms) { pr_err("%s, Not found target VM.\n", __func__); err = -1; goto exit; } - memcpy((void *)vm_cfg, (void *)pcfg, sizeof(struct acrn_vm_config)); + memcpy((void *)vm_cfg, (void *)pcfg, sizeof(struct acrn_vm_config_header)); if (plat_info != NULL) { - memcpy((void *)plat_info, (void *)&platform_info, sizeof(struct platform_info)); + memcpy((void *)plat_info, (void *)&platform_info, sizeof(struct acrn_platform_info)); pr_info("%s, l2_cat_shift=%u, l3_cat_shift=%u\n", - __func__, platform_info.l2_cat_shift, platform_info.l3_cat_shift); + __func__, platform_info.hw.l2_cat_shift, platform_info.hw.l3_cat_shift); } exit: diff --git a/devicemodel/hw/platform/acpi/acpi.c b/devicemodel/hw/platform/acpi/acpi.c index 1af259c05..52a19e9b1 100644 --- a/devicemodel/hw/platform/acpi/acpi.c +++ b/devicemodel/hw/platform/acpi/acpi.c @@ -274,17 +274,17 @@ int pcpuid_from_vcpuid(uint64_t guest_pcpu_bitmask, int vcpu_id) return find_nth_set_bit_index(guest_pcpu_bitmask, vcpu_id); } -int lapicid_from_pcpuid(struct platform_info *plat_info, int pcpu_id) +int lapicid_from_pcpuid(struct acrn_platform_info *plat_info, int pcpu_id) { - return plat_info->lapic_ids[pcpu_id]; + return plat_info->hw.lapic_ids[pcpu_id]; } static int basl_fwrite_madt(FILE *fp, struct vmctx *ctx) { int i; - struct acrn_vm_config vm_cfg; - struct platform_info plat_info; + struct acrn_vm_config_header vm_cfg; + struct acrn_platform_info plat_info; uint64_t dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask; if (vm_get_config(ctx, &vm_cfg, &plat_info)) { @@ -339,9 +339,9 @@ basl_fwrite_madt(FILE *fp, struct vmctx *ctx) return -1; } - assert(pcpu_id < MAX_PLATFORM_LAPIC_IDS); - if (pcpu_id >= MAX_PLATFORM_LAPIC_IDS) { - pr_err("%s,Err: pcpu id %u should be less than MAX_PLATFORM_LAPIC_IDS.\n", __func__, pcpu_id); + assert(pcpu_id < ACRN_PLATFORM_LAPIC_IDS_MAX); + if (pcpu_id >= ACRN_PLATFORM_LAPIC_IDS_MAX) { + pr_err("%s,Err: pcpu id %u should be less than ACRN_PLATFORM_LAPIC_IDS_MAX.\n", __func__, pcpu_id); return -1; } diff --git a/devicemodel/hw/platform/acpi/rtct.c b/devicemodel/hw/platform/acpi/rtct.c index 744b7ffee..169319674 100644 --- a/devicemodel/hw/platform/acpi/rtct.c +++ b/devicemodel/hw/platform/acpi/rtct.c @@ -39,7 +39,7 @@ static uint16_t guest_vcpu_num; static uint32_t guest_l2_cat_shift; static uint32_t guest_l3_cat_shift; -static uint32_t guest_lapicid_tbl[MAX_PLATFORM_LAPIC_IDS]; +static uint32_t guest_lapicid_tbl[ACRN_PLATFORM_LAPIC_IDS_MAX]; static uint64_t software_sram_base_hpa; static uint64_t software_sram_size; @@ -281,7 +281,7 @@ static int init_vrtct_v1(struct acpi_table_hdr *vrtct, struct acpi_table_hdr *na struct rtct_entry *entry; struct rtct_entry_data_ssram *ssram; struct rtct_entry_data_mem_hi_latency *mem_hi; - uint32_t lapicids[MAX_PLATFORM_LAPIC_IDS]; + uint32_t lapicids[ACRN_PLATFORM_LAPIC_IDS_MAX]; foreach_rtct_entry(native_rtct, entry) { if (entry->type == RTCT_ENTRY_TYPE_SSRAM) { @@ -289,7 +289,7 @@ static int init_vrtct_v1(struct acpi_table_hdr *vrtct, struct acpi_table_hdr *na plapic_num = (entry->size - RTCT_SSRAM_HEADER_SIZE) / sizeof(uint32_t); ssram = (struct rtct_entry_data_ssram *)entry->data; - memset(lapicids, 0, sizeof(lapicids[MAX_PLATFORM_LAPIC_IDS])); + memset(lapicids, 0, sizeof(lapicids[ACRN_PLATFORM_LAPIC_IDS_MAX])); vlapic_num = 0; for (i = 0; i < plapic_num; i++) { if (is_pcpu_assigned_to_guest(ssram->apic_id_tbl[i])) { @@ -391,7 +391,7 @@ static int passthru_rtct_to_guest(struct acpi_table_hdr *vrtct, struct acpi_tabl return 0; } -static int init_guest_lapicid_tbl(struct platform_info *platform_info, uint64_t guest_pcpu_bitmask) +static int init_guest_lapicid_tbl(struct acrn_platform_info *platform_info, uint64_t guest_pcpu_bitmask) { int pcpu_id = 0, vcpu_id = 0; @@ -440,11 +440,11 @@ uint64_t get_software_sram_size(void) uint8_t *build_vrtct(struct vmctx *ctx, void *cfg) { #define PTCT_BUF_SIZE 4096 - struct acrn_vm_config vm_cfg; + struct acrn_vm_config_header vm_cfg; struct acpi_table_hdr *rtct_cfg, *vrtct = NULL; uint64_t dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask; uint32_t gpu_rsvmem_base_gpa = 0; - struct platform_info platform_info; + struct acrn_platform_info platform_info; if ((cfg == NULL) || (ctx == NULL)) return NULL; @@ -464,7 +464,7 @@ uint8_t *build_vrtct(struct vmctx *ctx, void *cfg) pr_err("%s, get VM configuration fail.\n", __func__); goto error; } - assert(platform_info.cpu_num <= MAX_PLATFORM_LAPIC_IDS); + assert(platform_info.hw.cpu_num <= ACRN_PLATFORM_LAPIC_IDS_MAX); /* * pCPU bitmask of VM is configured in hypervisor by default but can be @@ -492,8 +492,8 @@ uint8_t *build_vrtct(struct vmctx *ctx, void *cfg) __func__, dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask); guest_vcpu_num = bitmap_weight(guest_pcpu_bitmask); - guest_l2_cat_shift = platform_info.l2_cat_shift; - guest_l3_cat_shift = platform_info.l3_cat_shift; + guest_l2_cat_shift = platform_info.hw.l2_cat_shift; + guest_l3_cat_shift = platform_info.hw.l3_cat_shift; if (init_guest_lapicid_tbl(&platform_info, guest_pcpu_bitmask) < 0) { pr_err("%s,init guest lapicid table fail.\n", __func__); diff --git a/devicemodel/include/acpi.h b/devicemodel/include/acpi.h index 71ca48b25..4bf14b77e 100644 --- a/devicemodel/include/acpi.h +++ b/devicemodel/include/acpi.h @@ -86,6 +86,6 @@ void power_button_init(struct vmctx *ctx); void power_button_deinit(struct vmctx *ctx); int pcpuid_from_vcpuid(uint64_t guest_pcpu_bitmask, int vcpu_id); -int lapicid_from_pcpuid(struct platform_info *plat_info, int pcpu_id); +int lapicid_from_pcpuid(struct acrn_platform_info *plat_info, int pcpu_id); #endif /* _ACPI_H_ */ diff --git a/devicemodel/include/public/hsm_ioctl_defs.h b/devicemodel/include/public/hsm_ioctl_defs.h index 59ac23884..380a8d129 100644 --- a/devicemodel/include/public/hsm_ioctl_defs.h +++ b/devicemodel/include/public/hsm_ioctl_defs.h @@ -52,18 +52,25 @@ #ifndef _VHM_IOCTL_DEFS_H_ #define _VHM_IOCTL_DEFS_H_ +#include + /* Commmon structures for ACRN/HSM/DM */ #include "acrn_common.h" +/* The ioctl type, documented in ioctl-number.rst */ +#define ACRN_IOCTL_TYPE 0xA2 + /* * Commmon IOCTL ID defination for HSM/DM */ #define _IC_ID(x, y) (((x)<<24)|(y)) #define IC_ID 0x43UL -/* General */ -#define IC_ID_GEN_BASE 0x0UL -#define IC_GET_PLATFORM_INFO _IC_ID(IC_ID, IC_ID_GEN_BASE + 0x03) +/* + * Common IOCTL IDs definition for ACRN userspace + */ +#define ACRN_IOCTL_GET_PLATFORM_INFO \ + _IOR(ACRN_IOCTL_TYPE, 0x03, struct acrn_platform_info) /* VM management */ #define IC_ID_VM_BASE 0x10UL @@ -280,96 +287,47 @@ struct ioreq_notify { uint32_t vcpu; }; -enum acrn_vm_load_order { - PRE_LAUNCHED_VM = 0, - SOS_VM, - POST_LAUNCHED_VM, - MAX_LOAD_ORDER +#define ACRN_PLATFORM_LAPIC_IDS_MAX 64 +/** + * struct acrn_platform_info - Information of a platform from hypervisor + * @hw.cpu_num: Physical CPU number of the platform + * @hw.version: Version of this structure + * @hw.l2_cat_shift: Order of the number of threads sharing L2 cache + * @hw.l3_cat_shift: Order of the number of threads sharing L3 cache + * @hw.lapic_ids: IDs of LAPICs of all threads + * @hw.reserved: Reserved for alignment and should be 0 + * @sw.max_vcpus_per_vm: Maximum number of vCPU of a VM + * @sw.max_vms: Maximum number of VM + * @sw.vm_config_size: Size of configuration of a VM + * @sw.vm_configss_addr: Memory address which user space provided to + * store the VM configurations + * @sw.max_kata_containers: Maximum number of VM for Kata containers + * @sw.reserved: Reserved for alignment and should be 0 + * + * If vm_configs_addr is provided, the driver uses a bounce buffer (kmalloced + * for continuous memory region) to fetch VM configurations data from the + * hypervisor. + */ +struct acrn_platform_info { + struct { + __u16 cpu_num; + __u16 version; + __u32 l2_cat_shift; + __u32 l3_cat_shift; + __u8 lapic_ids[ACRN_PLATFORM_LAPIC_IDS_MAX]; + __u8 reserved[52]; + } hw; + + struct { + __u16 max_vcpus_per_vm; + __u16 max_vms; + __u32 vm_config_size; + void *vm_configs_addr; + __u64 max_kata_containers; + __u8 reserved[104]; + } sw; }; -/** - * @brief data structure to parse configuration data of VM. - */ -struct acrn_vm_config { -#define MAX_VM_OS_NAME_LEN 32U - enum acrn_vm_load_order load_order; - char name[MAX_VM_OS_NAME_LEN]; - const uint8_t uuid[16]; - uint8_t reserved[2]; - uint8_t severity; - uint64_t cpu_affinity; - uint64_t guest_flags; - /* - * Ignore other members that are hypervisor specific, actual size - * of current structure can be parsed by 'vm_config_entry_size' of - * 'struct platform_info'. - */ -} __aligned(8); - -/** - * @brief data structure to track VHM platform information - */ -struct platform_info { - /** Hardware Information */ - /** Physical CPU number */ - uint16_t cpu_num; - - /** version of this structure */ - uint16_t version; - - uint32_t l2_cat_shift; - uint32_t l3_cat_shift; - - #define MAX_PLATFORM_LAPIC_IDS 64U - /** pLAPIC ID list */ - uint8_t lapic_ids[MAX_PLATFORM_LAPIC_IDS]; - - /** - * sizeof(uint8_t reserved0[]) + sizeof(l2_cat_shift) - * + sizeof(l3_cat_shift) + sizeof(uint8_t lapic_ids[]) = 124 - * - * Note: - * 1. DM needs to use the same logic as hypervisor to calculate vLAPIC IDs - * based on physical APIC IDs and CPU affinity setting. - * - * 2. Can only support at most 116 cores. And it assumes LAPIC ID is 8bits - * (X2APIC mode supports 32 bits) - */ - uint8_t reserved0[116U - MAX_PLATFORM_LAPIC_IDS]; - - /** Configuration Information */ - /** Maximum vCPU number for one VM. */ - uint16_t max_vcpus_per_vm; - - /** Maximum Kata container number in SOS VM */ - uint8_t max_kata_containers; - - uint8_t reserved1[7]; - - /** Number of configured VMs */ - uint16_t max_vms; - - /** - * The size of acrn_vm_config is various on different platforms. - * This is the size of this struct which is used by the caller - * to parse the vm_configs array. - */ - uint32_t vm_config_entry_size; - - /** - * Address to an array of struct acrn_vm_config, containing all - * the configurations of all VMs. VHM treats it as an opague data - * structure. - * - * The size of one array element is vm_config_entry_size while - * the number of elements is max_vms. - */ - uint64_t vm_configs_addr; - - /** Align the size of Configuration info to 128Bytes. */ - uint8_t reserved2[104]; -} __aligned(8); - struct acrn_ioeventfd { #define ACRN_IOEVENTFD_FLAG_PIO 0x01 #define ACRN_IOEVENTFD_FLAG_DATAMATCH 0x02 diff --git a/devicemodel/include/vmmapi.h b/devicemodel/include/vmmapi.h index 86343ecc9..2a4b543e6 100644 --- a/devicemodel/include/vmmapi.h +++ b/devicemodel/include/vmmapi.h @@ -151,5 +151,6 @@ void vm_reset_watchdog(struct vmctx *ctx); int vm_ioeventfd(struct vmctx *ctx, struct acrn_ioeventfd *args); int vm_irqfd(struct vmctx *ctx, struct acrn_irqfd *args); -int vm_get_config(struct vmctx *ctx, struct acrn_vm_config *vm_cfg, struct platform_info *plat_info); +int vm_get_config(struct vmctx *ctx, struct acrn_vm_config_header *vm_cfg, + struct acrn_platform_info *plat_info); #endif /* _VMMAPI_H_ */ diff --git a/hypervisor/include/arch/x86/asm/vm_config.h b/hypervisor/include/arch/x86/asm/vm_config.h index d179bdd90..016dc0401 100644 --- a/hypervisor/include/arch/x86/asm/vm_config.h +++ b/hypervisor/include/arch/x86/asm/vm_config.h @@ -65,21 +65,6 @@ .uuid = KATA_VM_UUID##idx, \ .severity = SEVERITY_STANDARD_VM -/* - * PRE_LAUNCHED_VM is launched by ACRN hypervisor, with LAPIC_PT; - * SOS_VM is launched by ACRN hypervisor, without LAPIC_PT; - * POST_LAUNCHED_VM is launched by ACRN devicemodel, with/without LAPIC_PT depends on usecases. - * - * Assumption: vm_configs array is completely initialized w.r.t. load_order member of - * acrn_vm_config for all the VMs. - */ -enum acrn_vm_load_order { - PRE_LAUNCHED_VM = 0, - SOS_VM, - POST_LAUNCHED_VM, /* Launched by Devicemodel in SOS_VM */ - MAX_LOAD_ORDER -}; - /* ACRN guest severity */ enum acrn_vm_severity { SEVERITY_SAFETY_VM = 0x40U, diff --git a/hypervisor/include/public/acrn_common.h b/hypervisor/include/public/acrn_common.h index ae4a26771..b165cb73a 100644 --- a/hypervisor/include/public/acrn_common.h +++ b/hypervisor/include/public/acrn_common.h @@ -663,6 +663,37 @@ struct acrn_intr_monitor { #define INTR_CMD_GET_DATA 0U #define INTR_CMD_DELAY_INT 1U +/* + * PRE_LAUNCHED_VM is launched by ACRN hypervisor, with LAPIC_PT; + * SOS_VM is launched by ACRN hypervisor, without LAPIC_PT; + * POST_LAUNCHED_VM is launched by ACRN devicemodel, with/without LAPIC_PT depends on usecases. + * + * Assumption: vm_configs array is completely initialized w.r.t. load_order member of + * acrn_vm_config for all the VMs. + */ +enum acrn_vm_load_order { + PRE_LAUNCHED_VM = 0, + SOS_VM, + POST_LAUNCHED_VM, /* Launched by Devicemodel in SOS_VM */ + MAX_LOAD_ORDER +}; + +#define MAX_VM_OS_NAME_LEN 32U + +struct acrn_vm_config_header { + enum acrn_vm_load_order load_order; + char name[MAX_VM_OS_NAME_LEN]; + const uint8_t uuid[16]; + uint8_t reserved[2]; + uint8_t severity; + uint64_t cpu_affinity; + uint64_t guest_flags; + /* + * The following are hv-specific members and are thus opaque. + * vm_config_entry_size determines the real size of this structure. + */ +} __aligned(8); + /** * @brief Info to configure virtual root port *