dm: Use new ioctl ACRN_IOCTL_GET_PLATFORM_INFO

IC_GET_PLATFORM_INFO	->	ACRN_IOCTL_GET_PLATFORM_INFO
struct acrn_vm_config	->	struct acrn_vm_config_header(DM only)
struct platform_info	->	struct acrn_platform_info

Tracked-On: #6282
Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com>
This commit is contained in:
Shuo A Liu 2021-07-07 11:10:04 +08:00 committed by wenlingz
parent 82fa2d6355
commit 3deb973b7a
8 changed files with 111 additions and 136 deletions

View File

@ -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:

View File

@ -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;
}

View File

@ -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__);

View File

@ -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_ */

View File

@ -52,18 +52,25 @@
#ifndef _VHM_IOCTL_DEFS_H_
#define _VHM_IOCTL_DEFS_H_
#include <linux/types.h>
/* 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

View File

@ -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_ */

View File

@ -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,

View File

@ -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
*