ANDROID: gunyah: Sync remaining gunyah drivers with latest

Apply remaining minor fixups from Gunyah v13 patches:

https://lore.kernel.org/all/20230509204801.2824351-1-quic_eberman@quicinc.com/

Bug: 279506910
Change-Id: I1a596b9df29d210c51b612845e4a1aafbea00441
Signed-off-by: Elliot Berman <quic_eberman@quicinc.com>
This commit is contained in:
Elliot Berman 2023-04-17 12:07:52 -07:00 committed by Carlos Llamas
parent afaf163329
commit 9a9fc8d1b2
12 changed files with 55 additions and 51 deletions

View File

@ -1,9 +1,9 @@
/* 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.
*/
#ifndef __ASM_GUNYAH_H_
#define __ASM_GUNYAH_H_
#ifndef _ASM_GUNYAH_H
#define _ASM_GUNYAH_H
#include <linux/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>

View File

@ -3,8 +3,8 @@
obj-$(CONFIG_GUNYAH_PLATFORM_HOOKS) += gunyah_platform_hooks.o
obj-$(CONFIG_GUNYAH_QCOM_PLATFORM) += gunyah_qcom.o
gunyah_rsc_mgr-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o vm_mgr_mm.o
obj-$(CONFIG_GUNYAH) += gunyah_rsc_mgr.o
gunyah-y += rsc_mgr.o rsc_mgr_rpc.o vm_mgr.o vm_mgr_mm.o
obj-$(CONFIG_GUNYAH) += gunyah.o
obj-$(CONFIG_GUNYAH_VCPU) += gunyah_vcpu.o
obj-$(CONFIG_GUNYAH_IRQFD) += gunyah_irqfd.o

View File

