mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-26 15:31:35 +00:00
dm: parse bootargs of vssram regions
1) With this patch, '--ssram' option is updated to enable vSSRAM feature support for ACRN user VMs. '--ssram' argument of Device Model shall follow below format: --ssram {Ln,vcpu=vcpu_set,size=nK|M;} example: --ssram L2,vcpu=0,1,size=4K;L2,vcpu=2,3,size=1M;L3,vcpu=all,size=2M 2) define data structure and variable to store the configuration data for later processing. 3) add new API to cleanup configuration data when VM shutdown. Tracked-On: #7010 Signed-off-by: Yonghua Huang <yonghua.huang@intel.com> Acked-by: Wang Yu1 <yu1.wang@intel.com>
This commit is contained in:
parent
db19e55f8f
commit
28713b3e3e
@ -67,6 +67,7 @@
|
|||||||
#include "pm_vuart.h"
|
#include "pm_vuart.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "pci_util.h"
|
#include "pci_util.h"
|
||||||
|
#include "vssram.h"
|
||||||
|
|
||||||
#define VM_MAXCPU 16 /* maximum virtual cpus */
|
#define VM_MAXCPU 16 /* maximum virtual cpus */
|
||||||
|
|
||||||
@ -164,7 +165,7 @@ usage(int code)
|
|||||||
" -W: force virtio to use single-vector MSI\n"
|
" -W: force virtio to use single-vector MSI\n"
|
||||||
" --mac_seed: set a platform unique string as a seed for generate mac address\n"
|
" --mac_seed: set a platform unique string as a seed for generate mac address\n"
|
||||||
" --ovmf: ovmf file path\n"
|
" --ovmf: ovmf file path\n"
|
||||||
" --ssram: Enable Software SRAM passthrough\n"
|
" --ssram: Congfiure Software SRAM parameters\n"
|
||||||
" --cpu_affinity: list of pCPUs assigned to this VM\n"
|
" --cpu_affinity: list of pCPUs assigned to this VM\n"
|
||||||
" --enable_trusty: enable trusty for guest\n"
|
" --enable_trusty: enable trusty for guest\n"
|
||||||
" --debugexit: enable debug exit function\n"
|
" --debugexit: enable debug exit function\n"
|
||||||
@ -794,7 +795,7 @@ static struct option long_options[] = {
|
|||||||
{"vtpm2", required_argument, 0, CMD_OPT_VTPM2},
|
{"vtpm2", required_argument, 0, CMD_OPT_VTPM2},
|
||||||
{"lapic_pt", no_argument, 0, CMD_OPT_LAPIC_PT},
|
{"lapic_pt", no_argument, 0, CMD_OPT_LAPIC_PT},
|
||||||
{"rtvm", no_argument, 0, CMD_OPT_RTVM},
|
{"rtvm", no_argument, 0, CMD_OPT_RTVM},
|
||||||
{"ssram", no_argument, 0, CMD_OPT_SOFTWARE_SRAM},
|
{"ssram", required_argument, 0, CMD_OPT_SOFTWARE_SRAM},
|
||||||
{"logger_setting", required_argument, 0, CMD_OPT_LOGGER_SETTING},
|
{"logger_setting", required_argument, 0, CMD_OPT_LOGGER_SETTING},
|
||||||
{"pm_notify_channel", required_argument, 0, CMD_OPT_PM_NOTIFY_CHANNEL},
|
{"pm_notify_channel", required_argument, 0, CMD_OPT_PM_NOTIFY_CHANNEL},
|
||||||
{"pm_by_vuart", required_argument, 0, CMD_OPT_PM_BY_VUART},
|
{"pm_by_vuart", required_argument, 0, CMD_OPT_PM_BY_VUART},
|
||||||
@ -936,7 +937,8 @@ main(int argc, char *argv[])
|
|||||||
is_rtvm = true;
|
is_rtvm = true;
|
||||||
break;
|
break;
|
||||||
case CMD_OPT_SOFTWARE_SRAM:
|
case CMD_OPT_SOFTWARE_SRAM:
|
||||||
/* TODO: we need to support parameter to specify Software SRAM size in the future */
|
if (parse_vssram_buf_params(optarg) != 0)
|
||||||
|
errx(EX_USAGE, "invalid vSSRAM buffer size param %s", optarg);
|
||||||
ssram = true;
|
ssram = true;
|
||||||
break;
|
break;
|
||||||
case CMD_OPT_ACPIDEV_PT:
|
case CMD_OPT_ACPIDEV_PT:
|
||||||
@ -1116,6 +1118,9 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
vm_fail:
|
vm_fail:
|
||||||
vm_deinit_vdevs(ctx);
|
vm_deinit_vdevs(ctx);
|
||||||
|
if (ssram)
|
||||||
|
clean_vssram_configs();
|
||||||
|
|
||||||
dev_fail:
|
dev_fail:
|
||||||
mevent_deinit();
|
mevent_deinit();
|
||||||
mevent_fail:
|
mevent_fail:
|
||||||
|
@ -16,10 +16,13 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "pci_core.h"
|
#include "pci_core.h"
|
||||||
#include "vmmapi.h"
|
#include "vmmapi.h"
|
||||||
#include "acpi.h"
|
#include "acpi.h"
|
||||||
|
#include "dm_string.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "vssram.h"
|
#include "vssram.h"
|
||||||
|
|
||||||
@ -32,6 +35,18 @@
|
|||||||
((uint64_t)e - (uint64_t)rtct) < rtct->length; \
|
((uint64_t)e - (uint64_t)rtct) < rtct->length; \
|
||||||
e = (struct rtct_entry *)((uint64_t)e + e->size))
|
e = (struct rtct_entry *)((uint64_t)e + e->size))
|
||||||
|
|
||||||
|
#define L2_CACHE 2
|
||||||
|
#define L3_CACHE 3
|
||||||
|
#define INVALID_CACHE_ID (-1)
|
||||||
|
#define INVALID_FD (-1)
|
||||||
|
#define VSSRAM_VCPUMASK_ALL ((uint64_t)-1)
|
||||||
|
#define MAX_VSSRAM_BUFFER_NUM (ACRN_PLATFORM_LAPIC_IDS_MAX << 1)
|
||||||
|
|
||||||
|
struct vssram_buf_param {
|
||||||
|
int level;
|
||||||
|
uint32_t size;
|
||||||
|
uint64_t vcpumask;
|
||||||
|
};
|
||||||
static uint16_t guest_vcpu_num;
|
static uint16_t guest_vcpu_num;
|
||||||
static uint64_t guest_pcpumask;
|
static uint64_t guest_pcpumask;
|
||||||
uint32_t guest_l2_cat_shift;
|
uint32_t guest_l2_cat_shift;
|
||||||
@ -42,6 +57,8 @@ static uint64_t vssram_size;
|
|||||||
static uint64_t vssram_gpa_base;
|
static uint64_t vssram_gpa_base;
|
||||||
static struct acpi_table_hdr *vrtct_table;
|
static struct acpi_table_hdr *vrtct_table;
|
||||||
|
|
||||||
|
static struct vssram_buf_param *vssram_buf_params;
|
||||||
|
|
||||||
uint8_t vrtct_checksum(uint8_t *vrtct, uint32_t length)
|
uint8_t vrtct_checksum(uint8_t *vrtct, uint32_t length)
|
||||||
{
|
{
|
||||||
uint8_t sum = 0;
|
uint8_t sum = 0;
|
||||||
@ -212,3 +229,148 @@ int init_vssram(struct vmctx *ctx)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief Cleanup vSSRAM configurations resource.
|
||||||
|
*
|
||||||
|
* @param void
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
void clean_vssram_configs(void)
|
||||||
|
{
|
||||||
|
if (vssram_buf_params) {
|
||||||
|
free(vssram_buf_params);
|
||||||
|
vssram_buf_params = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse input args for software SRAM configurations.
|
||||||
|
*
|
||||||
|
* @param opt Pointer input args string.
|
||||||
|
*
|
||||||
|
* @return 0 on success and non-zero on fail.
|
||||||
|
*
|
||||||
|
* @note Format of args shall be: "--ssram {Ln,vcpu=vcpu_set,size=nK|M;}"
|
||||||
|
* - "Ln,vcpu=vcpu_set,size=nK|M;" is used to configure one software SRAM region,
|
||||||
|
* multiple regions can be configured by separating them with semicolons(;).
|
||||||
|
* - Ln Cache level of software region, "L2"/"l3" and "L3"/"l3" are valid values
|
||||||
|
* for L2 and L3 cache respectively.
|
||||||
|
* - vcpu vCPU set of software region, multiple vCPU IDs can be configured by
|
||||||
|
* separating them with comma(,), "all"/"ALL" can be used to set all vCPUs.
|
||||||
|
* - size Size of software SRAM region, suffix of "K"/"k" or "M"/"m" must be used
|
||||||
|
* to indicate unit of Kilo bytes and Mega bytes respectively, this value
|
||||||
|
* must be decimal and page size(4Kbytes) aligned.
|
||||||
|
* - example: --ssram L2,vcpu=0,1,size=4K;L2,vcpu=2,3,size=1M;L3,vcpu=all,size=2M
|
||||||
|
*/
|
||||||
|
int parse_vssram_buf_params(const char *opt)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
uint32_t vcpu_id;
|
||||||
|
uint64_t vcpumask;
|
||||||
|
int level, shift, error = -1, index = 0;
|
||||||
|
struct vssram_buf_param *params;
|
||||||
|
char *cp_opt, *str, *elem, *s_elem, *level_str, *vcpu_str, *size_str, *endptr;
|
||||||
|
|
||||||
|
cp_opt = str = strdup(opt);
|
||||||
|
if (!str) {
|
||||||
|
fprintf(stderr, "%s: strdup returns NULL.\n", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
params = calloc(MAX_VSSRAM_BUFFER_NUM, sizeof(struct vssram_buf_param));
|
||||||
|
if (params == NULL) {
|
||||||
|
pr_err("%s malloc buffer.\n", __func__);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* param example: --ssram L2,vcpu=0,1,size=4K;L2,vcpu=2,3,size=1M;L3,vcpu=all,size=2M */
|
||||||
|
for (elem = strsep(&str, ";"); elem != NULL; elem = strsep(&str, ";")) {
|
||||||
|
if (strlen(elem) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
level_str = strsep(&elem, ",");
|
||||||
|
if (!strcmp(level_str, "L2") || !strcmp(level_str, "l2"))
|
||||||
|
level = L2_CACHE;
|
||||||
|
else if (!strcmp(level_str, "L3") || !strcmp(level_str, "l3"))
|
||||||
|
level = L3_CACHE;
|
||||||
|
else {
|
||||||
|
pr_err("invalid SSRAM buffer level:%s.\n", level_str);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
vcpu_str = strsep(&elem, "=");
|
||||||
|
if (strcmp(vcpu_str, "vcpu")) {
|
||||||
|
pr_err("%s is invalid, 'vcpu' must be specified.\n", vcpu_str);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
size_str = strstr(elem, "size=");
|
||||||
|
if (size_str == NULL) {
|
||||||
|
pr_err("invalid size parameter: %s\n", elem);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* split elem into vcpu ID list string and size string */
|
||||||
|
*(size_str - 1) = '\0';
|
||||||
|
vcpu_str = elem;
|
||||||
|
vcpumask = 0;
|
||||||
|
for (s_elem = strsep(&vcpu_str, ","); s_elem != NULL; s_elem = strsep(&vcpu_str, ",")) {
|
||||||
|
if (strlen(s_elem) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!strcmp(s_elem, "all") || !strcmp(s_elem, "ALL")) {
|
||||||
|
vcpumask = VSSRAM_VCPUMASK_ALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dm_strtoui(s_elem, &endptr, 10, &vcpu_id)) {
|
||||||
|
pr_err("invalid '%s' to specify vcpu ID.\n", s_elem);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
vcpumask |= (1 << vcpu_id);
|
||||||
|
}
|
||||||
|
if (bitmap_weight(vcpumask) == 0) {
|
||||||
|
pr_err("vCPU bitmask of ssram region is not set.\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
strsep(&size_str, "=");
|
||||||
|
if (strlen(size_str) == 0) {
|
||||||
|
pr_err("invalid size configuration.\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
size = strtoul(size_str, &endptr, 0);
|
||||||
|
switch (tolower((unsigned char)*endptr)) {
|
||||||
|
case 'm':
|
||||||
|
shift = 20;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
shift = 10;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("invalid size of '%s', only 'K','k'(KB) or 'M','m'(MB) can be suffixed!\n", size_str);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
size <<= shift;
|
||||||
|
if ((size == 0) || ((size & ~PAGE_MASK) != 0) || (size > VSSRAM_MAX_SIZE)) {
|
||||||
|
pr_err("size 0x%lx is invalid, 0 or not page-aligned, or too large.\n", size);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_info("config index[%d]: cache level:%d, size:%lx, vcpumask:%lx\n", index, level, size, vcpumask);
|
||||||
|
params[index].level = level;
|
||||||
|
params[index].size = size;
|
||||||
|
params[index].vcpumask = vcpumask;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
vssram_buf_params = params;
|
||||||
|
error = 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (error) {
|
||||||
|
free(params);
|
||||||
|
}
|
||||||
|
free(cp_opt);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
@ -44,6 +44,8 @@ struct rtct_entry_data_ssram_v2 {
|
|||||||
uint64_t get_vssram_gpa_base(void);
|
uint64_t get_vssram_gpa_base(void);
|
||||||
uint64_t get_vssram_size(void);
|
uint64_t get_vssram_size(void);
|
||||||
uint8_t *get_vssram_vrtct(void);
|
uint8_t *get_vssram_vrtct(void);
|
||||||
|
void clean_vssram_configs(void);
|
||||||
int init_vssram(struct vmctx *ctx);
|
int init_vssram(struct vmctx *ctx);
|
||||||
|
int parse_vssram_buf_params(const char *opt);
|
||||||
|
|
||||||
#endif /* RTCT_H */
|
#endif /* RTCT_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user