Skip to content

Commit d8c4e7d

Browse files
peterfangwenlingz
authored andcommitted
dm: add option to boot OVMF from acrn-dm
Use '--ovmf <OVMF image location>' when launching acrn-dm. Tracked-On: #1832 Signed-off-by: Peter Fang <peter.fang@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent 9e97fd0 commit d8c4e7d

File tree

6 files changed

+180
-1
lines changed

6 files changed

+180
-1
lines changed

devicemodel/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ SRCS += core/monitor.c
118118
SRCS += core/sw_load_common.c
119119
SRCS += core/sw_load_bzimage.c
120120
SRCS += core/sw_load_vsbl.c
121+
SRCS += core/sw_load_ovmf.c
121122
SRCS += core/sw_load_elf.c
122123
SRCS += core/smbiostbl.c
123124
SRCS += core/mevent.c

devicemodel/core/main.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ char *vmname;
8383
int guest_ncpus;
8484
char *guest_uuid_str;
8585
char *vsbl_file_name;
86+
char *ovmf_file_name;
8687
char *kernel_file_name;
8788
char *elf_file_name;
8889
uint8_t trusty_enabled;
@@ -158,6 +159,7 @@ usage(int code)
158159
" --dump: show build-in VM configurations\n"
159160
#endif
160161
" --vsbl: vsbl file path\n"
162+
" --ovmf: ovmf file path\n"
161163
" --part_info: guest partition info file path\n"
162164
" --enable_trusty: enable trusty for guest\n"
163165
" --ptdev_no_reset: disable reset check for ptdev\n"
@@ -242,6 +244,9 @@ high_bios_size(void)
242244
{
243245
size_t size = 0;
244246

247+
if (ovmf_file_name)
248+
size = ovmf_image_size();
249+
245250
return roundup2(size, 2 * MB);
246251
}
247252

@@ -715,6 +720,7 @@ sig_handler_term(int signo)
715720