@ -176,5 +176,5 @@ static bool gh_irqfd_compare(const struct gh_vm_function_instance *f,
DECLARE_GH_VM_FUNCTION_INIT(irqfd, GH_FN_IRQFD, 2, gh_irqfd_bind, gh_irqfd_unbind,
gh_irqfd_compare);
MODULE_DESCRIPTION("Gunyah irqfds");
MODULE_DESCRIPTION("Gunyah irqfd VM Function");
MODULE_LICENSE("GPL");

View File

@ -68,6 +68,9 @@ static bool gh_handle_mmio(struct gh_vcpu *vcpu,
len = vcpu_run_resp->state_data[1],
data = vcpu_run_resp->state_data[2];
if (WARN_ON(len > sizeof(u64)))
len = sizeof(u64);
if (vcpu_run_resp->state == GH_VCPU_ADDRSPACE_VMMIO_READ) {
vcpu->vcpu_run->mmio.is_write = 0;
/* Record that we need to give vCPU user's supplied value next gh_vcpu_run() */
@ -175,6 +178,8 @@ static int gh_vcpu_run(struct gh_vcpu *vcpu)
vcpu->state = GH_VCPU_READY;
break;
case GH_VCPU_MMIO_READ:
if (unlikely(vcpu->mmio_read_len > sizeof(state_data[0])))
vcpu->mmio_read_len = sizeof(state_data[0]);
memcpy(&state_data[0], vcpu->vcpu_run->mmio.data, vcpu->mmio_read_len);
vcpu->state = GH_VCPU_READY;
break;
@ -387,15 +392,9 @@ static long gh_vcpu_bind(struct gh_vm_function_instance *f)
if (r)
goto err_destroy_page;
fd = get_unused_fd_flags(O_CLOEXEC);
if (fd < 0) {
r = fd;
goto err_remove_vcpu;
}
if (!gh_vm_get(f->ghvm)) {
r = -ENODEV;
goto err_put_fd;
goto err_remove_resource_ticket;
}
vcpu->ghvm = f->ghvm;
@ -409,23 +408,30 @@ static long gh_vcpu_bind(struct gh_vm_function_instance *f)
goto err_put_gh_vm;
kref_get(&vcpu->kref);
snprintf(name, sizeof(name), "gh-vcpu:%d", vcpu->ticket.label);
fd = get_unused_fd_flags(O_CLOEXEC);
if (fd < 0) {
r = fd;
goto err_notifier;
}
snprintf(name, sizeof(name), "gh-vcpu:%u", vcpu->ticket.label);
file = anon_inode_getfile(name, &gh_vcpu_fops, vcpu, O_RDWR);
if (IS_ERR(file)) {
r = PTR_ERR(file);
goto err_notifier;
goto err_put_fd;
}
fd_install(fd, file);
return fd;
err_put_fd:
put_unused_fd(fd);
err_notifier:
gh_rm_notifier_unregister(f->rm, &vcpu->nb);
err_put_gh_vm:
gh_vm_put(vcpu->ghvm);
err_put_fd:
put_unused_fd(fd);
err_remove_vcpu:
err_remove_resource_ticket:
gh_vm_remove_resource_ticket(f->ghvm, &vcpu->ticket);
err_destroy_page:
free_page((unsigned long)vcpu->vcpu_run);
@ -458,5 +464,5 @@ static bool gh_vcpu_compare(const struct gh_vm_function_instance *f,
}
DECLARE_GH_VM_FUNCTION_INIT(vcpu, GH_FN_VCPU, 1, gh_vcpu_bind, gh_vcpu_unbind, gh_vcpu_compare);
MODULE_DESCRIPTION("Gunyah vCPU Driver");
MODULE_DESCRIPTION("Gunyah vCPU Function");
MODULE_LICENSE("GPL");

View File

@ -126,7 +126,8 @@ struct gh_rm_connection {
* @dev: pointer to device
* @tx_ghrsc: message queue resource to TX to RM
* @rx_ghrsc: message queue resource to RX from RM
* @msgq: mailbox instance of above
* @msgq: mailbox instance of TX/RX resources above
* @msgq_client: mailbox client of above msgq
* @active_rx_connection: ongoing gh_rm_connection for which we're receiving fragments
* @last_tx_ret: return value of last mailbox tx
* @call_xarray: xarray to allocate & lookup sequence IDs for Request/Response flows
@ -160,7 +161,7 @@ struct gh_rm {
/**
* gh_rm_remap_error() - Remap Gunyah resource manager errors into a Linux error code
* @gh_error: "Standard" return value from Gunyah resource manager
* @rm_error: "Standard" return value from Gunyah resource manager
*/
static inline int gh_rm_remap_error(enum gh_rm_error rm_error)
{
@ -378,7 +379,7 @@ static void gh_rm_notif_work(struct work_struct *work)
notification.work);
struct gh_rm *rm = connection->notification.rm;
blocking_notifier_call_chain(&rm->nh, connection->msg_id, connection->payload);
blocking_notifier_call_chain(&rm->nh, le32_to_cpu(connection->msg_id), connection->payload);
put_device(rm->dev);
kfree(connection->payload);

View File

@ -308,7 +308,7 @@ int gh_rm_mem_reclaim(struct gh_rm *rm, struct gh_rm_mem_parcel *parcel)
int ret;
ret = gh_rm_call(rm, GH_RM_RPC_MEM_RECLAIM, &req, sizeof(req), NULL, NULL);
/* Do not call platform mem reclaim hooks: the reclaim didn't happen*/
/* Only call the platform mem reclaim hooks if we reclaimed the memory */
if (ret)
return ret;
@ -348,7 +348,7 @@ EXPORT_SYMBOL_GPL(gh_rm_vm_set_firmware_mem);
int gh_rm_alloc_vmid(struct gh_rm *rm, u16 vmid)
{
struct gh_rm_vm_common_vmid_req req_payload = {
.vmid = vmid,
.vmid = cpu_to_le16(vmid),
};
struct gh_rm_vm_alloc_vmid_resp *resp_payload;
size_t resp_size;

View File

@ -11,6 +11,7 @@
#include <linux/gunyah_rsc_mgr.h>
#include <linux/gunyah_vm_mgr.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/xarray.h>
@ -385,7 +386,7 @@ static int gh_vm_rm_notification_status(struct gh_vm *ghvm, void *data)
{
struct gh_rm_vm_status_payload *payload = data;
if (payload->vmid != ghvm->vmid)
if (le16_to_cpu(payload->vmid) != ghvm->vmid)
return NOTIFY_OK;
/* All other state transitions are synchronous to a corresponding RM call */
@ -403,7 +404,7 @@ static int gh_vm_rm_notification_exited(struct gh_vm *ghvm, void *data)
{
struct gh_rm_vm_exited_payload *payload = data;
if (payload->vmid != ghvm->vmid)
if (le16_to_cpu(payload->vmid) != ghvm->vmid)
return NOTIFY_OK;
down_write(&ghvm->status_lock);
@ -413,6 +414,7 @@ static int gh_vm_rm_notification_exited(struct gh_vm *ghvm, void *data)
memcpy(&ghvm->exit_info.reason, payload->exit_reason,
min(GH_VM_MAX_EXIT_REASON_SIZE, ghvm->exit_info.reason_size));
up_write(&ghvm->status_lock);
wake_up(&ghvm->vm_status_wait);
return NOTIFY_DONE;
}
@ -441,9 +443,9 @@ static void gh_vm_stop(struct gh_vm *ghvm)
if (ret)
dev_warn(ghvm->parent, "Failed to stop VM: %d\n", ret);
}
ghvm->vm_status = GH_RM_VM_STATUS_EXITED;
up_write(&ghvm->status_lock);
wait_event(ghvm->vm_status_wait, ghvm->vm_status == GH_RM_VM_STATUS_EXITED);
}
static __must_check struct gh_vm *gh_vm_alloc(struct gh_rm *rm)
@ -663,9 +665,13 @@ static long gh_vm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (copy_from_user(&dtb_config, argp, sizeof(dtb_config)))
return -EFAULT;
if (dtb_config.guest_phys_addr + dtb_config.size < dtb_config.guest_phys_addr)
if (overflows_type(dtb_config.guest_phys_addr + dtb_config.size, u64))
return -EOVERFLOW;
/* Gunyah requires that dtb_config is page aligned */
if (!PAGE_ALIGNED(dtb_config.guest_phys_addr) || !PAGE_ALIGNED(dtb_config.size))
return -EINVAL;
ghvm->dtb_config = dtb_config;
r = 0;

View File

@ -3,8 +3,8 @@
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef _GH_PRIV_VM_MGR_H
#define _GH_PRIV_VM_MGR_H
#ifndef _GH_VM_MGR_H
#define _GH_VM_MGR_H
#include <linux/gunyah_rsc_mgr.h>
#include <linux/gunyah_vm_mgr.h>

View File

@ -119,14 +119,12 @@ int gh_vm_mem_alloc(struct gh_vm *ghvm, struct gh_userspace_memory_region *regio
if (ret)
return ret;
/* Check label is unique */
mapping = __gh_vm_mem_find_by_label(ghvm, region->label);
if (mapping) {
ret = -EEXIST;
goto unlock;
}
/* Check for overlap */
list_for_each_entry(tmp_mapping, &ghvm->memory_mappings, list) {
if (gh_vm_mem_overlap(tmp_mapping, region->guest_phys_addr,
region->memory_size)) {
@ -235,7 +233,6 @@ int gh_vm_mem_alloc(struct gh_vm *ghvm, struct gh_userspace_memory_region *regio
} else {
parcel->mem_entries[j].size = cpu_to_le64(entry_size);
j++;
BUG_ON(j >= parcel->n_mem_entries);
parcel->mem_entries[j].ipa_base =
cpu_to_le64(page_to_phys(curr_page));
entry_size = PAGE_SIZE;

View File

@ -14,13 +14,13 @@
#include <linux/mailbox_client.h>
#include <linux/types.h>
/* Follows resource manager's resource types for VM_GET_HYP_RESOURCES */
/* Matches resource manager's resource types for VM_GET_HYP_RESOURCES RPC */
enum gh_resource_type {
GH_RESOURCE_TYPE_BELL_TX = 0,
GH_RESOURCE_TYPE_BELL_RX = 1,
GH_RESOURCE_TYPE_MSGQ_TX = 2,
GH_RESOURCE_TYPE_MSGQ_RX = 3,
GH_RESOURCE_TYPE_VCPU = 4,
GH_RESOURCE_TYPE_VCPU = 4,
};
struct gh_resource {
@ -28,7 +28,6 @@ struct gh_resource {
u64 capid;
unsigned int irq;
/* To help allocator in vm manager */
struct list_head list;
u32 rm_label;
};
@ -37,7 +36,7 @@ struct gh_resource {
* Gunyah Message Queues
*/
#define GH_MSGQ_MAX_MSG_SIZE 240
#define GH_MSGQ_MAX_MSG_SIZE 240
struct gh_msgq_tx_data {
size_t length;
@ -144,16 +143,17 @@ static inline int gh_error_remap(enum gh_error gh_error)
}
enum gh_api_feature {
GH_FEATURE_DOORBELL = 1,
GH_FEATURE_MSGQUEUE = 2,
GH_FEATURE_VCPU = 5,
GH_FEATURE_MEMEXTENT = 6,
GH_FEATURE_DOORBELL = 1,
GH_FEATURE_MSGQUEUE = 2,
GH_FEATURE_VCPU = 5,
GH_FEATURE_MEMEXTENT = 6,
};
bool arch_is_gh_guest(void);
#define GH_API_V1 1
/* Other bits reserved for future use and will be zero */
#define GH_API_INFO_API_VERSION_MASK GENMASK_ULL(13, 0)
#define GH_API_INFO_BIG_ENDIAN BIT_ULL(14)
#define GH_API_INFO_IS_64BIT BIT_ULL(15)

View File

@ -10,7 +10,7 @@
#include <linux/notifier.h>
#include <linux/gunyah.h>
#define GH_VMID_INVAL U16_MAX
#define GH_VMID_INVAL U16_MAX
#define GH_MEM_HANDLE_INVAL U32_MAX
struct gh_rm;
@ -31,12 +31,6 @@ struct gh_rm_vm_exited_payload {
#define GH_RM_NOTIFICATION_VM_EXITED 0x56100001
enum gh_rm_vm_status {
/**
* RM doesn't have a state where load partially failed because
* only Linux
*/
GH_RM_VM_STATUS_LOAD_FAILED = -1,
GH_RM_VM_STATUS_NO_STATE = 0,
GH_RM_VM_STATUS_INIT = 1,
GH_RM_VM_STATUS_READY = 2,

View File

@ -56,8 +56,8 @@ static void print_help(char *cmd)
"Usage: %s <options>\n"
" --help, -h this menu\n"
" --image, -i <image> VM image file to load (e.g. a kernel Image) [Required]\n"
" --dtb, -d <dtb> Devicetree to load [Required]\n"
" --ramdisk, -r <ramdisk> Ramdisk to load\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"