[PATCH 2/6] x86: Remove static linking of guest fdt in Xvisor binary

29 views
Skip to first unread message

hcha...@xvisor-x86.org

unread,
May 19, 2022, 12:31:51 AM5/19/22
to xvisor...@googlegroups.com, Himanshu Chauhan
From: Himanshu Chauhan <hcha...@xvisor-x86.org>

Removed static linking of guest fdt in xvisor binary
Update the README on how to load the fdt
Remove some other unused files relating to xvisor disk creation.

Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>
---
.../board/x86_64_generic/dts/defconfig.dts | 2 -
.../{x86_64_guest.dtsi => amd_guest.dts} | 0
tests/x86/README | 25 +
tests/x86/create_hdd_partitions.expt | 36 --
tests/x86/guest_init.cmd | 13 -
tests/x86/hdd.layout | 7 -
tests/x86/intel-guest.dts | 225 +++++++++
tests/x86/lomount.c | 435 ------------------
.../one_guest.xscript} | 7 +-
9 files changed, 252 insertions(+), 498 deletions(-)
rename arch/x86/guests/{x86_64_guest.dtsi => amd_guest.dts} (100%)
create mode 100644 tests/x86/README
delete mode 100755 tests/x86/create_hdd_partitions.expt
delete mode 100644 tests/x86/guest_init.cmd
delete mode 100644 tests/x86/hdd.layout
create mode 100644 tests/x86/intel-guest.dts
delete mode 100644 tests/x86/lomount.c
rename tests/x86/{scripts/guest_init.cmd => xscripts/one_guest.xscript} (56%)

