mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-10 12:32:45 +00:00
hv: hypercalls: refactor permission-checking and dispatching logic
The current permission-checking and dispatching mechanism of hypercalls is not unified because: 1. Some hypercalls require the exact vCPU initiating the call, while the others only need to know the VM. 2. Different hypercalls have different permission requirements: the trusty-related ones are enabled by a guest flag, while the others require the initiating VM to be the Service OS. Without a unified logic it could be hard to scale when more kinds of hypercalls are added later. The objectives of this patch are as follows. 1. All hypercalls have the same prototype and are dispatched by a unified logic. 2. Permissions are checked by a unified logic without consulting the hypercall ID. To achieve the first objective, this patch modifies the type of the first parameter of hcall_* functions (which are the callbacks implementing the hypercalls) from `struct acrn_vm *` to `struct acrn_vcpu *`. The doxygen-style documentations are updated accordingly. To achieve the second objective, this patch adds to `struct hc_dispatch` a `permission_flags` field which specifies the guest flags that must ALL be set for a VM to be able to invoke the hypercall. The default value (which is 0UL) indicates that this hypercall is for SOS only. Currently only the `permission_flag` of trusty-related hypercalls have the non-zero value GUEST_FLAG_SECURE_WORLD_ENABLED. With `permission_flag`, the permission checking logic of hypercalls is unified as follows. 1. General checks i. If the VM is neither SOS nor having any guest flag that allows certain hypercalls, it gets #UD upon executing the `vmcall` instruction. ii. If the VM is allowed to execute the `vmcall` instruction, but attempts to execute it in ring 1, 2 or 3, the VM gets #GP(0). 2. Hypercall-specific checks i. If the hypercall is for SOS (i.e. `permission_flag` is 0), the initiating VM must be SOS and the specified target VM cannot be a pre-launched VM. Otherwise the hypercall returns -EINVAL without further actions. ii. If the hypercall requires certain guest flags, the initiating VM must have all the required flags. Otherwise the hypercall returns -EINVAL without further actions. iii. A hypercall with an unknown hypercall ID makes the hypercall returns -EINVAL without further actions. The logic above is different from the current implementation in the following aspects. 1. A pre-launched VM now gets #UD (rather than #GP(0)) when it attempts to execute `vmcall` in ring 1, 2 or 3. 2. A pre-launched VM now gets #UD (rather than the return value -EPERM) when it attempts to execute a trusty hypercall in ring 0. 3. The SOS now gets the return value -EINVAL (rather than -EPERM) when it attempts to invoke a trusty hypercall. 4. A post-launched VM with trusty support now gets the return value -EINVAL (rather than #UD) when it attempts to invoke a non-trusty hypercall or an invalid hypercall. v1 -> v2: - Update documentation that describe hypercall behavior. - Fix Doxygen warnings Tracked-On: #5924 Signed-off-by: Junjie Mao <junjie.mao@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
8fcd868a50
commit
ea4eadf0a5
@ -599,13 +599,16 @@ As shown in :numref:`security-hir`, there are some restrictions for
|
||||
hypercall invocation in the hypervisor design:
|
||||
|
||||
#. Hypercalls from ring 1~3 of any guest VM are not allowed. The
|
||||
hypervisor must discard such hypercalls silently. Only ring-0
|
||||
hypervisor must discard such hypercalls and inject ``#GP(0)`` instead. Only ring-0
|
||||
hypercalls from the guest VM are handled by the hypervisor.
|
||||
#. All the hypercalls (except world\_switch hypercall) must be called
|
||||
from the ring-0 driver of the Service VM.
|
||||
World\_switch Hypercall is used by the TIPC (Trusty IPC) driver to
|
||||
switch guest VM context between secure world and non-secure world.
|
||||
Further details will be discussed in the :ref:`secure_trusty` section.
|
||||
When a vCPU issues an unpermitted hypercall, the hypervisor shall either
|
||||
inject ``#UD`` (if the VM cannot issue hypercalls at all) or return ``-EINVAL``
|
||||
(if the VM is allowed to issue hypercalls but not this specific one).
|
||||
#. For those hypercalls that may result in data inconsistent intra hypervisor
|
||||
when they are executed concurrently, such as ``hcall_create_vm()``
|
||||
``hcll_destroy_vm()`` etc. spinlock is used to ensure these hypercalls
|
||||
|
@ -11,10 +11,16 @@ power management, and secure world switch.
|
||||
|
||||
There are some restrictions for hypercall and upcall:
|
||||
|
||||
#. Only specific VMs (currently the Service VM and the VM with trusty enabled)
|
||||
can invoke hypercalls. A VM that cannot invoke hypercalls will get ``#UD``
|
||||
(i.e. invalid opcode exception).
|
||||
#. Only ring 0 hypercalls from the guest VM are handled by the hypervisor;
|
||||
otherwise, the hypervisor will inject GP to the Guest VM.
|
||||
#. All the hypercalls (except secure world hypercalls) must be called from the Service VM;
|
||||
otherwise, the hypervisor will inject UD to the Guest VM.
|
||||
otherwise, the hypervisor will inject ``#GP(0)`` (i.e. generation protection
|
||||
exception with error code ``0``) to the Guest VM.
|
||||
#. Each VM is permitted to invoke a certain subset of hypercalls. Currently a VM
|
||||
with trusty enabled is allowed to invoke trusty hypercalls, and the Service
|
||||
VM is allowed to invoke the other hypercalls. A VM that invokes an
|
||||
unpermitted hypercall will get the return value ``-EINVAL``.
|
||||
see :ref:`secure-hypervisor-interface` for a detailed description.
|
||||
#. The hypervisor needs to protect the critical resources such as global VM and VCPU structures
|
||||
for VM and VCPU management hypercalls.
|
||||
|
@ -16,8 +16,15 @@
|
||||
#include <logmsg.h>
|
||||
|
||||
struct hc_dispatch {
|
||||
/* handler(struct acrn_vm *sos_vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2) */
|
||||
int32_t (*handler)(struct acrn_vm *, struct acrn_vm *, uint64_t, uint64_t);
|
||||
int32_t (*handler)(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/* The permission_flags is a bitmap of guest flags indicating whether a VM can invoke this hypercall:
|
||||
*
|
||||
* - If permission_flags == 0UL (which is the default value), this hypercall can only be invoked by the SOS.
|
||||
* - Otherwise, this hypercall can only be invoked by a VM whose guest flags have ALL set bits in
|
||||
* permission_flags.
|
||||
*/
|
||||
uint64_t permission_flags;
|
||||
};
|
||||
|
||||
/* VM Dispatch table for Exit condition handling */
|
||||
@ -85,9 +92,20 @@ static const struct hc_dispatch hc_dispatch_table[] = {
|
||||
[HC_IDX(HC_PROFILING_OPS)] = {
|
||||
.handler = hcall_profiling_ops},
|
||||
[HC_IDX(HC_GET_HW_INFO)] = {
|
||||
.handler = hcall_get_hw_info}
|
||||
.handler = hcall_get_hw_info},
|
||||
[HC_IDX(HC_INITIALIZE_TRUSTY)] = {
|
||||
.handler = hcall_initialize_trusty,
|
||||
.permission_flags = GUEST_FLAG_SECURE_WORLD_ENABLED},
|
||||
[HC_IDX(HC_WORLD_SWITCH)] = {
|
||||
.handler = hcall_world_switch,
|
||||
.permission_flags = GUEST_FLAG_SECURE_WORLD_ENABLED},
|
||||
[HC_IDX(HC_SAVE_RESTORE_SWORLD_CTX)] = {
|
||||
.handler = hcall_save_restore_sworld_ctx,
|
||||
.permission_flags = GUEST_FLAG_SECURE_WORLD_ENABLED},
|
||||
};
|
||||
|
||||
#define GUEST_FLAGS_ALLOWING_HYPERCALLS GUEST_FLAG_SECURE_WORLD_ENABLED
|
||||
|
||||
struct acrn_vm *parse_target_vm(struct acrn_vm *sos_vm, uint64_t hcall_id, uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *target_vm = NULL;
|
||||
@ -139,32 +157,43 @@ struct acrn_vm *parse_target_vm(struct acrn_vm *sos_vm, uint64_t hcall_id, uint6
|
||||
return target_vm;
|
||||
}
|
||||
|
||||
static int32_t dispatch_sos_hypercall(const struct acrn_vcpu *vcpu)
|
||||
static int32_t dispatch_hypercall(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
int32_t ret = -EINVAL;
|
||||
struct hc_dispatch *dispatch = NULL;
|
||||
struct acrn_vm *sos_vm = vcpu->vm;
|
||||
/* hypercall ID from guest*/
|
||||
uint64_t hcall_id = vcpu_get_gpreg(vcpu, CPU_REG_R8);
|
||||
/* hypercall param1 from guest*/
|
||||
uint64_t param1 = vcpu_get_gpreg(vcpu, CPU_REG_RDI);
|
||||
/* hypercall param2 from guest*/
|
||||
uint64_t param2 = vcpu_get_gpreg(vcpu, CPU_REG_RSI);
|
||||
struct acrn_vm *target_vm = parse_target_vm(sos_vm, hcall_id, param1, param2);
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
uint64_t guest_flags = get_vm_config(vm->vm_id)->guest_flags; /* hypercall ID from guest */
|
||||
uint64_t hcall_id = vcpu_get_gpreg(vcpu, CPU_REG_R8); /* hypercall ID from guest */
|
||||
|
||||
if (((target_vm == sos_vm)
|
||||
|| (((target_vm != NULL) && (target_vm != sos_vm) && is_postlaunched_vm(target_vm))))
|
||||
&& (HC_IDX(hcall_id) < ARRAY_SIZE(hc_dispatch_table))) {
|
||||
if (HC_IDX(hcall_id) < ARRAY_SIZE(hc_dispatch_table)) {
|
||||
const struct hc_dispatch *dispatch = &(hc_dispatch_table[HC_IDX(hcall_id)]);
|
||||
uint64_t permission_flags = dispatch->permission_flags;
|
||||
|
||||
/* Calculate dispatch table entry */
|
||||
dispatch = (struct hc_dispatch *)(hc_dispatch_table + HC_IDX(hcall_id));
|
||||
if (dispatch->handler != NULL) {
|
||||
get_vm_lock(target_vm);
|
||||
ret = dispatch->handler(sos_vm, target_vm, param1, param2);
|
||||
put_vm_lock(target_vm);
|
||||
}
|
||||
uint64_t param1 = vcpu_get_gpreg(vcpu, CPU_REG_RDI); /* hypercall param1 from guest */
|
||||
uint64_t param2 = vcpu_get_gpreg(vcpu, CPU_REG_RSI); /* hypercall param2 from guest */
|
||||
|
||||
if ((permission_flags == 0UL) && is_sos_vm(vm)) {
|
||||
/* A permission_flags of 0 indicates that this hypercall is for SOS to manage
|
||||
* post-launched VMs.
|
||||
*/
|
||||
struct acrn_vm *target_vm = parse_target_vm(vm, hcall_id, param1, param2);
|
||||
|
||||
if ((target_vm != NULL) && !is_prelaunched_vm(target_vm)) {
|
||||
get_vm_lock(target_vm);
|
||||
ret = dispatch->handler(vcpu, target_vm, param1, param2);
|
||||
put_vm_lock(target_vm);
|
||||
}
|
||||
} else if ((permission_flags != 0UL) &&
|
||||
((guest_flags & permission_flags) == permission_flags)) {
|
||||
ret = dispatch->handler(vcpu, vcpu->vm, param1, param2);
|
||||
} else {
|
||||
/* The vCPU is not allowed to invoke the given hypercall. Keep `ret` as -EINVAL and no
|
||||
* further actions required.
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -179,25 +208,27 @@ int32_t vmcall_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
/* hypercall ID from guest*/
|
||||
uint64_t hypcall_id = vcpu_get_gpreg(vcpu, CPU_REG_R8);
|
||||
uint64_t guest_flags = get_vm_config(vm->vm_id)->guest_flags;
|
||||
|
||||
if (!is_hypercall_from_ring0()) {
|
||||
vcpu_inject_gp(vcpu, 0U);
|
||||
ret = -EACCES;
|
||||
} else if (hypcall_id == HC_WORLD_SWITCH) {
|
||||
ret = hcall_world_switch(vcpu);
|
||||
} else if (hypcall_id == HC_INITIALIZE_TRUSTY) {
|
||||
/* hypercall param1 from guest*/
|
||||
uint64_t param1 = vcpu_get_gpreg(vcpu, CPU_REG_RDI);
|
||||
|
||||
ret = hcall_initialize_trusty(vcpu, param1);
|
||||
} else if (hypcall_id == HC_SAVE_RESTORE_SWORLD_CTX) {
|
||||
ret = hcall_save_restore_sworld_ctx(vcpu);
|
||||
} else if (is_sos_vm(vm)) {
|
||||
/* Dispatch the hypercall handler */
|
||||
ret = dispatch_sos_hypercall(vcpu);
|
||||
} else {
|
||||
/*
|
||||
* The following permission checks are applied to hypercalls.
|
||||
*
|
||||
* 1. Only SOS and VMs with specific guest flags (referred to as 'allowed VMs' hereinafter) can invoke
|
||||
* hypercalls by executing the `vmcall` instruction. Attempts to execute the `vmcall` instruction in the
|
||||
* other VMs will trigger #UD.
|
||||
* 2. Attempts to execute the `vmcall` instruction from ring 1, 2 or 3 in an allowed VM will trigger #GP(0).
|
||||
* 3. An allowed VM is permitted to only invoke some of the supported hypercalls depending on its load order and
|
||||
* guest flags. Attempts to invoke an unpermitted hypercall will make a vCPU see -EINVAL as the return
|
||||
* value. No exception is triggered in this case.
|
||||
*/
|
||||
if (!is_sos_vm(vm) && ((guest_flags & GUEST_FLAGS_ALLOWING_HYPERCALLS) == 0UL)) {
|
||||
vcpu_inject_ud(vcpu);
|
||||
ret = -ENODEV;
|
||||
} else if (!is_hypercall_from_ring0()) {
|
||||
vcpu_inject_gp(vcpu, 0U);
|
||||
ret = -EACCES;
|
||||
} else {
|
||||
ret = dispatch_hypercall(vcpu);
|
||||
}
|
||||
|
||||
if ((ret != -EACCES) && (ret != -ENODEV)) {
|
||||
|
@ -75,31 +75,31 @@ inline static bool is_severity_pass(uint16_t target_vmid)
|
||||
*
|
||||
* The function offline specific vcpu from SOS.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param param1 lapic id of the vcpu which wants to offline
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_sos_offline_cpu(struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_sos_offline_cpu(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct acrn_vcpu *vcpu;
|
||||
struct acrn_vcpu *target_vcpu;
|
||||
uint16_t i;
|
||||
int32_t ret = 0;
|
||||
uint64_t lapicid = param1;
|
||||
|
||||
pr_info("sos offline cpu with lapicid %ld", lapicid);
|
||||
|
||||
foreach_vcpu(i, vm, vcpu) {
|
||||
if (vlapic_get_apicid(vcpu_vlapic(vcpu)) == lapicid) {
|
||||
foreach_vcpu(i, vcpu->vm, target_vcpu) {
|
||||
if (vlapic_get_apicid(vcpu_vlapic(target_vcpu)) == lapicid) {
|
||||
/* should not offline BSP */
|
||||
if (vcpu->vcpu_id == BSP_CPU_ID) {
|
||||
if (target_vcpu->vcpu_id == BSP_CPU_ID) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
zombie_vcpu(vcpu, VCPU_ZOMBIE);
|
||||
offline_vcpu(vcpu);
|
||||
zombie_vcpu(target_vcpu, VCPU_ZOMBIE);
|
||||
offline_vcpu(target_vcpu);
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,14 +111,14 @@ int32_t hcall_sos_offline_cpu(struct acrn_vm *vm, __unused struct acrn_vm *targe
|
||||
*
|
||||
* The function only return api version information when VM is SOS_VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param param1 guest physical memory address. The api version returned
|
||||
* will be copied to this gpa
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_get_api_version(struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_get_api_version(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct hc_api_version version;
|
||||
@ -126,7 +126,7 @@ int32_t hcall_get_api_version(struct acrn_vm *vm, __unused struct acrn_vm *targe
|
||||
version.major_version = HV_API_MAJOR_VERSION;
|
||||
version.minor_version = HV_API_MINOR_VERSION;
|
||||
|
||||
return copy_to_gpa(vm, &version, param1, sizeof(version));
|
||||
return copy_to_gpa(vcpu->vm, &version, param1, sizeof(version));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,15 +135,16 @@ int32_t hcall_get_api_version(struct acrn_vm *vm, __unused struct acrn_vm *targe
|
||||
* The function returns basic hardware or configuration information
|
||||
* for the current platform.
|
||||
*
|
||||
* @param vm Pointer to VM data structure.
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall.
|
||||
* @param param1 GPA pointer to struct hc_platform_info.
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non zero in case of error.
|
||||
*/
|
||||
int32_t hcall_get_platform_info(struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_get_platform_info(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
struct hc_platform_info pi = { 0 };
|
||||
uint32_t entry_size = sizeof(struct acrn_vm_config);
|
||||
int32_t ret;
|
||||
@ -178,16 +179,18 @@ int32_t hcall_get_platform_info(struct acrn_vm *vm, __unused struct acrn_vm *tar
|
||||
* limitation for calling times of this function, will add MAX_VM_NUM
|
||||
* support later.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 guest physical memory address. This gpa points to
|
||||
* struct acrn_create_vm
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM, vm_config != NULL
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @pre get_vm_config(target_vm->vm_id) != NULL
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_create_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, __unused uint64_t param2)
|
||||
int32_t hcall_create_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
uint16_t vmid = target_vm->vm_id;
|
||||
int32_t ret = -1;
|
||||
struct acrn_vm *tgt_vm = NULL;
|
||||
@ -252,7 +255,7 @@ int32_t hcall_create_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_destroy_vm(__unused struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
int32_t hcall_destroy_vm(__unused struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
int32_t ret = -1;
|
||||
@ -276,7 +279,7 @@ int32_t hcall_destroy_vm(__unused struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_start_vm(__unused struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
int32_t hcall_start_vm(__unused struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
int32_t ret = -1;
|
||||
@ -301,7 +304,7 @@ int32_t hcall_start_vm(__unused struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_pause_vm(__unused struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
int32_t hcall_pause_vm(__unused struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
int32_t ret = -1;
|
||||
@ -326,7 +329,7 @@ int32_t hcall_pause_vm(__unused struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_reset_vm(__unused struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
int32_t hcall_reset_vm(__unused struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
int32_t ret = -1;
|
||||
@ -345,18 +348,20 @@ int32_t hcall_reset_vm(__unused struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
* it's only applied to BSP. AP always uses fixed init regs.
|
||||
* The function will return -1 if the targat VM or BSP doesn't exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to
|
||||
* struct acrn_vcpu_regs
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_vcpu_regs(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_set_vcpu_regs(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
struct acrn_set_vcpu_regs vcpu_regs;
|
||||
struct acrn_vcpu *vcpu;
|
||||
struct acrn_vcpu *target_vcpu;
|
||||
int32_t ret = -1;
|
||||
|
||||
/* Only allow setup init ctx while target_vm is inactive */
|
||||
@ -365,10 +370,10 @@ int32_t hcall_set_vcpu_regs(struct acrn_vm *vm, struct acrn_vm *target_vm, __unu
|
||||
} else if (vcpu_regs.vcpu_id >= MAX_VCPUS_PER_VM) {
|
||||
pr_err("%s: invalid vcpu_id for set_vcpu_regs\n", __func__);
|
||||
} else {
|
||||
vcpu = vcpu_from_vid(target_vm, vcpu_regs.vcpu_id);
|
||||
if (vcpu->state != VCPU_OFFLINE) {
|
||||
target_vcpu = vcpu_from_vid(target_vm, vcpu_regs.vcpu_id);
|
||||
if (target_vcpu->state != VCPU_OFFLINE) {
|
||||
if (is_valid_cr0_cr4(vcpu_regs.vcpu_regs.cr0, vcpu_regs.vcpu_regs.cr4)) {
|
||||
set_vcpu_regs(vcpu, &(vcpu_regs.vcpu_regs));
|
||||
set_vcpu_regs(target_vcpu, &(vcpu_regs.vcpu_regs));
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
@ -378,7 +383,7 @@ int32_t hcall_set_vcpu_regs(struct acrn_vm *vm, struct acrn_vm *target_vm, __unu
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t hcall_create_vcpu(__unused struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_create_vcpu(__unused struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
return 0;
|
||||
@ -391,15 +396,16 @@ int32_t hcall_create_vcpu(__unused struct acrn_vm *vm, __unused struct acrn_vm *
|
||||
* or IOAPIC, normally it triggers an edge IRQ.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 info for irqline
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_irqline(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_set_irqline(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
uint32_t irq_pic;
|
||||
int32_t ret = -1;
|
||||
struct acrn_irqline_ops *ops = (struct acrn_irqline_ops *)¶m2;
|
||||
@ -431,15 +437,16 @@ int32_t hcall_set_irqline(struct acrn_vm *vm, struct acrn_vm *target_vm, __unuse
|
||||
* Inject a MSI interrupt for a VM.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to struct acrn_msi_entry
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_inject_msi(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_inject_msi(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -1;
|
||||
|
||||
if (is_severity_pass(target_vm->vm_id) && !is_poweroff_vm(target_vm)) {
|
||||
@ -459,16 +466,18 @@ int32_t hcall_inject_msi(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused
|
||||
* Set the ioreq share buffer for a VM.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to
|
||||
* struct acrn_set_ioreq_buffer
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_ioreq_buffer(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_set_ioreq_buffer(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
uint64_t hpa;
|
||||
uint16_t i;
|
||||
int32_t ret = -1;
|
||||
@ -509,10 +518,10 @@ int32_t hcall_set_ioreq_buffer(struct acrn_vm *vm, struct acrn_vm *target_vm, __
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_notify_ioreq_finish(__unused struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
int32_t hcall_notify_ioreq_finish(__unused struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vcpu *vcpu;
|
||||
struct acrn_vcpu *target_vcpu;
|
||||
int32_t ret = -1;
|
||||
uint16_t vcpu_id = (uint16_t)param2;
|
||||
|
||||
@ -526,9 +535,9 @@ int32_t hcall_notify_ioreq_finish(__unused struct acrn_vm *vm, struct acrn_vm *t
|
||||
pr_err("%s, failed to get VCPU %d context from VM %d\n",
|
||||
__func__, vcpu_id, target_vm->vm_id);
|
||||
} else {
|
||||
vcpu = vcpu_from_vid(target_vm, vcpu_id);
|
||||
if (!vcpu->vm->sw.is_polling_ioreq) {
|
||||
signal_event(&vcpu->events[VCPU_EVENT_IOREQ]);
|
||||
target_vcpu = vcpu_from_vid(target_vm, vcpu_id);
|
||||
if (!target_vcpu->vm->sw.is_polling_ioreq) {
|
||||
signal_event(&target_vcpu->events[VCPU_EVENT_IOREQ]);
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
@ -538,7 +547,7 @@ int32_t hcall_notify_ioreq_finish(__unused struct acrn_vm *vm, struct acrn_vm *t
|
||||
}
|
||||
|
||||
/**
|
||||
*@pre Pointer vm shall point to SOS_VM
|
||||
*@pre is_sos_vm(vm)
|
||||
*@pre gpa2hpa(vm, region->sos_vm_gpa) != INVALID_HPA
|
||||
*/
|
||||
static void add_vm_memory_region(struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
@ -589,7 +598,7 @@ static void add_vm_memory_region(struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
}
|
||||
|
||||
/**
|
||||
*@pre Pointer vm shall point to SOS_VM
|
||||
*@pre is_sos_vm(vm)
|
||||
*/
|
||||
static int32_t set_vm_memory_region(struct acrn_vm *vm,
|
||||
struct acrn_vm *target_vm, const struct vm_memory_region *region)
|
||||
@ -624,17 +633,18 @@ static int32_t set_vm_memory_region(struct acrn_vm *vm,
|
||||
/**
|
||||
* @brief setup ept memory mapping for multi regions
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 guest physical address. This gpa points to
|
||||
* struct set_memmaps
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_vm_memory_regions(struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
int32_t hcall_set_vm_memory_regions(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
struct set_regions regions;
|
||||
struct vm_memory_region mr;
|
||||
uint32_t idx;
|
||||
@ -666,7 +676,7 @@ int32_t hcall_set_vm_memory_regions(struct acrn_vm *vm, struct acrn_vm *target_v
|
||||
}
|
||||
|
||||
/**
|
||||
*@pre Pointer vm shall point to SOS_VM
|
||||
*@pre is_sos_vm(vm)
|
||||
*/
|
||||
static int32_t write_protect_page(struct acrn_vm *vm,const struct wp_data *wp)
|
||||
{
|
||||
@ -712,17 +722,18 @@ static int32_t write_protect_page(struct acrn_vm *vm,const struct wp_data *wp)
|
||||
/**
|
||||
* @brief change guest memory page write permission
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to
|
||||
* struct wp_data
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_write_protect_page(struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
int32_t hcall_write_protect_page(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -1;
|
||||
uint64_t wp_gpa = param2;
|
||||
|
||||
@ -745,15 +756,16 @@ int32_t hcall_write_protect_page(struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
* Translate guest physical address to host physical address for a VM.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to struct vm_gpa2hpa
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_gpa_to_hpa(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_gpa_to_hpa(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -1;
|
||||
struct vm_gpa2hpa v_gpa2hpa;
|
||||
|
||||
@ -777,16 +789,18 @@ int32_t hcall_gpa_to_hpa(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused
|
||||
/**
|
||||
* @brief Assign one PCI dev to a VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_assign_pcidev including assign PCI device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_assign_pcidev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_assign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_assign_pcidev pcidev;
|
||||
|
||||
@ -805,16 +819,18 @@ int32_t hcall_assign_pcidev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unu
|
||||
/**
|
||||
* @brief Deassign one PCI dev from a VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_assign_pcidev including deassign PCI device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_deassign_pcidev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_deassign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_assign_pcidev pcidev;
|
||||
|
||||
@ -833,16 +849,18 @@ int32_t hcall_deassign_pcidev(struct acrn_vm *vm, struct acrn_vm *target_vm, __u
|
||||
/**
|
||||
* @brief Assign one MMIO dev to a VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_mmiodev including assign MMIO device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_assign_mmiodev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_assign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_mmiodev mmiodev;
|
||||
|
||||
@ -866,16 +884,18 @@ int32_t hcall_assign_mmiodev(struct acrn_vm *vm, struct acrn_vm *target_vm, __un
|
||||
/**
|
||||
* @brief Deassign one MMIO dev from a VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_mmiodev including deassign MMIO device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_deassign_mmiodev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_deassign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_mmiodev mmiodev;
|
||||
|
||||
@ -899,17 +919,18 @@ int32_t hcall_deassign_mmiodev(struct acrn_vm *vm, struct acrn_vm *target_vm, __
|
||||
/**
|
||||
* @brief Set interrupt mapping info of ptdev.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* hc_ptdev_irq including intr remapping info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_ptdev_intr_info(struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
int32_t hcall_set_ptdev_intr_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -1;
|
||||
|
||||
if (is_created_vm(target_vm)) {
|
||||
@ -950,17 +971,18 @@ int32_t hcall_set_ptdev_intr_info(struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
/**
|
||||
* @brief Clear interrupt mapping info of ptdev.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* hc_ptdev_irq including intr remapping info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_reset_ptdev_intr_info(struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
int32_t hcall_reset_ptdev_intr_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -1;
|
||||
|
||||
if (is_created_vm(target_vm) || is_paused_vm(target_vm)) {
|
||||
@ -1001,16 +1023,17 @@ int32_t hcall_reset_ptdev_intr_info(struct acrn_vm *vm, struct acrn_vm *target_v
|
||||
/**
|
||||
* @brief Get VCPU Power state.
|
||||
*
|
||||
* @param vm pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 cmd to show get which VCPU power state data
|
||||
* @param param2 VCPU power state data
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_get_cpu_pm_state(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_get_cpu_pm_state(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -1;
|
||||
uint64_t cmd = param1;
|
||||
|
||||
@ -1079,16 +1102,18 @@ int32_t hcall_get_cpu_pm_state(struct acrn_vm *vm, struct acrn_vm *target_vm, ui
|
||||
/**
|
||||
* @brief Get VCPU a VM's interrupt count data.
|
||||
*
|
||||
* @param vm pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_intr_monitor
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_vm_intr_monitor(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_vm_intr_monitor(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t status = -EINVAL;
|
||||
struct acrn_intr_monitor *intr_hdr;
|
||||
uint64_t hpa;
|
||||
@ -1133,13 +1158,13 @@ int32_t hcall_vm_intr_monitor(struct acrn_vm *vm, struct acrn_vm *target_vm, __u
|
||||
* not called, the hypervisor will use the default notifier vector(0xF3)
|
||||
* to notify the SOS kernel.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param param1 the expected notifier vector from guest
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_callback_vector(__unused struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_set_callback_vector(__unused struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
int32_t ret;
|
||||
@ -1175,16 +1200,17 @@ static struct emul_dev_ops *find_emul_dev_ops(struct acrn_emul_dev *dev)
|
||||
/**
|
||||
* @brief Add an emulated device in hypervisor.
|
||||
*
|
||||
* @param vm pointer to VM data structure
|
||||
* @param vmid ID of the VM
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param guest physical address. This gpa points to data structure of
|
||||
* acrn_emul_dev including information about PCI or legacy devices
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_add_vdev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_add_vdev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_emul_dev dev;
|
||||
struct emul_dev_ops *op;
|
||||
@ -1206,16 +1232,17 @@ int32_t hcall_add_vdev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused u
|
||||
/**
|
||||
* @brief Remove an emulated device in hypervisor.
|
||||
*
|
||||
* @param vm pointer to VM data structure
|
||||
* @param vmid ID of the VM
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param guest physical address. This gpa points to data structure of
|
||||
* acrn_emul_dev including information about PCI or legacy devices
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_remove_vdev(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_remove_vdev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, __unused uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -EINVAL;
|
||||
struct acrn_emul_dev dev;
|
||||
struct pci_vdev *vdev;
|
||||
|
@ -24,7 +24,8 @@
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_world_switch(struct acrn_vcpu *vcpu)
|
||||
int32_t hcall_world_switch(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
int32_t next_world_id = !(vcpu->arch.cur_context);
|
||||
int32_t ret = -EPERM;
|
||||
@ -46,12 +47,12 @@ int32_t hcall_world_switch(struct acrn_vcpu *vcpu)
|
||||
* * The hypervisor needs to save current vCPU contexts (Normal World)
|
||||
*
|
||||
* @param vcpu Pointer to vCPU data structure
|
||||
* @param param guest physical address. This gpa points to
|
||||
* trusty_boot_param structure
|
||||
* @param param1 guest physical address. This gpa points to trusty_boot_param structure
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, uint64_t param)
|
||||
int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
int32_t ret = -EFAULT;
|
||||
|
||||
@ -60,7 +61,7 @@ int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, uint64_t param)
|
||||
&& (vcpu->arch.cur_context == NORMAL_WORLD)) {
|
||||
struct trusty_boot_param boot_param;
|
||||
|
||||
if (copy_from_gpa(vcpu->vm, &boot_param, param, sizeof(boot_param)) == 0) {
|
||||
if (copy_from_gpa(vcpu->vm, &boot_param, param1, sizeof(boot_param)) == 0) {
|
||||
if (initialize_trusty(vcpu, &boot_param)) {
|
||||
vcpu->vm->sworld_control.flag.active = 1UL;
|
||||
ret = 0;
|
||||
@ -80,7 +81,8 @@ int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, uint64_t param)
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_save_restore_sworld_ctx(struct acrn_vcpu *vcpu)
|
||||
int32_t hcall_save_restore_sworld_ctx(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret = -EINVAL;
|
||||
|
@ -17,16 +17,18 @@
|
||||
/**
|
||||
* @brief Execute profiling operation
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param param1 profiling command to be executed
|
||||
* @param param2 guest physical address. This gpa points to
|
||||
* data structure required by each command
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_profiling_ops(struct acrn_vm *vm, __unused struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)
|
||||
int32_t hcall_profiling_ops(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
uint64_t param1, uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
int32_t ret;
|
||||
uint64_t cmd = param1;
|
||||
|
||||
@ -70,16 +72,17 @@ int32_t hcall_profiling_ops(struct acrn_vm *vm, __unused struct acrn_vm *target_
|
||||
/**
|
||||
* @brief Setup a share buffer for a VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param param1 guest physical address. This gpa points to
|
||||
* struct sbuf_setup_param
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_setup_sbuf(struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_setup_sbuf(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
struct sbuf_setup_param ssp;
|
||||
uint64_t *hva;
|
||||
|
||||
@ -97,18 +100,19 @@ int32_t hcall_setup_sbuf(struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup the hypervisor NPK log.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param param1 guest physical address. This gpa points to
|
||||
* struct hv_npk_log_param
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_setup_hv_npk_log(struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
* @brief Setup the hypervisor NPK log.
|
||||
*
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param param1 guest physical address. This gpa points to
|
||||
* struct hv_npk_log_param
|
||||
*
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_setup_hv_npk_log(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct acrn_vm *vm = vcpu->vm;
|
||||
struct hv_npk_log_param npk_param;
|
||||
|
||||
if (copy_from_gpa(vm, &npk_param, param1, sizeof(npk_param)) != 0) {
|
||||
@ -123,16 +127,16 @@ int32_t hcall_setup_hv_npk_log(struct acrn_vm *vm, __unused struct acrn_vm *targ
|
||||
/**
|
||||
* @brief Get hardware related info
|
||||
*
|
||||
* @param vm Pointer to vm data structure
|
||||
* @param param Guest physical address pointing to struct acrn_hw_info
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param param1 Guest physical address pointing to struct acrn_hw_info
|
||||
*
|
||||
* @pre vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @pre param1 shall be a valid physical address
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -1 in case of error
|
||||
*/
|
||||
int32_t hcall_get_hw_info(struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_get_hw_info(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
struct acrn_hw_info hw_info;
|
||||
@ -140,5 +144,5 @@ int32_t hcall_get_hw_info(struct acrn_vm *vm, __unused struct acrn_vm *target_vm
|
||||
(void)memset((void *)&hw_info, 0U, sizeof(hw_info));
|
||||
|
||||
hw_info.cpu_num = get_pcpu_nums();
|
||||
return copy_to_gpa(vm, &hw_info, param1, sizeof(hw_info));
|
||||
return copy_to_gpa(vcpu->vm, &hw_info, param1, sizeof(hw_info));
|
||||
}
|
||||
|
@ -27,31 +27,31 @@ bool is_hypercall_from_ring0(void);
|
||||
*
|
||||
* The function offline specific vcpu from SOS.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm not used
|
||||
* @param param1 lapic id of the vcpu which wants to offline
|
||||
* @param param2 not used
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_sos_offline_cpu(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_sos_offline_cpu(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Get hypervisor api version
|
||||
*
|
||||
* The function only return api version information when VM is SOS_VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm not used
|
||||
* @param param1 guest physical memory address. The api version returned
|
||||
* will be copied to this gpa
|
||||
* @param param2 not used
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_get_api_version(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_get_api_version(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Get basic platform information.
|
||||
@ -59,15 +59,15 @@ int32_t hcall_get_api_version(struct acrn_vm *vm, struct acrn_vm *target_vm, uin
|
||||
* The function returns basic hardware or configuration information
|
||||
* for the current platform.
|
||||
*
|
||||
* @param vm Pointer to VM data structure.
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall.
|
||||
* @param target_vm not used
|
||||
* @param param1 GPA pointer to struct hc_platform_info.
|
||||
* @param param2 not used
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, -1 in case of error.
|
||||
*/
|
||||
int32_t hcall_get_platform_info(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_get_platform_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief create virtual machine
|
||||
@ -76,16 +76,16 @@ int32_t hcall_get_platform_info(struct acrn_vm *vm, struct acrn_vm *target_vm, u
|
||||
* limitation for calling times of this function, will add MAX_VM_NUM
|
||||
* support later.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 guest physical memory address. This gpa points to
|
||||
* struct acrn_create_vm
|
||||
* @param param2 not used
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_create_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_create_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief destroy virtual machine
|
||||
@ -93,14 +93,14 @@ int32_t hcall_create_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t
|
||||
* Destroy a virtual machine, it will pause target VM then shutdown it.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm not used
|
||||
* @param vcpu not used
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 not used
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_destroy_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_destroy_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief reset virtual machine
|
||||
@ -110,14 +110,14 @@ int32_t hcall_destroy_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t
|
||||
* each vcpu state and do some initialization for guest.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm not used
|
||||
* @param vcpu not used
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 not used
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_reset_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_reset_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief start virtual machine
|
||||
@ -126,14 +126,14 @@ int32_t hcall_reset_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t p
|
||||
* The function will return -1 if the target VM does not exist or the
|
||||
* IOReq buffer page for the VM is not ready.
|
||||
*
|
||||
* @param vm not used
|
||||
* @param vcpu not used
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 not used
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_start_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_start_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief pause virtual machine
|
||||
@ -142,14 +142,14 @@ int32_t hcall_start_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t p
|
||||
* will return 0 directly for success.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm not used
|
||||
* @param vcpu not used
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 not used
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_pause_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_pause_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief set vcpu regs
|
||||
@ -158,7 +158,7 @@ int32_t hcall_pause_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t p
|
||||
* it's only applied to BSP. AP always uses fixed init regs.
|
||||
* The function will return -1 if the targat VM or BSP doesn't exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to
|
||||
@ -166,7 +166,7 @@ int32_t hcall_pause_vm(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t p
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_vcpu_regs(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_set_vcpu_regs(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief set or clear IRQ line
|
||||
@ -175,15 +175,15 @@ int32_t hcall_set_vcpu_regs(struct acrn_vm *vm, struct acrn_vm *target_vm, uint6
|
||||
* or IOAPIC, normally it triggers an edge IRQ.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 info for irqline
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_irqline(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_set_irqline(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief inject MSI interrupt
|
||||
@ -191,15 +191,15 @@ int32_t hcall_set_irqline(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_
|
||||
* Inject a MSI interrupt for a VM.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to struct acrn_msi_entry
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_inject_msi(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_inject_msi(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief set ioreq shared buffer
|
||||
@ -207,16 +207,16 @@ int32_t hcall_inject_msi(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t
|
||||
* Set the ioreq share buffer for a VM.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to
|
||||
* struct acrn_set_ioreq_buffer
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_ioreq_buffer(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_set_ioreq_buffer(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief notify request done
|
||||
@ -224,42 +224,43 @@ int32_t hcall_set_ioreq_buffer(struct acrn_vm *vm, struct acrn_vm *target_vm, ui
|
||||
* Notify the requestor VCPU for the completion of an ioreq.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm not used
|
||||
* @param vcpu not used
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 vcpu ID of the requestor
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_notify_ioreq_finish(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_notify_ioreq_finish(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief setup ept memory mapping for multi regions
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 guest physical address. This gpa points to
|
||||
* struct set_memmaps
|
||||
* @param param2 not used
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_vm_memory_regions(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_set_vm_memory_regions(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief change guest memory page write permission
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to
|
||||
* struct wp_data
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_write_protect_page(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_write_protect_page(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief translate guest physical address to host physical address
|
||||
@ -267,154 +268,155 @@ int32_t hcall_write_protect_page(struct acrn_vm *vm, struct acrn_vm *target_vm,
|
||||
* Translate guest physical address to host physical address for a VM.
|
||||
* The function will return -1 if the target VM does not exist.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to struct vm_gpa2hpa
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_gpa_to_hpa(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_gpa_to_hpa(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Assign one PCI dev to VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_assign_pcidev including assign PCI device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_assign_pcidev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_assign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Deassign one PCI dev to VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_assign_pcidev including deassign PCI device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_deassign_pcidev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_deassign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Assign one MMIO dev to VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_mmiodev including assign MMIO device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_assign_mmiodev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_assign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Deassign one MMIO dev to VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_mmiodev including deassign MMIO device info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_deassign_mmiodev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_deassign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Add an emulated device in hypervisor.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_emul_dev including information about PCI or legacy devices
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_add_vdev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_add_vdev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Remove an emulated device in hypervisor.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_emul_dev including information about PCI or legacy devices
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_remove_vdev(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_remove_vdev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Set interrupt mapping info of ptdev.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* hc_ptdev_irq including intr remapping info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_ptdev_intr_info(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_set_ptdev_intr_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Clear interrupt mapping info of ptdev.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* hc_ptdev_irq including intr remapping info
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_reset_ptdev_intr_info(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_reset_ptdev_intr_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Get VCPU Power state.
|
||||
*
|
||||
* @param vm pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 cmd to show get which VCPU power state data
|
||||
* @param param2 VCPU power state data
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_get_cpu_pm_state(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_get_cpu_pm_state(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Get VCPU a VM's interrupt count data.
|
||||
*
|
||||
* @param vm pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm Pointer to target VM data structure
|
||||
* @param param1 not used
|
||||
* @param param2 guest physical address. This gpa points to data structure of
|
||||
* acrn_intr_monitor
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_vm_intr_monitor(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_vm_intr_monitor(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @defgroup trusty_hypercall Trusty Hypercalls
|
||||
@ -436,11 +438,14 @@ int32_t hcall_vm_intr_monitor(struct acrn_vm *vm, struct acrn_vm *target_vm, uin
|
||||
* vCPU contexts
|
||||
*
|
||||
* @param vcpu Pointer to VCPU data structure
|
||||
* @param target_vm not used
|
||||
* @param param1 not used
|
||||
* @param param2 not used
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
|
||||
int32_t hcall_world_switch(struct acrn_vcpu *vcpu);
|
||||
int32_t hcall_world_switch(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Initialize environment for Trusty-OS on a vCPU.
|
||||
@ -451,21 +456,27 @@ int32_t hcall_world_switch(struct acrn_vcpu *vcpu);
|
||||
* * The hypervisor needs to save current vCPU contexts (Normal World)
|
||||
*
|
||||
* @param vcpu Pointer to vCPU data structure
|
||||
* @param param guest physical address. This gpa points to
|
||||
* trusty_boot_param structure
|
||||
* @param target_vm not used
|
||||
* @param param1 guest physical address. This gpa points to
|
||||
* trusty_boot_param structure
|
||||
* @param param2 not used
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, uint64_t param);
|
||||
int32_t hcall_initialize_trusty(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Save/Restore Context of Secure World.
|
||||
*
|
||||
* @param vcpu Pointer to VCPU data structure
|
||||
* @param target_vm not used
|
||||
* @param param1 not used
|
||||
* @param param2 not used
|
||||
*
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_save_restore_sworld_ctx(struct acrn_vcpu *vcpu);
|
||||
int32_t hcall_save_restore_sworld_ctx(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
|
||||
uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @}
|
||||
@ -479,48 +490,48 @@ int32_t hcall_save_restore_sworld_ctx(struct acrn_vcpu *vcpu);
|
||||
* not called, the hypervisor will use the default notifier vector(0xF7)
|
||||
* to notify the SOS kernel.
|
||||
*
|
||||
* @param vm not used
|
||||
* @param vcpu not used
|
||||
* @param target_vm not used
|
||||
* @param param1 the expected notifier vector from guest
|
||||
* @param param2 not used
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_set_callback_vector(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_set_callback_vector(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Setup a share buffer for a VM.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm not used
|
||||
* @param param1 guest physical address. This gpa points to
|
||||
* struct sbuf_setup_param
|
||||
* @param param2 not used
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_setup_sbuf(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_setup_sbuf(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Setup the hypervisor NPK log.
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm not used
|
||||
* @param param1 guest physical address. This gpa points to
|
||||
* struct hv_npk_log_param
|
||||
* @param param2 not used
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_setup_hv_npk_log(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_setup_hv_npk_log(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Get hardware related info
|
||||
*
|
||||
* @param vm Pointer to vm data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm not used
|
||||
* @param param1 Guest physical address pointing to struct acrn_hw_info
|
||||
* @param param2 not used
|
||||
@ -531,23 +542,23 @@ int32_t hcall_setup_hv_npk_log(struct acrn_vm *vm, struct acrn_vm *target_vm, ui
|
||||
* @retval 0 on success
|
||||
* @retval -1 in case of error
|
||||
*/
|
||||
int32_t hcall_get_hw_info(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_get_hw_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
/**
|
||||
* @brief Execute profiling operation
|
||||
*
|
||||
* @param vm Pointer to VM data structure
|
||||
* @param vcpu Pointer to vCPU that initiates the hypercall
|
||||
* @param target_vm not used
|
||||
* @param param1 profiling command to be executed
|
||||
* @param param2 guest physical address. This gpa points to
|
||||
* data structure required by each command
|
||||
*
|
||||
* @pre Pointer vm shall point to SOS_VM
|
||||
* @pre is_sos_vm(vcpu->vm)
|
||||
* @return 0 on success, non-zero on error.
|
||||
*/
|
||||
int32_t hcall_profiling_ops(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_profiling_ops(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
|
||||
int32_t hcall_create_vcpu(struct acrn_vm *vm, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
int32_t hcall_create_vcpu(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -8,25 +8,25 @@
|
||||
#include <errno.h>
|
||||
#include <asm/guest/vm.h>
|
||||
|
||||
int32_t hcall_setup_sbuf(__unused struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_setup_sbuf(__unused struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int32_t hcall_setup_hv_npk_log(__unused struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_setup_hv_npk_log(__unused struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int32_t hcall_get_hw_info(__unused struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_get_hw_info(__unused struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
int32_t hcall_profiling_ops(__unused struct acrn_vm *vm, __unused struct acrn_vm *target_vm,
|
||||
int32_t hcall_profiling_ops(__unused struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_vm,
|
||||
__unused uint64_t param1, __unused uint64_t param2)
|
||||
{
|
||||
return -EPERM;
|
||||
|
Loading…
Reference in New Issue
Block a user