dm: get lapic id from madt

GET_PLATFORM_INFO interface will be removed from ACRN hypervisor,
Service VM /ACRN-DM and other userland applications shall not use it any more.
For dm the lapic id was get from acrn_platform_info.
So in version 2.7, SOS madt table is parsed to get the lapic id for each pcpu.

There has an assumption. The SOS owned pcpu starts from physical cpu 0,
otherwise SOS doesn't know the mapping relationship between its vcpu0
and pcpu_id.

Tracked-On: #6724
Signed-off-by: Yuanyuan Zhao <yuanyuan.zhao@linux.intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Yuanyuan Zhao 2021-10-27 20:41:28 +08:00 committed by wenlingz
parent 9e8c1a1508
commit 4ad206ea5e
6 changed files with 177 additions and 8 deletions

View File

@ -108,6 +108,7 @@ SRCS += hw/platform/pty_vuart.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_parser.c
SRCS += hw/platform/rpmb/rpmb_sim.c
SRCS += hw/platform/rpmb/rpmb_backend.c
SRCS += hw/platform/rpmb/att_keybox.c

View File

@ -1012,6 +1012,11 @@ main(int argc, char *argv[])
exit(1);
}
if (parse_madt()) {
pr_err("parse madt failed\n");
exit(1);
}
if (!init_hugetlb()) {
pr_err("init_hugetlb failed\n");
exit(1);

View File

@ -272,11 +272,6 @@ 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 acrn_platform_info *plat_info, int pcpu_id)
{
return plat_info->hw.lapic_ids[pcpu_id];
}
static int
basl_fwrite_madt(FILE *fp, struct vmctx *ctx)
{
@ -343,7 +338,11 @@ basl_fwrite_madt(FILE *fp, struct vmctx *ctx)
return -1;
}
lapic_id = lapicid_from_pcpuid(&plat_info, pcpu_id);
lapic_id = lapicid_from_pcpuid(pcpu_id);
if (lapic_id == -1) {
pr_err("Get lapic id fail.\n");
return -1;
}
EFPRINTF(fp, "[0001]\t\tSubtable Type : 00\n");
EFPRINTF(fp, "[0001]\t\tLength : 08\n");

View File

@ -0,0 +1,131 @@
/*-
* Copyright (c) 2011 NetApp, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "dm.h"
#include "log.h"
#include "hsm_ioctl_defs.h"
#include "acpi.h"
static uint8_t lapic_ids[ACRN_PLATFORM_LAPIC_IDS_MAX] = {0xff};
int lapicid_from_pcpuid(int pcpu_id)
{
if (pcpu_id < 0 || pcpu_id >= ACRN_PLATFORM_LAPIC_IDS_MAX || lapic_ids[pcpu_id] == 0xff) {
return -1;
}
return (int)lapic_ids[pcpu_id];
}
static int
local_parse_madt(struct acpi_table_madt *madt)
{
uint16_t pcpu_num = 0U;
int ret = 0;
struct acpi_madt_local_apic *processor;
struct acpi_table_madt *madt_ptr;
void *first, *end, *iterator;
struct acpi_subtable_header *entry;
madt_ptr = madt;
first = madt_ptr + 1;
end = (void *)madt_ptr + madt_ptr->header.length;
for (iterator = first; (iterator) < (end); iterator += entry->length) {
entry = (struct acpi_subtable_header *)iterator;
if (entry->length < sizeof(struct acpi_subtable_header)) {
break;
}
if (entry->type == ACPI_MADT_TYPE_LOCAL_APIC) {
processor = (struct acpi_madt_local_apic *)iterator;
if ((processor->lapic_flags & ACPI_MADT_ENABLED) != 0U) {
if (pcpu_num < ACRN_PLATFORM_LAPIC_IDS_MAX) {
lapic_ids[pcpu_num] = processor->id;
}
pcpu_num++;
}
}
}
if (pcpu_num == 0) {
ret = -1;
}
return ret;
}
/*
* There has an assumption. The SOS owned pcpu starts from physical cpu 0,
* otherwise SOS doesn't know the mapping relationship between its vcpu0
* and pcpu_id.
*/
int parse_madt(void)
{
int ret = 0U;
ssize_t size;
struct acpi_table_madt *madt;
struct stat file_state;
int fd = open("/sys/firmware/acpi/tables/APIC", O_RDONLY);
if (fd < 0) {
pr_err("Fail to open sos APIC file!\n");
return -1;
}
if (fstat(fd, &file_state) == -1) {
pr_err("Fail to get apic file state!\n");
close(fd);
return -1;
}
madt = (struct acpi_table_madt *)malloc(file_state.st_size);
size = read(fd, madt, file_state.st_size);
if (size == file_state.st_size) {
ret = local_parse_madt(madt);
} else {
pr_err("Fail to read sos madt info!");
ret = -1;
}
free(madt);
close(fd);
return ret;
}

View File

@ -409,7 +409,11 @@ static int init_guest_lapicid_tbl(struct acrn_platform_info *platform_info, uint
if (pcpu_id < 0)
return -1;
guest_lapicid_tbl[vcpu_id] = lapicid_from_pcpuid(platform_info, pcpu_id);
guest_lapicid_tbl[vcpu_id] = lapicid_from_pcpuid(pcpu_id);
if (guest_lapicid_tbl[vcpu_id] == -1) {
pr_err("Get lapic id fail.\n");
return -1;
}
}
return 0;
}

View File

@ -41,6 +41,11 @@
#define IO_PMTMR 0x0 /* PM Timer is disabled in ACPI */
#define ACPI_MADT_TYPE_LOCAL_APIC 0U
#define ACPI_MADT_TYPE_IOAPIC 1U
#define ACPI_MADT_ENABLED 1U
#define ACPI_MADT_TYPE_LOCAL_APIC_NMI 4U
struct acpi_table_hdr {
/* ASCII table signature */
char signature[4];
@ -62,6 +67,29 @@ struct acpi_table_hdr {
uint32_t asl_compiler_revision;
} __attribute__((packed));
struct acpi_table_madt {
/* Common ACPI table header */
struct acpi_table_hdr header;
/* Physical address of local APIC */
uint32_t address;
uint32_t flags;
} __packed;
struct acpi_subtable_header {
uint8_t type;
uint8_t length;
} __packed;
struct acpi_madt_local_apic {
struct acpi_subtable_header header;
/* ACPI processor id */
uint8_t processor_id;
/* Processor's local APIC id */
uint8_t id;
uint32_t lapic_flags;
} __packed;
/* All dynamic table entry no. */
#define NHLT_ENTRY_NO 8
@ -89,6 +117,7 @@ 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 acrn_platform_info *plat_info, int pcpu_id);
int lapicid_from_pcpuid(int pcpu_id);
int parse_madt(void);
#endif /* _ACPI_H_ */