716721
enum {
717722
CMD_OPT_VSBL = 1000,
723+
CMD_OPT_OVMF,
718724
CMD_OPT_PART_INFO,
719725
CMD_OPT_TRUSTY_ENABLE,
720726
CMD_OPT_VIRTIO_POLL_ENABLE,
@@ -752,6 +758,7 @@ static struct option long_options[] = {
752758
{"dump", required_argument, 0, CMD_OPT_DUMP},
753759
#endif
754760
{"vsbl", required_argument, 0, CMD_OPT_VSBL},
761+
{"ovmf", required_argument, 0, CMD_OPT_OVMF},
755762
{"part_info", required_argument, 0, CMD_OPT_PART_INFO},
756763
{"enable_trusty", no_argument, 0,
757764
CMD_OPT_TRUSTY_ENABLE},
@@ -864,11 +871,17 @@ dm_run(int argc, char *argv[])
864871
print_version();
865872
break;
866873
case CMD_OPT_VSBL:
867-
if (acrn_parse_vsbl(optarg) != 0) {
874+
if (high_bios_size() == 0 && acrn_parse_vsbl(optarg) != 0) {
868875
errx(EX_USAGE, "invalid vsbl param %s", optarg);
869876
exit(1);
870877
}
871878
break;
879+
case CMD_OPT_OVMF:
880+
if (!vsbl_file_name && acrn_parse_ovmf(optarg) != 0) {
881+
errx(EX_USAGE, "invalid ovmf param %s", optarg);
882+
exit(1);
883+
}
884+
break;
872885
case CMD_OPT_PART_INFO:
873886
if (acrn_parse_guest_part_info(optarg) != 0) {
874887
errx(EX_USAGE,

devicemodel/core/sw_load_common.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ acrn_sw_load(struct vmctx *ctx)
239239
{
240240
if (vsbl_file_name)
241241
return acrn_sw_load_vsbl(ctx);
242+
else if (ovmf_file_name)
243+
return acrn_sw_load_ovmf(ctx);
242244
else if (kernel_file_name)
243245
return acrn_sw_load_bzimage(ctx);
244246
else if (elf_file_name)

devicemodel/core/sw_load_ovmf.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*-
2+
* Copyright (c) 2018 Intel Corporation
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
* 1. Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
15+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
* ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
18+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24+
* SUCH DAMAGE.
25+
*
26+
*/
27+
28+
#include <string.h>
29+
#include <stdio.h>
30+
#include <stdlib.h>
31+
#include <assert.h>
32+
33+
#include "dm.h"
34+
#include "vmmapi.h"
35+
#include "sw_load.h"
36+
37+
38+
/* ovmf binary layout:
39+
*
40+
* +--------------------------------------------------+ <--OVMF Top
41+
* | |offset: Top - 0x10 (reset vector) |
42+
* + SECFV |------------------------------------+
43+
* | |other |
44+
* +--------------------------------------------------+
45+
* | |
46+
* + FVMAIN_COMPACT +
47+
* | |
48+
* +--------------------------------------------------+
49+
* | |
50+
* + NV data storage +
51+
* | |
52+
* +--------------------------------------------------+
53+
*/
54+
55+
/* ovmf real entry is reset vector, which is (OVMF_TOP - 16) */
56+
#define OVMF_TOP(ctx) (4*GB)
57+
58+
static char ovmf_path[STR_LEN];
59+
static size_t ovmf_size;
60+
61+
extern int init_cmos_vrpmb(struct vmctx *ctx);
62+
63+
size_t
64+
ovmf_image_size(void)
65+
{
66+
return ovmf_size;
67+
}
68+
69+
int
70+
acrn_parse_ovmf(char *arg)
71+
{
72+
int error;
73+
size_t len = strlen(arg);
74+
75+
if (len < STR_LEN) {
76+
strncpy(ovmf_path, arg, len + 1);
77+
error = check_image(ovmf_path, 2 * MB, &ovmf_size);
78+
assert(!error);
79+
80+
ovmf_file_name = ovmf_path;
81+
printf("SW_LOAD: get ovmf path %s, size 0x%lx\n",
82+
ovmf_path, ovmf_size);
83+
return 0;
84+
} else
85+
return -1;
86+
}
87+
88+
static int
89+
acrn_prepare_ovmf(struct vmctx *ctx)
90+
{
91+
FILE *fp;
92+
size_t read;
93+
94+
fp = fopen(ovmf_path, "r");
95+
if (fp == NULL) {
96+
fprintf(stderr,
97+
"SW_LOAD ERR: could not open ovmf file: %s\n",
98+
ovmf_path);
99+
return -1;
100+
}
101+
102+
fseek(fp, 0, SEEK_END);
103+
104+
if (ftell(fp) != ovmf_size) {
105+
fprintf(stderr,
106+
"SW_LOAD ERR: ovmf file changed\n");
107+
fclose(fp);
108+
return -1;
109+
}
110+
111+
fseek(fp, 0, SEEK_SET);
112+
read = fread(ctx->baseaddr + OVMF_TOP(ctx) - ovmf_size,
113+
sizeof(char), ovmf_size, fp);
114+
115+
if (read < ovmf_size) {
116+
fprintf(stderr,
117+
"SW_LOAD ERR: could not read whole partition blob\n");
118+
fclose(fp);
119+
return -1;
120+
}
121+
122+
fclose(fp);
123+
printf("SW_LOAD: partition blob %s size %lu copy to guest 0x%lx\n",
124+
ovmf_path, ovmf_size, OVMF_TOP(ctx) - ovmf_size);
125+
126+
return 0;
127+
}
128+
129+
int
130+
acrn_sw_load_ovmf(struct vmctx *ctx)
131+
{
132+
int ret;
133+
134+
init_cmos_vrpmb(ctx);
135+
136+
ret = acrn_prepare_ovmf(ctx);
137+
138+
if (ret)
139+
return ret;
140+
141+
printf("SW_LOAD: ovmf_entry 0x%lx\n", OVMF_TOP(ctx) - 16);
142+
143+
/* set guest bsp state. Will call hypercall set bsp state
144+
* after bsp is created.
145+
*/
146+
memset(&ctx->bsp_regs, 0, sizeof(struct acrn_set_vcpu_regs));
147+
ctx->bsp_regs.vcpu_id = 0;
148+
149+
/* CR0_ET | CR0_NE */
150+
ctx->bsp_regs.vcpu_regs.cr0 = 0x30U;
151+
ctx->bsp_regs.vcpu_regs.cs_ar = 0x009FU;
152+
ctx->bsp_regs.vcpu_regs.cs_sel = 0xF000U;
153+
ctx->bsp_regs.vcpu_regs.cs_limit = 0xFFFFU;
154+
ctx->bsp_regs.vcpu_regs.cs_base = (OVMF_TOP(ctx) - 16) & 0xFFFF0000UL;
155+
ctx->bsp_regs.vcpu_regs.rip = (OVMF_TOP(ctx) - 16) & 0xFFFFUL;
156+
157+
return 0;
158+
}

devicemodel/include/dm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ extern int guest_ncpus;
3838
extern char *guest_uuid_str;
3939
extern uint8_t trusty_enabled;
4040
extern char *vsbl_file_name;
41+
extern char *ovmf_file_name;
4142
extern char *kernel_file_name;
4243
extern char *elf_file_name;
4344
extern char *vmname;

devicemodel/include/sw_load.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,14 @@ struct e820_entry {
5555
extern const struct e820_entry e820_default_entries[NUM_E820_ENTRIES];
5656
extern int with_bootargs;
5757

58+
size_t ovmf_image_size(void);
59+
5860
int acrn_parse_kernel(char *arg);
5961
int acrn_parse_ramdisk(char *arg);
6062
int acrn_parse_bootargs(char *arg);
6163
int acrn_parse_gvtargs(char *arg);
6264
int acrn_parse_vsbl(char *arg);
65+
int acrn_parse_ovmf(char *arg);
6366
int acrn_parse_elf(char *arg);
6467
int acrn_parse_guest_part_info(char *arg);
6568
char *get_bootargs(void);
@@ -73,6 +76,7 @@ int add_e820_entry(struct e820_entry *e820, int len, uint64_t start,
7376
int acrn_sw_load_bzimage(struct vmctx *ctx);
7477
int acrn_sw_load_elf(struct vmctx *ctx);
7578
int acrn_sw_load_vsbl(struct vmctx *ctx);
79+
int acrn_sw_load_ovmf(struct vmctx *ctx);
7680
int acrn_sw_load(struct vmctx *ctx);
7781
#endif
7882

0 commit comments

Comments
 (0)