diff --git a/arch/x86/board/x86_64_generic/dts/defconfig.dts b/arch/x86/board/x86_64_generic/dts/defconfig.dts
index 37d6ce2b..a314225f 100644
--- a/arch/x86/board/x86_64_generic/dts/defconfig.dts
+++ b/arch/x86/board/x86_64_generic/dts/defconfig.dts
@@ -82,5 +82,3 @@
"vfs run /system/init/startup";
};
};
-
-/include/ "../../../guests/x86_64_guest.dtsi"
diff --git a/arch/x86/guests/x86_64_guest.dtsi b/arch/x86/guests/amd_guest.dts
similarity index 100%
rename from arch/x86/guests/x86_64_guest.dtsi
rename to arch/x86/guests/amd_guest.dts
diff --git a/tests/x86/README b/tests/x86/README
new file mode 100644
index 00000000..5546bd15
--- /dev/null
+++ b/tests/x86/README
@@ -0,0 +1,25 @@
+
+1. Creating an initrd for Xvisor
+
+# mounting xvisor IDE disk on host
+Run the following command on the disk that was create using qemu command.
+This command should attach a loopback device to the disk and print the
+name of the loopback device.
+
+ $ sudo losetup --partscan --find --show xvisor-hd.disk
+ $ /dev/loop41 <<<< This is the loopback device attached to xvisor disk.
+
+We need to mount this on host
+ $ sudo mount /dev/<loopback device> <mountpoint>
+
+After that run the following commands:
+ $ mkdir -p <mountpoint>/system
+ $ mkdir -p <mountpoint>/guests/common
+ $ mkdir -p <mountpoint>/guests/intel
+ $ dtc -q -I dts -O dtb -o <mountpoint>/guests/intel/intel-guest.dtb ./tests/x86/intel-guest.dts
+ $ cp <seabiosdir>/out/bios.bin <mountpoint>/guests/common/bios.bin
+ $ cp tests/x86/xscripts/one_guest.xscript <mountpoint>/guests/intel/guest_create.xscript
+
+Now, the disk can be unmounted and the loopback device be detached.
+ $ umount <mountpoint>
+ $ sudo losetup -d /dev/<loopbackdevice>
diff --git a/tests/x86/create_hdd_partitions.expt b/tests/x86/create_hdd_partitions.expt
deleted file mode 100755
index b61b31e5..00000000
--- a/tests/x86/create_hdd_partitions.expt
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/expect -f
-
-set diskimage [lindex $argv 0];
-
-spawn fdisk $diskimage
-
-expect {
- "Command (m for help):" {
- send "n\r\n"
- expect {
- "Select (default p):" {
- send "p\r"
- expect {
- "Partition number " {
- send "1\r"
- expect {
- "First sector " {
- send "\r"
- expect {
- "Last sector, " {
- send "\r"
- expect {
- "Command (m for help):" {
- send "w\r"
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/tests/x86/guest_init.cmd b/tests/x86/guest_init.cmd
deleted file mode 100644
index b12d614e..00000000
--- a/tests/x86/guest_init.cmd
+++ /dev/null
@@ -1,13 +0,0 @@
-# Create the guest device tree node by copying from host.
-devtree node copy /guests guest0 /templates/x86_64_generic
-
-#Create the guest.
-guest create guest0
-
-#Copy guest BIOS
-#vfs guest_load guest0 0x80000 /coreboot.rom
-#vfs guest_load guest0 0xfff80000 /coreboot.rom
-
-#Uncomment below for sample bios
-vfs guest_load guest0 0x10000 /bios.rom
-#vfs guest_load guest0 0xfff10000 /bios.rom
diff --git a/tests/x86/hdd.layout b/tests/x86/hdd.layout
deleted file mode 100644
index 83a5987b..00000000
--- a/tests/x86/hdd.layout
+++ /dev/null
@@ -1,7 +0,0 @@
-# partition table of xvisor-hd.disk
-unit: sectors
-
-xvisor-hd.disk1 : start= 2048, size= 63488, Id=83
-xvisor-hd.disk2 : start= 0, size= 0, Id= 0
-xvisor-hd.disk3 : start= 0, size= 0, Id= 0
-xvisor-hd.disk4 : start= 0, size= 0, Id= 0
diff --git a/tests/x86/intel-guest.dts b/tests/x86/intel-guest.dts
new file mode 100644
index 00000000..4de9382b
--- /dev/null
+++ b/tests/x86/intel-guest.dts
@@ -0,0 +1,225 @@
+
+/dts-v1/;
+
+/ {
+ model = "x86_64";
+ device_type = "guest";
+ guest_asid = <1>;
+
+ vcpu_template {
+ device_type = "vcpu";
+ compatible = "x86_64,generic";
+ start_pc = <0xfff0>;
+ poweroff;
+ };
+
+ aspace {
+ guest_irq_count = <256>;
+ /*
+ * Memory Regions
+ *
+ * 0 - 640 KiB => Accessible RAM (old DOS area)
+ * 640 - 768 KiB => Legacy Video card memory
+ * 768 - 896 KiB => Expansion area (Old peripheral card ROM)
+ * 896 - 960 KiB => Extended System BIOS (SeaBIOS links here 0xexxxx)
+ * 960 - 1 MiB => System BIOS
+ * 1MiB - 4GiB-16bytes => RAM (High Memory)
+ * 4GiB-16 byte => RESET VECTOR (0xFFFFFFF0) This jumps to System BIOS (normal/extented).
+ */
+
+ /*
+ * 0x00000000 0x000003FF 1 KiB Real Mode IVT (Interrupt Vector Table)
+ * 0x00000400 0x000004FF 256 bytes BDA (BIOS data area)
+ * 0x00000500 0x00007BFF 30 KiB Conventional memory
+ * 0x00007C00 0x00007DFF 512 bytes OS BootSector
+ * 0x00007E00 0x0007FFFF 480.5 KiB Conventional memory
+ * 0x00080000 0x0009FBFF ~120 KiB Conventional memory
+ * 0x0009FC00 0x0009FFFF 1 KiB EBDA (Extended BIOS Data Area)
+ */
+ mem0 {
+ manifest_type = "real";
+ address_type = "memory";
+ guest_physical_addr = <0x00000000>;
+ physical_size = <0xA0000>;
+ device_type = "alloced_ram";
+ align_order = <12>; /* 4K alignment */
+ };
+
+ video0 {
+ manifest_type = "virtual";
+ address_type = "memory";
+ guest_physical_addr = <0xA0000>;
+ physical_size = <0x20000>;
+ device_type = "alloced_ram";
+ align_order = <12>;
+ };
+
+ /* ROMs for old peripheral cards */
+ expansion_rom {
+ manifest_type = "real";
+ address_type = "memory";
+ guest_physical_addr = <0xC0000>;
+ physical_size = <0x20000>;
+ device_type = "alloced_rom";
+ align_order = <12>;
+ };
+
+ /* Map in protected mode where BIOS will jump, Total 128K for BIOS */
+ extended_system_bios {
+ manifest_type = "real";
+ address_type = "memory";
+ guest_physical_addr = <0xE0000>;
+ physical_size = <0x10000>; /* 64K extended BIOS */
+ device_type = "alloced_rom";
+ align_order = <12>; /* 4K aligns */
+ };
+
+ system_bios {
+ manifest_type = "real";
+ address_type = "memory";
+ guest_physical_addr = <0xF0000>;
+ physical_size = <0x10000>; /* 64K system BIOS */
+ device_type = "alloced_rom";
+ align_order = <12>;
+ };
+
+ uart0 {
+ device_type = "serial";
+ compatible = "ns16550a";
+ manifest_type = "virtual";
+ address_type = "io";
+ guest_physical_addr = <0x2f8>;
+ physical_size = <0x8>;
+ fifo_size = <64>;
+ interrupts = <12>;
+ };
+
+ i440fx0 {
+ device_type = "pci-host-controller";
+ compatible = "i440fx";
+ manifest_type = "virtual";
+ address_type = "io";
+ guest_physical_addr = <0xcf8>;
+ physical_size = <8>;
+ nr_buses = <1>;
+ bus_start_id = <0>;
+ no-child-probe;
+
+ pci_bus0 {
+ devices {
+ virtio-blk0 {
+ device_type = "virtio";
+ compatible = "virtio,pci";
+ manifest_type = "virtual";
+ address_type = "io";
+ device_id = <2>;
+
+ bars {
+ bar0@virtio-blk0 {
+ manifest_type = "virtual";
+ address_type = "io";
+ device_type = "virtio";
+ compatible = "virtio,pci,bar";
+ barnum = <0>;
+ virtio_type = <2>;
+ guest_physical_addr = <0x610>;
+ physical_size = <0x100>;
+ blkdev = "hda0";
+ interrupts = <55>;
+ };
+ };
+ };
+ };
+ };
+ };
+
+ mc146818@0 {
+ device_type = "rtc";
+ compatible = "motorola,mc146818";
+ manifest_type = "virtual";
+ address_type = "io";
+ guest_physical_addr = <0x70>;
+ physical_size = <2>;
+ interrupts = <8>;
+ };
+
+ i8259@0 {
+ device_type = "pic";
+ compatible = "i8259a";
+ manifest_type = "virtual";
+ address_type = "io";
+ guest_physical_addr = <0x20>;
+ physical_size = <2>;
+ base_irq = <0>;
+ num_irq = <8>;
+ child_pic = <1>;
+ parent_irq = <256>; /* vector 16 to be presented on LAPIC */
+ master = <1>;
+ };
+
+ i8259@1 {
+ device_type = "pic";
+ compatible = "i8259a";
+ manifest_type = "virtual";
+ address_type = "io";
+ guest_physical_addr = <0xa0>;
+ physical_size = <2>;
+ base_irq = <8>;
+ num_irq = <8>;
+ child_pic = <1>;
+ parent_irq = <2>;
+ };
+
+/*
+ lapic {
+ device_type = "pic";
+ compatible = "lapic";
+ manifest_type = "virtual";
+ address_type = "memory";
+ guest_physical_addr = <0xfee00000>;
+ physical_size = <0x1000>;
+ base_irq = <16>;
+ num_irq = <240>;
+ };
+*/
+ hpet {
+ device_type = "hpet";
+ compatible = "hpet";
+ manifest_type = "virtual";
+ address_type = "memory";
+ guest_physical_addr = <0xfed00000>;
+ physical_size = <0x1000>;
+ id = <0>;
+ num_timers = <2>;
+ };
+
+ i8254@0 {
+ device_type = "pit";
+ compatible = "i8253,i8254";
+ manifest_type = "virtual";
+ address_type = "io";
+ guest_physical_addr = <0x40>;
+ physical_size = <4>;
+ interrupts = <0>;
+ };
+
+ ps2devices@0 {
+ device_type = "input";
+ compatible = "i8042,keyboard,mouse";
+ manifest_type = "virtual";
+ address_type = "io";
+ guest_physical_addr = <0x60>;
+ physical_size = <4>;
+ interrupts = <1 12>;
+ };
+
+ fw_cfg@0 {
+ device_type = "misc";
+ compatible = "fwcfg";
+ manifest_type = "virtual";
+ address_type = "io";
+ guest_physical_addr = <0x0510>;
+ physical_size = <0x2>;
+ };
+ };
+};
diff --git a/tests/x86/lomount.c b/tests/x86/lomount.c
deleted file mode 100644
index 74859e67..00000000
--- a/tests/x86/lomount.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * lomount - utility to mount partitions in a hard disk image
- *
- * Copyright (c) 2004 Jim Brown
- * Copyright (c) 2004 Brad Watson
- * Copyright (c) 2004 Mulyadi Santosa
- * Major rewrite by Tristan Gingold:
- * - Handle GPT partitions
- * - Handle large files
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/*
- * Return code:
- *
- * bit 7 set: lomount wrapper failed
- * bit 7 clear: lomount wrapper ok; mount's return code in low 7 bits
- * 0 success
- */
-
-enum
-{
- ERR_USAGE = 0x80, // Incorrect usage
- ERR_PART_PARSE, // Failed to parse partition table
- ERR_NO_PART, // No such partition
- ERR_NO_EPART, // No such extended partition
- ERR_MOUNT // Other failure of mount command
-};
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/wait.h>
-#include <errno.h>
-
-#define BUF 4096
-
-#define SECSIZE 512
-
-struct pentry
-{
- unsigned char bootable;
- unsigned char start_head;
- unsigned int start_cylinder;
- unsigned char start_sector;
- unsigned char system;
- unsigned char end_head;
- unsigned int end_cylinder;
- unsigned char end_sector;
- unsigned long long start_sector_abs;
- unsigned long long no_of_sectors_abs;
-};
-
-static void
-disp_entry (struct pentry *p)
-{
- printf ("%10llu - %10llu: %02x %x\n",
- SECSIZE * p->start_sector_abs,
- SECSIZE * (p->start_sector_abs + p->no_of_sectors_abs - 1),
- p->system,
- p->bootable);
-}
-
-static unsigned long
-read_le4 (unsigned char *p)
-{
- return (unsigned long) p[0]
- | ((unsigned long) p[1] << 8)
- | ((unsigned long) p[2] << 16)
- | ((unsigned long) p[3] << 24);
-}
-
-static unsigned long long
-read_le8 (unsigned char *p)
-{
- return (unsigned long long) p[0]
- | ((unsigned long long) p[1] << 8)
- | ((unsigned long long) p[2] << 16)
- | ((unsigned long long) p[3] << 24)
- | ((unsigned long long) p[4] << 32)
- | ((unsigned long long) p[5] << 40)
- | ((unsigned long long) p[6] << 48)
- | ((unsigned long long) p[7] << 56);
-}
-
-/* Return true if the partition table is a GPT protective MBR. */
-static int
-check_gpt (struct pentry *part, int nbr_part)
-{
- if (nbr_part != 4)
- return 0;
- if (part[0].system == 0xee
- && part[1].no_of_sectors_abs == 0
- && part[2].no_of_sectors_abs == 0
- && part[3].no_of_sectors_abs == 0)
- return 1;
- return 0;
-}
-
-static int
-load_gpt (const char *diskimage, struct pentry *parttbl[])
-{
- FILE *fd;
- size_t size;
- int fail = -1;
- unsigned char data[SECSIZE];
- unsigned long long entries_lba;
- unsigned long entry_size;
- struct pentry *part;
- int nbr_part;
- unsigned long long off;
- int i;
-
- fd = fopen(diskimage, "r");
- if (fd == NULL)
- {
- perror(diskimage);
- goto done;
- }
- fseeko (fd, SECSIZE, SEEK_SET);
- size = fread (&data, 1, sizeof(data), fd);
- if (size < (size_t)sizeof(data))
- {
- fprintf(stderr, "Could not read the GPT header of %s.\n",
- diskimage);
- goto done;
- }
-
- if (memcmp (data, "EFI PART", 8) != 0)
- {
- fprintf (stderr, "Bad GPT signature\n");
- goto done;
- }
-
- entries_lba = read_le8 (&data[72]);
- nbr_part = read_le4 (&data[80]);
- entry_size = read_le4 (&data[84]);
-
-#ifdef DEBUG
- fprintf(stderr, "lba entries: %llu, nbr_part: %u, entry_size: %lu\n",
- entries_lba, nbr_part, entry_size);
-#endif
- part = malloc (nbr_part * sizeof (struct pentry));
- if (part == NULL)
- {
- fprintf(stderr,"Cannot allocate memory\n");
- goto done;
- }
- memset (part, 0, nbr_part * sizeof (struct pentry));
- *parttbl = part;
-
- off = entries_lba * SECSIZE;
- for (i = 0; i < nbr_part; i++)
- {
- static const char unused_guid[16] = {0};
- fseeko (fd, off, SEEK_SET);
- size = fread (&data, 1, 128, fd);
- if (size < 128)
- {
- fprintf(stderr, "Could not read a GPT entry of %s.\n",
- diskimage);
- goto done;
- }
- if (memcmp (&data[0], unused_guid, 16) == 0)
- {
- part[i].start_sector_abs = 0;
- part[i].no_of_sectors_abs = 0;
- }
- else
- {
- part[i].start_sector_abs = read_le8 (&data[32]);
- part[i].no_of_sectors_abs = read_le8 (&data[40]);
-#ifdef DEBUG
- fprintf (stderr, "%d: %llu - %llu\n", i,
- part[i].start_sector_abs,
- part[i].no_of_sectors_abs);
-#endif
- /* Convert end to a number. */
- part[i].no_of_sectors_abs -=
- part[i].start_sector_abs - 1;
- }
- off += entry_size;
- }
-
- fail = nbr_part;
-
-done:
- if (fd)
- fclose(fd);
- return fail;
-}
-
-/* Read an MBR entry. */
-static void
-read_mbr_record (unsigned char pi[16], struct pentry *res)
-{
- res->bootable = *pi;
- res->start_head = *(pi + 1);
- res->start_cylinder = *(pi + 3) | ((*(pi + 2) << 2) & 0x300);
- res->start_sector = *(pi + 2) & 0x3f;
- res->system = *(pi + 4);
- res->end_head = *(pi + 5);
- res->end_cylinder = *(pi + 7) | ((*(pi + 6) << 2) & 0x300);
- res->end_sector = *(pi + 6) & 0x3f;
- res->start_sector_abs = read_le4 (&pi[8]);
- res->no_of_sectors_abs = read_le4 (&pi[12]);
-}
-
-/* Returns the number of partitions, -1 in case of failure. */
-int load_mbr(const char *diskimage, struct pentry *parttbl[])
-{
- FILE *fd;
- size_t size;
- int fail = -1;
- int nbr_part;
- int i;
- unsigned char *pi;
- unsigned char data [SECSIZE];
- unsigned long long extent;
- struct pentry *part;
-
- nbr_part = 0;
-
- fd = fopen(diskimage, "r");
- if (fd == NULL)
- {
- perror(diskimage);
- goto done;
- }
- size = fread (&data, 1, sizeof(data), fd);
- if (size < (size_t)sizeof(data))
- {
- fprintf(stderr, "Could not read the entire first sector of %s.\n", diskimage);
- goto done;
- }
-
- if (data [510] != 0x55 || data [511] != 0xaa)
- {
- fprintf(stderr,"MBR signature mismatch (invalid partition table?)\n");
- goto done;
- }
-
- /* There is at most 4*4 + 4 = 20 entries, also there should be only
- one extended partition. */
- part = malloc (20 * sizeof (struct pentry));
- if (part == NULL)
- {
- fprintf(stderr,"Cannot allocate memory\n");
- goto done;
- }
- *parttbl = part;
-
- /* Read MBR. */
- nbr_part = 4;
- for (i = 0; i < 4; i++)
- {
- pi = &data [446 + 16 * i];
- read_mbr_record (pi, &part[i]);
- }
-
- /* Read extended partitions. */
- for (i = 0; i < 4; i++)
- {
- if (part[i].system == 0xF || part[i].system == 0x5)
- {
- int j;
-
- extent = part[i].start_sector_abs * SECSIZE;
-
- fseeko (fd, extent, SEEK_SET);
- size = fread (&data, 1, sizeof(data), fd);
- if (size < (size_t)sizeof(data))
- {
- fprintf(stderr, "Could not read extended partition of %s.", diskimage);
- goto done;
- }
-
- for (j = 0; j < 4; j++)
- {
- int n;
- pi = &data [446 + 16 * j];
- n = nbr_part + j;
- read_mbr_record (pi, &part[n]);
- }
-
- nbr_part += 4;
- }
- }
-
- fail = nbr_part;
-
-done:
- if (fd)
- fclose(fd);
- return fail;
-}
-
-void usage(void)
-{
- fprintf(stderr, "Usage: lomount [-verbose] [OPTIONS] -diskimage FILE -partition NUM [OPTIONS]\n");
- fprintf(stderr, "All OPTIONS are passed through to 'mount'.\n");
- fprintf(stderr, "ex. lomount -t fs-type -diskimage hda.img -partition 1 /mnt\n");
- exit(ERR_USAGE);
-}
-
-int main(int argc, char ** argv)
-{
- int status;
- int nbr_part;
- struct pentry *parttbl;
- char buf[BUF], argv2[BUF];
- const char * diskimage = NULL;
- int partition = 0;
- unsigned long long sec, num, pnum;
- int i;
- size_t argv2_len = sizeof(argv2);
- int verbose = 0;
-
- argv2[0] = '\0';
-
- for (i = 1; i < argc; i ++)
- {
- if (strcmp(argv[i], "-diskimage")==0)
- {
- if (i == argc-1)
- usage();
- i++;
- diskimage = argv[i];
- }
- else if (strcmp(argv[i], "-partition")==0)
- {
- if (i == argc-1)
- usage();
- i++;
- partition = atoi(argv[i]);
- }
- else if (strcmp(argv[i], "-verbose")==0)
- {
- verbose++;
- }
- else
- {
- size_t len = strlen(argv[i]);
- if (len >= argv2_len-1)
- usage();
- strcat(argv2, argv[i]);
- strcat(argv2, " ");
- len -= (len+1);
- }
- }
- if (! diskimage || partition < 0)
- usage();
-
- nbr_part = load_mbr(diskimage, &parttbl);
- if (check_gpt (parttbl, nbr_part)) {
- free (parttbl);
- nbr_part = load_gpt (diskimage, &parttbl);
- }
- if (nbr_part < 0)
- return ERR_PART_PARSE;
- if (partition == 0)
- {
- printf("Please specify a partition number. Table is:\n");
- printf("Num Start - End OS Bootable\n");
- for (i = 0; i < nbr_part; i++)
- {
- if (parttbl[i].no_of_sectors_abs != 0)
- {
- printf ("%2d: ", i + 1);
- disp_entry (&parttbl[i]);
- }
- }
- if (partition == 0)
- return 0;
- }
- /* NOTE: need to make sure this always rounds down */
- //sec = total_known_sectors / sizeof_diskimage;
- /* The above doesn't work unless the disk image is completely
- filled by partitions ... unused space will thrown off the
- sector size. The calculation assumes the disk image is
- completely filled, and that the few sectors used to store
- the partition table/MBR are few enough that the calculated
- value is off by (larger than) a value less than one. */
- sec = 512; /* TODO: calculate real sector size */
-#ifdef DEBUG
- printf("sec: %llu\n", sec);
-#endif
- if (partition > nbr_part)
- {
- fprintf(stderr, "Bad partition number\n");
- return ERR_NO_EPART;
- }
- num = parttbl[partition-1].start_sector_abs;
- if (num == 0)
- {
- fprintf(stderr, "Partition %d was not found in %s.\n",
- partition, diskimage);
- return ERR_NO_PART;
- }
-
- pnum = sec * num;
-#ifdef DEBUG
- printf("offset = %llu\n", pnum);
-#endif
- snprintf(buf, sizeof(buf), "mount -oloop,offset=%lld %s %s",
- pnum, diskimage, argv2);
- if (verbose)
- printf("%s\n", buf);
-
- status = system(buf);
- if (WIFEXITED(status))
- status = WEXITSTATUS(status);
- else
- status = ERR_MOUNT;
- return status;
-}
diff --git a/tests/x86/scripts/guest_init.cmd b/tests/x86/xscripts/one_guest.xscript
similarity index 56%
rename from tests/x86/scripts/guest_init.cmd
rename to tests/x86/xscripts/one_guest.xscript
index c9be0820..43c2d383 100755
--- a/tests/x86/scripts/guest_init.cmd
+++ b/tests/x86/xscripts/one_guest.xscript
@@ -3,13 +3,10 @@
##########################################

# Create the guest's device tree node
-devtree node copy /guests guest0 /templates/x86_64_generic
+vfs guest_fdt_load guest0 /guests/intel/intel-guest.dtb 1

# Create the guest itself
guest create guest0

# Load the guest bios
-vfs guest_load guest0 0x80000 /coreboot.rom
-
-# Load guest bios in higher alias
-vfs guest_load guest0 0xfff80000 /coreboot.rom
+vfs guest_load guest0 0xE0000 /guests/common/bios.bin
--
2.25.1

hcha...@xvisor-x86.org

unread,
May 19, 2022, 12:31:53 AM5/19/22
to xvisor...@googlegroups.com, Himanshu Chauhan
From: Himanshu Chauhan <hcha...@xvisor-x86.org>

ljmp has two versions: absolute and indirect. Both have different
opcodes. This patch adds support for absolute version. Since ljmp
is a valid instruction only for 16-bit mode, we only support format
ljmp 16:16
i.e. two 16-bit operands.
if ljmp is seen in 32-bit or higher guest mode, it won't be decoded.

Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>
---
arch/x86/cpu/common/include/cpu_inst_decode.h | 10 ++++++++++
arch/x86/cpu/common/vm/cpu_inst_decode.c | 15 +++++++++++++++
2 files changed, 25 insertions(+)

diff --git a/arch/x86/cpu/common/include/cpu_inst_decode.h b/arch/x86/cpu/common/include/cpu_inst_decode.h
index ffd02ed0..85975fbe 100644
--- a/arch/x86/cpu/common/include/cpu_inst_decode.h
+++ b/arch/x86/cpu/common/include/cpu_inst_decode.h
@@ -34,6 +34,7 @@ typedef enum {
INST_TYPE_CLR_CR, /* directly modify cR e.g. clts */
INT_TYPE_SET_CR,
INST_TYPE_CACHE, /* TLB and cache operation */
+ INST_TYPE_LJMP_ABS, /* long jump to absolute address */
} inst_type;

/* Operand type in instruction */
@@ -119,6 +120,10 @@ typedef union mod_rm {
#define OPC_MOV_CR_TO_R 0x20
/* move Reg to crN */
#define OPC_MOV_R_TO_CR 0x22
+/* long jump (absolute address) */
+#define OPC_LJMP_ABS 0xEA
+/* long jump (indirect addressing) */
+#define OPC_LJMP_IND 0xFF

#define OPC_ESC_OPCODE 0x0f
#define OP_SIZE_REX_PREF 0x48
@@ -144,6 +149,11 @@ typedef struct {
struct {
u8 src_reg;
};
+
+ struct {
+ u32 ss; /* segment selector */
+ u32 offs; /* offset in segment */
+ } lja;
} inst;
} x86_decoded_inst_t;

diff --git a/arch/x86/cpu/common/vm/cpu_inst_decode.c b/arch/x86/cpu/common/vm/cpu_inst_decode.c
index efd049d5..db32c3e3 100644
--- a/arch/x86/cpu/common/vm/cpu_inst_decode.c
+++ b/arch/x86/cpu/common/vm/cpu_inst_decode.c
@@ -145,6 +145,21 @@ int x86_decode_inst(struct vcpu_hw_context *context, x86_inst inst,
dinst->inst.crn_mov.src_reg = X86_CR0_TS;
break;

+ case OPC_LJMP_ABS:
+ /*
+ * long jump abs is only defined in otherwise an exception
+ * will be generated 16-bit mode(real mode).
+ */
+ if (context->g_cr0 & (0x1UL << 31)) {
+ dinst->inst_type = INST_TYPE_LJMP_ABS;
+ dinst->inst_size = 5;
+ cinst++;
+ dinst->inst.lja.offs = *((u16 *)cinst);
+ cinst += sizeof(u16);
+ dinst->inst.lja.ss = *((u16 *)cinst);
+ } else
+ return VMM_EFAIL;
+ break;
default:
return VMM_EFAIL;
}
--
2.25.1

hcha...@xvisor-x86.org

unread,
May 19, 2022, 12:31:53 AM5/19/22
to xvisor...@googlegroups.com, Himanshu Chauhan
From: Himanshu Chauhan <hcha...@xvisor-x86.org>

The reset vector for guest is 0xFFF0. Our BIOS is in
extended BIOS area (0xE0000). So, the region to be
searched is 0xFFFF0. Once the host physical is found,
the EPT entry will be created only for the reset vector
i.e. 0xFFF0. This applies only for reset vector. After
the reset vector, CS is correctly populated and the
addresses come in range of BIOS addresses, so its regular
handling.

Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>
---
arch/x86/cpu/common/vm/vtx/intercept.c | 31 +++++++++++++++++---------
1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/arch/x86/cpu/common/vm/vtx/intercept.c b/arch/x86/cpu/common/vm/vtx/intercept.c
index 54f4c429..fa6fd84a 100644
--- a/arch/x86/cpu/common/vm/vtx/intercept.c
+++ b/arch/x86/cpu/common/vm/vtx/intercept.c
@@ -79,39 +79,48 @@ int vmx_handle_guest_realmode_page_fault(struct vcpu_hw_context *context)
u32 flags;
physical_addr_t hphys_addr;
physical_size_t availsz;
- physical_addr_t fault_gphys;
struct vmm_guest *guest = x86_vcpu_hw_context_guest(context);
+ u8 is_reset = 0;

physical_addr_t gla = vmr(GUEST_LINEAR_ADDRESS);

+ if (gla == 0xFFF0) {
+ is_reset = 1;
+ /* effective address = segment selector * 16 + offset.
+ * we will have a region for effective address. */
+ gla = ((0xF000 << 4) | gla);
+ }
VM_LOG(LVL_DEBUG, "[Real Mode] Faulting Address: 0x%"PRIx64"\n", gla);

- fault_gphys = (0xFFFF0000ULL + gla);
-
- VM_LOG(LVL_DEBUG, "(Real Mode) Looking for map from guest address: 0x%08lx\n",
- (fault_gphys & PAGE_MASK));
-
- rc = vmm_guest_physical_map(guest, (fault_gphys & PAGE_MASK),
+ /*
+ * At reset, the offset of execution is 0xfff0.
+ */
+ rc = vmm_guest_physical_map(guest, (gla & PAGE_MASK),
PAGE_SIZE, &hphys_addr, &availsz, &flags);
if (rc) {
- VM_LOG(LVL_ERR, "ERROR: No region mapped to guest physical 0x%"PRIx64"\n", fault_gphys);
+ VM_LOG(LVL_ERR, "ERROR: No region mapped to guest physical 0x%"PRIx64"\n", gla);
goto guest_bad_fault;
}

if (availsz < PAGE_SIZE) {
- VM_LOG(LVL_ERR, "ERROR: Size of the available mapping less than page size (%lu)\n", availsz);
+ VM_LOG(LVL_ERR, "ERROR: Size of the available mapping less "
+ "than page size (%lu)\n", availsz);
rc = VMM_EFAIL;
goto guest_bad_fault;
}

if (flags & (VMM_REGION_REAL | VMM_REGION_ALIAS)) {
- VM_LOG(LVL_DEBUG, "GP: 0x%"PRIx64" HP: 0x%"PRIx64" Size: %lu\n", gla, hphys_addr, availsz);
+ VM_LOG(LVL_DEBUG, "GP: 0x%"PRIx64" HP: 0x%"PRIx64" Size: %lu\n",
+ gla, hphys_addr, availsz);

gla &= PAGE_MASK;
+ /* page table entry will go only for offset. */
+ if (is_reset)
+ gla &= 0xFFFFUL;
hphys_addr &= PAGE_MASK;

VM_LOG(LVL_DEBUG, "Handle Page Fault: gphys: 0x%"PRIx64" hphys: 0x%"PRIx64"\n",
- fault_gphys, hphys_addr);
+ gla, hphys_addr);

rc = ept_create_pte_map(context, gla, hphys_addr, PAGE_SIZE,
(EPT_PROT_READ | EPT_PROT_WRITE | EPT_PROT_EXEC_S));
--
2.25.1

hcha...@xvisor-x86.org

unread,
May 19, 2022, 12:31:55 AM5/19/22
to xvisor...@googlegroups.com, Himanshu Chauhan
From: Himanshu Chauhan <hcha...@xvisor-x86.org>

PAM registers control the R/W to conventional memory.
BIOS uses these registers to mark RAM writable or read-only.
Via PAM0 register we tell BIOS that all RAM is writable.
The BIOS creates a shadow copy if the RAM is read-only.
From PAM0, we tell BIOS that there is no need of shadow
copy. This way we can handle the boot, with a single copy
of BIOS. QEMU uses 2 copies, one at lower addresses and
one at higher addresses.

Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>
---
emulators/pci/host/i440fx.c | 61 ++++++++++++++++++++++++++++++++++---
1 file changed, 57 insertions(+), 4 deletions(-)

diff --git a/emulators/pci/host/i440fx.c b/emulators/pci/host/i440fx.c
index e5d105c0..27035456 100644
--- a/emulators/pci/host/i440fx.c
+++ b/emulators/pci/host/i440fx.c
@@ -53,6 +53,44 @@ enum {
I440FX_LOG_LVL_VERBOSE
};

+enum {
+ I440FX_PMC_CS_VID0 = 0x0,
+ I440FX_PMC_CS_VID1 = 0x1,
+ I440FX_PMC_CS_DID0 = 0x2,
+ I440FX_PMC_CS_DID1 = 0x3,
+ I440FX_PMC_CS_PCICMD0 = 0x4,
+ I440FX_PMC_CS_PCICMD1 = 0x5,
+ I440FX_PMC_CS_PCISTS0 = 0x6,
+ I440FX_PMC_CS_PCISTS1 = 0x7,
+ I440FX_PMC_CS_RID = 0x8,
+ I440FX_PMC_CS_CLASSC0 = 0x9,
+ I440FX_PMC_CS_CLASSC1 = 0xa,
+ I440FX_PMC_CS_CLASSC2 = 0xb,
+ I440FX_PMC_CS_RES0 = 0xc,
+ I440FX_PMC_CS_MLT = 0xd,
+ I440FX_PMC_CS_HEADT = 0xe,
+ I440FX_PMC_CS_BIST = 0xf,
+ I440FX_PMC_CS_PMCCFG0 = 0x50,
+ I440FX_PMC_CS_PMCCFG1 = 0x51,
+ I440FX_PMC_CS_DETURBO = 0x52,
+ I440FX_PMC_CS_DBC = 0x53,
+ I440FX_PMC_CS_AXC = 0x54,
+ I440FX_PMC_CS_DRAMR0 = 0x55,
+ I440FX_PMC_CS_DRAMR1 = 0x56,
+ I440FX_PMC_CS_DRAMC = 0x57,
+ I440FX_PMC_CS_DRAMT = 0x58,
+ I440FX_PMC_CS_PAM0 = 0x59,
+ I440FX_PMC_CS_PAM1 = 0x5a,
+ I440FX_PMC_CS_PAM2 = 0x5b,
+ I440FX_PMC_CS_PAM3 = 0x5c,
+ I440FX_PMC_CS_PAM4 = 0x5d,
+ I440FX_PMC_CS_PAM5 = 0x5e,
+ I440FX_PMC_CS_PAM6 = 0x5f,
+ I440FX_PMC_CS_ERRCMD = 0x90,
+ I440FX_PMC_CS_ERRSTS = 0x91,
+ I440FX_PMC_CS_TRC = 0x93
+};
+
static int i440fx_default_log_lvl = I440FX_LOG_LVL_VERBOSE;

#define I440FX_LOG(lvl, fmt, args...) \
@@ -73,7 +111,7 @@ struct i440fx_state {
struct vmm_guest *guest;
struct vmm_devtree_node *node;
struct pci_host_controller *controller;
- i440fx_dev_registers_t *dev_regs;
+ i440fx_dev_registers_t dev_regs;
struct vmm_notifier_block guest_aspace_client;
u32 conf_add;
u32 conf_data;
@@ -81,11 +119,19 @@ struct i440fx_state {

static u32 i440fx_config_read(struct pci_class *pci_class, u16 reg_offset)
{
-#if 0 /* FIXME: populate this when i440fx is revisited. */
struct pci_host_controller *pcntrl = (struct pci_host_controller *)pci_class;
struct i440fx_state *s = container_of(&pcntrl, struct i440fx_state, controller);
-#endif
- return 0;
+
+ switch(reg_offset) {
+ case I440FX_PMC_CS_PAM0 ... I440FX_PMC_CS_PAM6:
+ vmm_printf("[%s]: Read from PAM%d\n", __func__, (reg_offset-I440FX_PMC_CS_PAM0));
+ return s->dev_regs.pam_regs[reg_offset - I440FX_PMC_CS_PAM0];
+
+ default:
+ vmm_printf("[%s]: Read from register %d is not supported\n", __func__, reg_offset);
+ return -1;
+ }
+ return -1;
}

static int i440fx_config_write(struct pci_class *pci_class, u16 reg_offset, u32 data)
@@ -264,6 +310,13 @@ static int i440fx_emulator_probe(struct vmm_guest *guest,

s->node = edev->node;
s->guest = guest;
+ s->dev_regs.pam_regs[0] = 0x33; /* BIOS read/write enable */
+ s->dev_regs.pam_regs[1] = 0x0; /* no read/write */
+ s->dev_regs.pam_regs[2] = 0x0;
+ s->dev_regs.pam_regs[3] = 0x0;
+ s->dev_regs.pam_regs[4] = 0x0;
+ s->dev_regs.pam_regs[5] = 0x33;
+ s->dev_regs.pam_regs[6] = 0x33; /* read/write enable to BIOS extension */
s->controller = vmm_zalloc(sizeof(struct pci_host_controller));
if (!s->controller) {
I440FX_LOG(LVL_ERR, "Failed to allocate pci host contoller for i440fx.\n");
--
2.25.1

hcha...@xvisor-x86.org

unread,
May 19, 2022, 12:31:57 AM5/19/22
to xvisor...@googlegroups.com, Himanshu Chauhan
From: Himanshu Chauhan <hcha...@xvisor-x86.org>

Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>
---
docs/x86/x86_64_generic.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/x86/x86_64_generic.txt b/docs/x86/x86_64_generic.txt
index 7b8119fa..bf177418 100644
--- a/docs/x86/x86_64_generic.txt
+++ b/docs/x86/x86_64_generic.txt
@@ -11,7 +11,7 @@ A. What is needed?

B. Steps to build a bootable image of Xvisor
1. Clone xvisor-x86_64 repo
- # git clone git://github.com/hschauhan/xvisor-x86_64.git
+ # git clone git://github.com/hschauhan/xvisor-x86.git

2. Build Xvisor with following command:
# make ARCH=x86 x86_64_generic-defconfig
@@ -33,7 +33,7 @@ B. Steps to build a bootable image of Xvisor
set default=0

menuentry "Xvisor x86_64" {
- multiboot /boot/vmm.bin earlyprint=vga
+ multiboot /boot/vmm.bin earlyprint=serial@0 console=serial@0
boot
}
-------8<----CUT-END----8<---------------
--
2.25.1

Anup Patel

unread,
May 24, 2022, 11:17:40 AM5/24/22
to Xvisor Devel, Himanshu Chauhan
On Thu, May 19, 2022 at 10:01 AM <hcha...@xvisor-x86.org> wrote:
>
> From: Himanshu Chauhan <hcha...@xvisor-x86.org>
>
> Removed static linking of guest fdt in xvisor binary
> Update the README on how to load the fdt
> Remove some other unused files relating to xvisor disk creation.
>
> Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>

Looks good to me.

Reviewed-by: Anup Patel <an...@brainfault.org>

Thanks,
Anup
> --
> You received this message because you are subscribed to the Google Groups "Xvisor Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to xvisor-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/xvisor-devel/20220519043124.2281884-1-hchauhan%40xvisor-x86.org.

Anup Patel

unread,
May 24, 2022, 11:18:18 AM5/24/22
to Xvisor Devel, Himanshu Chauhan
On Thu, May 19, 2022 at 10:01 AM <hcha...@xvisor-x86.org> wrote:
>
> From: Himanshu Chauhan <hcha...@xvisor-x86.org>
>
> ljmp has two versions: absolute and indirect. Both have different
> opcodes. This patch adds support for absolute version. Since ljmp
> is a valid instruction only for 16-bit mode, we only support format
> ljmp 16:16
> i.e. two 16-bit operands.
> if ljmp is seen in 32-bit or higher guest mode, it won't be decoded.
>
> Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>

Looks good to me.

Reviewed-by: Anup Patel <an...@brainfault.org>

Thanks,
Anup

> --
> You received this message because you are subscribed to the Google Groups "Xvisor Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to xvisor-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/xvisor-devel/20220519043124.2281884-2-hchauhan%40xvisor-x86.org.

Anup Patel

unread,
May 24, 2022, 11:19:02 AM5/24/22
to Xvisor Devel, Himanshu Chauhan
On Thu, May 19, 2022 at 10:01 AM <hcha...@xvisor-x86.org> wrote:
>
> From: Himanshu Chauhan <hcha...@xvisor-x86.org>
>
> The reset vector for guest is 0xFFF0. Our BIOS is in
> extended BIOS area (0xE0000). So, the region to be
> searched is 0xFFFF0. Once the host physical is found,
> the EPT entry will be created only for the reset vector
> i.e. 0xFFF0. This applies only for reset vector. After
> the reset vector, CS is correctly populated and the
> addresses come in range of BIOS addresses, so its regular
> handling.
>
> Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>

Looks good to me.

Reviewed-by: Anup Patel <an...@brainfault.org>

Thanks,
Anup

> --
> You received this message because you are subscribed to the Google Groups "Xvisor Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to xvisor-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/xvisor-devel/20220519043124.2281884-3-hchauhan%40xvisor-x86.org.

Anup Patel

unread,
May 24, 2022, 11:19:25 AM5/24/22
to Xvisor Devel, Himanshu Chauhan
On Thu, May 19, 2022 at 10:01 AM <hcha...@xvisor-x86.org> wrote:
>
> From: Himanshu Chauhan <hcha...@xvisor-x86.org>
>
> PAM registers control the R/W to conventional memory.
> BIOS uses these registers to mark RAM writable or read-only.
> Via PAM0 register we tell BIOS that all RAM is writable.
> The BIOS creates a shadow copy if the RAM is read-only.
> From PAM0, we tell BIOS that there is no need of shadow
> copy. This way we can handle the boot, with a single copy
> of BIOS. QEMU uses 2 copies, one at lower addresses and
> one at higher addresses.
>
> Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>

Looks good to me.

Reviewed-by: Anup Patel <an...@brainfault.org>

Thanks,
Anup

> --
> You received this message because you are subscribed to the Google Groups "Xvisor Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to xvisor-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/xvisor-devel/20220519043124.2281884-4-hchauhan%40xvisor-x86.org.

Anup Patel

unread,
May 24, 2022, 11:19:47 AM5/24/22
to Xvisor Devel, Himanshu Chauhan
On Thu, May 19, 2022 at 10:01 AM <hcha...@xvisor-x86.org> wrote:
>
> From: Himanshu Chauhan <hcha...@xvisor-x86.org>
>
> Signed-off-by: Himanshu Chauhan <hcha...@xvisor-x86.org>

Looks good to me.

Reviewed-by: Anup Patel <an...@brainfault.org>

Thanks,
Anup

> ---
> docs/x86/x86_64_generic.txt | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/docs/x86/x86_64_generic.txt b/docs/x86/x86_64_generic.txt
> index 7b8119fa..bf177418 100644
> --- a/docs/x86/x86_64_generic.txt
> +++ b/docs/x86/x86_64_generic.txt
> @@ -11,7 +11,7 @@ A. What is needed?
>
> B. Steps to build a bootable image of Xvisor
> 1. Clone xvisor-x86_64 repo
> - # git clone git://github.com/hschauhan/xvisor-x86_64.git
> + # git clone git://github.com/hschauhan/xvisor-x86.git
>
> 2. Build Xvisor with following command:
> # make ARCH=x86 x86_64_generic-defconfig
> @@ -33,7 +33,7 @@ B. Steps to build a bootable image of Xvisor
> set default=0
>
> menuentry "Xvisor x86_64" {
> - multiboot /boot/vmm.bin earlyprint=vga
> + multiboot /boot/vmm.bin earlyprint=serial@0 console=serial@0
> boot
> }
> -------8<----CUT-END----8<---------------
> --
> 2.25.1
>
> --
> You received this message because you are subscribed to the Google Groups "Xvisor Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to xvisor-devel...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/xvisor-devel/20220519043124.2281884-5-hchauhan%40xvisor-x86.org.
Reply all
Reply to author
Forward
0 new messages