mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-29 16:58:10 +00:00
dm: build vRTCT of Software SRAM for Post-launch RTVM
This patch prepares vRTCT for post-RTVM instead of pass-thru native RTCT: - Configurations are based on Service VM native RTCT. - Remap vLAPIC IDs in vRTCT. - Remap base address of SW SRAM memory regions from HPA to GPA. - HPA base of Software SRAM shall be parsed from PTCT instead of hardcoding. Tracked-On: #5649 Signed-off-by: Yonghua Huang <yonghua.huang@intel.com> Reviewed-by: Fei Li <fei1.li@intel.com> Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
parent
3005d074f0
commit
154a446c5c
@ -96,6 +96,7 @@ SRCS += hw/platform/ioc.c
|
|||||||
SRCS += hw/platform/ioc_cbc.c
|
SRCS += hw/platform/ioc_cbc.c
|
||||||
SRCS += hw/platform/pty_vuart.c
|
SRCS += hw/platform/pty_vuart.c
|
||||||
SRCS += hw/platform/acpi/acpi.c
|
SRCS += hw/platform/acpi/acpi.c
|
||||||
|
SRCS += hw/platform/acpi/rtct.c
|
||||||
SRCS += hw/platform/acpi/acpi_pm.c
|
SRCS += hw/platform/acpi/acpi_pm.c
|
||||||
SRCS += hw/platform/rpmb/rpmb_sim.c
|
SRCS += hw/platform/rpmb/rpmb_sim.c
|
||||||
SRCS += hw/platform/rpmb/rpmb_backend.c
|
SRCS += hw/platform/rpmb/rpmb_backend.c
|
||||||
|
@ -179,6 +179,11 @@ int acrn_parse_cpu_affinity(char *opt)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t vm_get_cpu_affinity_dm(void)
|
||||||
|
{
|
||||||
|
return cpu_affinity_bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
struct vmctx *
|
struct vmctx *
|
||||||
vm_create(const char *name, uint64_t req_buf, int *vcpu_num)
|
vm_create(const char *name, uint64_t req_buf, int *vcpu_num)
|
||||||
{
|
{
|
||||||
|
@ -1092,14 +1092,13 @@ int create_and_inject_vrtct(struct vmctx *ctx)
|
|||||||
size_t native_rtct_len;
|
size_t native_rtct_len;
|
||||||
size_t vrtct_len;
|
size_t vrtct_len;
|
||||||
uint8_t buf[RTCT_BUF_LEN] = {0};
|
uint8_t buf[RTCT_BUF_LEN] = {0};
|
||||||
|
uint8_t *vrtct;
|
||||||
struct vm_memmap memmap = {
|
struct vm_memmap memmap = {
|
||||||
.type = VM_MMIO,
|
.type = VM_MMIO,
|
||||||
.gpa = SOFTWARE_SRAM_BASE_GPA,
|
.gpa = SOFTWARE_SRAM_BASE_GPA,
|
||||||
.hpa = SOFTWARE_SRAM_BASE_HPA,
|
/* HPA base and size of Software SRAM shall be parsed from vRTCT. */
|
||||||
/* TODO: .len should be software ram_size+32kb (32kb is for CRL binary).
|
.hpa = 0,
|
||||||
*We also need to modify guest E820 to adapt to real config
|
.len = 0,
|
||||||
*/
|
|
||||||
.len = SOFTWARE_SRAM_MAX_SIZE,
|
|
||||||
.prot = PROT_ALL
|
.prot = PROT_ALL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1122,10 +1121,19 @@ int create_and_inject_vrtct(struct vmctx *ctx)
|
|||||||
}
|
}
|
||||||
close(native_rtct_fd);
|
close(native_rtct_fd);
|
||||||
|
|
||||||
vrtct_len = native_rtct_len;
|
vrtct = build_vrtct(ctx, (void *)buf);
|
||||||
|
if (vrtct == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
memcpy(vm_map_gpa(ctx, ACPI_BASE + RTCT_OFFSET, vrtct_len), buf, vrtct_len);
|
vrtct_len = ((struct acpi_table_hdr *)vrtct)->length;
|
||||||
|
if (vrtct_len > RTCT_BUF_LEN) {
|
||||||
|
pr_err("Warning: Size of vRTCT (%d bytes) overflows, pls update DSDT_OFFSET.\n", vrtct_len);
|
||||||
|
}
|
||||||
|
memcpy(vm_map_gpa(ctx, ACPI_BASE + RTCT_OFFSET, vrtct_len), vrtct, vrtct_len);
|
||||||
|
free(vrtct);
|
||||||
|
|
||||||
|
memmap.hpa = get_software_sram_base_hpa();
|
||||||
|
memmap.len = get_software_sram_size();
|
||||||
ioctl(ctx->fd, IC_UNSET_MEMSEG, &memmap);
|
ioctl(ctx->fd, IC_UNSET_MEMSEG, &memmap);
|
||||||
return ioctl(ctx->fd, IC_SET_MEMSEG, &memmap);
|
return ioctl(ctx->fd, IC_SET_MEMSEG, &memmap);
|
||||||
};
|
};
|
||||||
|
363
devicemodel/hw/platform/acpi/rtct.c
Normal file
363
devicemodel/hw/platform/acpi/rtct.c
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Intel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "pci_core.h"
|
||||||
|
#include "vmmapi.h"
|
||||||
|
#include "acpi.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "rtct.h"
|
||||||
|
|
||||||
|
#define RTCT_ENTRY_HEADER_SIZE 8
|
||||||
|
#define RTCT_PSRAM_HEADER_SIZE (RTCT_ENTRY_HEADER_SIZE + 20)
|
||||||
|
#define RTCT_MEM_HI_HEADER_SIZE (RTCT_ENTRY_HEADER_SIZE + 8)
|
||||||
|
|
||||||
|
#define BITMASK(nr) (1U << nr)
|
||||||
|
|
||||||
|
#define foreach_rtct_entry(rtct, e) \
|
||||||
|
for (e = (void *)rtct + sizeof(struct acpi_table_hdr); \
|
||||||
|
((uint64_t)e - (uint64_t)rtct) < rtct->length; \
|
||||||
|
e = (struct rtct_entry *)((uint64_t)e + e->size))
|
||||||
|
|
||||||
|
static uint64_t software_sram_base_hpa;
|
||||||
|
static uint64_t software_sram_size;
|
||||||
|
|
||||||
|
static uint8_t vrtct_checksum(uint8_t *vrtct, uint32_t length)
|
||||||
|
{
|
||||||
|
uint8_t sum = 0;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
sum += vrtct[i];
|
||||||
|
}
|
||||||
|
return -sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t lapicid_to_cpuid(uint32_t lapicid)
|
||||||
|
{
|
||||||
|
/* hardcode for TGL & EHL platform */
|
||||||
|
return (lapicid >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t vcpuid_to_vlapicid(uint32_t vcpuid)
|
||||||
|
{
|
||||||
|
/* keep vlapic same with vcpuid */
|
||||||
|
return vcpuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Build a vLAPIC ID table base on the pCPU bitmask of guest
|
||||||
|
* and pCPU bitmask of Software SRAM.
|
||||||
|
*
|
||||||
|
* @param sw_sram_pcpu_bitmask pCPU bitmask of Software SRAM region.
|
||||||
|
* @param guest_pcpu_bitmask pCUP bitmask of guest.
|
||||||
|
* @param vlapicid_tbl Pointer to buffer of vLAPIC ID table, caller shall
|
||||||
|
* guarantee it will not overflow.
|
||||||
|
*
|
||||||
|
* @return number of vlapic IDs filled to buffer.
|
||||||
|
*/
|
||||||
|
static int map_software_sram_vlapic_ids(uint64_t sw_sram_pcpu_bitmask, uint64_t guest_pcpu_bitmask,
|
||||||
|
uint32_t *vlapicid_tbl)
|
||||||
|
{
|
||||||
|
uint32_t vcpuid = 0;
|
||||||
|
int i, vlapicid_num = 0;
|
||||||
|
int guest_pcpu_index_start = ffsl(guest_pcpu_bitmask) - 1;
|
||||||
|
int guest_pcpu_index_end = flsl(guest_pcpu_bitmask) - 1;
|
||||||
|
|
||||||
|
for (i = guest_pcpu_index_start; i <= guest_pcpu_index_end; i++) {
|
||||||
|
if ((guest_pcpu_bitmask & BITMASK(i)) != 0) {
|
||||||
|
if ((sw_sram_pcpu_bitmask & BITMASK(i)) != 0) {
|
||||||
|
vlapicid_tbl[vlapicid_num++] = vcpuid_to_vlapicid(vcpuid);
|
||||||
|
}
|
||||||
|
vcpuid++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vlapicid_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct rtct_entry *get_free_rtct_entry(struct acpi_table_hdr *rtct)
|
||||||
|
{
|
||||||
|
return (struct rtct_entry *)((uint8_t *)rtct + rtct->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void add_rtct_entry(struct acpi_table_hdr *rtct, struct rtct_entry *e)
|
||||||
|
{
|
||||||
|
rtct->length += e->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a new Software SRAM region entry to virtual RTCT.
|
||||||
|
*
|
||||||
|
* @param vrtct Pointer to virtual RTCT.
|
||||||
|
* @param cache_level Cache level of Software SRAM region.
|
||||||
|
* @param base Base address of Software SRAM region.
|
||||||
|
* @param ways Cache ways of Software SRAM region.
|
||||||
|
* @param size Size of Software SRAM region.
|
||||||
|
* @param sw_sram_pcpu_bitmask pCPU bitmask of Software SRAM region.
|
||||||
|
* @param guest_pcpu_bitmask pCUP bitmask of guest.
|
||||||
|
*
|
||||||
|
* @return 0 on success and non-zero on fail.
|
||||||
|
*/
|
||||||
|
static int vrtct_add_psram_entry(struct acpi_table_hdr *vrtct, uint32_t cache_level, uint64_t base, uint32_t ways,
|
||||||
|
uint32_t size, uint64_t sw_sram_pcpu_bitmask, uint64_t guest_pcpu_bitmask)
|
||||||
|
{
|
||||||
|
int vlapicid_num;
|
||||||
|
struct rtct_entry *rtct_entry;
|
||||||
|
struct rtct_entry_data_psram *sw_sram;
|
||||||
|
|
||||||
|
rtct_entry = get_free_rtct_entry(vrtct);
|
||||||
|
rtct_entry->format = 1;
|
||||||
|
rtct_entry->type = RTCT_ENTRY_TYPE_PSRAM;
|
||||||
|
|
||||||
|
sw_sram = (struct rtct_entry_data_psram *)rtct_entry->data;
|
||||||
|
sw_sram->cache_level = cache_level;
|
||||||
|
sw_sram->base = base;
|
||||||
|
sw_sram->ways = ways;
|
||||||
|
sw_sram->size = size;
|
||||||
|
|
||||||
|
vlapicid_num = map_software_sram_vlapic_ids(sw_sram_pcpu_bitmask, guest_pcpu_bitmask, sw_sram->apic_id_tbl);
|
||||||
|
if (vlapicid_num <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
rtct_entry->size = RTCT_PSRAM_HEADER_SIZE + (vlapicid_num * sizeof(uint32_t));
|
||||||
|
add_rtct_entry(vrtct, rtct_entry);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a memory hierarchy entry to virtual RTCT.
|
||||||
|
*
|
||||||
|
* @param vrtct Pointer to virtual RTCT.
|
||||||
|
* @param hierarchy Memory hierarchy(2: cache level-2, 3:cache level-3, 256: the last level)
|
||||||
|
* @param clock_cycles Latency value of memory 'hierarchy'.
|
||||||
|
* @param vcpu_num Number of guest vCPU.
|
||||||
|
*
|
||||||
|
* @return 0 on success and non-zero on fail.
|
||||||
|
*/
|
||||||
|
static int vrtct_add_mem_hierarchy_entry(struct acpi_table_hdr *vrtct, uint32_t hierarchy,
|
||||||
|
uint32_t clock_cycles, uint64_t vcpu_num)
|
||||||
|
{
|
||||||
|
int vcpuid;
|
||||||
|
struct rtct_entry *rtct_entry;
|
||||||
|
struct rtct_entry_data_mem_hi_latency *mem_hi;
|
||||||
|
|
||||||
|
rtct_entry = get_free_rtct_entry(vrtct);
|
||||||
|
rtct_entry->format = 1;
|
||||||
|
rtct_entry->type = RTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY;
|
||||||
|
|
||||||
|
mem_hi = (struct rtct_entry_data_mem_hi_latency *)rtct_entry->data;
|
||||||
|
mem_hi->hierarchy = hierarchy;
|
||||||
|
mem_hi->clock_cycles = clock_cycles;
|
||||||
|
|
||||||
|
for (vcpuid = 0; vcpuid < vcpu_num; vcpuid++) {
|
||||||
|
mem_hi->apic_id_tbl[vcpuid] = vcpuid_to_vlapicid(vcpuid);
|
||||||
|
}
|
||||||
|
rtct_entry->size = RTCT_MEM_HI_HEADER_SIZE + (vcpu_num * sizeof(uint32_t));
|
||||||
|
|
||||||
|
add_rtct_entry(vrtct, rtct_entry);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Update the base address of Software SRAM regions in vRTCT from
|
||||||
|
* host physical address(HPA) to guest physical address(GPA).
|
||||||
|
*
|
||||||
|
* @param vrtct Pointer to virtual RTCT.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
static void remap_software_sram_regions(struct acpi_table_hdr *vrtct)
|
||||||
|
{
|
||||||
|
struct rtct_entry *entry;
|
||||||
|
struct rtct_entry_data_psram *sw_sram_region;
|
||||||
|
uint64_t hpa_bottom, hpa_top;
|
||||||
|
|
||||||
|
hpa_bottom = (uint64_t)-1;
|
||||||
|
hpa_top = 0;
|
||||||
|
|
||||||
|
foreach_rtct_entry(vrtct, entry) {
|
||||||
|
if (entry->type == RTCT_ENTRY_TYPE_PSRAM) {
|
||||||
|
sw_sram_region = (struct rtct_entry_data_psram *)entry->data;
|
||||||
|
if (hpa_bottom > sw_sram_region->base) {
|
||||||
|
hpa_bottom = sw_sram_region->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hpa_top < sw_sram_region->base + sw_sram_region->size) {
|
||||||
|
hpa_top = sw_sram_region->base + sw_sram_region->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pr_info("%s, hpa_bottom:%lx, hpa_top:%lx.\n", __func__, hpa_bottom, hpa_top);
|
||||||
|
|
||||||
|
software_sram_base_hpa = hpa_bottom;
|
||||||
|
software_sram_size = hpa_top - hpa_bottom;
|
||||||
|
|
||||||
|
foreach_rtct_entry(vrtct, entry) {
|
||||||
|
if (entry->type == RTCT_ENTRY_TYPE_PSRAM) {
|
||||||
|
sw_sram_region = (struct rtct_entry_data_psram *)entry->data;
|
||||||
|
sw_sram_region->base = SOFTWARE_SRAM_BASE_GPA + (sw_sram_region->base - hpa_bottom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize Software SRAM and memory hierarchy entries in virtual RTCT,
|
||||||
|
* configurations of these entries are from native RTCT.
|
||||||
|
*
|
||||||
|
* @param vrtct Pointer to virtual RTCT.
|
||||||
|
* @param native_rtct Pointer to native RTCT.
|
||||||
|
* @param guest_pcpu_bitmask pCUP bitmask of guest.
|
||||||
|
*
|
||||||
|
* @return 0 on success and non-zero on fail.
|
||||||
|
*/
|
||||||
|
static int passthru_rtct_to_guest(struct acpi_table_hdr *vrtct, struct acpi_table_hdr *native_rtct,
|
||||||
|
uint64_t guest_pcpu_bitmask)
|
||||||
|
{
|
||||||
|
int i, cpu_num, rc = 0;
|
||||||
|
uint64_t sw_sram_pcpu_bitmask;
|
||||||
|
struct rtct_entry *entry;
|
||||||
|
struct rtct_entry_data_psram *sw_sram;
|
||||||
|
struct rtct_entry_data_mem_hi_latency *mem_hi;
|
||||||
|
|
||||||
|
foreach_rtct_entry(native_rtct, entry) {
|
||||||
|
switch (entry->type) {
|
||||||
|
case RTCT_ENTRY_TYPE_PSRAM:
|
||||||
|
{
|
||||||
|
/* Get native CPUs of Software SRAM region */
|
||||||
|
cpu_num = (entry->size - RTCT_PSRAM_HEADER_SIZE) / sizeof(uint32_t);
|
||||||
|
sw_sram = (struct rtct_entry_data_psram *)entry->data;
|
||||||
|
sw_sram_pcpu_bitmask = 0;
|
||||||
|
for (i = 0; i < cpu_num; i++) {
|
||||||
|
sw_sram_pcpu_bitmask |= (1U << lapicid_to_cpuid(sw_sram->apic_id_tbl[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sw_sram_pcpu_bitmask & guest_pcpu_bitmask) != 0) {
|
||||||
|
/*
|
||||||
|
* argument 'base' is set to HPA(sw_sram->base) in passthru RTCT
|
||||||
|
* soluation as it is required to calculate Software SRAM regions range
|
||||||
|
* in host physical address space, this 'base' will be updated to
|
||||||
|
* GPA when mapping all Software SRAM regions from HPA to GPA.
|
||||||
|
*/
|
||||||
|
rc = vrtct_add_psram_entry(vrtct, sw_sram->cache_level, sw_sram->base,
|
||||||
|
sw_sram->ways, sw_sram->size, sw_sram_pcpu_bitmask, guest_pcpu_bitmask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY:
|
||||||
|
{
|
||||||
|
mem_hi = (struct rtct_entry_data_mem_hi_latency *)entry->data;
|
||||||
|
rc = vrtct_add_mem_hierarchy_entry(vrtct, mem_hi->hierarchy, mem_hi->clock_cycles,
|
||||||
|
bitmap_weight(guest_pcpu_bitmask));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
remap_software_sram_regions(vrtct);
|
||||||
|
vrtct->checksum = vrtct_checksum((uint8_t *)vrtct, vrtct->length);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t get_software_sram_base_hpa(void)
|
||||||
|
{
|
||||||
|
return software_sram_base_hpa;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t get_software_sram_size(void)
|
||||||
|
{
|
||||||
|
return software_sram_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize virtual RTCT based on configurations from native RTCT in Service VM.
|
||||||
|
*
|
||||||
|
* @param ctx Pointer to context of guest.
|
||||||
|
* @param cfg Pointer to configuration data, it pointers to native RTCT in passthru RTCT solution.
|
||||||
|
*
|
||||||
|
* @return Pointer to virtual RTCT data on success and NULL on fail.
|
||||||
|
*/
|
||||||
|
uint8_t *build_vrtct(struct vmctx *ctx, void *cfg)
|
||||||
|
{
|
||||||
|
#define PTCT_BUF_SIZE 4096
|
||||||
|
struct acrn_vm_config vm_cfg;
|
||||||
|
struct acpi_table_hdr *rtct_cfg, *vrtct = NULL;
|
||||||
|
uint64_t dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask;
|
||||||
|
|
||||||
|
if ((cfg == NULL) || (ctx == NULL))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rtct_cfg = (struct acpi_table_hdr *)cfg;
|
||||||
|
vrtct = malloc(PTCT_BUF_SIZE);
|
||||||
|
if (vrtct == NULL) {
|
||||||
|
pr_err("%s, Failed to allocate vRTCT buffer.\n", __func__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy((void *)vrtct, (void *)rtct_cfg, sizeof(struct acpi_table_hdr));
|
||||||
|
vrtct->length = sizeof(struct acpi_table_hdr);
|
||||||
|
vrtct->checksum = 0;
|
||||||
|
|
||||||
|
if (vm_get_config(ctx, &vm_cfg)) {
|
||||||
|
pr_err("%s, get VM configuration fail.\n", __func__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pCPU bitmask of VM is configured in hypervisor by default but can be
|
||||||
|
* overwritten by '--cpu_affinity' argument of DM if this bitmask is
|
||||||
|
* the subset of bitmask configured in hypervisor.
|
||||||
|
*
|
||||||
|
* FIXME: The cpu_affinity does not only mean the vcpu's pcpu affinity but
|
||||||
|
* also indicates the maximum vCPU number of guest. Its name should be renamed
|
||||||
|
* to pu_bitmask to avoid confusing.
|
||||||
|
*/
|
||||||
|
hv_cpu_bitmask = vm_cfg.cpu_affinity;
|
||||||
|
dm_cpu_bitmask = vm_get_cpu_affinity_dm();
|
||||||
|
if ((dm_cpu_bitmask != 0) && ((dm_cpu_bitmask & ~hv_cpu_bitmask) == 0)) {
|
||||||
|
guest_pcpu_bitmask = dm_cpu_bitmask;
|
||||||
|
} else {
|
||||||
|
guest_pcpu_bitmask = hv_cpu_bitmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guest_pcpu_bitmask == 0) {
|
||||||
|
pr_err("%s,Err: Invalid guest_pcpu_bitmask.\n", __func__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_info("%s, dm_cpu_bitmask:0x%x, hv_cpu_bitmask:0x%x, guest_cpu_bitmask: 0x%x\n",
|
||||||
|
__func__, dm_cpu_bitmask, hv_cpu_bitmask, guest_pcpu_bitmask);
|
||||||
|
|
||||||
|
if (passthru_rtct_to_guest(vrtct, rtct_cfg, guest_pcpu_bitmask)) {
|
||||||
|
pr_err("%s, initialize vRTCT fail.", __func__);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint8_t *)vrtct;
|
||||||
|
error:
|
||||||
|
free(vrtct);
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -39,6 +39,27 @@
|
|||||||
|
|
||||||
#define IO_PMTMR 0x0 /* PM Timer is disabled in ACPI */
|
#define IO_PMTMR 0x0 /* PM Timer is disabled in ACPI */
|
||||||
|
|
||||||
|
struct acpi_table_hdr {
|
||||||
|
/* ASCII table signature */
|
||||||
|
char signature[4];
|
||||||
|
/* Length of table in bytes, including this header */
|
||||||
|
uint32_t length;
|
||||||
|
/* ACPI Specification minor version number */
|
||||||
|
uint8_t revision;
|
||||||
|
/* To make sum of entire table == 0 */
|
||||||
|
uint8_t checksum;
|
||||||
|
/* ASCII OEM identification */
|
||||||
|
char oem_id[6];
|
||||||
|
/* ASCII OEM table identification */
|
||||||
|
char oem_table_id[8];
|
||||||
|
/* OEM revision number */
|
||||||
|
uint32_t oem_revision;
|
||||||
|
/* ASCII ASL compiler vendor ID */
|
||||||
|
char asl_compiler_id[4];
|
||||||
|
/* ASL compiler version */
|
||||||
|
uint32_t asl_compiler_revision;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
/* All dynamic table entry no. */
|
/* All dynamic table entry no. */
|
||||||
#define NHLT_ENTRY_NO 8
|
#define NHLT_ENTRY_NO 8
|
||||||
|
|
||||||
|
@ -7,10 +7,46 @@
|
|||||||
#ifndef RTCT_H
|
#ifndef RTCT_H
|
||||||
#define RTCT_H
|
#define RTCT_H
|
||||||
|
|
||||||
|
#define RTCT_ENTRY_TYPE_PTCD_LIMIT 1U
|
||||||
|
#define RTCT_ENTRY_TYPE_PTCM_BINARY 2U
|
||||||
|
#define RTCT_ENTRY_TYPE_WRC_L3_MASKS 3U
|
||||||
|
#define RTCT_ENTRY_TYPE_GT_L3_MASKS 4U
|
||||||
|
#define RTCT_ENTRY_TYPE_PSRAM 5U
|
||||||
|
#define RTCT_ENTRY_TYPE_STREAM_DATAPATH 6U
|
||||||
|
#define RTCT_ENTRY_TYPE_TIMEAWARE_SUBSYS 7U
|
||||||
|
#define RTCT_ENTRY_TYPE_RT_IOMMU 8U
|
||||||
|
#define RTCT_ENTRY_TYPE_MEM_HIERARCHY_LATENCY 9U
|
||||||
|
|
||||||
/* TODO: Move to high-memory region. */
|
/* TODO: Move to high-memory region. */
|
||||||
#define SOFTWARE_SRAM_BASE_HPA 0x40080000UL
|
#define SOFTWARE_SRAM_BASE_HPA 0x40080000UL
|
||||||
#define SOFTWARE_SRAM_BASE_GPA 0x40080000UL
|
#define SOFTWARE_SRAM_BASE_GPA 0x40080000UL
|
||||||
#define SOFTWARE_SRAM_MAX_SIZE 0x00800000UL
|
#define SOFTWARE_SRAM_MAX_SIZE 0x00800000UL
|
||||||
|
|
||||||
|
struct rtct_entry {
|
||||||
|
uint16_t size;
|
||||||
|
uint16_t format;
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t data[64];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
|
struct rtct_entry_data_psram {
|
||||||
|
uint32_t cache_level;
|
||||||
|
uint64_t base;
|
||||||
|
uint32_t ways;
|
||||||
|
uint32_t size;
|
||||||
|
uint32_t apic_id_tbl[64];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
|
struct rtct_entry_data_mem_hi_latency {
|
||||||
|
uint32_t hierarchy;
|
||||||
|
uint32_t clock_cycles;
|
||||||
|
uint32_t apic_id_tbl[64];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
uint64_t get_software_sram_base_hpa(void);
|
||||||
|
uint64_t get_software_sram_size(void);
|
||||||
|
uint8_t *build_vrtct(struct vmctx *ctx, void *cfg);
|
||||||
|
|
||||||
#endif /* RTCT_H */
|
#endif /* RTCT_H */
|
||||||
|
@ -89,6 +89,14 @@ flsl(uint64_t mask)
|
|||||||
return mask ? 64 - __builtin_clzl(mask) : 0;
|
return mask ? 64 - __builtin_clzl(mask) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns the number of 1-bits in bits. */
|
||||||
|
static inline int
|
||||||
|
bitmap_weight(uint64_t bits)
|
||||||
|
{
|
||||||
|
return __builtin_popcountl(bits);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* memory barrier */
|
/* memory barrier */
|
||||||
#define mb() ({ asm volatile("mfence" ::: "memory"); (void)0; })
|
#define mb() ({ asm volatile("mfence" ::: "memory"); (void)0; })
|
||||||
|
|
||||||
|
@ -140,6 +140,7 @@ int vm_add_hv_vdev(struct vmctx *ctx, struct acrn_emul_dev *dev);
|
|||||||
int vm_remove_hv_vdev(struct vmctx *ctx, struct acrn_emul_dev *dev);
|
int vm_remove_hv_vdev(struct vmctx *ctx, struct acrn_emul_dev *dev);
|
||||||
|
|
||||||
int acrn_parse_cpu_affinity(char *arg);
|
int acrn_parse_cpu_affinity(char *arg);
|
||||||
|
uint64_t vm_get_cpu_affinity_dm(void);
|
||||||
int vm_create_vcpu(struct vmctx *ctx, uint16_t vcpu_id);
|
int vm_create_vcpu(struct vmctx *ctx, uint16_t vcpu_id);
|
||||||
int vm_set_vcpu_regs(struct vmctx *ctx, struct acrn_set_vcpu_regs *cpu_regs);
|
int vm_set_vcpu_regs(struct vmctx *ctx, struct acrn_set_vcpu_regs *cpu_regs);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user