[PATCH 3/3] HV: Passthru ABL.timestamps and ABL.consbuf to SOS


Kaige Fu
 

From: Kaige Fu <kaige.fu@...>

BTM tool will read ABL log from ABL.timestamps addr
and number of entry and ABL.consbuf addr. So, passthru
them to SOS.

Signed-off-by: Kaige Fu <kaige.fu@...>
---
common/vm_load.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 86 insertions(+), 6 deletions(-)

diff --git a/common/vm_load.c b/common/vm_load.c
index af4512c..48edf51 100644
--- a/common/vm_load.c
+++ b/common/vm_load.c
@@ -35,6 +35,9 @@
#include <bsp_extern.h>
#include <hv_debug.h>
#include <zeropage.h>
+#include <multiboot.h>
+
+#define MAX_CMD_LEN 64

static uint32_t create_e820_table(struct e820_entry *_e820)
{
@@ -129,6 +132,61 @@ int load_guest(struct vm *vm, struct vcpu *vcpu)
return ret;
}

+static int parse_abl_consbuf(uint64_t *addr)
+{
+ const char consbuf[] = "ABL.consbuf=";
+ struct multiboot_info *mbi;
+ char *cmdline;
+ char *start;
+ size_t prefix_len = strnlen_s(consbuf, MAX_CMD_LEN);
+
+ if (boot_regs[0] != MULTIBOOT_INFO_MAGIC) {
+ pr_info("%s, No multiboot info found", __func__);
+ return -EINVAL;
+ }
+
+ mbi = (struct multiboot_info *)((uint64_t)boot_regs[1]);
+ if (mbi && (mbi->mi_flags & 0x4)) {
+ cmdline = (char *)HPA2HVA((uint64_t)mbi->mi_cmdline);
+ start = strnstr_s(cmdline, consbuf, MAX_CMD_LEN);
+ *addr = strtoul(start + prefix_len, NULL, 16);
+ return 0;
+ } else {
+ pr_info("%s, No valid cmdline from ABL", __func__);
+ }
+ return -1;
+}
+
+static int parse_abl_timestamp(uint64_t *addr, uint64_t *entry)
+{
+ const char timestamps[] = "ABL.timestamps=";
+ struct multiboot_info *mbi;
+ char *cmdline;
+ char *start, *endptr;
+ size_t prefix_len = strnlen_s(timestamps, MAX_CMD_LEN);
+
+ if (boot_regs[0] != MULTIBOOT_INFO_MAGIC) {
+ pr_info("%s, No multiboot info found", __func__);
+ return -EINVAL;
+ }
+
+ mbi = (struct multiboot_info *)((uint64_t)boot_regs[1]);
+ if (mbi && (mbi->mi_flags & 0x4)) {
+ cmdline = (char *)HPA2HVA((uint64_t)mbi->mi_cmdline);
+ start = strnstr_s(cmdline, timestamps, MAX_CMD_LEN);
+
+ /* Get count of entry for timestamps */
+ *entry = strtoul(start + prefix_len, &endptr, 10);
+
+ /* timestamps format: ABL.timestamps=#entry@addr */
+ *addr = strtoul(endptr + 1, NULL, 16);
+ return 0;
+ } else {
+ pr_info("%s, No valid cmdline from ABL", __func__);
+ }
+ return -1;
+}
+
int general_sw_loader(struct vm *vm, struct vcpu *vcpu)
{
int ret = 0;
@@ -138,6 +196,10 @@ int general_sw_loader(struct vm *vm, struct vcpu *vcpu)
char dyn_bootargs[100] = {0};
uint32_t kernel_entry_offset;
struct zero_page *zeropage;
+ /* Address of timestamps and consbuf passed from ABL */
+ uint64_t ts_addr, consbuf_addr;
+ uint64_t ts_cnt; /* Count of timestamps passed from ABL */
+ size_t len, offset = 0;

ASSERT(vm != NULL, "Incorrect argument");

@@ -190,13 +252,14 @@ int general_sw_loader(struct vm *vm, struct vcpu *vcpu)
#ifdef CONFIG_CMA
/* add "cma=XXXXM@0xXXXXXXXX" to cmdline*/
if (is_vm0(vm) && (e820_mem.max_ram_blk_size > 0)) {
- snprintf(dyn_bootargs, 100, " cma=%dM@0x%llx\n",
+ len = snprintf(dyn_bootargs, 100, " cma=%dM@0x%llx\n",
(e820_mem.max_ram_blk_size >> 20),
e820_mem.max_ram_blk_base);
/* Delete '\n' at the end of cmdline */
strcpy_s((char *)hva
- +vm->sw.linux_info.bootargs_size - 1,
+ +vm->sw.linux_info.bootargs_size + offset - 1,
100, dyn_bootargs);
+ offset = offset + len - 1;
}
#else
/* add "hugepagesz=1G hugepages=x" to cmdline for 1G hugepage
@@ -214,17 +277,34 @@ int general_sw_loader(struct vm *vm, struct vcpu *vcpu)
3;
#endif
if (reserving_1g_pages > 0) {
- snprintf(dyn_bootargs, 100,
- " hugepagesz=1G hugepages=%d\n",
- reserving_1g_pages);
+ len = snprintf(dyn_bootargs, 100,
+ " hugepagesz=1G hugepages=%d\n",
+ reserving_1g_pages);
/* Delete '\n' at the end of cmdline */
strcpy_s((char *)hva
- +vm->sw.linux_info.bootargs_size - 1,
+ +vm->sw.linux_info.bootargs_size + offset - 1,
100, dyn_bootargs);
+ offset = offset + len - 1;
}
}
#endif

+ /* Passthrough ABL timestamps and log buf cmdline to SOS */
+ if (!parse_abl_timestamp(&ts_addr, &ts_cnt)
+ && !parse_abl_consbuf(&consbuf_addr)) {
+ len = snprintf(dyn_bootargs, 100,
+ " ABL.timestamps=%llu@0x%llx ABL.consbuf=0x%llx",
+ ts_cnt, ts_addr, consbuf_addr);
+
+ /* Delete '\n' at the end of cmdline */
+ strcpy_s((char *)hva
+ + vm->sw.linux_info.bootargs_size + offset - 1,
+ 100, dyn_bootargs);
+ offset = offset + len - 1;
+ } else {
+ pr_info("%s, Parse ABL timestamps or consbuf failed", __func__);
+ }
+
/* Check if a RAM disk is present with Linux guest */
if (vm->sw.linux_info.ramdisk_src_addr) {
/* Get host-physical address for guest RAM disk */
--
2.7.4

Join acrn-dev@lists.projectacrn.org to automatically receive all group messages.