ANDROID: virt: gunyah: Sync with latest documentation and sample
Sync with latest documentation and sample code from v14 of Gunyah patches: https://lore.kernel.org/all/20230613172054.3959700-1-quic_eberman@quicinc.com/ Bug: 287037804 Change-Id: I8893922e6b8096fdd5dff1b22ebce96e72cdb7c3 Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
This commit is contained in:
parent
60662882b7
commit
705a9b5feb
@ -136,7 +136,7 @@ Code Seq# Include File Comments
|
||||
'F' DD video/sstfb.h conflict!
|
||||
'G' 00-3F drivers/misc/sgi-gru/grulib.h conflict!
|
||||
'G' 00-0F xen/gntalloc.h, xen/gntdev.h conflict!
|
||||
'G' 00-0f linux/gunyah.h conflict!
|
||||
'G' 00-0F linux/gunyah.h conflict!
|
||||
'H' 00-7F linux/hiddev.h conflict!
|
||||
'H' 00-0F linux/hidraw.h conflict!
|
||||
'H' 01 linux/mei.h conflict!
|
||||
|
@ -7,14 +7,12 @@ Virtual Machine Manager
|
||||
The Gunyah Virtual Machine Manager is a Linux driver to support launching
|
||||
virtual machines using Gunyah.
|
||||
|
||||
Except for some basic information about the location of initial binaries,
|
||||
most of the configuration about a Gunyah virtual machine is described in the
|
||||
VM's devicetree. The devicetree is generated by userspace. Interacting with the
|
||||
virtual machine is still done via the kernel and VM configuration requires some
|
||||
of the corresponding functionality to be set up in the kernel. For instance,
|
||||
sharing userspace memory with a VM is done via the `GH_VM_SET_USER_MEM_REGION`_
|
||||
ioctl. The VM itself is configured to use the memory region via the
|
||||
devicetree.
|
||||
Configuration of a Gunyah virtual machine is done via a devicetree. When the VM
|
||||
is launched, memory is provided by the host VM which contains the devictree.
|
||||
Gunyah reads the devicetree to configure the memory map and create resources
|
||||
such as vCPUs for the VM. Memory can be shared with the VM with
|
||||
`GH_VM_SET_USER_MEM_REGION`_. Userspace can interact with the resources in Linux
|
||||
by adding "functions" to the VM.
|
||||
|
||||
Gunyah Functions
|
||||
================
|
||||
@ -56,6 +54,9 @@ GH_CREATE_VM
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Creates a Gunyah VM. The argument is reserved for future use and must be 0.
|
||||
A successful call will return a Gunyah VM file descriptor. See
|
||||
`Gunyah VM API Descriptions`_ for list of IOCTLs that can be made on this file
|
||||
file descriptor.
|
||||
|
||||
Gunyah VM API Descriptions
|
||||
--------------------------
|
||||
@ -70,8 +71,8 @@ unique per virtual machine.
|
||||
|
||||
While VMM is guest-agnostic and allows runtime addition of memory regions,
|
||||
Linux guest virtual machines do not support accepting memory regions at runtime.
|
||||
Thus, memory regions should be provided before starting the VM and the VM must
|
||||
be configured to accept these at boot-up.
|
||||
Thus, for Linux guests, memory regions should be provided before starting the VM
|
||||
and the VM must be configured via the devicetree to accept these at boot-up.
|
||||
|
||||
The guest physical address is used by Linux kernel to check that the requested
|
||||
user regions do not overlap and to help find the corresponding memory region
|
||||
@ -87,7 +88,7 @@ GH_VM_SET_DTB_CONFIG
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This ioctl sets the location of the VM's devicetree blob and is used by Gunyah
|
||||
Resource Manager to allocate resources. The guest physical memory should be part
|
||||
Resource Manager to allocate resources. The guest physical memory must be part
|
||||
of the primary memory parcel provided to the VM prior to GH_VM_START.
|
||||
|
||||
.. kernel-doc:: include/uapi/linux/gunyah.h
|
||||
@ -104,7 +105,7 @@ GH_VM_ADD_FUNCTION
|
||||
This ioctl registers a Gunyah VM function with the VM manager. The VM function
|
||||
is described with a &struct gh_fn_desc.type and some arguments for that type.
|
||||
Typically, the function is added before the VM starts, but the function doesn't
|
||||
"operate" until the VM starts with `GH_VM_START`_. For example, vCPU ioclts will
|
||||
"operate" until the VM starts with `GH_VM_START`_. For example, vCPU ioctls will
|
||||
all return an error until the VM starts because the vCPUs don't exist until the
|
||||
VM is started. This allows the VMM to set up all the kernel functions needed for
|
||||
the VM *before* the VM starts.
|
||||
|
@ -123,7 +123,7 @@ struct gh_rm_connection {
|
||||
|
||||
/**
|
||||
* struct gh_rm - private data for communicating w/Gunyah resource manager
|
||||
* @dev: pointer to device
|
||||
* @dev: pointer to RM platform device
|
||||
* @tx_ghrsc: message queue resource to TX to RM
|
||||
* @rx_ghrsc: message queue resource to RX from RM
|
||||
* @msgq: mailbox instance of TX/RX resources above
|
||||
|
@ -617,7 +617,7 @@ static int gh_vm_ensure_started(struct gh_vm *ghvm)
|
||||
if (ret)
|
||||
return ret;
|
||||
/** gh_vm_start() is guaranteed to bring status out of
|
||||
* GH_RM_VM_STATUS_LOAD, thus inifitely recursive call is not
|
||||
* GH_RM_VM_STATUS_LOAD, thus infinitely recursive call is not
|
||||
* possible
|
||||
*/
|
||||
return gh_vm_ensure_started(ghvm);
|
||||
|
@ -21,6 +21,16 @@ int __must_check gh_vm_get(struct gh_vm *ghvm);
|
||||
void gh_vm_put(struct gh_vm *ghvm);
|
||||
|
||||
struct gh_vm_function_instance;
|
||||
/**
|
||||
* struct gh_vm_function - Represents a function type
|
||||
* @type: value from &enum gh_fn_type
|
||||
* @name: friendly name for debug purposes
|
||||
* @mod: owner of the function type
|
||||
* @bind: Called when a new function of this type has been allocated.
|
||||
* @unbind: Called when the function instance is being destroyed.
|
||||
* @compare: Compare function instance @f's argument to the provided arg.
|
||||
* Return true if they are equivalent. Used on GH_VM_REMOVE_FUNCTION.
|
||||
*/
|
||||
struct gh_vm_function {
|
||||
u32 type;
|
||||
const char *name;
|
||||
@ -84,9 +94,26 @@ void gh_vm_function_unregister(struct gh_vm_function *f);
|
||||
module_gh_vm_function(_name); \
|
||||
MODULE_ALIAS_GH_VM_FUNCTION(_type, _idx)
|
||||
|
||||
/**
|
||||
* struct gh_vm_resource_ticket - Represents a ticket to reserve exclusive access to VM resource(s)
|
||||
* @vm_list: for @gh_vm->resource_tickets
|
||||
* @resources: List of resource(s) associated with this ticket(members are from @gh_resource->list)
|
||||
* @resource_type: Type of resource this ticket reserves
|
||||
* @label: Label of the resource from resource manager this ticket reserves.
|
||||
* @owner: owner of the ticket
|
||||
* @populate: callback provided by the ticket owner and called when a resource is found that
|
||||
* matches @resource_type and @label. Note that this callback could be called
|
||||
* multiple times if userspace created mutliple resources with the same type/label.
|
||||
* This callback may also have significant delay after gh_vm_add_resource_ticket()
|
||||
* since gh_vm_add_resource_ticket() could be called before the VM starts.
|
||||
* @unpopulate: callback provided by the ticket owner and called when the ticket owner should no
|
||||
* no longer use the resource provided in the argument. When unpopulate() returns,
|
||||
* the ticket owner should not be able to use the resource any more as the resource
|
||||
* might being freed.
|
||||
*/
|
||||
struct gh_vm_resource_ticket {
|
||||
struct list_head vm_list; /* for gh_vm's resource tickets list */
|
||||
struct list_head resources; /* resources associated with this ticket */
|
||||
struct list_head vm_list;
|
||||
struct list_head resources;
|
||||
enum gh_resource_type resource_type;
|
||||
u32 label;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -21,6 +21,11 @@
|
||||
|
||||
#include <linux/gunyah.h>
|
||||
|
||||
#define DEFAULT_GUEST_BASE 0x80000000
|
||||
#define DEFAULT_GUEST_SIZE 0x6400000 /* 100 MiB */
|
||||
#define DEFAULT_DTB_OFFSET 0x45f0000 /* 70MiB - 64 KiB */
|
||||
#define DEFAULT_RAMDISK_OFFSET 0x4600000 /* 70MiB */
|
||||
|
||||
struct vm_config {
|
||||
int image_fd;
|
||||
int dtb_fd;
|
||||
@ -29,7 +34,6 @@ struct vm_config {
|
||||
uint64_t guest_base;
|
||||
uint64_t guest_size;
|
||||
|
||||
uint64_t image_offset;
|
||||
off_t image_size;
|
||||
uint64_t dtb_offset;
|
||||
off_t dtb_size;
|
||||
@ -44,7 +48,6 @@ static struct option options[] = {
|
||||
{ "ramdisk", optional_argument, NULL, 'r' },
|
||||
{ "base", optional_argument, NULL, 'B' },
|
||||
{ "size", optional_argument, NULL, 'S' },
|
||||
{ "image_offset", optional_argument, NULL, 'I' },
|
||||
{ "dtb_offset", optional_argument, NULL, 'D' },
|
||||
{ "ramdisk_offset", optional_argument, NULL, 'R' },
|
||||
{ }
|
||||
@ -58,12 +61,12 @@ static void print_help(char *cmd)
|
||||
" --image, -i <image> VM image file to load (e.g. a kernel Image) [Required]\n"
|
||||
" --dtb, -d <dtb> Devicetree file to load [Required]\n"
|
||||
" --ramdisk, -r <ramdisk> Ramdisk file to load\n"
|
||||
" --base, -B <address> Set the base address of guest's memory [Default: 0x80000000]\n"
|
||||
" --size, -S <number> The number of bytes large to make the guest's memory [Default: 0x6400000 (100 MB)]\n"
|
||||
" --image_offset, -I <number> Offset into guest memory to load the VM image file [Default: 0x10000]\n"
|
||||
" --dtb_offset, -D <number> Offset into guest memory to load the DTB [Default: 0]\n"
|
||||
" --ramdisk_offset, -R <number> Offset into guest memory to load a ramdisk [Default: 0x4600000]\n"
|
||||
, cmd);
|
||||
" --base, -B <address> Set the base address of guest's memory [Default: 0x%08x]\n"
|
||||
" --size, -S <number> The number of bytes large to make the guest's memory [Default: 0x%08x]\n"
|
||||
" --dtb_offset, -D <number> Offset into guest memory to load the DTB [Default: 0x%08x]\n"
|
||||
" --ramdisk_offset, -R <number> Offset into guest memory to load a ramdisk [Default: 0x%08x]\n"
|
||||
, cmd, DEFAULT_GUEST_BASE, DEFAULT_GUEST_SIZE,
|
||||
DEFAULT_DTB_OFFSET, DEFAULT_RAMDISK_OFFSET);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@ -74,18 +77,19 @@ int main(int argc, char **argv)
|
||||
char *guest_mem;
|
||||
struct vm_config config = {
|
||||
/* Defaults good enough to boot static kernel and a basic ramdisk */
|
||||
.image_fd = -1,
|
||||
.dtb_fd = -1,
|
||||
.ramdisk_fd = -1,
|
||||
.guest_base = 0x80000000,
|
||||
.guest_size = 0x6400000, /* 100 MB */
|
||||
.image_offset = 0,
|
||||
.dtb_offset = 0x45f0000,
|
||||
.ramdisk_offset = 0x4600000, /* put at +70MB (30MB for ramdisk) */
|
||||
.guest_base = DEFAULT_GUEST_BASE,
|
||||
.guest_size = DEFAULT_GUEST_SIZE,
|
||||
.dtb_offset = DEFAULT_DTB_OFFSET,
|
||||
.ramdisk_offset = DEFAULT_RAMDISK_OFFSET,
|
||||
};
|
||||
struct stat st;
|
||||
int opt, optidx, ret = 0;
|
||||
long l;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "hi:d:r:B:S:I:D:R:c:", options, &optidx)) != -1) {
|
||||
while ((opt = getopt_long(argc, argv, "hi:d:r:B:S:D:R:c:", options, &optidx)) != -1) {
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
config.image_fd = open(optarg, O_RDONLY | O_CLOEXEC);
|
||||
@ -139,14 +143,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
config.guest_size = l;
|
||||
break;
|
||||
case 'I':
|
||||
l = strtol(optarg, NULL, 0);
|
||||
if (l == LONG_MIN) {
|
||||
perror("Failed to parse image offset");
|
||||
return -1;
|
||||
}
|
||||
config.image_offset = l;
|
||||
break;
|
||||
case 'D':
|
||||
l = strtol(optarg, NULL, 0);
|
||||
if (l == LONG_MIN) {
|
||||
@ -172,13 +168,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.image_fd || !config.dtb_fd) {
|
||||
if (config.image_fd == -1 || config.dtb_fd == -1) {
|
||||
print_help(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (config.image_offset + config.image_size > config.guest_size) {
|
||||
fprintf(stderr, "Image offset and size puts it outside guest memory. Make image smaller or increase guest memory size.\n");
|
||||
if (config.image_size > config.guest_size) {
|
||||
fprintf(stderr, "Image size puts it outside guest memory. Make image smaller or increase guest memory size.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -222,7 +218,7 @@ int main(int argc, char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read(config.image_fd, guest_mem + config.image_offset, config.image_size) < 0) {
|
||||
if (read(config.image_fd, guest_mem, config.image_size) < 0) {
|
||||
perror("Failed to read image into guest memory");
|
||||
return -1;
|
||||
}
|
||||
@ -264,7 +260,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
while (1)
|
||||
sleep(10);
|
||||
pause();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user