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!
|
'F' DD video/sstfb.h conflict!
|
||||||
'G' 00-3F drivers/misc/sgi-gru/grulib.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 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-7F linux/hiddev.h conflict!
|
||||||
'H' 00-0F linux/hidraw.h conflict!
|
'H' 00-0F linux/hidraw.h conflict!
|
||||||
'H' 01 linux/mei.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
|
The Gunyah Virtual Machine Manager is a Linux driver to support launching
|
||||||
virtual machines using Gunyah.
|
virtual machines using Gunyah.
|
||||||
|
|
||||||
Except for some basic information about the location of initial binaries,
|
Configuration of a Gunyah virtual machine is done via a devicetree. When the VM
|
||||||
most of the configuration about a Gunyah virtual machine is described in the
|
is launched, memory is provided by the host VM which contains the devictree.
|
||||||
VM's devicetree. The devicetree is generated by userspace. Interacting with the
|
Gunyah reads the devicetree to configure the memory map and create resources
|
||||||
virtual machine is still done via the kernel and VM configuration requires some
|
such as vCPUs for the VM. Memory can be shared with the VM with
|
||||||
of the corresponding functionality to be set up in the kernel. For instance,
|
`GH_VM_SET_USER_MEM_REGION`_. Userspace can interact with the resources in Linux
|
||||||
sharing userspace memory with a VM is done via the `GH_VM_SET_USER_MEM_REGION`_
|
by adding "functions" to the VM.
|
||||||
ioctl. The VM itself is configured to use the memory region via the
|
|
||||||
devicetree.
|
|
||||||
|
|
||||||
Gunyah Functions
|
Gunyah Functions
|
||||||
================
|
================
|
||||||
@ -56,6 +54,9 @@ GH_CREATE_VM
|
|||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
Creates a Gunyah VM. The argument is reserved for future use and must be 0.
|
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
|
Gunyah VM API Descriptions
|
||||||
--------------------------
|
--------------------------
|
||||||
@ -70,8 +71,8 @@ unique per virtual machine.
|
|||||||
|
|
||||||
While VMM is guest-agnostic and allows runtime addition of memory regions,
|
While VMM is guest-agnostic and allows runtime addition of memory regions,
|
||||||
Linux guest virtual machines do not support accepting memory regions at runtime.
|
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
|
Thus, for Linux guests, memory regions should be provided before starting the VM
|
||||||
be configured to accept these at boot-up.
|
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
|
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
|
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
|
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.
|
of the primary memory parcel provided to the VM prior to GH_VM_START.
|
||||||
|
|
||||||
.. kernel-doc:: include/uapi/linux/gunyah.h
|
.. 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
|
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.
|
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
|
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
|
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
|
VM is started. This allows the VMM to set up all the kernel functions needed for
|
||||||
the VM *before* the VM starts.
|
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
|
* 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
|
* @tx_ghrsc: message queue resource to TX to RM
|
||||||
* @rx_ghrsc: message queue resource to RX from RM
|
* @rx_ghrsc: message queue resource to RX from RM
|
||||||
* @msgq: mailbox instance of TX/RX resources above
|
* @msgq: mailbox instance of TX/RX resources above
|
||||||
|
@ -617,7 +617,7 @@ static int gh_vm_ensure_started(struct gh_vm *ghvm)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
/** gh_vm_start() is guaranteed to bring status out of
|
/** 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
|
* possible
|
||||||
*/
|
*/
|
||||||
return gh_vm_ensure_started(ghvm);
|
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);
|
void gh_vm_put(struct gh_vm *ghvm);
|
||||||
|
|
||||||
struct gh_vm_function_instance;
|
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 {
|
struct gh_vm_function {
|
||||||
u32 type;
|
u32 type;
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -84,9 +94,26 @@ void gh_vm_function_unregister(struct gh_vm_function *f);
|
|||||||
module_gh_vm_function(_name); \
|
module_gh_vm_function(_name); \
|
||||||
MODULE_ALIAS_GH_VM_FUNCTION(_type, _idx)
|
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 gh_vm_resource_ticket {
|
||||||
struct list_head vm_list; /* for gh_vm's resource tickets list */
|
struct list_head vm_list;
|
||||||
struct list_head resources; /* resources associated with this ticket */
|
struct list_head resources;
|
||||||
enum gh_resource_type resource_type;
|
enum gh_resource_type resource_type;
|
||||||
u32 label;
|
u32 label;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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>
|
#include <stdlib.h>
|
||||||
@ -21,6 +21,11 @@
|
|||||||
|
|
||||||
#include <linux/gunyah.h>
|
#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 {
|
struct vm_config {
|
||||||
int image_fd;
|
int image_fd;
|
||||||
int dtb_fd;
|
int dtb_fd;
|
||||||
@ -29,7 +34,6 @@ struct vm_config {
|
|||||||
uint64_t guest_base;
|
uint64_t guest_base;
|
||||||
uint64_t guest_size;
|
uint64_t guest_size;
|
||||||
|
|
||||||
uint64_t image_offset;
|
|
||||||
off_t image_size;
|
off_t image_size;
|
||||||
uint64_t dtb_offset;
|
uint64_t dtb_offset;
|
||||||
off_t dtb_size;
|
off_t dtb_size;
|
||||||
@ -44,7 +48,6 @@ static struct option options[] = {
|
|||||||
{ "ramdisk", optional_argument, NULL, 'r' },
|
{ "ramdisk", optional_argument, NULL, 'r' },
|
||||||
{ "base", optional_argument, NULL, 'B' },
|
{ "base", optional_argument, NULL, 'B' },
|
||||||
{ "size", optional_argument, NULL, 'S' },
|
{ "size", optional_argument, NULL, 'S' },
|
||||||
{ "image_offset", optional_argument, NULL, 'I' },
|
|
||||||
{ "dtb_offset", optional_argument, NULL, 'D' },
|
{ "dtb_offset", optional_argument, NULL, 'D' },
|
||||||
{ "ramdisk_offset", optional_argument, NULL, 'R' },
|
{ "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"
|
" --image, -i <image> VM image file to load (e.g. a kernel Image) [Required]\n"
|
||||||
" --dtb, -d <dtb> Devicetree file to load [Required]\n"
|
" --dtb, -d <dtb> Devicetree file to load [Required]\n"
|
||||||
" --ramdisk, -r <ramdisk> Ramdisk file to load\n"
|
" --ramdisk, -r <ramdisk> Ramdisk file to load\n"
|
||||||
" --base, -B <address> Set the base address of guest's memory [Default: 0x80000000]\n"
|
" --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: 0x6400000 (100 MB)]\n"
|
" --size, -S <number> The number of bytes large to make the guest's memory [Default: 0x%08x]\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: 0x%08x]\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: 0x%08x]\n"
|
||||||
" --ramdisk_offset, -R <number> Offset into guest memory to load a ramdisk [Default: 0x4600000]\n"
|
, cmd, DEFAULT_GUEST_BASE, DEFAULT_GUEST_SIZE,
|
||||||
, cmd);
|
DEFAULT_DTB_OFFSET, DEFAULT_RAMDISK_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -74,18 +77,19 @@ int main(int argc, char **argv)
|
|||||||
char *guest_mem;
|
char *guest_mem;
|
||||||
struct vm_config config = {
|
struct vm_config config = {
|
||||||
/* Defaults good enough to boot static kernel and a basic ramdisk */
|
/* Defaults good enough to boot static kernel and a basic ramdisk */
|
||||||
|
.image_fd = -1,
|
||||||
|
.dtb_fd = -1,
|
||||||
.ramdisk_fd = -1,
|
.ramdisk_fd = -1,
|
||||||
.guest_base = 0x80000000,
|
.guest_base = DEFAULT_GUEST_BASE,
|
||||||
.guest_size = 0x6400000, /* 100 MB */
|
.guest_size = DEFAULT_GUEST_SIZE,
|
||||||
.image_offset = 0,
|
.dtb_offset = DEFAULT_DTB_OFFSET,
|
||||||
.dtb_offset = 0x45f0000,
|
.ramdisk_offset = DEFAULT_RAMDISK_OFFSET,
|
||||||
.ramdisk_offset = 0x4600000, /* put at +70MB (30MB for ramdisk) */
|
|
||||||
};
|
};
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int opt, optidx, ret = 0;
|
int opt, optidx, ret = 0;
|
||||||
long l;
|
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) {
|
switch (opt) {
|
||||||
case 'i':
|
case 'i':
|
||||||
config.image_fd = open(optarg, O_RDONLY | O_CLOEXEC);
|
config.image_fd = open(optarg, O_RDONLY | O_CLOEXEC);
|
||||||
@ -139,14 +143,6 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
config.guest_size = l;
|
config.guest_size = l;
|
||||||
break;
|
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':
|
case 'D':
|
||||||
l = strtol(optarg, NULL, 0);
|
l = strtol(optarg, NULL, 0);
|
||||||
if (l == LONG_MIN) {
|
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]);
|
print_help(argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.image_offset + config.image_size > config.guest_size) {
|
if (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");
|
fprintf(stderr, "Image size puts it outside guest memory. Make image smaller or increase guest memory size.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +218,7 @@ int main(int argc, char **argv)
|
|||||||
return -1;
|
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");
|
perror("Failed to read image into guest memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -264,7 +260,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
sleep(10);
|
pause();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user