Skip to content

Commit

Permalink
hv: vm_event: create vm_event support
Browse files Browse the repository at this point in the history
This patch creates vm_event support in HV, including:
1. Create vm_event data type.
2. Add vm_event sbuf and its initializer. The sbuf will be allocated by
   DM in Service VM. Its page address will then be share to HV through
   hypercall.
3. Add an API to send the HV generated event.

Tracked-On: #8547
Signed-off-by: Wu Zhou <wu.zhou@intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
  • Loading branch information
izhouwu authored and acrnsi-robot committed Feb 1, 2024
1 parent 852f10c commit 581ec58
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 0 deletions.
1 change: 1 addition & 0 deletions hypervisor/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ HW_C_SRCS += common/schedule.c
HW_C_SRCS += common/event.c
HW_C_SRCS += common/efi_mmap.c
HW_C_SRCS += common/sbuf.c
HW_C_SRCS += common/vm_event.c
ifeq ($(CONFIG_SCHED_NOOP),y)
HW_C_SRCS += common/sched_noop.c
endif
Expand Down
2 changes: 2 additions & 0 deletions hypervisor/arch/x86/guest/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,8 @@ int32_t create_vm(uint16_t vm_id, uint64_t pcpu_bitmap, struct acrn_vm_config *v
passthrough_smbios(vm, get_acrn_boot_info());
#endif

vm->sw.vm_event_sbuf = NULL;

status = init_vpci(vm);
if (status == 0) {
enable_iommu();
Expand Down
4 changes: 4 additions & 0 deletions hypervisor/common/sbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <errno.h>
#include <asm/cpu.h>
#include <asm/per_cpu.h>
#include <vm_event.h>

uint32_t sbuf_next_ptr(uint32_t pos_arg,
uint32_t span, uint32_t scope)
Expand Down Expand Up @@ -93,6 +94,9 @@ int32_t sbuf_setup_common(struct acrn_vm *vm, uint16_t cpu_id, uint32_t sbuf_id,
case ACRN_ASYNCIO:
ret = init_asyncio(vm, hva);
break;
case ACRN_VM_EVENT:
ret = init_vm_event(vm, hva);
break;
default:
pr_err("%s not support sbuf_id %d", __func__, sbuf_id);
ret = -1;
Expand Down
48 changes: 48 additions & 0 deletions hypervisor/common/vm_event.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2020-2023 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#include <errno.h>
#include <util.h>
#include <acrn_hv_defs.h>
#include <asm/guest/vm.h>
#include <vm_event.h>
#include <sbuf.h>

int32_t init_vm_event(struct acrn_vm *vm, uint64_t *hva)
{
struct shared_buf *sbuf = (struct shared_buf *)hva;
int ret = -1;

stac();
if (sbuf != NULL) {
if (sbuf->magic == SBUF_MAGIC) {
vm->sw.vm_event_sbuf = sbuf;
spinlock_init(&vm->vm_event_lock);
ret = 0;
}
}
clac();

return ret;
}

int32_t send_vm_event(struct acrn_vm *vm, struct vm_event *event)
{
struct shared_buf *sbuf = (struct shared_buf *)vm->sw.vm_event_sbuf;
int32_t ret = -ENODEV;
uint32_t size_sent;

if (sbuf != NULL) {
spinlock_obtain(&vm->vm_event_lock);
size_sent = sbuf_put(sbuf, (uint8_t *)event);
spinlock_release(&vm->vm_event_lock);
if (size_sent == sizeof(struct vm_event)) {
arch_fire_hsm_interrupt();
ret = 0;
}
}
return ret;
}
2 changes: 2 additions & 0 deletions hypervisor/include/arch/x86/asm/guest/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct vm_sw_info {
/* HVA to IO shared page */
void *io_shared_page;
void *asyncio_sbuf;
void *vm_event_sbuf;
/* If enable IO completion polling mode */
bool is_polling_ioreq;
};
Expand Down Expand Up @@ -146,6 +147,7 @@ struct acrn_vm {
struct asyncio_desc aio_desc[ACRN_ASYNCIO_MAX];
struct list_head aiodesc_queue;
spinlock_t asyncio_lock; /* Spin-lock used to protect asyncio add/remove for a VM */
spinlock_t vm_event_lock;

enum vpic_wire_mode wire_mode;
struct iommu_domain *iommu; /* iommu domain of this VM */
Expand Down
16 changes: 16 additions & 0 deletions hypervisor/include/common/vm_event.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* Copyright (C) 2019-2023 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#ifndef VM_EVENT_H
#define VM_EVENT_H

#include <types.h>
#include <acrn_common.h>

int32_t init_vm_event(struct acrn_vm *vm, uint64_t *hva);
int32_t send_vm_event(struct acrn_vm *vm, struct vm_event *event);

#endif /* VM_EVENT_H */
48 changes: 48 additions & 0 deletions hypervisor/include/public/acrn_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@ enum {
/* The sbuf with above ids are created each pcpu */
ACRN_SBUF_PER_PCPU_ID_MAX,
ACRN_ASYNCIO = 64,
ACRN_VM_EVENT,
};

/* Make sure sizeof(struct shared_buf) == SBUF_HEAD_SIZE */
Expand All @@ -792,6 +793,53 @@ struct shared_buf {
uint32_t padding[6];
};

/**
* VM event architecture:
* +------------------------------------------------------+
* | Service VM |
* | +----------------------------+ |
* | | DM +--------------------+ | |
* | | | [ event source ] | | |
* | | +-+------------+-----+ | |
* | | | (eventfd) |(sbuf) | |
* | | v v | |
* | | +------------------------+ | (socket) +---------+ |
* | | | [event deliver logic] |-+---------->| Libvirt | |
* | | +------------------------+ | +---------+ |
* | | ^ ^ | |
* | +-------|------------|-------+ |
* | | (eventfd) | (sbuf) |
* +---------|------------|-------------------------------+
* +---------|------------|-------------------------------+
* | kernel [HSM] | |
* | ^ | |
* +---------|------------|-------------------------------+
* |upcall |
* +---------+------------+-------------------------------+
* | HV [ event source ] |
* +------------------------------------------------------+
*
* For event sources in HV
* - HV puts the event in the shared ring sbuf.
* - The hypervisor notifies the service VM via upcall.
* - HSM in the service VM notifies device model via eventfd.
* - The device model fetches and handles events from the shared ring sbuf.
* For event sources in DM
* - DM puts the event in the DM event ring sbuf.
* - DM notifies event delivery logic via eventfd.
* - The event delivery logic fetches and handles events from the DM event ring sbuf.
*/
#define VM_EVENT_RTC_CHG 0U
#define VM_EVENT_POWEROFF 1U
#define VM_EVENT_TRIPLE_FAULT 2U

#define VM_EVENT_DATA_LEN 28U

struct vm_event {
uint32_t type;
uint8_t event_data[VM_EVENT_DATA_LEN];
};

/**
* @}
*/
Expand Down

0 comments on commit 581ec58

Please sign in to comment.