Implement the SBI IPI (Inter-Processor Interrupt) extension to enable
guest VMs to send software interrupts between virtual CPUs.
The implementation handles the SBI_IPI_SEND_IPI function call, which
allows a guest to target one or more vCPUs using either:
- A mask (bitmap of target harts relative to a base hart ID)
- Broadcast mode (when mask_base is UINT64_MAX)
The IPI is delivered by asserting the VS-level software interrupt
(VSSIP, bit 2) on each target vCPU. Proper validation is performed
to ensure hart IDs are within valid range and all masked harts exist.
Tracked-On: #8851
Signed-off-by: Haoyu Tang <haoyu.tang@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Implement the SBI TIME (Timer) extension to allow guest VMs to program
virtual timer interrupts through the SBI interface.
The implementation handles the SBI_TIME_SET_TIMER function call, which
allows guests to set the vstimecmp CSR to schedule timer interrupts.
The vstimecmp value is written directly to the CSR and saved in the
vCPU context.
Tracked-On: #8851
Signed-off-by: Haoyu Tang <haoyu.tang@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Replace SBI passthrough with proper virtualization of base extension
queries. For the Service VM, forward actual machine vendor/arch/impl
IDs from the underlying SBI. For guest VMs, provide dummy ACRN-specific
IDs to maintain isolation.
Changes:
- Return vSBI spec version 2.0 for GET_SPEC_VERSION
- Return ACRN implementation ID (55) and version for GET_IMP_ID/GET_IMP_VERSION
- Forward real mvendorid/marchid/mimpid to Service VM
- Provide dummy vendor/arch/impl IDs (0/0/0) to guest VMs
- Store machine IDs in vm_arch structure during VM initialization
- Remove unnecessary SBI passthrough for base extension queries
This provides better isolation and control over the virtual SBI
interface exposed to guests.
Tracked-On: #8851
Signed-off-by: Haoyu Tang <haoyu.tang@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Add wrapper functions to query machine vendor ID (mvendorid),
architecture ID (marchid), and implementation ID (mimpid) through
the SBI base extension.
These IDs identify the RISC-V processor vendor, microarchitecture,
and specific implementation respectively. The hypervisor needs to
retrieve these values from the underlying SBI firmware to forward
them to the Service VM via vSBI, allowing the Service VM to see
the actual hardware characteristics.
Tracked-On: #8851
Signed-off-by: Haoyu Tang <haoyu.tang@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Add virtual interrupt injection infrastructure for RISC-V hypervisor.
Implement vcpu_set_intr() and vcpu_clear_intr() to manage virtual
interrupt pending state by updating irqs_pending bitmap.
Add vcpu_inject_pending_intr() to inject pending interrupts into
VS-mode by updating HVIP CSR with atomic operations.
Tracked-On: #8844
Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Add virtual exception handling infrastructure for RISC-V hypervisor
and enables proper virtualization of RISC-V exceptions by allowing
the hypervisor to inject exceptions into guest VS-mode.
- Implement vcpu_set_trap() to inject traps to VS-mode
- Implement vcpu_queue_exception() to queue exceptions for vCPU injection
- Process pending exception requests in riscv_process_vcpu_requests()
v1->v2:
change vcpu_redirect_trap -> vcpu_set_trap
Tracked-On: #8844
Signed-off-by: Yi Y Sun <yi.y.sun@intel.com>
Signed-off-by: Jian Jun Chen <jian.jun.chen@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
RISC-V vcpu capability is represented by an ISA extension string.
Add API to adjust this string for virtual FDT.
Tracked-On: #8841
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Currently dbcn outputs directly to console. Outputs to ACRN
shell vm_console when other dependencies are ready.
Tracked-On: #8841
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Initialize Service VM vFDT by reserving hypervisor and pre-launched VM
memory regions.
The vFDT is copied to Service VM to the place just before the kernel
load address, and this needs to be fixed later when MMU module is
implemented.
Tracked-On: #8841
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Original interrupt context save/restore routine saves to/restore from
per-cpu stack. This commit modifies it to support saving to/restoring
from address pointed to by sscratch register.
When sscratch is 0, the assembly is functionally equivalent to the
old version (save to/restore from per-cpu stack)
When sscratch is not 0, the assembly saves to/restores from the place
that sscratch points to.
hstatus is also added to the trap frame as this affects the virtual
mode the trap returns to.
Tracked-On: #8841
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Signed-off-by: Haicheng Li <haicheng.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Unlike x86 which explicitly distinguishes guest traps and host traps (VM
exits vs. IDT trap gates), risc-v unifies them to a single trap gate
with bits in multiple CSRs representing the privilege mode before the
trap. This commit follows this design.
Due to this change the arch_vcpu_thread in risc-v was basically
abandoned, and used only as a first-time entry point to guest, with the
rest of the original x86 arch_vcpu_thread being re-implemented following
above single-entry design.
Save/restore routine is also being re-implemented to account for
both hs-mode traps and v-mode traps. sscratch is used to mark the place
where the context is being saved to/restored from. When sscratch is
zero at the time of the trap, the context is saved into host stack.
When sscratch is non-zero, the context is saved to vcpu->arch.regs
(similar for restore).
Tracked-On: #8841
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Signed-off-by: Haicheng Li <haicheng.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
This patch integrates RISC-V with the common IRQ framework:
- Register software and timer interrupt handlers via request_irq().
- Refine dispatch_interrupt() to handle interrupts via do_irq().
Tracked-On: #8845
Signed-off-by: Shiqing Gao <shiqing.gao@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Include the common IRQ header rather than the arch-specific version.
This follows the style we defined for multi-arch development.
Remaining RISC-V related files will be updated in later patches when
integration with the common IRQ framework is implemented.
Tracked-On: #8845
Signed-off-by: Shiqing Gao <shiqing.gao@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Move the declarations of arch-specific IRQ functions from their
arch-specific headers into the common header file.
Also rename these functions from xxx_arch() to arch_xxx() for better
naming consistency across architectures.
This change follows the style defined for multi-arch development.
Tracked-On: #8845
Signed-off-by: Shiqing Gao <shiqing.gao@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
This patch fixes two bugs. The reason for writing them
into one commit is that they are related and the fixes
change the same places.
The first bug:
The size of struct stack_frame is 0x78, not 0x80, but
the save/restore assembly routine allocates/deallocates
the size of stack frame by 0x80.
The vcpu thread stack is initialized by allocating
sizeof(struct stack_frame) from the top of the stack
and put initial values there (arch_build_stack_frame).
The vcpu thread stack will underflow at the first
time this thread gets scheduled. So the fix is to change
the 0x80 to 0x78 in save/restore routine.
The second bug:
Save/restore routine needs to capture sstatus, as different
threads might have different interrupt enabling settings.
For example, vcpu threads always get scheduled out when the
interrupts are disabled, but idle thread needs to have the
interrupts enabled. So sstatus needs to be saved/restored.
The fix is to add a new member sstatus in struct stack_frame.
Adding a new member in struct stack_frame boost the size
of struct stack_frame to 0x80, which in this case the fix
of the first bug is no longer needed.
Tracked-On: #8838
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
There are two reasons to use inline functions and numbered-CSR
instead of simply string concat.
1, With old style, CSR names have to be written in lower cases
and cannot prefix anything. This sometimes causes confusion with
variables. For example, csr_write(sstatus, sstatus). Changing to
inline function with MACROs can reduce confusion:
csr_write(CSR_SSTATUS, sstatus)
2, Using number macros allows us to manage CSRs in a more organized
way. We can now put CSR names in variables or arrays and access them
using variables instead of just string names.
Tracked-On: #8838
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Bare boot protocol is a protocol to be used when there are no protocols
(such as multiboot1/2) are available: ACRN have no way to know where its
modules are being loaded, how large they are, and what are their command
line arguments.
Bare boot protocol allows you to pre-configure (hard-code) modules' address and
sizes. ACRN will find modules based on the pre-configured information
without the need of a bootloader passing information to it.
Tracked-On: #8838
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Besides implementing copy_from/to_gpa, this commit also wraps a dummy
commit in mmu.c that exposes API of adding hv mmu mapping.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
For service and pre-launched VMs, the image loaders in ACRN
are functioning the same way as an in-guest bootloader such
as GRUB, which allows ACRN to load a guest image and start
directly from there and therefore skipping the firmware
initialization stage.
To re-use image loader code as much as possible, the image loader
logic is splitted into two stages, the loading stage and
environmental preparation stage. Most part of the loading stage
are common logic, and environmental preparation stage should
be completely arch-specific.
The best place for stage two loader logic is arch_vm_prepare_bsp,
which prepares vcpu register states based on the loaded image
(entry point, load address, etc.).
This commit refactors only the rawimage loader. Other loaders
are left for future improvement.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
prepare_os_image should not touch vcpu internal state.
Move this operation to arch_vm_prepare_bsp.
Since arch_vm_prepare_bsp now changes vcpu registers,
this action also affects the logic of resume_vm_from_s3.
Refactor resume_vm_from_s3 to avoid direct call to
start_vm.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Move vm_config to common scope. This change also affects auto-generated
C/H files from configuration tools.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Move reset_vm to common scope and remove unused reset_mode.
The reset_mode in x86 reset_vm code is simply used as an if condition
on whether the prepare_os_image should be executed. The entire
if body will never be true as we don't support resetting Service VM
without resetting ACRN hypervisor. To reset Service VM, the only
way is through a platform reset. Therefore the prepare_os_image
action will never be called. Delete this action.
Once the if condition and prepare_os_image action is deleted,
the input parameter "mode" is useless. Delete that too. The reset_vm
API in ACRN is simply a "warm reset". It does not need to take
input.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
The shutdown_vm is renamed to destroy_vm,
and introduce arch_deinit_vm as mandatory arch public API.
The original shutdown_vm checks if all VMs are shutting down,
and shutdown platform if no other VMs are running.
This logic is moved to the caller of original shutdown_vm
except hypercall, as we post-launched VM shutdown should not
trigger platform shutdown.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
start_vm is moved to common scope calling
arch_vm_start_bsp, which is a mandatory API
for all archs.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
The logic in prepare_vm can be embedded to launch_vms
and create_vm with better readability.
The movement does not change original logic.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Li Fei <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
launch_vms and create_vm need to be moved together as both of
them reference file-static structures. All related structures
and helpers accessing structures are also moved.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Li Fei <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Adjust kick_vcpu logic and move to common scope.
Moves also vcpu_make_request to common scope and adds
vcpu_has_pending_request and vcpu_take_request helpers.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Li Fei <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
Move reset_vcpu to common. Original x86 reset_vcpu
takes an extra parameter to handle both reset and init reset.
Common API hides this detail and let arch specific code handle
this.
This patch also renames x86 specific vcpu_reset_internal to
x86_vcpu_reset_internal.
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>
vlapic state updating basically updates a per-VM variable of
vlapic mode. vlapic mode updating should NOT happen with each
and every vcpu state update. Consider the case where a VM has
all vcpus except the last one being X2APIC, and the last one
is in the process of transitioning to X2APIC. When HV is emulating
the transitioning, request processing fails and we zombie this
vcpu. This causes the vlapic_mode to be incorrectly set to
X2APIC.
vlapic mode updating should be confined to the following cases:
1, when guest changes APIC mode
2, when guest receives SIPI/INIT
Here we also prove that the logic is correct/equivalent as before.
update_vm_vlapic_state is called in vcpu state transitioning functions:
offline_vcpu, zombie_vcpu, reset_vcpu, launch_vcpu.
launch_vcpu:
launch_vcpu is called in two places. vBSP launch and vAP launch.
vBSP launch does not need to update vlapic state as by default
vm->arch_vm.vlapic_mode is set to XAPIC_MODE (set in create_vm).
vAP launch is handled by this patch.
reset_vcpu:
reset_vcpu is called in two places. INIT_RESET and VM reset.
INIT_RESET is handled in this patch. VM reset does not need to
update_vm_vlapic_state as we manually set this to default XAPIC
in reset_vm.
zombie_vcpu:
As stated above, zombie_vcpu should NOT change vlapic mode, as
the action of zombie_vcpu is transparent to guest. It is only called
to pause vcpu thread.
offline_vcpu:
Offline_vcpu is called in two places: shutdown_vm and hypercall to
offline Service VM vcpus. In the first case it doesn't matter as
VM is being destroyed. In the second case, Service VM is already
in one of XAPIC or X2APIC mode, and offlining vcpus does not change
this mode (therefore not needed).
Tracked-On: #8830
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Acked-by: Wang Yu1 <yu1.wang@intel.com>