Skip to content

Commit 6367650

Browse files
zjin7wenlingz
authored andcommitted
hv: debug: add the hypervisor NPK log
The npk_log is a log destination for the hypervisor, similar to the console_log and the mem_log. It can be enabled/disabled/configured by the SOS kernel via the hypercall HC_SETUP_HV_NPK_LOG. The configuration includes: 1. Set the MMIO base address of the reserved NPK master. 2. Set the log level of the hypervisor NPK log. After that, the npk_log can be enabled to write the hypervisor logs to the MMIO address of the reserved NPK master with a simple header. Signed-off-by: Zhi Jin <zhi.jin@intel.com> Signed-off-by: Liu, Xiaojing <xiaojing.liu@intel.com> Reviewed-by: CHEN Gang <gang.c.chen@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent 3c6df9b commit 6367650

File tree

8 files changed

+183
-13
lines changed

8 files changed

+183
-13
lines changed

hypervisor/arch/x86/Kconfig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ config LOG_BUF_SIZE
5050

5151
config LOG_DESTINATION
5252
int "Bitmap of consoles where logs are printed"
53-
default 3
53+
default 7
5454

5555
config CPU_UP_TIMEOUT
5656
int "Timeout in ms when bringing up secondary CPUs"
@@ -99,6 +99,10 @@ config MEM_LOGLEVEL_DEFAULT
9999
int "Default loglevel in memory"
100100
default 5
101101

102+
config NPK_LOGLEVEL_DEFAULT
103+
int "Default loglevel for the hypervisor NPK log"
104+
default 5
105+
102106
config LOW_RAM_SIZE
103107
hex "Size of the low RAM region"
104108
default 0x00010000

hypervisor/debug/logmsg.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,17 @@ void do_logmsg(uint32_t severity, const char *fmt, ...)
8989
uint16_t pcpu_id;
9090
bool do_console_log;
9191
bool do_mem_log;
92+
bool do_npk_log;
9293
char *buffer;
9394

9495
do_console_log = (((logmsg.flags & LOG_FLAG_STDOUT) != 0U) &&
9596
(severity <= console_loglevel));
9697
do_mem_log = (((logmsg.flags & LOG_FLAG_MEMORY) != 0U) &&
9798
(severity <= mem_loglevel));
99+
do_npk_log = ((logmsg.flags & LOG_FLAG_NPK) != 0U &&
100+
(severity <= npk_loglevel));
98101

99-
if (!do_console_log && !do_mem_log) {
102+
if (!do_console_log && !do_mem_log && !do_npk_log) {
100103
return;
101104
}
102105

@@ -124,6 +127,10 @@ void do_logmsg(uint32_t severity, const char *fmt, ...)
124127
- strnlen_s(buffer, LOG_MESSAGE_MAX_SIZE), fmt, args);
125128
va_end(args);
126129

130+
/* Check if flags specify to output to NPK */
131+
if (do_npk_log)
132+
npk_log_write(buffer, strnlen_s(buffer, LOG_MESSAGE_MAX_SIZE));
133+
127134
/* Check if flags specify to output to stdout */
128135
if (do_console_log) {
129136
spinlock_irqsave_obtain(&(logmsg.lock), &rflags);

hypervisor/debug/npk_log.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright (C) 2018 Intel Corporation.
3+
* SPDX-License-Identifier: BSD-3-Clause
4+
*/
5+
6+
#include <hypervisor.h>
7+
8+
static int npk_log_enabled, npk_log_setup_ref;
9+
static uint64_t base;
10+
11+
static inline int npk_write(const char *value, void *addr, size_t sz)
12+
{
13+
int ret = -1;
14+
15+
if (sz >= 8U) {
16+
mmio_write64(*(uint64_t *)value, addr);
17+
ret = 8;
18+
} else if (sz >= 4U) {
19+
mmio_write32(*(uint32_t *)value, addr);
20+
ret = 4;
21+
} else if (sz >= 2U) {
22+
mmio_write16(*(uint16_t *)value, addr);
23+
ret = 2;
24+
} else if (sz >= 1U) {
25+
mmio_write8(*(uint8_t *)value, addr);
26+
ret = 1;
27+
}
28+
29+
return ret;
30+
}
31+
32+
void npk_log_setup(struct hv_npk_log_param *param)
33+
{
34+
int i;
35+
36+
pr_info("HV_NPK_LOG: cmd %d param 0x%llx\n", param->cmd,
37+
param->mmio_addr);
38+
39+
param->res = HV_NPK_LOG_RES_KO;
40+
if (atomic_inc_return(&npk_log_setup_ref) > 1)
41+
goto out;
42+
43+
switch (param->cmd) {
44+
case HV_NPK_LOG_CMD_CONF:
45+
if (param->mmio_addr || param->loglevel != 0xffffU)
46+
param->res = HV_NPK_LOG_RES_OK;
47+
case HV_NPK_LOG_CMD_ENABLE:
48+
if (param->mmio_addr)
49+
base = param->mmio_addr;
50+
if (param->loglevel != 0xffffU)
51+
npk_loglevel = param->loglevel;
52+
if (base && param->cmd == HV_NPK_LOG_CMD_ENABLE) {
53+
if (!npk_log_enabled)
54+
for (i = 0; i < phys_cpu_num; i++)
55+
per_cpu(npk_log_ref, i) = 0;
56+
param->res = HV_NPK_LOG_RES_OK;
57+
npk_log_enabled = 1;
58+
}
59+
break;
60+
case HV_NPK_LOG_CMD_DISABLE:
61+
npk_log_enabled = 0;
62+
param->res = HV_NPK_LOG_RES_OK;
63+
break;
64+
case HV_NPK_LOG_CMD_QUERY:
65+
param->res = npk_log_enabled ? HV_NPK_LOG_RES_ENABLED :
66+
HV_NPK_LOG_RES_DISABLED;
67+
param->loglevel = npk_loglevel;
68+
param->mmio_addr = base;
69+
break;
70+
default:
71+
pr_err("HV_NPK_LOG: unknown cmd (%d)\n", param->cmd);
72+
break;
73+
}
74+
75+
out:
76+
pr_info("HV_NPK_LOG: result %d\n", param->res);
77+
atomic_dec32((uint32_t *)&npk_log_setup_ref);
78+
}
79+
80+
void npk_log_write(const char *buf, size_t buf_len)
81+
{
82+
uint32_t cpu_id = get_cpu_id();
83+
struct npk_chan *channel = (struct npk_chan *)base;
84+
const char *p = buf;
85+
int sz;
86+
uint32_t ref;
87+
size_t len;
88+
89+
if (!npk_log_enabled || !channel)
90+
return;
91+
92+
/* calculate the channel offset based on cpu_id and npk_log_ref */
93+
ref = (atomic_inc_return((int *)&per_cpu(npk_log_ref, cpu_id)) - 1)
94+
& HV_NPK_LOG_REF_MASK;
95+
channel += (cpu_id << HV_NPK_LOG_REF_SHIFT) + ref;
96+
len = min(buf_len, HV_NPK_LOG_MAX);
97+
mmio_write32(HV_NPK_LOG_HDR, &(channel->DnTS));
98+
mmio_write16(len, &(channel->Dn));
99+
100+
for (sz = 0; sz >= 0; p += sz)
101+
sz = npk_write(p, &(channel->Dn), buf + len - p);
102+
103+
mmio_write8(0U, &(channel->FLAG));
104+
105+
atomic_dec32(&per_cpu(npk_log_ref, cpu_id));
106+
}

hypervisor/debug/shell.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ static struct shell_cmd shell_cmds[] = {
128128
/* The initial log level*/
129129
uint32_t console_loglevel = CONFIG_CONSOLE_LOGLEVEL_DEFAULT;
130130
uint32_t mem_loglevel = CONFIG_MEM_LOGLEVEL_DEFAULT;
131+
uint32_t npk_loglevel = CONFIG_NPK_LOGLEVEL_DEFAULT;
131132

132133
static struct shell hv_shell;
133134
static struct shell *p_shell = &hv_shell;
@@ -872,17 +873,21 @@ static int shell_loglevel(int argc, char **argv)
872873
{
873874
char str[MAX_STR_SIZE] = {0};
874875

875-
if (argc == 1) {
876-
snprintf(str, MAX_STR_SIZE,
877-
"console_loglevel: %u, mem_loglevel: %u\r\n",
878-
console_loglevel, mem_loglevel);
879-
shell_puts(str);
880-
} else if (argc == 2) {
881-
console_loglevel = atoi(argv[1]);
882-
} else if (argc == 3) {
883-
console_loglevel = atoi(argv[1]);
876+
switch (argc) {
877+
case 4:
878+
npk_loglevel = atoi(argv[3]);
879+
case 3:
884880
mem_loglevel = atoi(argv[2]);
885-
} else {
881+
case 2:
882+
console_loglevel = atoi(argv[1]);
883+
break;
884+
case 1:
885+
snprintf(str, MAX_STR_SIZE, "console_loglevel: %u, "
886+
"mem_loglevel: %u, npk_loglevel: %u\r\n",
887+
console_loglevel, mem_loglevel, npk_loglevel);
888+
shell_puts(str);
889+
break;
890+
default:
886891
return -EINVAL;
887892
}
888893

hypervisor/debug/shell_priv.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ struct shell {
9090
#define SHELL_CMD_LOGDUMP_HELP "log buffer dump"
9191

9292
#define SHELL_CMD_LOG_LVL "loglevel"
93-
#define SHELL_CMD_LOG_LVL_PARAM "[console_loglevel] [mem_loglevel]"
93+
#define SHELL_CMD_LOG_LVL_PARAM "[<console_loglevel> [<mem_loglevel> " \
94+
"[npk_loglevel]]]"
9495
#define SHELL_CMD_LOG_LVL_HELP "get(para is NULL), or set loglevel [0-6]"
9596

9697
#define SHELL_CMD_CPUID "cpuid"

hypervisor/include/arch/x86/per_cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct per_cpu_region {
2323
uint64_t *sbuf[ACRN_SBUF_ID_MAX];
2424
uint64_t vmexit_cnt[64];
2525
uint64_t vmexit_time[64];
26+
uint32_t npk_log_ref;
2627
#endif
2728
uint64_t irq_count[NR_IRQS];
2829
uint64_t softirq_pending;

hypervisor/include/debug/logmsg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
/* Logging flags */
2020
#define LOG_FLAG_STDOUT 0x00000001U
2121
#define LOG_FLAG_MEMORY 0x00000002U
22+
#define LOG_FLAG_NPK 0x00000004U
2223
#define LOG_ENTRY_SIZE 80
2324
/* Size of buffer used to store a message being logged,
2425
* should align to LOG_ENTRY_SIZE.
@@ -29,6 +30,7 @@
2930

3031
extern uint32_t console_loglevel;
3132
extern uint32_t mem_loglevel;
33+
extern uint32_t npk_loglevel;
3234
void init_logmsg(__unused uint32_t mem_size, uint32_t flags);
3335
void print_logmsg_buffer(uint16_t pcpu_id);
3436
void do_logmsg(uint32_t severity, const char *fmt, ...);

hypervisor/include/debug/npk_log.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,51 @@
66
#ifndef NPK_LOG_H
77
#define NPK_LOG_H
88

9+
#define HV_NPK_LOG_REF_SHIFT 2U
10+
#define HV_NPK_LOG_REF_MASK ((1U << HV_NPK_LOG_REF_SHIFT) - 1U)
11+
12+
#define HV_NPK_LOG_MAX 1024U
13+
#define HV_NPK_LOG_HDR 0x01000242U
14+
15+
enum {
16+
HV_NPK_LOG_CMD_INVALID,
17+
HV_NPK_LOG_CMD_CONF,
18+
HV_NPK_LOG_CMD_ENABLE,
19+
HV_NPK_LOG_CMD_DISABLE,
20+
HV_NPK_LOG_CMD_QUERY,
21+
};
22+
23+
enum {
24+
HV_NPK_LOG_RES_INVALID,
25+
HV_NPK_LOG_RES_OK,
26+
HV_NPK_LOG_RES_KO,
27+
HV_NPK_LOG_RES_ENABLED,
28+
HV_NPK_LOG_RES_DISABLED,
29+
};
30+
31+
struct hv_npk_log_param;
32+
33+
struct npk_chan {
34+
uint64_t Dn;
35+
uint64_t DnM;
36+
uint64_t DnTS;
37+
uint64_t DnMTS;
38+
uint64_t USER;
39+
uint64_t USER_TS;
40+
uint32_t FLAG;
41+
uint32_t FLAG_TS;
42+
uint32_t MERR;
43+
uint32_t unused;
44+
} __packed;
45+
46+
#ifdef HV_DEBUG
47+
void npk_log_setup(struct hv_npk_log_param *param);
48+
void npk_log_write(const char *buf, size_t len);
49+
#else
950
static inline void npk_log_setup(__unused struct hv_npk_log_param *param)
1051
{}
52+
static inline void npk_log_write(__unused const char *buf, __unused size_t len)
53+
{}
54+
#endif /* HV_DEBUG */
1155

1256
#endif /* NPK_LOG_H */

0 commit comments

Comments
 (0)