Compare commits

...

43 Commits
v3.3 ... master

Author SHA1 Message Date
dongpingx
60fc6c2bc4 misc: upgrade dependency for acrn-configurator
upgrade crossbeam-channel to 0.5.15 which is used by tauri's component `tao`

Tracked-On: #8769
Signed-off-by: DongpingX Wu <dongpingx.wu@intel.com>
2025-04-15 16:36:04 +08:00
dongpingx
a737902715 misc: upgrade two dependencies for acrn-configurator
upgrade openssl to 0.10.72
upgrade tokio to 1.43.1

Tracked-On: #8768
Signed-off-by: DongpingX Wu <dongpingx.wu@intel.com>
2025-04-09 15:21:03 +08:00
Yichong Tang
27aee66f88 hv: hyperv: Add hyperv page destory function
In current code process, hyperv data in struct vm_arch is never cleared
during VM shutdown and is retained to next VM launch. As the enabled
bit of hypercall_page msr is not clear, hypercall page might cause fatal
error such as Windows VM BSOD during VM restart and memory
remapping. Hyperv page destory function can ensure hyperv page is
destory during each VM shutdown so hyperv related config such as
hypercall page is established correctly during each VM launch.

Tracked-On: #8755
Signed-off-by: Yichong Tang <yichong.tang@intel.com>
2025-03-10 15:36:03 +08:00
Yifan Liu
11d7c0dcb3 dm: Fix concurrent acrn-dm hugetlb init race
During init of hugetlb we check and create /run/hugepage/acrn folder.
Concurrent acrn-dm instances might race between the time of check and
create.

This commit ignore EEXIST error when creating directory.

Tracked-On: #8764
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
2025-03-07 17:20:56 +08:00
Haoyu Tang
bff0493d25 hv: fix stac/clac context in get_initrd_load_addr()
Tracked-On: #8761
Signed-off-by: Haoyu Tang <haoyu.tang@intel.com>
2025-02-24 16:44:22 +08:00
dongpingx
ef49283e51 misc: resolve dependabot alerts
upgrade nanoid to 3.3.8
upgrade idna to 1.0.0
upgrade vite to >=3.2.11, actually locked at 6.0.3
upgrade rollup to >=2.79.2, actually locked at 4.28.1

Tracked-On: #8751
Signed-off-by: dongpingx <dongpingx.wu@intel.com>
2024-12-19 21:51:42 +08:00
yuhuanX
e8b100aab2 doc: Change TSC Chair from Junjie to Yu due to job change.
Tracked-On: #8746
Signed-off-by: YuhuanX Huang <yuhuanx.huang@intel.com>
2024-11-04 12:06:34 +08:00
Haiwei Li
95859dea34 doc: add module design for peripheral ivshmem device
GAI Tooling Notice: These contents may have been developed with support from one
or more generative artificial intelligence solutions.

This patch is to add doxygen style comments for some elements in
vp-dm_vperipheral ivshmem module.

Tracked-On: #8665

Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-10-09 09:50:54 +08:00
Zhang Chen
b55440dce9 config_tools: Add ivshmem region ID to launch script
Add missed ivshmem region ID. If no region ID in scenario,
will set 0 as default.

Tracked-On: #8645

Signed-off-by: Zhang Chen <chen.zhang@intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
2024-09-23 02:06:18 +08:00
Gao, Shiqing
9d7f14e783 hv: release: fix the compilation error
This patch fixes the following compilation error when including
`release/uart16550.c` into the module test.

./release/uart16550.c:14:6: error: conflicting types for ‘get_pio_dbg_uart_cfg’; have ‘bool(uint64_t *, uint64_t *)’ {aka ‘_Bool(long unsigned int *, long unsigned int *)’}
   14 | bool get_pio_dbg_uart_cfg(__unused uint64_t *pio_address, __unused uint64_t *nbytes) {
      |      ^~~~~~~~~~~~~~~~~~~~

./include/debug/uart16550.h:142:6: note: previous declaration of ‘get_pio_dbg_uart_cfg’ with type ‘bool(uint16_t *, uint32_t *)’ {aka ‘_Bool(short unsigned int *, unsigned int *)’}
  142 | bool get_pio_dbg_uart_cfg(uint16_t *pio_address, uint32_t *nbytes);
      |      ^~~~~~~~~~~~~~~~~~~~

Tracked-On: #861

Signed-off-by: Gao, Shiqing <shiqing.gao@intel.com>
2024-09-18 15:57:33 +08:00
David B. Kinder
4d2537aafe doc: remove me from CODEOWNERS
I retired from Intel as of Sep 30, 2024

Signed-off-by: David B. Kinder <david.b.kinder@intel.com>
2024-09-17 16:52:49 -04:00
Jiaqing Zhao
8aca9eb12f dm: uart: add escape sequence Ctrl-a x to exit dm
When guest console is redirected to stdio, Ctrl-c is also passed to
guest. Add escape sequence Ctrl-a x to send SIGINT to exit acrn-dm
in such case.

Tracked-On: #8731
Signed-off-by: Jiaqing Zhao <jiaqing.zhao@linux.intel.com>
Reviewed-by: Jian Jun Chen <jian.jun.chen@intel.com>
2024-09-14 10:03:52 +08:00
Yuan Lu
dbc3ff39aa hv: vm_reset: simulate RESET_CONTROL(0xCF9) register
Add reset_control in acrn_vm. Use this reset_control to simulate
RESET_CONTROL(0xCF9) register in hypervisor.

Tracked-On: #8724
Signed-off-by: Yuan Lu <yuan.y.lu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
2024-09-12 14:09:17 +08:00
Haiwei Li
fcffdf8dbd misc: fix two IOAPIC related configs
For Service VM, the I/O APIC number and RTE number are from platform.
Otherwise, hypervisor emulates one I/O APIC and 48 RTEs. But
'MAX_IOAPIC_NUM' is always 1 and 'MAX_IOAPIC_LINES' is always 120 for
now.

This patch is introduced to fix these issues.

Tracked-On: #8725
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
Suggested-by: Junjie Mao <junjie.mao@intel.com>
Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-09-11 15:10:45 +08:00
Yonghua Huang
7d15cc5255 doc: add IVSHMEM region ID support
Add guide to configure IVSHMEM Region ID.

Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
2024-09-11 13:45:46 +08:00
Jiaqing Zhao
eae668268e hv: handle reboot from Service VM properly
Service VM may write 0x6 to port 0xcf9 to trigger a warm reset, but
current hypervisor always performs a cold reset by writing 0xE to CF9.
Hypervisor should reboot the system in the same mode as Service VM
specified. Specific OS features (like linux pstore) requires warm
reset to keep data across reboot.

The behavior of hv console's reboot command (cold reset) remains
unchanged.

Tracked-On: #8539
Signed-off-by: Jiaqing Zhao <jiaqing.zhao@linux.intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
2024-09-09 14:37:16 +08:00
Haiwei Li
17c4ce75a1 hv: cpuid: expose CPUID.EAX=07H subleaf to VMs
Per SDM, VPDPBUSD/VPDPBUSDS/VPDPWSSD/VPDPWSSDS instructions depend on
CPUID Feature Flag 'AVX-VNNI, AVX512_VNNI, AVX512VL'. 'AVX512_VNNI' and
'AVX512VL' are already exposed to any VM.

'AVX-VNNI' is in CPUID.(EAX=07H,ECX=1):EAX.AVX-VNNI[bit 4]. This patch
is to expose all the CPUID.EAX=07H subleaf features to VMs.

Mask corresponding bits if want to disable some features in the future.

Tracked-On: #8710
Reviewed-by: Fei Li <fei1.li@intel.com>
Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-09-09 14:03:51 +08:00
Haiwei Li
1571a6d5f2 doc: add module design for peripheral vhost_bridge device
GAI Tooling Notice: These contents may have been developed with support from one
or more generative artificial intelligence solutions.

This patch is to add doxygen style comments for some elements in
vp-dm_vperipheral vhost_bridge module.

Tracked-On: #8665

Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-09-03 09:51:43 +08:00
Haiwei Li
9a4c41cdc4 hv: vhostbridge: add comments to clarify the statement
A vhostbridge can be emulated in hypervisor. Function `init_vhostbridge()` is
used to initialize a virtual host bridge and it configures the PCI configuration
space.

However, some configuration elements are not clearly described, which affects
maintainability and readability. This patch add some comments to address it.

Tracked-On: #8665

Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-09-03 09:51:43 +08:00
Haoyu Tang
fa1f2ba7df local_gva2gpa_common: optimize code
Remove unreachable code branch in line 163:
if CR0 enabled WP, supervisor-mode writing a read-only page have
been checked in line 109.

Merge redundant checking:
if smap is enabled, supervisor-mode can't access user-mode address
when eflags.ac disabled.

Tracked-On: #8708
Signed-off-by: Haoyu Tang <haoyu.tang@intel.com>
2024-08-30 15:19:51 +08:00
caixuanx
0198edf145 doc: modify v3.3 release notes
Delete the redundant field "Celadon" in "Enabling Celadon as User VM"
2024-08-26 13:39:49 +08:00
Yi Sun
e07a9618f9 hv: ENODEV should be able to be set into RAX as hypercall return value
Some hypercalls return -ENODEV which should be set into RAX as return
value, e.g. HC_ASSIGN_PCIDEV. So, remove the check in
vmcall_vmexit_handler() and change return value to -EACCESS if the
hypercall is not sent from Service VM or allowed VM.

Tracked-On: #8598
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
2024-08-23 10:14:14 +08:00
Haiwei Li
aba53e78ef doc: add module design for peripheral vuart device
GAI Tooling Notice: These contents may have been developed with support from one
or more generative artificial intelligence solutions.

This patch is to add doxygen style comments for some elements in
vp-dm_vperipheral vuart module.

Tracked-On: #8665

Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-08-20 17:23:42 +08:00
Haiwei Li
436cb9cddf doc: add module design for peripheral vpci_bridge device
GAI Tooling Notice: These contents may have been developed with support from one
or more generative artificial intelligence solutions.

This patch is to add doxygen style comments for some elements in
vp-dm_vperipheral vpci_bridge module.

Tracked-On: #8665

Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-08-20 16:51:08 +08:00
Haiwei Li
172c56fe0a doc: add module design for peripheral vrtc device
GAI Tooling Notice: These contents may have been developed with support from one
or more generative artificial intelligence solutions.

This patch is to add doxygen style comments for some elements in vp-dm_vperipheral
vrtc module.

Tracked-On: #8665

Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-08-20 13:36:13 +08:00
Chen, Jinshi
48a102e6b0 hv: fix testability issues that impact module test
This patch fixes the following testability issues identified by the dynamic
module test.

Global variables defined in function scope cannot be referenced outside
the function, making it impossible to check the return value of these
functions.

Tracked-On: #861

Signed-off-by: Chen, Jinshi <jinshi.chen@intel.com>
2024-08-19 10:21:28 +08:00
Yuan Lu
95bfc87eec hv: hypercall: change condition for hcall_get_cpu_pm_state
After rebooting guest, CPPC initialization failed because _CST and _CPC
missed in DSDT table. When writing _CST and _CPC in DSDT table, it gets
cx_cnt or px_cnt as condition. Getting cx_cnt or px_cnt triggers
the hypercall hcall_get_cpu_pm_state. The hypercall hcall_get_cpu_pm_state
uses VM_CREATED as VM state's condition. While, after rebooting guest,
the VM state is VM_PAUSED when writing _CST and _CPC in DSDT table.
Therefore, changing VM state's condition from VM_CREATED to VM_CREATED or
VM_PAUSED for hcall_get_cpu_pm_state can solve the CPPC initialization
failed issue after rebooting guest.

Tracked-On: #8695
Signed-off-by: Yuan Lu <yuan.y.lu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
2024-08-16 09:21:26 +08:00
Gao, Shiqing
ce96ba3fae hv: multiboot: fix compilation error for module test
Fix below compilation error when building the module test for multiboot_priv.h.
./boot/multiboot/multiboot_priv.h: In function ‘boot_from_multiboot’:
./boot/multiboot/multiboot_priv.h:33:27: error: ‘MULTIBOOT_INFO_MAGIC’ undeclared (first use in this function)
   33 |         return ((magic == MULTIBOOT_INFO_MAGIC) && (info != 0U));

Tracked-On: #861

Signed-off-by: Gao, Shiqing <shiqing.gao@intel.com>
2024-08-15 15:21:46 +08:00
Yuan Lu
88cf1229a7 dm: acpi: support CPPC V2 capability in _OSC of DSDT for ACRN guest.
After upgrading to guest kernel 6.1.80, it checks the CPPC V2 capability
in _OSC of DSDT. To support it for ACRN guest, add CPPC V2 capability in
_OSC of DSDT. Currently we only support CPPC V2 capability in _OSC of
DSDT.

Tracked-On: #8691
Signed-off-by: Yuan Lu <yuan.y.lu@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
2024-08-15 14:35:04 +08:00
Yonghua Huang
4e552b0785 hv: allow guest with the highest severity to read RESET_CONTROL
Guest VM, such as Linux, may read RESET_CONTROL(0xCF9) register
before writing to, in this case, ACRN should not always return
dummy value.

Tracked-On: #8688
Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
2024-08-12 10:06:15 +08:00
Jiaqing Zhao
5c351bee0f hv: vtd: allocate drhd_dev_scope based on board file
Determine the size of drhd_dev_scope based on DRHD_MAX_DEVSCOPE_COUNT
in board file instead of hardcoding. The current default value 16 will
be used if it is not defined in board file to keep compatibility, a
warning will be raised in this case.

Tracked-On: #8494
Signed-off-by: Jiaqing Zhao <jiaqing.zhao@linux.intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
2024-08-05 15:51:17 +08:00
Jiaqing Zhao
65f84d6ae6 board_inspector: generate maximum DRHD devscope count
Add a new field DRHD_MAX_DEVSCOPE_COUNT in board file representing
maximum devscope count in a DMAR structure for statically allocating
drhd_dev_scope array in hypervisor.

Tracked-On: #8494
Signed-off-by: Jiaqing Zhao <jiaqing.zhao@linux.intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
2024-08-05 15:51:17 +08:00
Jiayuan Yang
069afc6519 doc: specify numpy version in sample application guide
histapp.py cannot run on numpy>=2, thus specify numpy<2 via pip install
command.

Tracked-On: #8664
Signed-off-by: Jiayuan Yang <jiayuan.yang@intel.com>
2024-08-05 14:04:59 +08:00
Jiayuan Yang
2474421fba doc: add release note draft for release 3.3
In this release note:
1. New features
2. Configurator and Board inspector updates
3. Docs updates
4. Fixed issues and known issues

Signed-off-by: Jiayuan Yang <jiayuan.yang@intel.com>
2024-08-05 14:04:59 +08:00
Jiayuan Yang
81529af1ca doc: update SOS to 22.04.4 in GSG and sample application guide
In this guide, each VM continue to use 22.04. SOS upgrade is done in
GSG(22.04.2->22.04.4).

Tracked-On: #8664
Signed-off-by: Jiayuan Yang <jiayuan.yang@intel.com>
2024-08-05 14:04:35 +08:00
Jiayuan Yang
f189d773c7 doc: add ACRN v3.3 Maintenance hardware-rpl asus minipc
In v3.3 release, Maintenance hardware is change from Vecow to Asus mini
PC.

Tracked-On: #8677
Signed-off-by: Jiayuan Yang <jiayuan.yang@intel.com>
2024-08-05 14:04:35 +08:00
Jiayuan Yang
17d67247dc doc: revert Ubuntu24.04 support in GSG
Since Ubuntu24.04 requires 6.8 kernel(as shown in Ubuntu linux kernel
release lifecycle), we need to revert the ubuntu24.04 support in GSG to
suit our 6.1 acrn kernel.

Tracked-On: #8664
Signed-off-by: Jiayuan Yang <jiayuan.yang@intel.com>
2024-08-05 14:04:35 +08:00
Haiwei Li
fa2b8fcfbe doc: add module design for some defines in hwmgmt_page
GAI Tooling Notice: These contents may have been developed with support from one
or more generative artificial intelligence solutions.

ACRN hypervisor is decomposed into a series of components and modules. The
module design in hypervisor is to add inline doxygen style comments above
functions, macros, structures, etc.

This patch is to add comments for some elements in hwmgmt_page module.

Tracked-On: #8665

Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-08-01 14:50:27 +08:00
Haiwei Li
cb431d9df4 doc: add custom commands in acrn.doxyfile
`consistency` is used to describe the consistency rule and `alignment`
is used to describe the align info.

These two are used to enhance the documentation inside a struct comment
block.

Signed-off-by: Gao, Shiqing <shiqing.gao@intel.com>
2024-08-01 13:23:21 +08:00
dongpingx
4924766b67 misc: fix openssl's vulnerability for tauri
Trivy scaned one vulnerability three days ago and we fixed it now.

The title for vulnerability is openssl's `MemBio:get_buf` has undefined
behavior with empty buffers.

I tested through building configurator, launching it and generating
scenario.xml & launch scripts. I confirmed the result is correct.

Signed-off-by: dongpingx <dongpingx.wu@intel.com>
Tracked-On: #8668
2024-07-30 10:06:31 +08:00
Jiaqing Zhao
2dc56a8f23 hv: add GUEST_FLAG_STATELESS flag
GUEST_FLAG_STATELESS indicates guest is running a stateless operating
system and need to be shutdown forcefully without data loss. This flag
is only appalicable to pre-launched VM. For TEE_VM, this flag will be
set implicitly.

Tracked-On: #8671
Signed-off-by: Jiaqing Zhao <jiaqing.zhao@linux.intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
2024-07-30 09:26:50 +08:00
Haiwei Li
c4ea248bc9 hv: remove Service VM delayed loading
Now multiboot modules memory is already reserved from e820 in function
`alloc_mods_memory()` and Service VM will not corrupt pre-launched VM
modules.

So remove the code of Service VM delayed loading.

Tracked-On: #8652
Signed-off-by: Haiwei Li <haiwei.li@intel.com>
2024-07-18 11:26:49 +08:00
wenlingz
44a603a579 version: v3.4
Signed-off-by: wenlingz <wenling.zhang@intel.com>
2024-07-18 10:32:56 +08:00
63 changed files with 3129 additions and 986 deletions

View File

@ -15,7 +15,7 @@
Makefile @terryzouhao @NanlinXie
/hypervisor/ @dongyaozu @lifeix @junjiemao1
/devicemodel/ @ywan170 @chejianj
/doc/ @dbkinder @NanlinXie
/doc/ @NanlinXie
/misc/debug_tools/acrn_crashlog/ @ywan170 @lifeix
/misc/debug_tools/acrn_log/ @ywan170 @lifeix
/misc/debug_tools/acrn_trace/ @ywan170 @lifeix
@ -27,4 +27,4 @@ Makefile @terryzouhao @NanlinXie
/misc/packaging/ @terryzouhao @NanlinXie
/misc/hv_prebuild/ @terryzouhao @NanlinXie
*.rst @dbkinder @NanlinXie
*.rst @NanlinXie

View File

@ -48,7 +48,7 @@ the TSC and its membership, are described in the project's `technical-charter`_.
These are the current TSC voting members and chair person:
- Junjie Mao (chair): junjie.mao@intel.com
- Yu Wang (chair): yu1.wang@intel.com
- Helmut Buchsbaum: helmut.buchsbaum@tttech-industrial.com
- Thomas Gleixner: thomas.gleixner@intel.com

View File

@ -1,3 +1,3 @@
MAJOR_VERSION=3
MINOR_VERSION=3
MINOR_VERSION=4
EXTRA_VERSION=-unstable

View File

@ -555,8 +555,13 @@ bool init_hugetlb(void)
path[i] = 0;
if (access(path, F_OK) != 0) {
if (mkdir(path, 0755) < 0) {
pr_err("mkdir %s failed.\n", path);
return -1;
/* We might have multiple acrn-dm instances booting VMs at
* the same time
*/
if (errno != EEXIST) {
pr_err("mkdir %s failed: %s\n", path, errormsg(errno));
return false;
}
}
}
path[i] = '/';

View File

@ -883,6 +883,7 @@ basl_fwrite_dsdt(FILE *fp, struct vmctx *ctx)
acpi_dev_write_dsdt(ctx);
osc_write_ospm_dsdt(ctx, basl_ncpu);
pm_write_dsdt(ctx, basl_ncpu);
dsdt_line("}");

View File

@ -430,3 +430,62 @@ void pm_write_dsdt(struct vmctx *ctx, int ncpu)
dsdt_line(" }");
}
}
/* _OSC: Operating System Capabilities
* Currently only support CPPC v2 capability.
* CPPC v2 capability: revision 2 of the _CPC object.
* If all vcpus don't support _CPC object, no need to add _OSC in DSDT.
*/
void osc_write_ospm_dsdt(struct vmctx *ctx, int ncpu)
{
int ret;
bool support_cpc = false;
uint8_t px_cnt;
/* check px_cnt on vBSP */
ret = get_vcpu_px_cnt(ctx, 0, &px_cnt);
if (ret == 0 && px_cnt == 0) {
/* px_cnt = 0 Indicates vcpu supports continuous pstate.
*/
support_cpc = true;
}
if (support_cpc) {
/* Scope (_SB._OSC) */
dsdt_line("");
dsdt_line(" Scope (_SB)");
dsdt_line(" {");
dsdt_line(" Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities");
dsdt_line(" {");
dsdt_line(" CreateDWordField (Arg3, 0x00, STS0)");
dsdt_line(" CreateDWordField (Arg3, 0x04, CAP0)");
dsdt_line(" If ((Arg0 == ToUUID (\"0811b06e-4a27-44f9-8d60-3cbbc22e7b48\") /* Platform-wide OSPM Capabilities */))");
dsdt_line(" {");
dsdt_line(" If ((Arg1 == One))");
dsdt_line(" {");
dsdt_line(" If ((CAP0 & 0x40))");
dsdt_line(" {");
dsdt_line(" CAP0 &= 0x00000040");
dsdt_line(" }");
dsdt_line(" Else");
dsdt_line(" {");
dsdt_line(" STS0 &= 0xFFFFFF00");
dsdt_line(" STS0 |= 0x02");
dsdt_line(" }");
dsdt_line(" }");
dsdt_line(" Else");
dsdt_line(" {");
dsdt_line(" STS0 &= 0xFFFFFF00");
dsdt_line(" STS0 |= 0x0A");
dsdt_line(" }");
dsdt_line(" }");
dsdt_line(" Else");
dsdt_line(" {");
dsdt_line(" STS0 &= 0xFFFFFF00");
dsdt_line(" STS0 |= 0x06");
dsdt_line(" }");
dsdt_line(" Return (Arg3)");
dsdt_line(" }");
dsdt_line(" }");
dsdt_line("");
}
}

View File

@ -29,6 +29,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
@ -94,6 +95,8 @@ static struct {
{ COM5_BASE, COM5_IRQ, false},
};
static bool stdio_ctrl_a_pressed = false;
#define UART_NLDEVS (ARRAY_SIZE(uart_lres))
enum uart_be_type {
@ -717,6 +720,18 @@ uart_backend_read(struct uart_backend *be)
switch (be->be_type) {
case UART_BE_STDIO:
rc = read(be->fd, &rb, 1);
if (rb == 0x01) { // Ctrl-a
DPRINTF(("%s: Got Ctrl-a\n", __func__));
stdio_ctrl_a_pressed = true;
} else if (stdio_ctrl_a_pressed) {
if (rb == 'x') {
DPRINTF(("%s: Got Ctrl-a x\n", __func__));
kill(getpid(), SIGINT);
}
stdio_ctrl_a_pressed = false;
}
break;
case UART_BE_TTY:
/* fd is used to read */
rc = read(be->fd, &rb, 1);

View File

@ -127,4 +127,6 @@ int acrn_parse_iasl(char *arg);
int get_iasl_compiler(void);
int check_iasl_version(void);
void osc_write_ospm_dsdt(struct vmctx *ctx, int ncpu);
#endif /* _ACPI_H_ */

View File

@ -241,6 +241,8 @@ TAB_SIZE = 4
# Allow for rst directives and advanced functions e.g. grid tables
ALIASES = "rst=\verbatim embed:rst:leading-asterisk"
ALIASES += "endrst=\endverbatim"
ALIASES += consistency="\par consistency:^^"
ALIASES += alignment="\par alignment:^^"
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"

View File

@ -38,15 +38,15 @@ Before you begin, make sure your machines have the following prerequisites:
* Software specifications
- Ubuntu Desktop 24.04 LTS (ACRN development is not supported on Windows.)
- Ubuntu Desktop 22.04 LTS (ACRN development is not supported on Windows.)
**Target system**:
* Hardware specifications
- Target board (see :ref:`hardware_tested`)
- Ubuntu Desktop 24.04 LTS bootable USB disk: download the latest `Ubuntu
Desktop 24.04 LTS ISO image <https://releases.ubuntu.com/noble/>`__ and
- Ubuntu Desktop 22.04 LTS bootable USB disk: download the latest `Ubuntu
Desktop 22.04 LTS ISO image <https://releases.ubuntu.com/jammy/>`__ and
follow the `Ubuntu documentation
<https://ubuntu.com/tutorials/create-a-usb-stick-on-ubuntu#1-overview>`__
for creating the USB disk.
@ -75,7 +75,7 @@ Prepare the Development Computer
To set up the ACRN build environment on the development computer:
#. On the development computer, run the following command to confirm that Ubuntu
Desktop 24.04 is running:
Desktop 22.04 is running:
.. code-block:: bash
@ -119,8 +119,8 @@ To set up the ACRN build environment on the development computer:
xsltproc clang-format bc libpixman-1-dev libsdl2-dev libegl-dev \
libgles-dev libdrm-dev gnu-efi libelf-dev liburing-dev \
build-essential git-buildpackage devscripts dpkg-dev equivs lintian \
apt-utils pristine-tar dh-python acpica-tools
sudo pip3 install "elementpath==2.5.0" lxml "xmlschema==1.9.2" defusedxml tqdm
apt-utils pristine-tar dh-python acpica-tools python3-tqdm \
python3-elementpath python3-lxml python3-xmlschema python3-defusedxml
#. Get the ACRN hypervisor and ACRN kernel source code, and check out the
@ -172,7 +172,7 @@ To set up the target hardware environment:
#. Connect the monitor and power supply cable.
#. Connect the target system to the LAN with the Ethernet cable.
#. Connect the target system to the LAN with the Ethernet cable or wifi.
Example of a target system with cables connected:
@ -182,13 +182,13 @@ Example of a target system with cables connected:
Install OS on the Target
============================
The target system needs Ubuntu Desktop 24.04 LTS to run the Board Inspector
The target system needs Ubuntu Desktop 22.04 LTS to run the Board Inspector
tool. You can read the full instructions to download, create a bootable USB
drive, and `Install Ubuntu desktop
<https://ubuntu.com/tutorials/install-ubuntu-desktop#1-overview>`_ on the Ubuntu
site. We'll provide a summary here:
To install Ubuntu 24.04:
To install Ubuntu 22.04:
#. Insert the Ubuntu bootable USB disk into the target system.
@ -248,9 +248,10 @@ Configure Target BIOS Settings
#. Boot your target and enter the BIOS configuration editor.
Tip: When you are booting your target, you'll see an option (quickly) to
enter the BIOS configuration editor, typically by pressing :kbd:`F2` or :kbd:`DEL` during
the boot and before the GRUB menu (or Ubuntu login screen) appears. If you
are not quick enough, you can still choose ``UEFI settings`` in the GRUB menu.
enter the BIOS configuration editor, typically by pressing :kbd:`F2`
or :kbd:`DEL` during the boot and before the GRUB menu (or Ubuntu login
screen) appears. If you are not quick enough, you can still choose
``UEFI settings`` in the GRUB menu or just reboot the system to try again.
#. Configure these BIOS settings:
@ -467,9 +468,9 @@ post-launched User VM. Each User VM has its own launch script.
#. Confirm that the **VM type** is ``Standard``. In the previous step,
``STD`` in the VM name is short for Standard.
#. Scroll down to **Memory size (MB)** and change the value to ``4096``. For
this example, we will use Ubuntu 24.04 to boot the post-launched VM.
Ubuntu 24.04 needs at least 4096 MB to boot.
#. Scroll down to **Memory size (MB)** and change the value to ``2048``. For
this example, we will use Ubuntu 22.04 to boot the post-launched VM.
Ubuntu 22.04 needs at least 2048 MB to boot.
#. For **Physical CPU affinity**, select pCPU ID ``0``, then click **+** and
select pCPU ID ``1`` to affine (or pin) the VM to CPU cores 0 and 1. (That will
@ -479,17 +480,17 @@ post-launched User VM. Each User VM has its own launch script.
default options.
#. For **Virtio block device**, click **+** and enter
``/home/acrn/acrn-work/user-vm1.img``. This parameter
``/home/acrn/acrn-work/ubuntu-22.04.4-desktop-amd64.iso``. This parameter
specifies the VM's OS image and its location on the target system. Later
in this guide, you will create the image file to that directory. (If you used
in this guide, you will save the ISO file to that directory. (If you used
a different username when installing Ubuntu on the target system, here's
where you'll need to change the ``acrn`` username to the username you used.)
.. image:: images/configurator-postvm01.png
.. image:: images/configurator_postvm01.png
:align: center
:class: drop-shadow
.. image:: images/configurator-postvm02.png
.. image:: images/configurator_postvm02.png
:align: center
:class: drop-shadow
@ -574,7 +575,6 @@ Build ACRN
ls *acrn-service-vm*.deb
linux-headers-6.1.80-acrn-service-vm_6.1.80-acrn-service-vm-1_amd64.deb
linux-image-6.1.80-acrn-service-vm_6.1.80-acrn-service-vm-1_amd64.deb
linux-image-6.1.80-acrn-service-vm-dbg_6.1.80-acrn-service-vm-1_amd64.deb
linux-libc-dev_6.1.80-acrn-service-vm-1_amd64.deb
#. Use the ``scp`` command to copy files from your development computer to the
@ -634,11 +634,11 @@ Install ACRN
────────────────────────────────────────────────────────────────────────────────
Ubuntu
Advanced options for Ubuntu
Ubuntu-ACRN Board Inspector, with Linux 6.8.0-35-generic
Ubuntu-ACRN Board Inspector, with Linux 6.5.0-18-generic
Ubuntu-ACRN Board Inspector, with Linux 6.1.80-acrn-service-vm
Memory test (memtest86+x64.efi)
Memory test (memtest86+x64.efi, serial console)
Ubuntu with ACRN hypervisor, with Linux 6.8.0-35-generic (ACRN 3.3)
Ubuntu with ACRN hypervisor, with Linux 6.5.0-18-generic (ACRN 3.3)
*Ubuntu with ACRN hypervisor, with Linux 6.1.80-acrn-service-vm (ACRN 3.3)
UEFI Firmware Settings
@ -688,24 +688,21 @@ The ACRN hypervisor boots the Ubuntu Service VM automatically.
Launch the User VM
*******************
#. On the target system, download the Ubuntu cloud images ``noble-server-cloudimg-amd64.img``
for the User VM into the ``~/acrn-work/`` directory (the location we said
in the ACRN Configurator for the scenario configuration for the VM):
#. On the target system, use the web browser to visit the `official Ubuntu website <https://releases.ubuntu.com/jammy/>`__ and
get the Ubuntu Desktop 22.04 LTS ISO image
``ubuntu-22.04.4-desktop-amd64.iso`` for the User VM. (The same image you
specified earlier in the ACRN Configurator UI.) Alternatively, instead of
downloading it again, you could use ``scp`` to copy the ISO
image file from the development system to the ``~/acrn-work`` directory on the target system.
.. code-block:: bash
cd ~/acrn-work/
wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img ./
#. We need to do some steps before booting into cloud image User VM: Set up username and password both to ``acrn``;
Change the image format to ``raw`` and change the image size:
#. If you downloaded the ISO file on the target system, copy it from the
Downloads directory to the ``~/acrn-work/`` directory (the location we said
in the ACRN Configurator for the scenario configuration for the VM), for
example:
.. code-block:: bash
sudo apt install qemu-utils guestfs-tools
sudo virt-customize -a ./noble-server-cloudimg-amd64.img --run-command 'useradd -m -s /bin/bash acrn' --run-command 'echo "acrn:acrn" | chpasswd' --run-command 'systemctl disable systemd-networkd-wait-online.service'
qemu-img convert -f qcow2 -O raw ./noble-server-cloudimg-amd64.img ./user-vm1.img
qemu-img -f raw ./user-vm1.img 16G
cp ~/Downloads/ubuntu-22.04.4-desktop-amd64.iso ~/acrn-work
#. Launch the User VM:
@ -720,9 +717,34 @@ Launch the User VM
.. code-block:: console
Ubuntu 24.04 LTS ubuntu hvc0
Welcome to Ubuntu 22.04.4 LTS (GNU/Linux 6.5.0-18-generic x86_64)
ubuntu login:
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Expanded Security Maintenance for Applications is not enabled.
0 updates can be applied immediately.
Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
ubuntu@ubuntu:~$
#. This User VM and the Service VM are running different Ubuntu images. Use this
command to see that the User VM is running the downloaded Ubuntu image:
@ -730,7 +752,7 @@ Launch the User VM
.. code-block:: console
acrn@ubuntu:~$ uname -r
6.8.0-36-generic
6.5.0-18-generic
Then open a new terminal window and use the command to see that the Service
VM is running the ``acrn-kernel`` Service VM image:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 541 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 KiB

After

Width:  |  Height:  |  Size: 84 KiB

View File

@ -117,7 +117,7 @@ As a normal (e.g., **acrn**) user, follow these steps:
cd ~/acrn-work/acrn-hypervisor
git fetch --all
git checkout release_3.2
git checkout release_3.3
#. Build the ACRN sample application source code::
@ -522,6 +522,7 @@ Install and Run ACRN on the Target System
and then the ``histapp.py`` application::
pip install "numpy<2"
sudo python3 /root/histapp.py
At this point, the HMI_VM is running and we've started the HMI parts of

View File

@ -74,52 +74,52 @@ level includes the activities described in the lower levels.
.. # Note For easier editing, I'm using unicode non-printing spaces in this table to help force the width of the first two columns to help prevent wrapping (using &nbsp; isn't compact enough)
+------------------------+---------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| | | .. rst-class:: |
| | | centered |
| | | |
| | | ACRN Version |
| | +-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+
| Intel Processor Family | Tested Products                 | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| Code Name | | centered | centered | centered | centered | centered | centered | centered | centered | centered |
| | | | | | | | | | | |
| | | v1.0 | v1.6.1 | v2.0 | v2.5 | v2.6 | v2.7 | v3.0 | v3.1 | v3.2 |
+========================+=================================+===================+===================+===================+===================+===================+===================+===================+===================+===================+
| Raptor Lake | `ASUS PN64-E1`_ | | .. rst-class:: |
| | | | centered |
| | | | |
| | | | Community |
+------------------------+---------------------------------+-----------------------------------------------------------------------------------------------------------------------+-------------------+-------------------+-------------------+
| Alder Lake | | `ASRock iEPF-9010S-EY4`_, | | .. rst-class:: | .. rst-class:: |
| | | `ASRock iEP-9010E`_ | | centered | centered |
| | | | | |
| | | | Release | Community |
+------------------------+---------------------------------+-----------------------------------------------------------------------------------------------------------------------+-------------------+---------------------------------------+
| Tiger Lake | `Vecow SPC-7100`_ | | .. rst-class:: |
| | | | centered |
| | | | |
| | | | Maintenance |
+------------------------+---------------------------------+-----------------------------------------------------------+-------------------+---------------------------------------+-----------------------------------------------------------+
| Tiger Lake | `NUC11TNHi5`_ | | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| | | | centered | centered | centered |
| | | | | | |
| | | | Release | Maintenance | Community |
+------------------------+---------------------------------+---------------------------------------+-------------------+-------------------+-------------------+-------------------+-----------------------------------------------------------+
| Whiskey Lake | `WHL-IPC-I5`_ | | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| | | | centered | centered | centered |
| | | | | | |
| | | | Release | Maintenance | Community |
+------------------------+---------------------------------+-------------------+-------------------+-------------------+-------------------+-------------------+-------------------------------------------------------------------------------+
| Kaby Lake | `NUC7i7DNHE`_ | | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| | | | centered | centered | centered |
| | | | | | |
| | | | Release | Maintenance | Community |
+------------------------+---------------------------------+-------------------+-------------------+---------------------------------------+---------------------------------------------------------------------------------------------------+
| Apollo Lake | | `NUC6CAYH`_, | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| | | `UP2-N3350`_, | centered | centered | centered |
| | | `UP2-N4200`_, | | | |
| | | `UP2-x5-E3940`_ | Release | Maintenance | Community |
+------------------------+---------------------------------+-------------------+-------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
+------------------------+---------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| | | .. rst-class:: |
| | | centered |
| | | |
| | | ACRN Version |
| | +-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+-------------------+
| Intel Processor Family | Tested Products                 | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| Code Name | | centered | centered | centered | centered | centered | centered | centered | centered | centered | centered |
| | | | | | | | | | | | |
| | | v1.0 | v1.6.1 | v2.0 | v2.5 | v2.6 | v2.7 | v3.0 | v3.1 | v3.2 | v3.3 |
+========================+=================================+===================+===================+===================+===================+===================+===================+===================+===================+===================+===================+
| Raptor Lake | `ASUS PN64-E1`_ | | .. rst-class:: | .. rst-class:: |
| | | | centered | centered |
| | | | | |
| | | | Community | Maintenance |
+------------------------+---------------------------------+-----------------------------------------------------------------------------------------------------------------------+-------------------+-------------------+-------------------+-------------------+
| Alder Lake | | `ASRock iEPF-9010S-EY4`_, | | .. rst-class:: | .. rst-class:: |
| | | `ASRock iEP-9010E`_ | | centered | centered |
| | | | | |
| | | | Release | Community |
+------------------------+---------------------------------+-----------------------------------------------------------------------------------------------------------------------+-------------------+---------------------------------------+-------------------+
| Tiger Lake | `Vecow SPC-7100`_ | | .. rst-class:: | .. rst-class:: |
| | | | centered | centered |
| | | | | |
| | | | Maintenance | Community |
+------------------------+---------------------------------+-----------------------------------------------------------+-------------------+---------------------------------------+-----------------------------------------------------------+-------------------+
| Tiger Lake | `NUC11TNHi5`_ | | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| | | | centered | centered | centered |
| | | | | | |
| | | | Release | Maintenance | Community |
+------------------------+---------------------------------+---------------------------------------+-------------------+-------------------+-------------------+-------------------+-------------------------------------------------------------------------------+
| Whiskey Lake | `WHL-IPC-I5`_ | | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| | | | centered | centered | centered |
| | | | | | |
| | | | Release | Maintenance | Community |
+------------------------+---------------------------------+-------------------+-------------------+-------------------+-------------------+-------------------+---------------------------------------------------------------------------------------------------+
| Kaby Lake | `NUC7i7DNHE`_ | | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| | | | centered | centered | centered |
| | | | | | |
| | | | Release | Maintenance | Community |
+------------------------+---------------------------------+-------------------+-------------------+---------------------------------------+-----------------------------------------------------------------------------------------------------------------------+
| Apollo Lake | | `NUC6CAYH`_, | .. rst-class:: | .. rst-class:: | .. rst-class:: |
| | | `UP2-N3350`_, | centered | centered | centered |
| | | `UP2-N4200`_, | | | |
| | | `UP2-x5-E3940`_ | Release | Maintenance | Community |
+------------------------+---------------------------------+-------------------+-------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
* **Release**: New ACRN features are complete and tested for the listed product.
This product is recommended for this ACRN version. Support for older products

View File

@ -0,0 +1,199 @@
.. _release_notes_3.3:
ACRN v3.3 (Aug 2024)
####################
We are pleased to announce the release of the Project ACRN hypervisor
version 3.3.
ACRN is a flexible, lightweight reference hypervisor that is built with
real-time and safety-criticality in mind. It is optimized to streamline
embedded development through an open-source platform. See the
:ref:`introduction` introduction for more information.
All project ACRN source code is maintained in the
https://github.com/projectacrn/acrn-hypervisor repository and includes
folders for the ACRN hypervisor, the ACRN device model, tools, and
documentation. You can download this source code either as a zip or
tar.gz file (see the `ACRN v3.3 GitHub release page
<https://github.com/projectacrn/acrn-hypervisor/releases/tag/v3.3>`_) or
use Git ``clone`` and ``checkout`` commands::
git clone https://github.com/projectacrn/acrn-hypervisor
cd acrn-hypervisor
git checkout v3.3
The project's online technical documentation is also tagged to
correspond with a specific release: generated v3.3 documents can be
found at https://projectacrn.github.io/3.3/. Documentation for the
latest development branch is found at https://projectacrn.github.io/latest/.
ACRN v3.3 requires Ubuntu 22.04. Follow the instructions in the
:ref:`gsg` to get started with ACRN.
What's New in v3.3
******************
Generic Main VM Support
The v3.3 release now supports a new scenario called "Main VM". A "Service VM"
has two characteristics: (1) it is the default owner of physical resources
and (2) it can invoke VM management hypercalls. This release adds support
to configure a VM with only the physical resource ownership characteristic
and calling this a "Main VM". An example scenario is a pre-launched TEE
(Trusted Execution Environment) VM and a main REE (Rich Execution Environment)
VM.
Enabling Celadon as User VM
The acrn hypervisor now supports Celadon as User VM OS. Celadon is an
open-source project by Intel that provides a reference software stack for Android
on Intel architecture platforms, aiming to enable developers to optimize and test
Android on Intel-based devices.
Virtual Processor Performance Controls (vHWP)
The v3.3 release provides virtual HWP feature to a VM so that the VM can check
hardware performance ranges and adjust performance levels for performance or
power consumption.
Virtual Thermal Monitor and Software Controlled Clock Facilities
This release is able to virtualize processor thermal sensors and
controls for thermal management in VMs.
Hypervisor Runtime Core PM
The v3.3 release enhances processor power management in the hypervisor
at runtime to reduce power consumption when a core is idle.
Guest S3 Support
The v3.3 release supports suspend-to-RAM of post-launched VMs running
with OVMF.
System Performance Optimization - Virtio-blk Multi-Virtqueue Support
This release optimizes the virtio-block backend performance by allowing
multiple virtqueues between a frontend driver and the backend.
Notification of VM Events
Emit events (such as RTC changes and power cycles) to the monitor socket for
customizing further actions upon such events.
Enhance device model passthrough
This release support passthrough PCI device with legacy interrupt, some ACPI device like
GPIO controller, legacy UART.
ServiceVM supervisor role
User can config ServicVM as supervisor role in result it can manage the power status of
any guest VM.
Upgrading to v3.3 from Previous Releases
****************************************
We recommend you generate a new board XML for your target system with the v3.3
Board Inspector. You should also use the v3.3 Configurator to generate a new
scenario XML file and launch scripts. Scenario XML files and launch scripts
created by previous ACRN versions will not work with the v3.3 ACRN hypervisor
build process and could produce unexpected errors during the build.
Given the scope of changes for the v3.3 release, we have recommendations for how
to upgrade from prior ACRN versions:
1. Start fresh from our :ref:`gsg`. This is the best way to ensure you have a
v3.3-ready board XML file from your target system and generate a new scenario
XML and launch scripts from the new ACRN Configurator that are consistent and
will work for the v3.3 build system.
#. Use the :ref:`upgrader tool <upgrading_configuration>` to attempt upgrading
your configuration files that worked with prior releases. You'll need the
matched pair of scenario XML and launch XML files from a prior configuration,
and use them to create a new merged scenario XML file. See
:ref:`upgrading_configuration` for details.
#. Manually edit your previous older scenario XML and launch XML files to make them
compatible with v3.3. This is not our recommended approach.
Here are some additional details about upgrading to the v3.3 release.
Generate New Board XML
======================
Board XML files, generated by ACRN Board Inspector, contain board information
that is essential for building the ACRN hypervisor and setting up User VMs.
Compared to previous versions, ACRN v3.3 adds the following information to the
board XML file for supporting new features and fixes:
* Fix typo in PCIe PTM Capability name (See :acrn-pr:`8607`)
* Support motherboard which exposes MCFG1/MCFG2 instad of one ACPI MCFG
table. (See :acrn-pr:`8513`)
See the :ref:`board_inspector_tool` documentation for a complete list of steps
to install and run the tool.
Update Configuration Options
============================
As explained in this :ref:`upgrading_configuration` document, we do provide a
tool that can assist upgrading your existing pre-v3.3 scenario XML files in the
new merged v3.3 format. From there, you can use the v3.3 ACRN Configurator UI to
open the upgraded scenario file for viewing and further editing if the upgrader
tool lost meaningful data during the conversion.
The ACRN Configurator adds the following features and fixes to improve the user
experience:
* Support Main VM configuration. (See :acrn-pr:`8658`)
* Change Service VM to supervisor role. (See :acrn-pr:`8630`)
* Fix Vue3 version and update braces version (See :acrn-pr:`8627`)
* Fix openssl's vulnerability for tauri (See :acrn-pr:`8670`)
* Fix v-model used on props for Vue3 making strictly checking (See :acrn-pr:`8597`)
* Support vUART two options in configurator (See :acrn-pr:`8649`)
* Add checking cpu affinity and serial port for post-launch VM and hypervisor
while the user click to append a new VM. (See :acrn-pr:`8602`)
See the :ref:`scenario-config-options` documentation for details about all the
available configuration options in the new Configurator.
Document Updates
****************
Here are some of the more significant documentation updates from the v3.2 release:
.. rst-class:: rst-columns2
* :ref:`gsg`
* :ref:`using_celadon_as_user_vm`
* :ref:`release_notes_3.3`
* :ref:`hv-config`
* :ref:`acrn_configurator_tool`
* :ref:`GSG_sample_app`
* :ref:`acrnshell`
Fixed Issues Details
********************
.. comment example item
- :acrn-issue:`5626` - Host Call Trace once detected
- :acrn-issue:`8608` - hybrid vcpuid support
- :acrn-issue:`8590` - Hypervisor crashes after rebooting post-launched vm with passthrogh device for lots of times
- :acrn-issue:`8599` - Should clear pcpu_active_bitmap in start_pcpu
- :acrn-issue:`8590` - Hypervisor crashes after rebooting post-launched vm with passthrogh device for lots of times
- :acrn-issue:`8576` - Update-grub failed with GRUB 2.12
- :acrn-issue:`8518` - Initial boot log is lost in vm_console
- :acrn-issue:`8509` - S3 feature of Service VM OS is not available
- :acrn-issue:`8506` - Unable to passthrough USB device on bus 5 to guest
- :acrn-issue:`8500` - Add weight support for BVT scheduler
- :acrn-issue:`8495` - Service VM dead loops when booting up on platform with reserved memory as the last e820 entry
- :acrn-issue:`8492` - passthru multifunction device at function 0 will cause sub-function devices lost
- :acrn-issue:`8537` - Emulate COM3/4 in devicemodel
- :acrn-issue:`8491` - need to expose service vm config pointer
- :acrn-issue:`8579` - debian: fix broken grub config with grub 2.12
- :acrn-issue:`6631` - Fix Kata support with modify network configuration
Known Issues
************
- :acrn-issue:`6978` - openstack failed since ACRN v2.7
- :acrn-issue:`7827` - Pre_launched standard VMs cannot share CPU with Service VM in configurator
- :acrn-issue:`8471` - PTM enabling failure on i225 NIC
- :acrn-issue:`8472` - Failed to clear memory for post-launched standard VM

View File

@ -67,6 +67,9 @@ For the shared memory region:
#. Enter a name for the shared memory region.
#. Select the source of the emulation, either Hypervisor or Device Model.
#. Select the size of the shared memory region.
#. **Enter shared memory region ID, which can be in hexadecimal or decimal format**.
.. note::
Default value is 0 and IDs in 0x001 ~ 0xFFF are reserved, 0x1000 ~ 0xFFFF are available.
#. Select at least two VMs that can use the shared memory region.
#. Enter a virtual Board:Device.Function (BDF) address for each VM or leave it
blank. If the field is blank, the tool provides an address when the
@ -88,4 +91,4 @@ Learn More
ACRN supports multiple inter-VM communication methods. For a comparison, see
:ref:`inter-vm_communication`.
For details on ACRN IVSHMEM high-level design, see :ref:`ivshmem-hld`.
For details on ACRN IVSHMEM high-level design, see :ref:`ivshmem-hld`.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -65,7 +65,6 @@ static int32_t local_gva2gpa_common(struct acrn_vcpu *vcpu, const struct page_wa
int32_t ret = 0;
int32_t fault = 0;
bool is_user_mode_addr = true;
bool is_page_rw_flags_on = true;
if (pw_info->level < 1U) {
ret = -EINVAL;
@ -108,7 +107,6 @@ static int32_t local_gva2gpa_common(struct acrn_vcpu *vcpu, const struct page_wa
* Case2: Usermode */
fault = 1;
}
is_page_rw_flags_on = false;
}
}
@ -142,34 +140,8 @@ static int32_t local_gva2gpa_common(struct acrn_vcpu *vcpu, const struct page_wa
*/
/* if smap is enabled and supervisor-mode access */
if ((fault == 0) && pw_info->is_smap_on && (!pw_info->is_user_mode_access) &&
is_user_mode_addr) {
bool acflag = ((vcpu_get_rflags(vcpu) & RFLAGS_AC) != 0UL);
/* read from user mode address, eflags.ac = 0 */
if ((!pw_info->is_write_access) && (!acflag)) {
fault = 1;
} else if (pw_info->is_write_access) {
/* write to user mode address */
/* cr0.wp = 0, eflags.ac = 0 */
if ((!pw_info->wp) && (!acflag)) {
fault = 1;
}
/* cr0.wp = 1, eflags.ac = 1, r/w flag is 0
* on any paging structure entry
*/
if (pw_info->wp && acflag && (!is_page_rw_flags_on)) {
fault = 1;
}
/* cr0.wp = 1, eflags.ac = 0 */
if (pw_info->wp && (!acflag)) {
fault = 1;
}
} else {
/* do nothing */
}
is_user_mode_addr && ((vcpu_get_rflags(vcpu) & RFLAGS_AC) == 0UL)) {
fault = 1;
}
/* instruction fetch from user-mode address, smep on */

View File

@ -309,3 +309,14 @@ hyperv_init_vcpuid_entry(uint32_t leaf, uint32_t subleaf, uint32_t flags,
dev_dbg(DBG_LEVEL_HYPERV, "hv: %s: leaf=%x subleaf=%x flags=%x eax=%x ebx=%x ecx=%x edx=%x",
__func__, leaf, subleaf, flags, entry->eax, entry->ebx, entry->ecx, entry->edx);
}
void
hyperv_page_destory(struct acrn_vm *vm)
{
/* Reset the hypercall page */
vm->arch_vm.hyperv.hypercall_page.enabled = 0U;
/* Reset OS id */
vm->arch_vm.hyperv.guest_os_id.val64 = 0UL;
/* Reset the TSC page */
vm->arch_vm.hyperv.ref_tsc_page.enabled = 0UL;
}

View File

@ -120,66 +120,6 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf,
entry->flags = flags;
switch (leaf) {
case 0x07U:
if (subleaf == 0U) {
uint64_t cr4_reserved_mask = get_cr4_reserved_bits();
cpuid_subleaf(leaf, subleaf, &entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
entry->ebx &= ~(CPUID_EBX_PQM | CPUID_EBX_PQE);
/* mask LA57 */
entry->ecx &= ~CPUID_ECX_LA57;
/* mask SGX and SGX_LC */
entry->ebx &= ~CPUID_EBX_SGX;
entry->ecx &= ~CPUID_ECX_SGX_LC;
/* mask MPX */
entry->ebx &= ~CPUID_EBX_MPX;
/* mask Intel Processor Trace, since 14h is disabled */
entry->ebx &= ~CPUID_EBX_PROC_TRC;
/* mask CET shadow stack and indirect branch tracking */
entry->ecx &= ~CPUID_ECX_CET_SS;
entry->edx &= ~CPUID_EDX_CET_IBT;
if ((cr4_reserved_mask & CR4_FSGSBASE) != 0UL) {
entry->ebx &= ~CPUID_EBX_FSGSBASE;
}
if ((cr4_reserved_mask & CR4_SMEP) != 0UL) {
entry->ebx &= ~CPUID_EBX_SMEP;
}
if ((cr4_reserved_mask & CR4_SMAP) != 0UL) {
entry->ebx &= ~CPUID_EBX_SMAP;
}
if ((cr4_reserved_mask & CR4_UMIP) != 0UL) {
entry->ecx &= ~CPUID_ECX_UMIP;
}
if ((cr4_reserved_mask & CR4_PKE) != 0UL) {
entry->ecx &= ~CPUID_ECX_PKE;
}
if ((cr4_reserved_mask & CR4_LA57) != 0UL) {
entry->ecx &= ~CPUID_ECX_LA57;
}
if ((cr4_reserved_mask & CR4_PKS) != 0UL) {
entry->ecx &= ~CPUID_ECX_PKS;
}
} else {
entry->eax = 0U;
entry->ebx = 0U;
entry->ecx = 0U;
entry->edx = 0U;
}
break;
case 0x16U:
cpu_info = get_pcpu_info();
if (cpu_info->cpuid_level >= 0x16U) {
@ -480,6 +420,93 @@ static int32_t set_vcpuid_cache(struct acrn_vm *vm)
return result;
}
static int32_t set_vcpuid_extfeat(struct acrn_vm *vm)
{
uint64_t cr4_reserved_mask = get_cr4_reserved_bits();
int32_t result = 0;
struct vcpuid_entry entry;
uint32_t i, sub_leaves;
/* cpuid.07h.0h */
cpuid_subleaf(CPUID_EXTEND_FEATURE, 0U, &entry.eax, &entry.ebx, &entry.ecx, &entry.edx);
entry.ebx &= ~(CPUID_EBX_PQM | CPUID_EBX_PQE);
if (is_vsgx_supported(vm->vm_id)) {
entry.ebx |= CPUID_EBX_SGX;
}
#ifdef CONFIG_VCAT_ENABLED
if (is_vcat_configured(vm)) {
/* Bit 15: Supports Intel Resource Director Technology (Intel RDT) Allocation capability if 1 */
entry.ebx |= CPUID_EBX_PQE;
}
#endif
/* mask LA57 */
entry.ecx &= ~CPUID_ECX_LA57;
/* mask SGX and SGX_LC */
entry.ebx &= ~CPUID_EBX_SGX;
entry.ecx &= ~CPUID_ECX_SGX_LC;
/* mask MPX */
entry.ebx &= ~CPUID_EBX_MPX;
/* mask Intel Processor Trace, since 14h is disabled */
entry.ebx &= ~CPUID_EBX_PROC_TRC;
/* mask CET shadow stack and indirect branch tracking */
entry.ecx &= ~CPUID_ECX_CET_SS;
entry.edx &= ~CPUID_EDX_CET_IBT;
/* mask WAITPKG */
entry.ecx &= ~CPUID_ECX_WAITPKG;
if ((cr4_reserved_mask & CR4_FSGSBASE) != 0UL) {
entry.ebx &= ~CPUID_EBX_FSGSBASE;
}
if ((cr4_reserved_mask & CR4_SMEP) != 0UL) {
entry.ebx &= ~CPUID_EBX_SMEP;
}
if ((cr4_reserved_mask & CR4_SMAP) != 0UL) {
entry.ebx &= ~CPUID_EBX_SMAP;
}
if ((cr4_reserved_mask & CR4_UMIP) != 0UL) {
entry.ecx &= ~CPUID_ECX_UMIP;
}
if ((cr4_reserved_mask & CR4_PKE) != 0UL) {
entry.ecx &= ~CPUID_ECX_PKE;
}
if ((cr4_reserved_mask & CR4_LA57) != 0UL) {
entry.ecx &= ~CPUID_ECX_LA57;
}
if ((cr4_reserved_mask & CR4_PKS) != 0UL) {
entry.ecx &= ~CPUID_ECX_PKS;
}
entry.leaf = CPUID_EXTEND_FEATURE;
entry.subleaf = 0U;
entry.flags = CPUID_CHECK_SUBLEAF;
result = set_vcpuid_entry(vm, &entry);
if (result == 0) {
sub_leaves = entry.eax;
for (i = 1U; i <= sub_leaves; i++) {
cpuid_subleaf(CPUID_EXTEND_FEATURE, i, &entry.eax, &entry.ebx, &entry.ecx, &entry.edx);
entry.subleaf = i;
result = set_vcpuid_entry(vm, &entry);
if (result != 0) {
break;
}
}
}
return result;
}
static void guest_cpuid_06h(struct acrn_vm *vm, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
{
cpuid_subleaf(CPUID_THERMAL_POWER, *ecx, eax, ebx, ecx, edx);
@ -644,23 +671,7 @@ int32_t set_vcpuid_entries(struct acrn_vm *vm)
break;
/* 0x07U */
case CPUID_EXTEND_FEATURE:
init_vcpuid_entry(i, 0U, CPUID_CHECK_SUBLEAF, &entry);
if (entry.eax != 0U) {
pr_warn("vcpuid: only support subleaf 0 for cpu leaf 07h");
entry.eax = 0U;
}
if (is_vsgx_supported(vm->vm_id)) {
entry.ebx |= CPUID_EBX_SGX;
}
entry.ecx &= ~CPUID_ECX_WAITPKG;
#ifdef CONFIG_VCAT_ENABLED
if (is_vcat_configured(vm)) {
/* Bit 15: Supports Intel Resource Director Technology (Intel RDT) Allocation capability if 1 */
entry.ebx |= CPUID_EBX_PQE;
}
#endif
result = set_vcpuid_entry(vm, &entry);
result = set_vcpuid_extfeat(vm);
break;
/* 0x12U */
case CPUID_SGX_CAP:

View File

@ -177,10 +177,8 @@ bool is_stateful_vm(const struct acrn_vm *vm)
{
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
/* TEE VM doesn't has its own state. The TAs will do the content
* flush by themselves, HV and OS doesn't need to care about the state.
*/
return ((vm_config->guest_flags & GUEST_FLAG_TEE) == 0U);
/* TEE VM has GUEST_FLAG_STATELESS set implicitly */
return ((vm_config->guest_flags & GUEST_FLAG_STATELESS) == 0U);
}
/**
@ -959,6 +957,10 @@ int32_t shutdown_vm(struct acrn_vm *vm)
offline_vcpu(vcpu);
}
#ifdef CONFIG_HYPERV_ENABLED
hyperv_page_destory(vm);
#endif
/* after guest_flags not used, then clear it */
vm_config = get_vm_config(vm->vm_id);
vm_config->guest_flags &= ~DM_OWNED_GUEST_FLAG_MASK;
@ -1087,7 +1089,6 @@ void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec)
start_vm(vm);
}
static uint8_t loaded_pre_vm_nr = 0U;
/**
* Prepare to create vm/vcpu for vm
*
@ -1095,7 +1096,7 @@ static uint8_t loaded_pre_vm_nr = 0U;
*/
int32_t prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config)
{
int32_t err = 0;
int32_t err = -1;
struct acrn_vm *vm = NULL;
#ifdef CONFIG_SECURITY_VM_FIXUP
@ -1103,41 +1104,15 @@ int32_t prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config)
#endif
if (get_vmid_by_name(vm_config->name) != vm_id) {
pr_err("Invalid VM name: %s", vm_config->name);
err = -1;
} else {
/* Service VM and pre-launched VMs launch on all pCPUs defined in vm_config->cpu_affinity */
err = create_vm(vm_id, vm_config->cpu_affinity, vm_config, &vm);
}
if (err == 0) {
if (is_prelaunched_vm(vm)) {
build_vrsdp(vm);
}
if (is_service_vm(vm)) {
/* We need to ensure all modules of pre-launched VMs have been loaded already
* before loading Service VM modules, otherwise the module of pre-launched VMs could
* be corrupted because Service VM kernel might pick any usable RAM to extract kernel
* when KASLR enabled.
* In case the pre-launched VMs aren't loaded successfuly that cause deadlock here,
* use a 10000ms timer to break the waiting loop.
*/
uint64_t start_tick = cpu_ticks();
while (loaded_pre_vm_nr != PRE_VM_NUM) {
uint64_t timeout = ticks_to_ms(cpu_ticks() - start_tick);
if (timeout > 10000U) {
pr_err("Loading pre-launched VMs timeout!");
break;
}
if (err == 0) {
if (is_prelaunched_vm(vm)) {
build_vrsdp(vm);
}
}
err = prepare_os_image(vm);
if (is_prelaunched_vm(vm)) {
loaded_pre_vm_nr++;
err = prepare_os_image(vm);
}
}

View File

@ -73,16 +73,13 @@ static bool handle_reset_reg_read(struct acrn_vcpu *vcpu, __unused uint16_t addr
__unused size_t bytes)
{
bool ret = true;
struct acrn_vm *vm = vcpu->vm;
if (is_postlaunched_vm(vcpu->vm)) {
if (is_postlaunched_vm(vm)) {
/* re-inject to DM */
ret = false;
} else {
/*
* - reset control register 0xcf9: hide this from guests for now.
* - FADT reset register: the read behavior is not defined in spec, keep it simple to return all '1'.
*/
vcpu->req.reqs.pio_request.value = ~0U;
vcpu->req.reqs.pio_request.value = vm->reset_control;
}
return ret;
@ -91,7 +88,7 @@ static bool handle_reset_reg_read(struct acrn_vcpu *vcpu, __unused uint16_t addr
/**
* @pre vm != NULL
*/
static bool handle_common_reset_reg_write(struct acrn_vcpu *vcpu, bool reset)
static bool handle_common_reset_reg_write(struct acrn_vcpu *vcpu, bool reset, bool warm)
{
struct acrn_vm *vm = vcpu->vm;
bool ret = true;
@ -101,7 +98,7 @@ static bool handle_common_reset_reg_write(struct acrn_vcpu *vcpu, bool reset)
poweroff_if_rt_vm(vm);
if (get_highest_severity_vm(true) == vm) {
reset_host();
reset_host(warm);
} else if (is_postlaunched_vm(vm)) {
/* re-inject to DM */
ret = false;
@ -138,7 +135,7 @@ static bool handle_common_reset_reg_write(struct acrn_vcpu *vcpu, bool reset)
static bool handle_kb_write(struct acrn_vcpu *vcpu, __unused uint16_t addr, size_t bytes, uint32_t val)
{
/* ignore commands other than system reset */
return handle_common_reset_reg_write(vcpu, ((bytes == 1U) && (val == 0xfeU)));
return handle_common_reset_reg_write(vcpu, ((bytes == 1U) && (val == 0xfeU)), false);
}
static bool handle_kb_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t bytes)
@ -168,9 +165,12 @@ static bool handle_kb_read(struct acrn_vcpu *vcpu, uint16_t addr, size_t bytes)
*/
static bool handle_cf9_write(struct acrn_vcpu *vcpu, __unused uint16_t addr, size_t bytes, uint32_t val)
{
/* We don't differentiate among hard/soft/warm/cold reset */
struct acrn_vm *vm = vcpu->vm;
vm->reset_control = val & 0xeU;
return handle_common_reset_reg_write(vcpu,
((bytes == 1U) && ((val & 0x4U) == 0x4U) && ((val & 0xaU) != 0U)));
((bytes == 1U) && ((val & 0x4U) == 0x4U) && ((val & 0xaU) != 0U)),
((val & 0x8U) == 0U));
}
/**
@ -185,7 +185,7 @@ static bool handle_reset_reg_write(struct acrn_vcpu *vcpu, uint16_t addr, size_t
struct acpi_reset_reg *reset_reg = get_host_reset_reg_data();
if (val == reset_reg->val) {
ret = handle_common_reset_reg_write(vcpu, true);
ret = handle_common_reset_reg_write(vcpu, true, false);
} else {
/*
* ACPI defines the reset value but doesn't specify the meaning of other values.

View File

@ -257,7 +257,7 @@ static int32_t dispatch_hypercall(struct acrn_vcpu *vcpu)
*/
int32_t vmcall_vmexit_handler(struct acrn_vcpu *vcpu)
{
int32_t ret;
int32_t ret = -EACCES;
struct acrn_vm *vm = vcpu->vm;
/* hypercall ID from guest*/
uint64_t hypcall_id = vcpu_get_gpreg(vcpu, CPU_REG_R8);
@ -275,17 +275,13 @@ int32_t vmcall_vmexit_handler(struct acrn_vcpu *vcpu)
*/
if (!is_service_vm(vm) && !is_guest_hypercall(vm)) {
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)) {
vcpu_set_gpreg(vcpu, CPU_REG_RAX, (uint64_t)ret);
}
if (ret < 0) {
pr_err("ret=%d hypercall=0x%lx failed in %s\n", ret, hypcall_id, __func__);
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 2011 NetApp, Inc.
* Copyright (c) 2017-2022 Intel Corporation.
* Copyright (c) 2017-2024 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -41,6 +41,11 @@
static uint64_t hv_ram_size;
static void *ppt_mmu_pml4_addr;
/**
* @brief The sanitized page
*
* The sanitized page is used to mitigate l1tf.
*/
static uint8_t sanitized_page[PAGE_SIZE] __aligned(PAGE_SIZE);
/* PPT VA and PA are identical mapping */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2022 Intel Corporation.
* Copyright (C) 2018-2024 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -8,6 +8,19 @@
#include <asm/page.h>
#include <logmsg.h>
/**
* @addtogroup hwmgmt_page
*
* @{
*/
/**
* @file
* @brief Implementation of page management.
*
* This file provides the core functionality required for allocating and freeing memory pages. It's a fundamental
* support to manage memory resources.
*/
struct page *alloc_page(struct page_pool *pool)
{
@ -57,3 +70,7 @@ void free_page(struct page_pool *pool, struct page *page)
bitmap_clear_nolock(bit, pool->bitmap + idx);
spinlock_release(&pool->lock);
}
/**
* @}
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2022 Intel Corporation.
* Copyright (C) 2018-2024 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -11,8 +11,29 @@
#include <asm/mmu.h>
#include <logmsg.h>
/**
* @addtogroup hwmgmt_page
*
* @{
*/
/**
* @file
* @brief Implementation page table management.
*
* This file implements the external APIs to establish, modify, delete, or look for the mapping information. It also
* defines some helper functions to implement the features that are commonly used in this file.
*
*/
#define DBG_LEVEL_MMU 6U
/**
* @brief Host physical address of the sanitized page.
*
* The sanitized page is used to mitigate l1tf. This variable is used to store the host physical address of the
* sanitized page.
*/
static uint64_t sanitized_page_hpa;
static void sanitize_pte_entry(uint64_t *ptep, const struct pgtable *table)
@ -28,6 +49,26 @@ static void sanitize_pte(uint64_t *pt_page, const struct pgtable *table)
}
}
/**
* @brief Initializes a sanitized page.
*
* This function is responsible for initializing a sanitized page. It sets the page table entries in this sanitized page
* to point to the host physical address of the sanitized page itself.
*
* The static variable 'sanitized_page_hpa' will be set and the `sanitized_page` will be initialized.
*
* @param[out] sanitized_page The page to be sanitized.
* @param[in] hpa The host physical address that the page table entries in the sanitized page will point to.
*
* @return None
*
* @pre sanitized_page != NULL
* @pre ((uint64_t)sanitized_page & (PAGE_SIZE - 1)) == 0x0U
* @pre hpa != 0U
* @pre (hpa & (PAGE_SIZE - 1)) == 0x0U
*
* @post N/A
*/
void init_sanitized_page(uint64_t *sanitized_page, uint64_t hpa)
{
uint64_t i;
@ -256,18 +297,62 @@ static void modify_or_del_pdpte(const uint64_t *pml4e, uint64_t vaddr_start, uin
}
}
/*
* type: MR_MODIFY
* modify [vaddr, vaddr + size ) memory type or page access right.
* prot_clr - memory type or page access right want to be clear
* prot_set - memory type or page access right want to be set
* @pre: the prot_set and prot_clr should set before call this function.
* If you just want to modify access rights, you can just set the prot_clr
* to what you want to set, prot_clr to what you want to clear. But if you
* want to modify the MT, you should set the prot_set to what MT you want
* to set, prot_clr to the MT mask.
* type: MR_DEL
* delete [vaddr_base, vaddr_base + size ) memory region page table mapping.
/**
* @brief Modify or delete the mappings associated with the specified address range.
*
* This function modifies the properties of an existing mapping or deletes it entirely from the page table. The input
* address range is specified by [vaddr_base, vaddr_base + size). It is used when changing the access permissions of a
* memory region or when freeing a previously mapped region. This operation is critical for dynamic memory management,
* allowing the system to adapt to changes in memory usage patterns or to reclaim resources.
*
* For error case behaviors:
* - If the 'type' is MR_MODIFY and any page referenced by the PML4E in the specified address range is not present, the
* function asserts that the operation is invalid.
* For normal case behaviors(when the error case conditions are not satisfied):
* - If any page referenced by the PDPTE/PDE/PTE in the specified address range is not present, there is no change to
* the corresponding mapping and it continues the operation.
* - If any PDPTE/PDE in the specified address range maps a large page and the large page address exceeds the specified
* address range, the function splits the large page into next level page to allow for the modification or deletion of
* the mappings and the execute right will be recovered by the callback function table->recover_exe_right() when a 2MB
* page is split to 4KB pages.
* - If the 'type' is MR_MODIFY, the function modifies the properties of the existing mapping to match the specified
* properties.
* - If the 'type' is MR_DEL, the function will set corresponding page table entries to point to the sanitized page.
*
* @param[inout] pml4_page A pointer to the specified PML4 table.
* @param[in] vaddr_base The specified input address determining the start of the input address range whose mapping
* information is to be updated.
* For hypervisor's MMU, it is the host virtual address.
* For each VM's EPT, it is the guest physical address.
* @param[in] size The size of the specified input address range whose mapping information is to be updated.
* @param[in] prot_set Bit positions representing the specified properties which need to be set.
* Bits specified by prot_clr are cleared before each bit specified by prot_set is set to 1.
* @param[in] prot_clr Bit positions representing the specified properties which need to be cleared.
* Bits specified by prot_clr are cleared before each bit specified by prot_set is set to 1.
* @param[in] table A pointer to the struct pgtable containing the information of the specified memory operations.
* @param[in] type The type of operation to perform (MR_MODIFY or MR_DEL).
*
* @return None
*
* @pre pml4_page != NULL
* @pre table != NULL
* @pre (type == MR_MODIFY) || (type == MR_DEL)
* @pre For x86 hypervisor, the following conditions shall be met if "type == MR_MODIFY".
* - (prot_set & ~(PAGE_RW | PAGE_USER | PAGE_PWT | PAGE_PCD | PAGE_ACCESSED | PAGE_DIRTY | PAGE_PSE | PAGE_GLOBAL
* | PAGE_PAT_LARGE | PAGE_NX) == 0)
* - (prot_clr & ~(PAGE_RW | PAGE_USER | PAGE_PWT | PAGE_PCD | PAGE_ACCESSED | PAGE_DIRTY | PAGE_PSE | PAGE_GLOBAL
* | PAGE_PAT_LARGE | PAGE_NX) == 0)
* @pre For the VM EPT mappings, the following conditions shall be met if "type == MR_MODIFY".
* - (prot_set & ~(EPT_RD | EPT_WR | EPT_EXE | EPT_MT_MASK) == 0)
* - (prot_set & EPT_MT_MASK) == EPT_UNCACHED || (prot_set & EPT_MT_MASK) == EPT_WC ||
* (prot_set & EPT_MT_MASK) == EPT_WT || (prot_set & EPT_MT_MASK) == EPT_WP || (prot_set & EPT_MT_MASK) == EPT_WB
* - (prot_clr & ~(EPT_RD | EPT_WR | EPT_EXE | EPT_MT_MASK) == 0)
* - (prot_clr & EPT_MT_MASK) == EPT_UNCACHED || (prot_clr & EPT_MT_MASK) == EPT_WC ||
* (prot_clr & EPT_MT_MASK) == EPT_WT || (prot_clr & EPT_MT_MASK) == EPT_WP || (prot_clr & EPT_MT_MASK) == EPT_WB
*
* @post N/A
*
* @remark N/A
*/
void pgtable_modify_or_del_map(uint64_t *pml4_page, uint64_t vaddr_base, uint64_t size,
uint64_t prot_set, uint64_t prot_clr, const struct pgtable *table, uint32_t type)
@ -422,10 +507,46 @@ static void add_pdpte(const uint64_t *pml4e, uint64_t paddr_start, uint64_t vadd
}
}
/*
* action: MR_ADD
* add [vaddr_base, vaddr_base + size ) memory region page table mapping.
* @pre: the prot should set before call this function.
/**
* @brief Add new page table mappings.
*
* This function maps a virtual address range specified by [vaddr_base, vaddr_base + size) to a physical address range
* starting from 'paddr_base'.
*
* - If any subrange within [vaddr_base, vaddr_base + size) is already mapped, there is no change to the corresponding
* mapping and it continues the operation.
* - When a new 1GB or 2MB mapping is established, the callback function table->tweak_exe_right() is invoked to tweak
* the execution bit.
* - When a new page table referenced by a new PDPTE/PDE is created, all entries in the page table are initialized to
* point to the sanitized page by default.
* - Finally, the new mappings are established and initialized according to the specified address range and properties.
*
* @param[inout] pml4_page A pointer to the specified PML4 table hierarchy.
* @param[in] paddr_base The specified physical address determining the start of the physical memory region.
* It is the host physical address.
* @param[in] vaddr_base The specified input address determining the start of the input address space.
* For hypervisor's MMU, it is the host virtual address.
* For each VM's EPT, it is the guest physical address.
* @param[in] size The size of the specified input address space.
* @param[in] prot Bit positions representing the specified properties which need to be set.
* @param[in] table A pointer to the struct pgtable containing the information of the specified memory operations.
*
* @return None
*
* @pre pml4_page != NULL
* @pre Any subrange within [vaddr_base, vaddr_base + size) shall already be unmapped.
* @pre For x86 hypervisor mapping, the following condition shall be met.
* - prot & ~(PAGE_PRESENT| PAGE_RW | PAGE_USER | PAGE_PWT | PAGE_PCD | PAGE_ACCESSED | PAGE_DIRTY | PAGE_PSE |
* PAGE_GLOBAL | PAGE_PAT_LARGE | PAGE_NX) == 0
* @pre For VM EPT mapping, the following conditions shall be met.
* - prot & ~(EPT_RD | EPT_WR | EPT_EXE | EPT_MT_MASK | EPT_IGNORE_PAT) == 0
* - (prot & EPT_MT_MASK) == EPT_UNCACHED || (prot & EPT_MT_MASK) == EPT_WC || (prot & EPT_MT_MASK) == EPT_WT ||
* (prot & EPT_MT_MASK) == EPT_WP || (prot & EPT_MT_MASK) == EPT_WB
* @pre table != NULL
*
* @post N/A
*
* @remark N/A
*/
void pgtable_add_map(uint64_t *pml4_page, uint64_t paddr_base, uint64_t vaddr_base,
uint64_t size, uint64_t prot, const struct pgtable *table)
@ -455,6 +576,24 @@ void pgtable_add_map(uint64_t *pml4_page, uint64_t paddr_base, uint64_t vaddr_ba
}
}
/**
* @brief Create a new root page table.
*
* This function initializes and returns a new root page table. It is typically used during the setup of a new execution
* context, such as initializing a hypervisor PML4 table or creating a virtual machine. The root page table is essential
* for defining the virtual memory layout for the context.
*
* It creates a new root page table and every entries in the page table are initialized to point to the sanitized page.
* Finally, the function returns the root page table pointer.
*
* @param[in] table A pointer to the struct pgtable containing the information of the specified memory operations.
*
* @return A pointer to the newly created root page table.
*
* @pre table != NULL
*
* @post N/A
*/
void *pgtable_create_root(const struct pgtable *table)
{
uint64_t *page = (uint64_t *)alloc_page(table->pool);
@ -462,6 +601,31 @@ void *pgtable_create_root(const struct pgtable *table)
return page;
}
/**
* @brief Create a root page table for Secure World.
*
* This function initializes a new root page table for Secure World. It is intended to be used during the initialization
* phase of Trusty, setting up isolated memory regions for secure execution. Secure world can access Normal World's
* memory, but Normal World cannot access Secure World's memory. The PML4T/PDPT for Secure World are separated from
* Normal World. PDT/PT are shared in both Secure World's EPT and Normal World's EPT. So this function copies the PDPTEs
* from the Normal World to the Secure World.
*
* - It creates a new root page table and every entries are initialized to point to the sanitized page by default.
* - The access right specified by prot_clr is cleared for Secure World PDPTEs.
* - Finally, the function returns the new root page table pointer.
*
* @param[in] table A pointer to the struct pgtable containing the information of the specified memory operations.
* @param[in] nworld_pml4_page A pointer to pml4 table hierarchy in Normal World.
* @param[in] prot_table_present Mask indicating the page referenced is present.
* @param[in] prot_clr Bit positions representing the specified properties which need to be cleared.
*
* @return A pointer to the newly created root page table for Secure World.
*
* @pre table != NULL
* @pre nworld_pml4_page != NULL
*
* @post N/A
*/
void *pgtable_create_trusty_root(const struct pgtable *table,
void *nworld_pml4_page, uint64_t prot_table_present, uint64_t prot_clr)
{
@ -474,7 +638,7 @@ void *pgtable_create_trusty_root(const struct pgtable *table,
* Secure world can access Normal World's memory,
* but Normal World can not access Secure World's memory.
* The PML4/PDPT for Secure world are separated from
* Normal World.PD/PT are shared in both Secure world's EPT
* Normal World. PD/PT are shared in both Secure world's EPT
* and Normal World's EPT
*/
pml4_base = pgtable_create_root(table);
@ -508,7 +672,39 @@ void *pgtable_create_trusty_root(const struct pgtable *table,
}
/**
* @pre (pml4_page != NULL) && (pg_size != NULL)
* @brief Look for the paging-structure entry that contains the mapping information for the specified input address.
*
* This function looks for the paging-structure entry that contains the mapping information for the specified input
* address of the translation process. It is used to search the page table hierarchy for the entry corresponding to the
* given virtual address. The function traverses the page table hierarchy from the PML4 down to the appropriate page
* table level, returning the entry if found.
*
* - If specified address is mapped in the page table hierarchy, it will return a pointer to the page table entry that
* maps the specified address.
* - If the specified address is not mapped in the page table hierarchy, it will return NULL.
*
* @param[in] pml4_page A pointer to the specified PML4 table hierarchy.
* @param[in] addr The specified input address whose mapping information is to be searched.
* For hypervisor's MMU, it is the host virtual address.
* For each VM's EPT, it is the guest physical address.
* @param[out] pg_size A pointer to the size of the page controlled by the returned paging-structure entry.
* @param[in] table A pointer to the struct pgtable which provides the page pool and callback functions to be used when
* creating the new page.
*
* @return A pointer to the paging-structure entry that maps the specified input address.
*
* @retval non-NULL There is a paging-structure entry that contains the mapping information for the specified input
* address.
* @retval NULL There is no paging-structure entry that contains the mapping information for the specified input
* address.
*
* @pre pml4_page != NULL
* @pre pg_size != NULL
* @pre table != NULL
*
* @post N/A
*
* @remark N/A
*/
const uint64_t *pgtable_lookup_entry(uint64_t *pml4_page, uint64_t addr, uint64_t *pg_size, const struct pgtable *table)
{
@ -548,3 +744,7 @@ const uint64_t *pgtable_lookup_entry(uint64_t *pml4_page, uint64_t addr, uint64_
return pret;
}
/**
* @}
*/

View File

@ -244,10 +244,10 @@ void host_enter_s3(const struct pm_s_state_data *sstate_data, uint32_t pm1a_cnt_
resume_console();
}
void reset_host(void)
void reset_host(bool warm)
{
struct acrn_acpi_generic_address *gas = &(host_reset_reg.reg);
uint8_t reboot_code = warm ? CF9_RESET_WARM : CF9_RESET_COLD;
/* TODO: gracefully shut down all guests before doing host reset. */
@ -256,11 +256,6 @@ void reset_host(void)
* The platform we are running must support at least one of reset method:
* - ACPI reset
* - 0xcf9 reset
*
* UEFI more likely sets the reset value as 0x6 (not 0xe) for 0xcf9 port.
* This asserts PLTRST# to reset devices on the platform, but not the
* SLP_S3#/4#/5# signals, which power down the systems. This might not be
* enough for us.
*/
if ((gas->space_id == SPACE_SYSTEM_IO) &&
(gas->bit_width == 8U) && (gas->bit_offset == 0U) &&
@ -270,7 +265,8 @@ void reset_host(void)
/* making sure bit 2 (RST_CPU) is '0', when the reset command is issued. */
pio_write8(0x2U, 0xcf9U);
udelay(50U);
pio_write8(0xeU, 0xcf9U);
pio_write8(reboot_code, 0xcf9U);
udelay(50U);
}
pr_fatal("%s(): can't reset host.", __func__);

View File

@ -156,30 +156,30 @@ struct intr_remap_table {
struct page tables[MAX_IR_ENTRIES/DMAR_NUM_IR_ENTRIES_PER_PAGE];
};
static struct page root_tables[CONFIG_MAX_IOMMU_NUM] __aligned(PAGE_SIZE);
static inline uint8_t *get_root_table(uint32_t dmar_index)
{
static struct page root_tables[CONFIG_MAX_IOMMU_NUM] __aligned(PAGE_SIZE);
return root_tables[dmar_index].contents;
}
static struct context_table ctx_tables[CONFIG_MAX_IOMMU_NUM] __aligned(PAGE_SIZE);
static inline uint8_t *get_ctx_table(uint32_t dmar_index, uint8_t bus_no)
{
static struct context_table ctx_tables[CONFIG_MAX_IOMMU_NUM] __aligned(PAGE_SIZE);
return ctx_tables[dmar_index].buses[bus_no].contents;
}
/*
* @pre dmar_index < CONFIG_MAX_IOMMU_NUM
*/
static struct page qi_queues[CONFIG_MAX_IOMMU_NUM] __aligned(PAGE_SIZE);
static inline void *get_qi_queue(uint32_t dmar_index)
{
static struct page qi_queues[CONFIG_MAX_IOMMU_NUM] __aligned(PAGE_SIZE);
return (void *)qi_queues[dmar_index].contents;
}
static struct intr_remap_table ir_tables[CONFIG_MAX_IOMMU_NUM] __aligned(PAGE_SIZE);
static inline void *get_ir_table(uint32_t dmar_index)
{
static struct intr_remap_table ir_tables[CONFIG_MAX_IOMMU_NUM] __aligned(PAGE_SIZE);
return (void *)ir_tables[dmar_index].tables[0].contents;
}
@ -1158,9 +1158,9 @@ static void do_action_for_iommus(void (*action)(struct dmar_drhd_rt *))
}
}
static struct iommu_domain iommu_domains[MAX_DOMAIN_NUM];
struct iommu_domain *create_iommu_domain(uint16_t vm_id, uint64_t translation_table, uint32_t addr_width)
{
static struct iommu_domain iommu_domains[MAX_DOMAIN_NUM];
struct iommu_domain *domain;
/* TODO: check if a domain with the vm_id exists */

View File

@ -61,7 +61,7 @@ static void *get_initrd_load_addr(struct acrn_vm *vm, uint64_t kernel_start)
kernel_init_size = zeropage->hdr.init_size;
kernel_align = zeropage->hdr.kernel_alignment;
initrd_addr_max = zeropage->hdr.initrd_addr_max;
stac();
clac();
kernel_end = roundup(kernel_start, kernel_align) + kernel_init_size;
if (initrd_addr_max != 0U) {

View File

@ -109,7 +109,8 @@ static void *do_load_elf64(struct acrn_vm *vm)
*/
(void)copy_to_gpa(vm, p_elf_img + p_prg_tbl_head64->p_offset,
p_prg_tbl_head64->p_paddr, (uint32_t)p_prg_tbl_head64->p_filesz);
/* copy_to_gpa has it's stac/clac inside. So call stac again here. */
/* copy_to_gpa has its own stac/clac inside. Call stac again here to keep
* the context. */
stac();
}
p_prg_tbl_head64++;
@ -174,7 +175,8 @@ static void *do_load_elf32(struct acrn_vm *vm)
*/
(void)copy_to_gpa(vm, p_elf_img + p_prg_tbl_head32->p_offset,
p_prg_tbl_head32->p_paddr, p_prg_tbl_head32->p_filesz);
/* copy_to_gpa has it's stac/clac inside. So call stac again here. */
/* copy_to_gpa has its own stac/clac inside. Call stac again here to keep
* the context. */
stac();
}
p_prg_tbl_head32++;

View File

@ -7,6 +7,8 @@
#ifndef MULTIBOOT_PRIV_H
#define MULTIBOOT_PRIV_H
#include <multiboot_std.h>
#ifdef CONFIG_MULTIBOOT2
/*
* @post boot_regs[1] stores the address pointer that point to a valid multiboot2 info

View File

@ -1102,7 +1102,7 @@ int32_t hcall_get_cpu_pm_state(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm
int32_t ret = -1;
uint64_t cmd = param1;
if (is_created_vm(target_vm)) {
if (is_created_vm(target_vm) || is_paused_vm(target_vm)) {
switch (cmd & PMCMD_TYPE_MASK) {
case ACRN_PMCMD_GET_PX_CNT: {
uint8_t px_cnt;

View File

@ -1531,7 +1531,7 @@ static int32_t shell_cpuid(int32_t argc, char **argv)
static int32_t shell_reboot(__unused int32_t argc, __unused char **argv)
{
reset_host();
reset_host(false);
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2022 Intel Corporation.
* Copyright (C) 2020-2024 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -14,6 +14,20 @@
#include <ivshmem_cfg.h>
#include "vpci_priv.h"
/**
* @addtogroup vp-dm_vperipheral
*
* @{
*/
/**
* @file
* @brief Implementation of Inter-VM shared memory device (ivshmem).
*
* This file defines marcos, data structure and functions to support ivshmem devices. It also implements necessary
* functions to model a ivshmem device as a PCI device.
*/
/* config space of ivshmem device */
#define IVSHMEM_CLASS 0x05U
#define IVSHMEM_REV 0x01U
@ -69,6 +83,25 @@ struct ivshmem_device {
static struct ivshmem_device ivshmem_dev[IVSHMEM_DEV_NUM];
static spinlock_t ivshmem_dev_lock = { .head = 0U, .tail = 0U, };
/**
* @brief Initialize the shared memory regions for all ivshmem devices.
*
* An ivshmem device is used to transfer data between VMs based on shared memory region. Basic ivshmem information is
* configured in scenario file. After compilation, every shared memory region is stored in struct ivshmem_shm_region.
* This function initializes all shared memory regions for ivshmem devices and it is usually called before all VMs are
* created.
*
* IVSHMEM_SHM_SIZE is the sum of all ivshmem shared memory regions in bytes. It rounds IVSHMEM_SHM_SIZE up to PDE_SIZE
* (1 GiB) and allocates a contiguous block of memory for these memory regions from host e820. For detailed allocation
* operations, refer to e820_alloc_memory(). The function then iterates over the memory regions and assigns the
* allocated physical addresses to each region.
*
* @return None
*
* @pre N/A
*
* @post N/A
*/
void init_ivshmem_shared_memory()
{
uint32_t i;
@ -186,8 +219,36 @@ static void create_ivshmem_device(struct pci_vdev *vdev)
memset(&ivshmem_dev[i].mmio, 0U, sizeof(uint32_t) * 4);
}
/*
* @pre vdev->priv_data != NULL
/**
* @brief Handle MMIO (Memory-Mapped I/O) operations for the ivshmem device.
*
* BAR0 is used for device registers. This function handles MMIO read and write operations to the ivshmem device BAR0.
*
* Per the specification, the access offset within should be 4-byte aligned, the access size should be 4 bytes, and the
* access offset exceeds 16 bytes are reserved. So the request needs to meet these conditions, otherwise, it does
* nothing and directly returns 0.
* - For a read operation, the read value is stored in the input mmio request structure:
* - Doorbell register is a write-only register, so it sets the read value to 0.
* - Otherwise, it reads specified register value of the ivshmem device.
* - For a write operation:
* - IVPosition register is a read-only register, so it does nothing if writing to IVPosition.
* - Writing to the Doorbell register requests to interrupt a peer. It extracts the peer ID and vector index from the
* input mmio value. If the peer is valid (peer ivshmem device exists, MSI-X is enabled, the MSI-X table entry
* corresponding to the vector index exists and is not masked), it injects an MSI to the peer VM. For more details
* about the MSI injection, refer to vlapic_inject_msi().
* - Otherwise, it writes the value to the specified register of the ivshmem device.
* - Finally, it returns 0.
*
* @param[inout] io_req Pointer to the I/O request structure that contains the MMIO request information.
* @param[inout] data Pointer to the pci_vdev structure that is treated as an ivshmem device.
*
* @return Always return 0.
*
* @pre io_req != NULL
* @pre data != NULL
* @pre data->priv_data != NULL
*
* @post retval == 0
*/
static int32_t ivshmem_mmio_handler(struct io_request *io_req, void *data)
{
@ -227,6 +288,27 @@ static int32_t ivshmem_mmio_handler(struct io_request *io_req, void *data)
return 0;
}
/**
* @brief Read the PCI configuration space of the ivshmem device.
*
* This function reads the configuration space of the specified virtual PCI device that is configured as a ivshmem
* device. It is used to retrieve the configuration data of the ivshmem device for further processing or validation.
*
* It directly reads the configuration space of the ivshmem device by calling pci_vdev_read_vcfg().
*
* @param[in] vdev Pointer to the virtual PCI device whose configuration is to be read.
* @param[in] offset Offset within the configuration space to start reading from.
* @param[in] bytes Number of bytes to read from the configuration space.
* @param[inout] val Pointer to the buffer where the read configuration data will be stored.
*
* @return Always return 0.
*
* @pre vdev != NULL
* @pre val != NULL
* @pre offset + bytes <= 0x1000
*
* @post retval == 0
*/
static int32_t read_ivshmem_vdev_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t *val)
{
*val = pci_vdev_read_vcfg(vdev, offset, bytes);
@ -234,6 +316,30 @@ static int32_t read_ivshmem_vdev_cfg(struct pci_vdev *vdev, uint32_t offset, uin
return 0;
}
/**
* @brief Unmap the specified BAR for the ivshmem device.
*
* This function unmaps the specified BAR for the ivshmem device. It is typically called during the destroy phase of the
* ivshmem device or when guest updates the BAR register.
*
* - BAR0 and BAR1 are used for device registers and MSI-X table and PBA, respectively. If the specified idx is 0 or 1
* and the field base_gpa in the specified vBAR is not 0, it unregisters the mmio range handler for the BAR by calling
* unregister_mmio_emulation_handler().
* - BAR2 maps the shared memory object. If the specified idx is 2 and the field base_gpa in vBAR2 is not 0, it releases
* the ept memory mapping for the shared memory region by calling ept_del_mr().
* - Otherwise, it does nothing.
*
* @param[inout] vdev Pointer to the PCI device that is treated as an ivshmem device.
* @param[in] idx Index of the BAR to be unmapped.
*
* @return None
*
* @pre vdev != NULL
* @pre vdev->vpci != NULL
* @pre idx < PCI_BAR_COUNT
*
* @post N/A
*/
static void ivshmem_vbar_unmap(struct pci_vdev *vdev, uint32_t idx)
{
struct acrn_vm *vm = vpci2vm(vdev->vpci);
@ -246,9 +352,35 @@ static void ivshmem_vbar_unmap(struct pci_vdev *vdev, uint32_t idx)
}
}
/*
/**
* @brief Map the virtual BAR for the ivshmem device.
*
* This function maps the specified virtual BAR for the ivshmem device. It is typically called when guest updates the
* BAR register.
*
* - BAR0 is used for device registers. If the specified idx is 0 and the field base_gpa in the specified vBAR is not 0,
* it registers the mmio range handler (via the callback ivshmem_mmio_handler) for the BAR and deletes the 4KB ept
* memory mapping for the BAR by calling ept_del_mr().
* - BAR1 is used for MSI-X table and PBA. If the specified idx is 1 and the field base_gpa in the specified vBAR is not
* 0, it registers the mmio range handler (via the callback vmsix_handle_table_mmio_access) for the BAR and deletes
* the ept memory mapping for the BAR by calling ept_del_mr(). It also sets the mmio_gpa field in the vdev->msix to
* the GPA of the BAR for MSI-X table access.
* - BAR2 maps the shared memory object. If the specified idx is 2, the field base_gpa in vBAR2 is not 0 and the field
* base_hpa in vBAR2 is not INVALID_HPA, it adds the ept memory mapping as (EPT_RD|EPT_WR|EPT_WB|EPT_IGNORE_PAT) for
* the BAR by calling ept_add_mr().
* - Otherwise, it does nothing.
*
* @param[inout] vdev Pointer to the PCI device that is treated as an ivshmem device.
* @param[in] idx Index of the BAR to be mapped.
*
* @return None
*
* @pre vdev != NULL
* @pre vdev->priv_data != NULL
* @pre msix->table_offset == 0U
* @pre bar_idx < PCI_BAR_COUNT
*
* @post N/A
*/
static void ivshmem_vbar_map(struct pci_vdev *vdev, uint32_t idx)
{
@ -270,6 +402,32 @@ static void ivshmem_vbar_map(struct pci_vdev *vdev, uint32_t idx)
}
}
/**
* @brief Write to the virtual ivshmem device configuration space.
*
* This function handles writes to the configuration space of the specified virtual PCI device that is configured as an
* ivshmem device. It is typically called when the guest writes to the ivshmem device's configuration space.
*
* - If the write request is for a BAR register, it updates the BAR with the provided value. It also needs to update the
* ept mapping and mmio emulation handler based on the bar information. For detailed operations, refer to
* vpci_update_one_vbar(), ivshmem_vbar_map() and ivshmem_vbar_unmap().
* - If the write request is for the MSI-X capability register, it specially handles the write request. For detailed
* operations, refer to write_vmsix_cap_reg().
* - Otherwise, the function writes the provided value to the specified configuration space register.
* - Finally, the function returns 0.
*
* @param[inout] vdev Pointer to the virtual PCI device whose configuration is to be written.
* @param[in] offset Offset within the configuration space to start writing to.
* @param[in] bytes Number of bytes to write.
* @param[in] val The value to be written to the register.
*
* @return Always return 0.
*
* @pre vdev != NULL
* @pre offset + bytes <= 0x1000
*
* @post retval == 0
*/
static int32_t write_ivshmem_vdev_cfg(struct pci_vdev *vdev, uint32_t offset, uint32_t bytes, uint32_t val)
{
if (vbar_access(vdev, offset)) {
@ -284,9 +442,30 @@ static int32_t write_ivshmem_vdev_cfg(struct pci_vdev *vdev, uint32_t offset, ui
return 0;
}
/*
/**
* @brief Initialize the specified BAR for the ivshmem device.
*
* The ivshmem PCI device has three BARs: BAR0, BAR1, and BAR2. BAR0/BAR1 is a 32-bit memory BAR and BAR2 is a 64-bit
* memory BAR. This function initializes a specified BAR for the ivshmem device. It is typically called during the
* initialization phase of the ivshmem device.
*
* - If bar_idx exceeds 2, the function does nothing.
* - For BAR2, it finds the shared memory region based on the shared memory region name. If the shared memory region is
* not found, the function does nothing.
* - It updates corresponding fields in the pci_vbar structure of specified bar_idx.
* - It configures the Base Address Register in the device's configuration space.
* - For a 64-bit memory BAR (BAR2 for now), it also sets up the next Base Address Register as the high 32 bits.
*
* @param[inout] vdev Pointer to the PCI device that is treated as an ivshmem device.
* @param[in] bar_idx Index of the BAR to be initialized.
*
* @return None
*
* @pre vdev != NULL
* @pre vdev->pci_dev_config != NULL
* @pre bar_idx < PCI_BAR_COUNT
*
* @post N/A
*/
static void init_ivshmem_bar(struct pci_vdev *vdev, uint32_t bar_idx)
{
@ -327,6 +506,40 @@ static void init_ivshmem_bar(struct pci_vdev *vdev, uint32_t bar_idx)
}
}
/**
* @brief Initialize a virtual ivshmem device.
*
* This function initializes the specified virtual PCI device as an ivshmem device. It sets up the device to follow the
* specifications. Because the ivshmem is introduced by QEMU, the spec link is
* https://www.qemu.org/docs/master/specs/ivshmem-spec.html. This function is usually used in the initialization phase
* of VM.
*
* - It sets the pcidev field in ivshmem_device (all ivshmem devices emulated by hypervisor are static stored based on
* the configuration) to the vdev and sets the priv_data field in the specified vdev to new ivshmem_device structure
* data, indicating the association between the virtual PCI device and the ivshmem device.
* - Per the ivshmem specification and PCI Express Base Specification, it initializes the ivshmem device configuration
* space with appropriate values:
* - The device ID and Vendor ID is 0x11101af4.
* - It sets subsystem vendor ID to 0x8086 (Intel) and subsystem ID to the region ID of the shared memory region.
* - It sets up the MSI-X capability with 8 MSI-X table entries and maps the table and PBA into BAR1. For detailed
* operations, refer to add_vmsix_capability().
* - It initializes BAR0 for the device to hold device registers (256 Byte MMIO).
* - It initializes BAR1 for the device to hold MSI-X table and PBA.
* - It initializes BAR2 for the device to map the shared memory object. Because BAR2 is a 64-bit memory BAR, it also
* sets up the next Base Address Register as the high 32 bits and the total number of bars is set to 4.
* - It binds the device to the ivshmem server (hosts in hypervisor) for inter-VM communication.
* - Finally, it sets the user field to vdev, indicating that this ivshmem is used by a VM.
*
* @param[inout] vdev Pointer to the virtual PCI device to be initialized.
*
* @return None
*
* @pre vdev != NULL
* @pre vdev->pci_dev_config != NULL
* @pre vdev->pci != NULL
*
* @post N/A
*/
static void init_ivshmem_vdev(struct pci_vdev *vdev)
{
struct acrn_vm_pci_dev_config *dev_config = vdev->pci_dev_config;
@ -359,8 +572,25 @@ static void init_ivshmem_vdev(struct pci_vdev *vdev)
vdev->user = vdev;
}
/*
/**
* @brief Deinitialize a virtual ivshmem device.
*
* This function deinitializes the specified virtual PCI device that was previously initialized as an ivshmem device.
*
* - It unbinds the device from the ivshmem server (hosts in hypervisor).
* - It sets the priv_data field in the specified vdev to NULL and sets the pcidev field in ivshmem_device to NULL,
* indicating the disassociation between the virtual PCI device and the ivshmem device.
* - It sets the user field to NULL, indicating that this virtual device is not owned by any VM.
*
* @param[inout] vdev Pointer to the virtual PCI device to be deinitialized.
*
* @return None
*
* @pre vdev != NULL
* @pre vdev->priv_data != NULL
* @pre vdev->pci != NULL
*
* @post N/A
*/
static void deinit_ivshmem_vdev(struct pci_vdev *vdev)
{
@ -376,8 +606,39 @@ static void deinit_ivshmem_vdev(struct pci_vdev *vdev)
}
/**
* @brief Create a virtual ivshmem device based on the specified device information.
*
* Basic ivshmem information is configured in the scenario file. After compilation, some device configurations of every
* ivshmem PCI device are stored in struct acrn_vm_pci_dev_config and every shared memory region is stored in struct
* ivshmem_shm_region. This function creates one virtual ivshmem device based on the input device information. The
* user-space tool(such as acrn-dm) may add an ivshmem device for a post-launch VM and this device is emulated in
* hypervisor. This function is used for the case for now and it is usually used in the initialization phase of a
* post-launch VM.
*
* - Per the ivshmem specification, BAR2 maps the shared memory object. For the ivshmem device to be created, the shared
* memory region name is stored in dev->args and the size of the shared memory region is stored in
* dev->io_size[IVSHMEM_SHM_BAR].
* - It traverses all configured PCI devices of the specified VM. Based on the input shared memory region name, it finds
* corresponding acrn_vm_pci_dev_config and ivshmem_shm_region.
* - If the acrn_vm_pci_dev_config is not found or the ivshmem_shm_region is not found or the size of ivshmem_shm_region
* is not equal to the size specified in dev->io_size[IVSHMEM_SHM_BAR], the function returns -EINVAL.
* - Otherwise, update the acrn_vm_pci_dev_config with input device information specified in dev and initializes a new
* virtual PCI device as an ivshmem device. For detailed operations, refer to vpci_init_vdev(). The function returns
* -EINVAL if the vpci_init_vdev() fails.
* - Finally, it returns 0 on success.
*
* @param[inout] vm Pointer to the VM that owns the ivshmem device.
* @param[in] dev Pointer to the device information to create an ivshmem device.
*
* @return A int32_t value to indicate the status of the ivshmem device creation.
*
* @retval 0 On success.
* @retval -EINVAL If the ivshmem device creation fails.
*
* @pre vm != NULL
* @pre dev != NULL
*
* @post retval <= 0
*/
int32_t create_ivshmem_vdev(struct acrn_vm *vm, struct acrn_vdev *dev)
{
@ -403,7 +664,7 @@ int32_t create_ivshmem_vdev(struct acrn_vm *vm, struct acrn_vdev *dev)
if (vdev != NULL) {
ret = 0;
}
}
}
break;
}
}
@ -415,6 +676,27 @@ int32_t create_ivshmem_vdev(struct acrn_vm *vm, struct acrn_vdev *dev)
return ret;
}
/**
* @brief Destroy the virtual ivshmem device.
*
* This function is the counterpart of create_ivshmem_vdev(). This function destroys the specified virtual PCI device
* that was previously initialized as an ivshmem device. It is usually used for a post-launch VM to destroy the ivshmem
* device.
*
* - It updates all BARs of the specified vdev. For detailed operations, refer to vpci_update_one_vbar() and the
* function ivshmem_vbar_unmap().
* - It deinitializes the specified virtual PCI device. For detailed operations, refer to vpci_deinit_vdev().
* - Finally, it returns 0.
*
* @param[inout] vdev Pointer to the virtual PCI device to be destroyed.
*
* @return Always return 0.
*
* @pre vdev != NULL
* @pre vdev->vpci != NULL
*
* @post retval == 0
*/
int32_t destroy_ivshmem_vdev(struct pci_vdev *vdev)
{
uint32_t i;
@ -431,10 +713,26 @@ int32_t destroy_ivshmem_vdev(struct pci_vdev *vdev)
return 0;
}
/**
* @brief Data structure implementation for virtual Inter-VM shared memory device (ivshmem) operations.
*
* The ivshmem is actually first introduced by QEMU to share a memory region between multiple VMs and host. It is
* modeled as a PCI device exposing said memory to the VM as a PCI BAR. ACRN also introduces it to transfer data between
* VMs based on the shared memory region. Struct pci_vdev_ops is used to define the operations of virtual PCI device and
* definition here is used to support ivshmem device.
*
* @consistency N/A
* @alignment N/A
*
* @remark N/A
*/
const struct pci_vdev_ops vpci_ivshmem_ops = {
.init_vdev = init_ivshmem_vdev,
.deinit_vdev = deinit_ivshmem_vdev,
.write_vdev_cfg = write_ivshmem_vdev_cfg,
.read_vdev_cfg = read_ivshmem_vdev_cfg,
};
/**
* @}
*/
#endif

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 2011 NetApp, Inc.
* Copyright (c) 2018-2022 Intel Corporation.
* Copyright (c) 2018-2024 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -39,75 +39,131 @@
#include <vacpi.h>
/**
* @pre vdev != NULL
* @pre vdev->vpci != NULL
* @addtogroup vp-dm_vperipheral
*
* @{
*/
/* The chart below shows the hostbridge DID high-byte of the platform later than broadwell, whose PCIEXBAR are always
located in the PCI hostbridge config space at the offset 0x60. This chart may need further extension in the future
--------------------------------------------------------------------------------------
platform | hostbridge DID high-byte
--------------------------------------------------------------------------------------
SKL(6-gen) | 0x19
APL(6-gen Atom) | 0x5a
KBL(7/8-gen) | 0x59
CFL/CFL-R(8/9-gen) | 0x3e
ICL(10-gen) | 0x9b
EHL(11-gen) | 0x45
TGL(11-gen) | 0x9a
--------------------------------------------------------------------------------------
/**
* @file
* @brief Implementation of virtual PCI host bridge.
*
* This file defines operations to support virtual PCI host bridge. All the operation related APIs are registered as the
* callbacks in the global variable "struct pci_vdev_ops vhostbridge_ops".
*/
/*
The chart below shows the hostbridge DID high-byte of the platform later than broadwell, whose PCIEXBAR are always
located in the PCI hostbridge config space at the offset 0x60. This chart may need further extension in the future
--------------------------------------------------------------------------------------
platform | hostbridge DID high-byte
--------------------------------------------------------------------------------------
SKL(6-gen) | 0x19
APL(6-gen Atom) | 0x5a
KBL(7/8-gen) | 0x59
CFL/CFL-R(8/9-gen) | 0x3e
ICL(10-gen) | 0x9b
EHL(11-gen) | 0x45
TGL(11-gen) | 0x9a
--------------------------------------------------------------------------------------
*/
static const uint32_t hostbridge_did_highbytes[] = {0x19U, 0x5aU, 0x59U, 0x3eU, 0x9aU, 0x45U, 0x9bU};
/*
The vhostbridge we currently emulated is "Celeron N3350/Pentium N4200/Atom E3900 Series Host Bridge",
which belongs to Intel Appollo Lake processors family, and the device id is 5af0
TODO:
1. In the future, we may add one or more virtual hostbridges for CPUs that are incompatible in layout with the current
one
2. Besides PCIEXBAR(0x60), there are also some registers needs to be emulated more precisely rather than be treated as
read-only and hard-coded, listed below:
TODO:
1. In the future, we may add one or more virtual hostbridges for CPUs that are incompatible in layout with the current one
2. Besides PCIEXBAR(0x60), there are also some registers needs to be emulated more precisely rather than be treated as read-only and hard-coded, listed below:
----------------------------------------------------------------------------------------------------------------
reg | offset | length | current status | remark
----------------------------------------------------------------------------------------------------------------
STATUS_COMMAND | 0x8 | dword | unemulated | pci status and command
SVID_SID | 0x2C | dword | unemulated | subsys id and subsys vendor id
MCHBAR | 0x48 | qword | hard-coded | BAR of memory controller hub
GGC | 0x50 | dword | hard-coded | graphics & mem controller hub graphics CR
DEVEN | 0x54 | dword | hard-coded | device enable register
PAVPC | 0x58 | dword | hard-coded | protected audio video path control
TOUUD | 0xA8 | qword | hard-coded | top of upper usable DRAM
BDSM | 0xB0 | dword | hard-coded | base of data stolen memory
BGSM | 0xB4 | dword | hard-coded | base of graphics stolen memory
TSEGMB | 0xB8 | dword | hard-coded | top segmentmemory base
TOLUD | 0xBC | dword | hard-coded | top of lower usable dram
SKPD | 0xDC | dword | unemulated | scratchpad
CAPID0_CAPCTRL0 | 0xe0 | dword | hard-coded | capability 0 control
----------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
reg |offset |length |current status |remark
-----------------------------------------------------------------------------------------------
STATUS_COMMAND |0x8 |dword |unemulated |pci status and command
SVID_SID |0x2C |dword |unemulated |subsys id and subsys vendor id
MCHBAR |0x48 |qword |hard-coded |BAR of memory controller hub
GGC |0x50 |dword |hard-coded |graphics & mem controller hub graphics CR
DEVEN |0x54 |dword |hard-coded |device enable register
PAVPC |0x58 |dword |hard-coded |protected audio video path control
TOUUD |0xA8 |qword |hard-coded |top of upper usable DRAM
BDSM |0xB0 |dword |hard-coded |base of data stolen memory
BGSM |0xB4 |dword |hard-coded |base of graphics stolen memory
TSEGMB |0xB8 |dword |hard-coded |top segmentmemory base
TOLUD |0xBC |dword |hard-coded |top of lower usable dram
SKPD |0xDC |dword |unemulated |scratchpad
CAPID0_CAPCTRL0 |0xe0 |dword |hard-coded |capability 0 control
-----------------------------------------------------------------------------------------------
*/
/**
* @brief Initialize the virtual host bridge.
*
* A host bridge is a PCI device that is used to support the pci devices under it. This function initializes the
* specified virtual PCI device as a host bridge. It's usually called during the initialization of a VM.
*
* This function emulates the virtual host bridge as a "Celeron N3350/Pentium N4200/Atom E3900 Series Host Bridge",
* which belongs to Intel Apollo Lake processors family, and the device id is 0x5af0. Per "Section 9 C-Unit in Intel®
* Pentium® and Celeron® Processor N- and J- Series, Datasheet Volume 2", it initializes related type info registers in
* configuration space.
* PCI Express Enhanced Configuration Range Base Address Register (PCIEXBAR) is emulated differently for pre-launched
* VMs and Service VM, to support PCI Express Enhanced Configuration Access Mechanism (ECAM).
* - For a pre-launched VM, it is emulated as 'USER_VM_VIRT_PCI_MMCFG_BASE | 0x1'. USER_VM_VIRT_PCI_MMCFG_BASE
* (0xE0000000) is the hard-coded virtual PCI MMCFG address base for pre/post-launched VMs. Bit 0 is set to 1 to
* indicate that the base address defined in the PCIEXBAR register is active.
* - For a Service VM, it is emulated to be the same value as the physical PCIEXBAR. It is not used for now, mainly for
* feature extension in the future.
* Finally, it sets the field parent_user to NULL and the field user to vdev, indicating that this vPCI bridge is used
* by a VM.
*
* @param[inout] vdev Pointer to the virtual PCI device to be initialized.
*
* @return None
*
* @pre vdev != NULL
* @pre vdev->vpci != NULL
*
* @post N/A
*/
static void init_vhostbridge(struct pci_vdev *vdev)
{
union pci_bdf hostbridge_bdf = {.value = 0x0U};
uint32_t pciexbar_low = 0x0U, pciexbar_high = 0x0U, phys_did, i;
/* Refer to Section 9 C-Unit in Intel® Pentium® and Celeron® Processor N- and J- Series, Datasheet Volume 2 */
/* PCI config space */
pci_vdev_write_vcfg(vdev, PCIR_VENDOR, 2U, 0x8086U);
pci_vdev_write_vcfg(vdev, PCIR_DEVICE, 2U, 0x5af0U);
pci_vdev_write_vcfg(vdev, PCIR_REVID, 1U, 0xbU);
pci_vdev_write_vcfg(vdev, PCIR_HDRTYPE, 1U, (PCIM_HDRTYPE_NORMAL | PCIM_MFDEV));
pci_vdev_write_vcfg(vdev, PCIR_CLASS, 1U, PCIC_BRIDGE);
pci_vdev_write_vcfg(vdev, PCIR_SUBCLASS, 1U, PCIS_BRIDGE_HOST);
pci_vdev_write_vcfg(vdev, 0x34U, 1U, 0xe0U);
pci_vdev_write_vcfg(vdev, 0x3cU, 1U, 0xe0U);
pci_vdev_write_vcfg(vdev, PCIR_CLASS, 1U, PCIC_BRIDGE);
pci_vdev_write_vcfg(vdev, PCIR_HDRTYPE, 1U, (PCIM_HDRTYPE_NORMAL | PCIM_MFDEV));
/* First Capability Register is CAPID0_CAPCTRL0 */
pci_vdev_write_vcfg(vdev, PCIR_CAP_PTR, 1U, 0xe0U);
pci_vdev_write_vcfg(vdev, PCIR_INTERRUPT_LINE, 1U, 0xe0U);
/* Memory Controller Hub Base Address Register, MCHBAR_LO */
/* MCHBAR[38:15] is {MCHBAR_HI[6:0],MCHBAR_LO[31:15]} */
pci_vdev_write_vcfg(vdev, 0x48U, 4U, 0xfed10001U);
/* Graphics and Memory Controller Hub Graphics Control Register, GGC */
/* [15:8] is Graphics Memory Select (GMS), 512MB */
pci_vdev_write_vcfg(vdev, 0x50U, 4U, 0x000002c1U);
/* Device Enable Register, DEVEN */
pci_vdev_write_vcfg(vdev, 0x54U, 4U, 0x00000033U);
/* Protected Audio Video Path Control, PAVPC */
pci_vdev_write_vcfg(vdev, 0x58U, 4U, 0x7ff00007U);
/* Top of Upper Usable DRAM Low, TOUUD_LO */
pci_vdev_write_vcfg(vdev, 0xa8U, 4U, 0x80000000U);
/* Top of Upper Usable DRAM High, TOUUD_HI */
pci_vdev_write_vcfg(vdev, 0xacU, 4U, 0x00000002U);
/* Base of Data Stolen Memory, BDSM */
pci_vdev_write_vcfg(vdev, 0xb0U, 4U, 0x7c000001U);
/* Base of Graphics Stolen Memory, BGSM */
pci_vdev_write_vcfg(vdev, 0xb4U, 4U, 0x7b800001U);
/* Top Segment Memory Base, TSEGMB */
pci_vdev_write_vcfg(vdev, 0xb8U, 4U, 0x7b000001U);
/* Top of Lower Usable DRAM, TOLUD */
pci_vdev_write_vcfg(vdev, 0xbcU, 4U, 0x80000001U);
/* Capability ID0 Capability Control, CAPID0_CAPCTRL0 */
/* CAP_ID: 9h, NEXT_CAP: 0h, CAPIDLEN: Ch, CAPID_VER: 1h */
pci_vdev_write_vcfg(vdev, 0xe0U, 4U, 0x010c0009U);
pci_vdev_write_vcfg(vdev, 0xf4U, 4U, 0x011c0f00U);
@ -117,34 +173,69 @@ static void init_vhostbridge(struct pci_vdev *vdev)
*/
pciexbar_low = USER_VM_VIRT_PCI_MMCFG_BASE | 0x1U;
} else {
/*Inject physical ECAM value to Service VM vhostbridge since Service VM may check PCIe-MMIO Base Address with it */
/* Inject physical ECAM value to Service VM vhostbridge since Service VM may check PCIe-MMIO Base
Address with it */
phys_did = pci_pdev_read_cfg(hostbridge_bdf, PCIR_DEVICE, 2);
for (i = 0U; i < (sizeof(hostbridge_did_highbytes) / sizeof(uint32_t)); i++) {
if (((phys_did & 0xff00U) >> 8) == hostbridge_did_highbytes[i]) {
/* The offset of PCIEXBAR register is 0x60 on Intel platforms, and no counter-case is encountered yet */
/* The offset of PCIEXBAR register is 0x60 on Intel platforms, and no counter-case is
encountered yet */
pciexbar_low = pci_pdev_read_cfg(hostbridge_bdf, 0x60U, 4);
pciexbar_high = pci_pdev_read_cfg(hostbridge_bdf, 0x64U, 4);
break;
}
}
}
/* PCI Express Enhanced Configuration Range Base Address Low, PCIEXBAR_LO */
pci_vdev_write_vcfg(vdev, 0x60U, 4, pciexbar_low);
/* PCI Express Enhanced Configuration Range Base Address High, PCIEXBAR_HI */
pci_vdev_write_vcfg(vdev, 0x64U, 4, pciexbar_high);
vdev->parent_user = NULL;
vdev->user = vdev;
}
static void deinit_vhostbridge(__unused struct pci_vdev *vdev)
/**
* @brief Deinitialize the virtual host bridge.
*
* This function deinitializes the specified virtual PCI device that was previously initialized as a host bridge.
*
* For the specified vdev, it sets the fields parent_user and user to NULL, indicating that this virtual device is not
* owned by any VM.
*
* @param[inout] vdev Pointer to the virtual PCI device.
*
* @return None
*
* @pre vdev != NULL
*
* @post N/A
*/
static void deinit_vhostbridge(struct pci_vdev *vdev)
{
vdev->parent_user = NULL;
vdev->user = NULL;
}
/**
* @brief Read the configuration space of the virtual host bridge.
*
* This function reads the configuration space of the specified virtual PCI device that is configured as a host bridge.
* It is used to retrieve specific configuration data of the virtual host bridge for further processing or validation.
*
* It reads the configuration space of the virtual host bridge and stores the read configuration data in the provided
* buffer.
*
* @param[in] vdev Pointer to the virtual PCI device whose configuration space is to be read.
* @param[in] offset Offset within the configuration space to read from.
* @param[in] bytes Number of bytes to read from the configuration space.
* @param[inout] val Pointer to the buffer where the read configuration data will be stored.
*
* @return Always return 0.
*
* @pre vdev != NULL
* @pre vdev->vpci != NULL
* @pre val != NULL
*
* @post retval == 0
*/
static int32_t read_vhostbridge_cfg(struct pci_vdev *vdev, uint32_t offset,
uint32_t bytes, uint32_t *val)
@ -153,10 +244,25 @@ static int32_t read_vhostbridge_cfg(struct pci_vdev *vdev, uint32_t offset,
return 0;
}
/**
* @brief Write to the virtual host bridge configuration space.
*
* This function writes to the configuration space of the specified virtual PCI device that is configured as a host
* bridge. It is used to update specific configuration settings based on the provided parameters.
*
* For the non-BAR configuration space, it writes the provided value to the configuration space of the virtual host
* bridge. For the BAR configuration space, it is read-only and the write operation is ignored.
*
* @param[inout] vdev Pointer to the virtual PCI device whose configuration space is to be written.
* @param[in] offset Offset within the configuration space to start writing to.
* @param[in] bytes Number of bytes to write to the configuration space.
* @param[in] val Value to be written to the configuration space.
*
* @return Always return 0.
*
* @pre vdev != NULL
* @pre vdev->vpci != NULL
*
* @post retval == 0
*/
static int32_t write_vhostbridge_cfg(struct pci_vdev *vdev, uint32_t offset,
uint32_t bytes, uint32_t val)
@ -167,9 +273,27 @@ static int32_t write_vhostbridge_cfg(struct pci_vdev *vdev, uint32_t offset,
return 0;
}
/**
* @brief Data structure implementation for virtual host bridge operations.
*
* Struct pci_vdev_ops is used to define the operations of virtual PCI device and definition here is used to support
* virtual host bridge.
*
* A pre-launched VM may have some pci devices and a host bridge is needed to support these devices. This struct is used
* to define the operations of virtual host bridge in this case for now.
*
* @consistency N/A
* @alignment N/A
*
* @remark N/A
*/
const struct pci_vdev_ops vhostbridge_ops = {
.init_vdev = init_vhostbridge,
.deinit_vdev = deinit_vhostbridge,
.write_vdev_cfg = write_vhostbridge_cfg,
.read_vdev_cfg = read_vhostbridge_cfg,
};
/**
* @}
*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2011 NetApp, Inc.
* Copyright (c) 2019-2022 Intel Corporation.
* Copyright (c) 2019-2024 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -50,6 +50,41 @@
#include <pci.h>
#include "vpci_priv.h"
/**
* @addtogroup vp-dm_vperipheral
*
* @{
*/
/**
* @file
* @brief Implementation of virtual PCI bridge.
*
* This file defines operations to support virtual PCI bridge. It implements struct pci_vdev_ops and related functions.
*/
/**
* @brief Initializes the vPCI bridge.
*
* A PCI bridge is also a PCI device. This function initializes the specified virtual PCI device as a PCI bridge. A vPCI
* bridge is based on a physical PCI bridge and is used for Service VM. It's usually used in the initialization phase of
* Service VM, when the pre-launched VM exists.
*
* It initializes most of the virtual PCI configuration space registers based on the physical PCI bridge registers,
* except those that specify the type information, which is emulated. Such type related registers include Vendor ID,
* Device ID, Revision ID, Header Type, class and sub-class code. Finally, it sets the field parent_user to NULL and
* the field user to vdev, indicating that this vPCI bridge is used by a VM.
* Note that the physical PCI bridge registers are already initialized and configured during the initialization of the
* physical PCI hierarchy.
*
* @param[inout] vdev Pointer to the virtual PCI device to be initialized.
*
* @return None
*
* @pre vdev != NULL
*
* @post N/A
*/
static void init_vpci_bridge(struct pci_vdev *vdev)
{
uint32_t offset, val;
@ -74,12 +109,51 @@ static void init_vpci_bridge(struct pci_vdev *vdev)
vdev->user = vdev;
}
static void deinit_vpci_bridge(__unused struct pci_vdev *vdev)
/**
* @brief Deinitializes the vPCI bridge.
*
* This function deinitializes the specified virtual PCI device that was previously initialized as a PCI bridge.
*
* For the specified vdev, it sets the fields parent_user and user to NULL, indicating that this virtual device is not
* owned by any VM.
*
* @param[inout] vdev Pointer to the virtual PCI device to be deinitialized.
*
* @return None
*
* @pre vdev != NULL
*
* @post N/A
*/
static void deinit_vpci_bridge(struct pci_vdev *vdev)
{
vdev->parent_user = NULL;
vdev->user = NULL;
}
/**
* @brief Reads the configuration of the vPCI bridge.
*
* This function reads the configuration space of the specified virtual PCI device that is configured as a PCI bridge.
* It is used to retrieve the configuration data of the vPCI bridge for further processing or validation.
*
* - For PCI configuration space (offset <= 0x100U), it reads the configuration space of the vPCI bridge.
* - For PCI Express Extended configuration space (offset > 0x100U), it simply passthrough by reading directly from the
* physical device.
* - The read configuration data is stored in the buffer pointed to by val.
*
* @param[in] vdev Pointer to the virtual PCI device whose configuration is to be read.
* @param[in] offset Offset within the configuration space to start reading from.
* @param[in] bytes Number of bytes to read from the configuration space.
* @param[inout] val Pointer to the buffer where the read configuration data will be stored.
*
* @return Always return 0.
*
* @pre vdev != NULL
* @pre val != NULL
*
* @post retval == 0
*/
static int32_t read_vpci_bridge_cfg(struct pci_vdev *vdev, uint32_t offset,
uint32_t bytes, uint32_t *val)
{
@ -93,15 +167,54 @@ static int32_t read_vpci_bridge_cfg(struct pci_vdev *vdev, uint32_t offset,
return 0;
}
/**
* @brief Writes the configuration of the vPCI bridge.
*
* This function writes to the configuration space of the specified virtual PCI device that is configured as a PCI
* bridge. It is used to update the configuration data of the vPCI bridge. However, the configuration space of the vPCI
* bridge is read-only, so this function does not perform any operation.
*
* It just returns 0 without any operation.
*
* @param[in] vdev Pointer to the virtual PCI device whose configuration is to be written (unused in this function).
* @param[in] offset Offset within the configuration space to start writing to (unused in this function).
* @param[in] bytes Number of bytes to write to the configuration space (unused in this function).
* @param[in] val Value to be written to the configuration space (unused in this function).
*
* @return Always return 0.
*
* @pre vdev != NULL
*
* @post retval == 0
*/
static int32_t write_vpci_bridge_cfg(__unused struct pci_vdev *vdev, __unused uint32_t offset,
__unused uint32_t bytes, __unused uint32_t val)
{
return 0;
}
/**
* @brief Data structure implementation for virtual PCI bridge operations.
*
* Struct pci_vdev_ops is used to define the operations of virtual PCI device and definition here is used to support PCI
* bridge.
*
* All PCI devices (including PCI bridge) on platform are passed to Service VM by default. But PCI bridges should be
* emulated by hypervisor if pre-launched VM exists. This struct is used to define the operations of virtual PCI bridge
* in this case.
*
* @consistency N/A
* @alignment N/A
*
* @remark N/A
*/
const struct pci_vdev_ops vpci_bridge_ops = {
.init_vdev = init_vpci_bridge,
.deinit_vdev = deinit_vpci_bridge,
.write_vdev_cfg = write_vpci_bridge_cfg,
.read_vdev_cfg = read_vpci_bridge_cfg,
};
/**
* @}
*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2014, Neel Natu (neel@freebsd.org)
* Copyright (c) 2022 Intel Corporation.
* Copyright (c) 2024 Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,6 +34,20 @@
#include "mc146818rtc.h"
/**
* @addtogroup vp-dm_vperipheral
*
* @{
*/
/**
* @file
* @brief Implementation of virtual RTC device.
*
* This file provides the implementation of the virtual RTC device. The virtual RTC device is used to provide the RTC
* service to the guest VMs. It is a part of the virtual peripheral devices.
*/
/* #define DEBUG_RTC */
#ifdef DEBUG_RTC
# define RTC_DEBUG pr_info
@ -489,8 +503,34 @@ static void vrtc_set_reg_b(struct acrn_vrtc *vrtc, uint8_t newval)
}
/**
* @brief Read from the virtual RTC device.
*
* This function reads the value from the RTC register specified by the address port. To read from the virtual RTC
* device, the guest writes the register index to the RTC address port and then reads the register value from the RTC
* data port. This function is used to simulate the behavior of reading in a virtualized environment.
*
* - If the accessed port is CMOS_ADDR_PORT, it will set the value as index cached in last write (0 by default) and
* return.
* - If the accessed port is CMOS_DATA_PORT,
* - For Service VM, it will directly read the value from the physical CMOS register.
* - For a non-Service VM, it will return false indicating the read operation failed if the address is greater than
* RTC_CENTURY. Otherwise, the read operation will be emulated.
*
* @param[inout] vcpu Pointer to the virtual CPU that is reading from the virtual RTC. The value read from the virtual
* RTC will be stored in the PIO request.
* @param[in] addr The address port to read from.
* @param[in] width The width of the data to be read. This is not used in this function.
*
* @return A boolean value indicating whether the read operation is successful.
*
* @retval true Successfully read from the virtual RTC device.
* @retval false Failed to read from the virtual RTC device.
*
* @pre vcpu != NULL
* @pre vcpu->vm != NULL
* @pre addr == 0x70U || addr == 0x71U
*
* @post N/A
*/
static bool vrtc_read(struct acrn_vcpu *vcpu, uint16_t addr, __unused size_t width)
{
@ -536,8 +576,39 @@ static inline bool vrtc_is_time_register(uint32_t offset)
}
/**
* @brief Write a value to the virtual RTC.
*
* This function writes a specified value to the virtual RTC at a given offset. To write to the virtual RTC, the guest
* writes the register index to the RTC address port and then writes the register value to the RTC data port. This
* function is used to simulate the behavior of writing in a virtualized environment.
*
* - If the accessed port is CMOS_ADDR_PORT and the width is 1 byte, it will store the value as the index and return.
* - If the accessed port is CMOS_DATA_PORT,
* - For Service VM, it will directly write the value to the physical CMOS register. If the physical date/time is
* changed, for RT VMs and pre-launched VMs, the RTC/TSC snapshots will be updated. Those snapshots are used to
* emulate the virtual date/time for non-Service VM.
* - For a non-Service VM, it will ignore the write to the RTC_STATUSA, RTC_INTR and RTC_STATUSD. Otherwise, it will
* update the virtual register value and RTC time. And for Post-launched VM, it will send a VM event to notify the
* VM of the change in the RTC time if the address port is in the range of the time registers.
*
* @param[inout] vcpu Pointer to the virtual CPU that is writing to the virtual RTC.
* @param[in] addr The address port to write to.
* @param[in] width Width of the value to be written to the virtual RTC.
* @param[in] value Value to be written to the virtual RTC.
*
* @return A boolean value indicating whether the write operation is handled successfully, which is always true in
* current design. It either updates the physical registers, updates the virtual registers, or ignores the
* write.
*
* @retval true The write operation is handled successfully.
*
* @pre vcpu != NULL
* @pre vcpu->vm != NULL
* @pre addr == 0x70U || addr == 0x71U
*
* @post N/A
*
* @remark N/A
*/
static bool vrtc_write(struct acrn_vcpu *vcpu, uint16_t addr, size_t width,
uint32_t value)
@ -707,6 +778,29 @@ void resume_vrtc(void)
calibrate_setup_timer();
}
/**
* @brief Initialize the virtual RTC.
*
* This function initializes the virtual RTC (Real-Time Clock) device for the given virtual machine. It sets up the
* necessary data structures and state required for the RTC to function correctly. This function should be called during
* the initialization phase of the virtual machine.
*
* - When Service VM's vRTC device is initialized, a periodic timer (every 3 hours) is set up to calibrate the virtual
* date/time of other VMs. When the calibration timer is triggered, for RT VMs and pre-launched VMs, the TSC/RTC
* snapshots are updated to reflect the physical TSC/RTC-time at that moment.
* - When non-Service VM's vRTC device is initialized, the TSC/RTC snapshots are initialized to reflect the physical
* TSC/RTC-time at the moment.
*
* @param[inout] vm The virtual machine that contains the virtual RTC to be initialized.
*
* @return None
*
* @pre vm != NULL
*
* @post N/A
*
* @remark N/A
*/
void vrtc_init(struct acrn_vm *vm)
{
struct vm_io_range range = {
@ -725,3 +819,7 @@ void vrtc_init(struct acrn_vm *vm)
vm->vrtc.base_tsc = cpu_ticks();
}
}
/**
* @}
*/

View File

@ -1,7 +1,7 @@
/*-
* Copyright (c) 2012 NetApp, Inc.
* Copyright (c) 2013 Neel Natu <neel@freebsd.org>
* Copyright (c) 2018-2022 Intel Corporation.
* Copyright (c) 2018-2024 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -36,6 +36,20 @@
#include <asm/guest/vm.h>
#include <logmsg.h>
/**
* @addtogroup vp-dm_vperipheral
*
* @{
*/
/**
* @file
* @brief Implementation of virtual UART device.
*
* This file implements all the APIs to support virtual UART device. It also defines some helper functions to simulate
* the device that are commonly used in this file.
*/
#define init_vuart_lock(vu) spinlock_init(&((vu)->lock))
#define obtain_vuart_lock(vu, flags) spinlock_irqsave_obtain(&((vu)->lock), &(flags))
#define release_vuart_lock(vu, flags) spinlock_irqrestore_release(&((vu)->lock), (flags))
@ -376,8 +390,31 @@ static void write_reg(struct acrn_vuart *vu, uint16_t reg, uint8_t value_u8)
release_vuart_lock(vu, rflags);
}
/*
* @pre: vu != NULL
/**
* @brief Write a value to a register in the virtual UART.
*
* This function writes a 8-bit value to a specified register in the virtual UART (vUART). It is a basic function used
* for port I/O write or MMIO write.
*
* - When the following conditions are met, data is sent to the target vUART's RXFIFO:
* 1) The target vUART exists for the specified vUART, which is used for communication.
* 2) The accessed register is the THR (Transmitter Holding Register).
* 3) Loopback mode is not enabled.
* 4) DLAB (Divisor Latch Access Bit) is not set.
* - Additionally, to ensure reliable communication, it raises the THRE interrupt (indicating that more data can be
* processed) only if the target vUART's RXFIFO is not full.
* - If these conditions are not met, the virtual registers specified by the offset are updated according to the 16550
* UART specification.
*
* @param[inout] vu The virtual UART structure to which the register value is to be written.
* @param[in] offset The offset of the register within the vUART.
* @param[in] value_u8 The 8-bit value to be written to the register.
*
* @return None
*
* @pre vu != NULL
*
* @post N/A
*/
void vuart_write_reg(struct acrn_vuart *vu, uint16_t offset, uint8_t value_u8)
{
@ -401,8 +438,28 @@ void vuart_write_reg(struct acrn_vuart *vu, uint16_t offset, uint8_t value_u8)
}
/**
* @brief Write a value to a port in the legacy virtual UART.
*
* This function writes a value to the legacy virtual UART (vUART) based on the specified port address. It is used to
* handle I/O port write operations in the VM by updating the vUART's register. This function is typically called when
* the vCPU needs to write data to the vUART during emulation of I/O port operations.
*
* - Based on the specified port address, it first finds the vUART device within the VM corresponding to the given vCPU.
* - If the vUART is found, the value is written to the corresponding register. For detailed write operations, refer to
* vuart_write_reg().
* - If the vUART is not found, the write operation is ignored.
*
* @param[inout] vcpu A pointer to the vCPU that initiates the write operation.
* @param[in] offset_arg The port address to write to.
* @param[in] width The width of the write operation (unused in this function).
* @param[in] value The value to be written to the register.
*
* @return Always returns true.
*
* @pre vcpu != NULL
* @pre vcpu->vm != NULL
*
* @post N/A
*/
static bool vuart_write(struct acrn_vcpu *vcpu, uint16_t offset_arg,
__unused size_t width, uint32_t value)
@ -435,7 +492,28 @@ static void notify_target(const struct acrn_vuart *vu)
}
/**
* @brief Read a register from the virtual UART.
*
* This function returns the 8-bit value of a specified register. It is a basic function used for port I/O read or MMIO
* read. The registers in the UART will affect each other, such as reading the LSR register will clear some bits in it.
* This function carefully simulates this behavior.
*
* - If the DLAB bit in LCR is set, only the DLL and DLH registers are accessed. Other registers are considered as 0.
* - Otherwise, according to the UART16550 specification, set and read the corresponding register. For registers greater
* than 0x07 (SCR), the value will be 0xFF.
* - It will toggle the interrupt.
* - For communication vUART, when the data in FIFO is read out (read from RBR), it will notify the target vUART to send
* more data.
* - Finally, it will return the value of the specified register.
*
* @param[inout] vu Pointer to the virtual UART device.
* @param[in] offset The specified offset of the register to read.
*
* @return The value of the specified register.
*
* @pre vu != NULL
*
* @post N/A
*/
uint8_t vuart_read_reg(struct acrn_vuart *vu, uint16_t offset)
{
@ -529,8 +607,27 @@ uint8_t vuart_read_reg(struct acrn_vuart *vu, uint16_t offset)
}
/**
* @brief Read a value from a port in the legacy virtual UART.
*
* This function reads a value from the legacy virtual UART (vUART) based on the specified port address. It is used to
* handle I/O port read operations in the VM by retrieving the value from the vUART's registers. This function is
* typically called when the vCPU needs to read data from the vUART during emulation of I/O port operations.
*
* - Based on the specified port address, it first finds the vUART device within the VM corresponding to the given vCPU.
* - If the vUART is found, the value is read from the corresponding virtual register and stored in the vCPU's PIO
* request. For detailed read operations, refer to vuart_read_reg().
* - If the vUART is not found, the vCPU's PIO request remains unchanged.
*
* @param[inout] vcpu A pointer to the vCPU that initiates the read operation.
* @param[in] offset_arg The port address to read from.
* @param[in] width The width of the read operation (unused in this function).
*
* @return Always returns true.
*
* @pre vcpu != NULL
* @pre vcpu->vm != NULL
*
* @post N/A
*/
static bool vuart_read(struct acrn_vcpu *vcpu, uint16_t offset_arg, __unused size_t width)
{
@ -628,6 +725,27 @@ static void vuart_deinit_connection(struct acrn_vuart *vu)
vu->target_vu = NULL;
}
/**
* @brief Check if any of the vUARTs in the given VM uses the specified INTx interrupt.
*
* This function checks whether the INTx interrupt is already used by vUART. It's usually used when the hypervisor
* tries to add a new INTx remapping.
*
* It will check all the vUARTs in the VM to see if any of them uses the specified INTx interrupt. If any of the vUARTs
* is active and using the specified INTx interrupt, the function will return true. Otherwise, it will return false.
*
* @param[in] vm Pointer to the VM.
* @param[in] intx_gsi The INTx interrupt number to check against the vUART configurations.
*
* @return A boolean value indicating if any of the vUARTs in the VM uses the specified INTx interrupt.
*
* @retval true If any of the vUARTs in the VM uses the specified INTx interrupt.
* @retval false If none of the vUARTs in the VM uses the specified INTx interrupt.
*
* @pre vm != NULL
*
* @post N/A
*/
bool is_vuart_intx(const struct acrn_vm *vm, uint32_t intx_gsi)
{
uint8_t i;
@ -641,6 +759,28 @@ bool is_vuart_intx(const struct acrn_vm *vm, uint32_t intx_gsi)
return ret;
}
/**
* @brief Initialize legacy virtual UART devices.
*
* This function initializes the legacy virtual UARTs (vUARTs) in hypervisor. A vUART is emulated as a 16550 UART device
* and can exchange data between the hypervisor and a VM or between two VMs. It sets up the necessary configurations and
* resources required for the vUARTs to function correctly. This function is usually called during VM creation.
*
* A VM can have several vUARTs (including legacy and PCI vUARTs). The first vUART is used for the VM console, and the
* rest are used for communication between VMs. Every legacy vUART device defined in the vUART configuration list is
* initialized and configured. It will also register port I/O handlers for every vUART device and set up the connection
* between vUARTs for communication.
*
* @param[inout] vm Pointer to the VM that owns the vUART devices.
* @param[in] vu_config Pointer to the vUART configuration structure list that contains the configuration information.
*
* @return None
*
* @pre vm != NULL
* @pre vu_config != NULL
*
* @post N/A
*/
void init_legacy_vuarts(struct acrn_vm *vm, const struct vuart_config *vu_config)
{
uint8_t i;
@ -668,6 +808,24 @@ void init_legacy_vuarts(struct acrn_vm *vm, const struct vuart_config *vu_config
}
}
/**
* @brief Deinitialize legacy virtual UART devices.
*
* This function deinitializes the legacy virtual UARTs (vUARTs) in hypervisor. It cleans up the resources and
* configurations that were set up for the vUARTs during initialization. This function should be called when the vUARTs
* are no longer needed, such as when a VM is being destroyed.
*
* The function will deinitialize all vUARTs associated with the given VM. It will set the active flag to false and
* remove the connection between vUARTs for communication.
*
* @param[inout] vm Pointer to the VM that owns the vUART devices.
*
* @return None
*
* @pre vm != NULL
*
* @post N/A
*/
void deinit_legacy_vuarts(struct acrn_vm *vm)
{
uint8_t i;
@ -683,6 +841,26 @@ void deinit_legacy_vuarts(struct acrn_vm *vm)
}
}
/**
* @brief Initialize a PCI virtual UART device.
*
* This function initializes a PCI-based virtual UART (vUART) in hypervisor. A MCS9900 controller is emulated as a PCI
* device, and the vUART device is a part of the MCS9900 controller. This function is usually called during the VM
* creation and after the MCS9900 controller device is initialized.
*
* A VM can have several vUARTs (including legacy and PCI vUARTs). The first vUART is used for the VM console, and the
* rest are used for communication between VMs. The PCI vUARTs are only used for communication between VMs for now. It
* will initialize the vUART associated with the given PCI device and set up the connection between vUARTs for
* communication.
*
* @param[inout] vdev Pointer to the PCI device that owns the vUART.
*
* @return None
*
* @pre vdev != NULL
*
* @post N/A
*/
void init_pci_vuart(struct pci_vdev *vdev)
{
struct acrn_vuart *vu = vdev->priv_data;
@ -705,6 +883,24 @@ void init_pci_vuart(struct pci_vdev *vdev)
}
/**
* @brief Deinitialize a PCI virtual UART device.
*
* This function deinitializes a PCI virtual UART (vUART) in hypervisor. It cleans up the resources and configurations
* that were set up for the vUART during initialization. This function should be called when the vUART is no longer
* needed, such as when a VM is being destroyed.
*
* The function will deinitialize the vUART associated with the given PCI device. It will set the active flag to false
* and remove the connection between vUARTs for communication.
*
* @param[inout] vdev Pointer to the PCI device that owns the vUART.
*
* @return None
*
* @pre vdev != NULL
*
* @post N/A
*/
void deinit_pci_vuart(struct pci_vdev *vdev)
{
struct acrn_vuart *vu = vdev->priv_data;
@ -715,3 +911,7 @@ void deinit_pci_vuart(struct pci_vdev *vdev)
vuart_deinit_connection(vu);
}
}
/**
* @}
*/

View File

@ -111,7 +111,7 @@
/* CPUID.07H:ECX.PKE */
#define CPUID_ECX_PKE (1U<<3U)
/* CPUID.07H:ECX.WAITPKG */
#define CPUID_ECX_WAITPKG (1U<<5U)
#define CPUID_ECX_WAITPKG (1U<<5U)
/* CPUID.07H:ECX.CET_SS */
#define CPUID_ECX_CET_SS (1U<<7U)
/* CPUID.07H:ECX.LA57 */

View File

@ -64,4 +64,5 @@ int32_t hyperv_rdmsr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *rval);
void hyperv_init_time(struct acrn_vm *vm);
void hyperv_init_vcpuid_entry(uint32_t leaf, uint32_t subleaf, uint32_t flags,
struct vcpuid_entry *entry);
void hyperv_page_destory(struct acrn_vm *vm);
#endif

View File

@ -181,6 +181,7 @@ struct acrn_vm {
struct acrn_vrtc vrtc;
uint64_t intr_inject_delay_delta; /* delay of intr injection */
uint32_t reset_control;
} __aligned(PAGE_SIZE);
/*

View File

@ -12,6 +12,9 @@
#define BIT_SLP_EN 13U
#define BIT_WAK_STS 15U
#define CF9_RESET_WARM 0x6
#define CF9_RESET_COLD 0xE
struct cpu_state_info {
uint8_t px_cnt; /* count of all Px states */
const struct acrn_pstate_data *px_data;
@ -38,7 +41,7 @@ extern void asm_enter_s3(const struct pm_s_state_data *sstate_data, uint32_t pm1
extern void restore_s3_context(void);
struct cpu_state_info *get_cpu_pm_state_info(void);
struct acpi_reset_reg *get_host_reset_reg_data(void);
void reset_host(void);
void reset_host(bool warm);
void init_frequency_policy(void);
void apply_frequency_policy(void);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2022 Intel Corporation.
* Copyright (C) 2018-2024 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -10,6 +10,28 @@
#include <asm/lib/spinlock.h>
#include <board_info.h>
/**
* @defgroup hwmgmt_page hwmgmt.page
* @ingroup hwmgmt
* @brief Support the basic paging mechanism.
*
* This module mainly provides the interfaces to manipulate the paging structures.
* These operations are commonly used by:
* 1. hypervisor's MMU (Memory Management Unit) to manage the host page tables;
* 2. EPT to manage the extended page tables for guest.
* It also provides the interfaces to conduct the address translation between Host Physical Address and Host Virtual
* Address.
*
* @{
*/
/**
* @file
* @brief All APIs to support page management.
*
* This file defines macros, structures and function declarations for managing memory pages.
*/
#define PAGE_SHIFT 12U
#define PAGE_SIZE (1U << PAGE_SHIFT)
#define PAGE_MASK 0xFFFFFFFFFFFFF000UL
@ -22,26 +44,96 @@
/* size of the high MMIO address space: 1GB */
#define PLATFORM_HI_MMIO_SIZE 0x40000000UL
/**
* @brief Calculate the number of page map level-4(PML4) that is requested to control the memory region with the
* specified size.
*
* Page map level-4(PML4) table is the top-level table in the x86-64 paging hierarchy. Each entry in the PML4 table can
* potentially map a 512 GiB region, with the entire PML4 table capable of addressing up to 256 TiB. So 1 PML4 table is
* enough to control the entire physical address space.
*/
#define PML4_PAGE_NUM(size) 1UL
/**
* @brief Calculate the number of page directory pointer tables(PDPT) that is requested to control the memory region
* with the specified size.
*
* A page directory pointer table(PDPT) can be referenced by a PML4E and each PML4E controls access to a 512-GByte
* region. It is supposed to be called when hypervisor allocates the page-directory-pointer tables for hypervisor and
* all VMs.
*/
#define PDPT_PAGE_NUM(size) (((size) + PML4E_SIZE - 1UL) >> PML4E_SHIFT)
/**
* @brief Calculate the number of page directories(PD) that is requested to control the memory region with the specified
* size.
*
* A page directory(PD) can be referenced by a PDPTE and each PDPTE controls access to a 1-GByte region. It is supposed
* to be called when hypervisor allocates the page directories for hypervisor and all VMs.
*/
#define PD_PAGE_NUM(size) (((size) + PDPTE_SIZE - 1UL) >> PDPTE_SHIFT)
/**
* @brief Calculate the number of page tables(PT) that is requested to control the memory region with the specified
* size.
*
* A page table(PT) can be referenced by a PDE and each PDE controls access to a 2-MByte region. It is supposed to be
* called when hypervisor allocates the page tables for hypervisor and all VMs.
*/
#define PT_PAGE_NUM(size) (((size) + PDE_SIZE - 1UL) >> PDE_SHIFT)
/**
* @brief Data structure to illustrate a 4-KByte memory region with an alignment of 4-KByte.
*
* This data structure is used to illustrate a 4-KByte memory region with an alignment of 4-KByte, calling it a 4-KByte
* page. It can be used to support the memory management in hypervisor and the extended page-table mechanism for VMs. It
* can also be used when hypervisor accesses the 4-KByte aligned memory region whose size is a multiple of 4-KByte.
*
* @consistency N/A
* @alignment 4096
*
* @remark N/A
*/
struct page {
uint8_t contents[PAGE_SIZE];
uint8_t contents[PAGE_SIZE]; /**< A 4-KByte page in the memory. */
} __aligned(PAGE_SIZE);
/**
* @brief Data structure that contains a pool of memory pages.
*
* This structure is designed to manage a collection of memory pages, facilitating efficient allocation,
* deallocation, and reuse of pages. It is typically used in scenarios where memory allocation performance
* is critical, such as in operating systems or high-performance applications. The page pool aims to minimize
* the overhead associated with frequent memory page allocations by maintaining a ready-to-use pool of pages.
* It is used to support the memory management in hypervisor and the extended page-table mechanism for VMs.
*
* @consistency N/A
* @alignment N/A
*
* @remark N/A
*/
struct page_pool {
struct page *start_page;
spinlock_t lock;
uint64_t bitmap_size;
uint64_t *bitmap;
uint64_t last_hint_id;
struct page *dummy_page;
struct page *start_page; /**< The first page in the pool. */
spinlock_t lock; /**< The spinlock to protect simultaneous access of the page pool. */
/**
* @brief A pointer to the bitmap that represents the allocation status of each page in the pool.
*
* The bitmap is a data structure that represents the allocation status of each page in the pool. Each bit in
* the bitmap corresponds to a page in the pool. If the bit is set to 1, the page is allocated; otherwise, the
* page is free. The bitmap is used to track the allocation status of each page in the pool.
*/
uint64_t *bitmap;
uint64_t bitmap_size; /**< The number of bitmap. */
uint64_t last_hint_id; /**< The last bitmap ID that is used to allocate a page. */
/**
* @brief A pointer to the dummy page
*
* This is used when there's no page available in the pool.
*/
struct page *dummy_page;
};
struct page *alloc_page(struct page_pool *pool);
void free_page(struct page_pool *pool, struct page *page);
#endif /* PAGE_H */
/**
* @}
*/

View File

@ -1,18 +1,27 @@
/*
* Copyright (C) 2018-2022 Intel Corporation.
* Copyright (C) 2018-2024 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file pgtable.h
*
* @brief Address translation and page table operations
*/
#ifndef PGTABLE_H
#define PGTABLE_H
#include <asm/page.h>
/**
* @addtogroup hwmgmt_page
*
* @{
*/
/**
* @file
* @brief All APIs to support page table management
*
* This file defines macros, structures, declarations and functions related for managing page tables.
*
*/
#define PAGE_PRESENT (1UL << 0U)
#define PAGE_RW (1UL << 1U)
#define PAGE_USER (1UL << 2U)
@ -148,65 +157,129 @@
/**
* @brief Page tables level in IA32 paging mode
*
* 4-level paging in IA32 mode may map linear addresses to 4-KByte pages, 2-MByte pages, or 1-GByte pages. The 4 levels
* are PML4, PDPT, PD, and PT. The value to present each level is fixed.
*/
enum _page_table_level {
/**
* @brief The PML4 level in the page tables
*/
IA32E_PML4 = 0,
/**
* @brief The Page-Directory-Pointer-Table level in the page tables
*/
IA32E_PDPT = 1,
/**
* @brief The Page-Directory level in the page tables
*/
IA32E_PD = 2,
/**
* @brief The Page-Table level in the page tables
*/
IA32E_PT = 3,
IA32E_PML4 = 0, /**< The Page-Map-Level-4(PML4) level in the page tables.
* The value is fixed to 0. */
IA32E_PDPT = 1, /**< The Page-Directory-Pointer-Table(PDPT) level in the page tables. */
IA32E_PD = 2, /**< The Page-Directory(PD) level in the page tables. */
IA32E_PT = 3, /**< The Page-Table(PT) level in the page tables. */
};
/**
* @brief Data structure that contains the related operations and properties of page table.
*
* This structure is used to add/modify/delete page table.
*
* @consistency N/A
* @alignment N/A
*
* @remark N/A
*/
struct pgtable {
/**
* @brief Default memory access rights.
*
* A linear address can be translated to a physical address by the page tables. The translation is controlled by
* the memory access rights, as defined by the architecture's memory system design. The default memory access
* rights can be used to set the memory access rights for a page table entry when the page table is created.
*/
uint64_t default_access_right;
/**
* @brief Mask to check if the page referenced by entry is present.
*
* The presence of a page is indicated by specific bits in the entry, as defined by the architecture's memory
* system design. For example, in ept table entry it's indicated by bit0|bit1|bit2, and in mmu table entry it's
* indicated by bit 0.
*/
uint64_t pgentry_present_mask;
struct page_pool *pool;
struct page_pool *pool; /**< Pointer to the page pool used for managing pages. */
/**
* @brief Function to check if large pages are supported.
*
* This function is used to check if large pages are supported for a specific page table level and memory access
* rights.
*/
bool (*large_page_support)(enum _page_table_level level, uint64_t prot);
void (*clflush_pagewalk)(const void *p);
void (*tweak_exe_right)(uint64_t *entry);
void (*recover_exe_right)(uint64_t *entry);
void (*clflush_pagewalk)(const void *p); /**< Function to flush a page table entry from the cache. */
void (*tweak_exe_right)(uint64_t *entry); /**< Function to tweak execution rights for an entry. */
void (*recover_exe_right)(uint64_t *entry); /**< Function to recover execution rights for an entry. */
};
/**
* @brief Check whether the page referenced by the specified paging-structure entry is present or not.
*
* This function is used to check if the page referenced is present. A paging-structure entry references a page. The
* presence of a page is indicated by specific bits in the entry, as defined by the architecture's memory system design.
* For example, in ept table entry it's indicated by bit0|bit1|bit2, and in mmu table entry it's indicated by bit 0.
*
* This function checks whether the page referenced exists based on specific bits.
*
* @param[in] table A pointer to the structure pgtable which provides the mask to check whether page referenced is
* present or not.
* @param[in] pte The paging-structure entry to check.
*
* @return A boolean value indicating if the page referenced by the specified paging-structure entry is present
*
* @retval true Indicates the page referenced is present.
* @retval false Indicates the page referenced is not present.
*
* @pre table != NULL
*
* @post N/A
*/
static inline bool pgentry_present(const struct pgtable *table, uint64_t pte)
{
return ((table->pgentry_present_mask & (pte)) != 0UL);
}
/**
* @brief Address space translation
* @brief Translate a host physical address to a host virtual address before paging mode enabled.
*
* @addtogroup acrn_mem ACRN Memory Management
* @{
*/
/* hpa <--> hva, now it is 1:1 mapping */
/**
* @brief Translate host-physical address to host-virtual address
* This function is used to translate a host physical address to a host virtual address before paging mode enabled. HPA
* is 1:1 mapping to HVA.
*
* @param[in] x The specified host-physical address
* It returns the host virtual address that corresponds to the given host physical address.
*
* @return The translated host-virtual address
* @param[in] x The host physical address
*
* @return The translated host virtual address
*
* @retval NULL if x == 0
*
* @pre N/A
*
* @post N/A
*
* @remark This function is used before paging mode enabled.
*/
static inline void *hpa2hva_early(uint64_t x)
{
return (void *)x;
}
/**
* @brief Translate host-virtual address to host-physical address
* @brief Translate a host virtual address to a host physical address before paging mode enabled.
*
* @param[in] x The specified host-virtual address
* This function is used to translate a host virtual address to a host physical address before paging mode enabled. HVA
* is 1:1 mapping to HPA.
*
* @return The translated host-physical address
* It returns the host physical address that corresponds to the given host virtual address.
*
* @param[in] x The host virtual address to be translated
*
* @return The translated host physical address
*
* @retval 0 if x == NULL
*
* @pre N/A
*
* @post N/A
*
* @remark This function is used before paging mode enabled.
*/
static inline uint64_t hva2hpa_early(void *x)
{
@ -214,22 +287,47 @@ static inline uint64_t hva2hpa_early(void *x)
}
/**
* @brief Translate host-physical address to host-virtual address
* @brief Translate a host physical address to a host virtual address.
*
* @param[in] x The specified host-physical address
* This function is used to translate a host physical address to a host virtual address. HPA is 1:1 mapping to HVA.
*
* @return The translated host-virtual address
* It returns the host virtual address that corresponds to the given host physical address.
*
* @param[in] x The host physical address to be translated.
*
* @return The translated host virtual address
*
* @retval NULL if x == 0
*
* @pre N/A
*
* @post N/A
*
* @remark This function is used after paging mode enabled.
*/
static inline void *hpa2hva(uint64_t x)
{
return (void *)x;
}
/**
* @brief Translate host-virtual address to host-physical address
* @brief Translate a host virtual address to a host physical address.
*
* @param[in] x The specified host-virtual address
* This function is used to translate a host virtual address to a host physical address. HVA is 1:1 mapping to HPA.
*
* @return The translated host-physical address
* It returns the host physical address that corresponds to the given host virtual address.
*
* @param[in] x The host virtual address to be translated.
*
* @return The translated host physical address.
*
* @retval 0 if x == NULL
*
* @pre N/A
*
* @post N/A
*
* @remark This function is used after paging mode enabled.
*/
static inline uint64_t hva2hpa(const void *x)
{
@ -271,21 +369,101 @@ static inline uint64_t *pde_page_vaddr(uint64_t pde)
return hpa2hva(pde & PDE_PFN_MASK);
}
/**
* @brief Calculate the page map level-4 table entry(PML4E) for a specified input address.
*
* The page map level-4 table(PML4T) contains 512 entries, each of which points to a page directory pointer table(PDPT).
* Address has the index to the PML4E in PML4T. This function is used to calculate the address of PML4E. It is typically
* used during the page translation process.
*
* It will return a pointer to the page map level-4 table entry(PML4E).
*
* @param[in] pml4_page A pointer to a page map level-4 table(PML4T) page.
* @param[in] addr The address value for which the page map level-4 table entry(PML4E) address is to be calculated.
* For hypervisor's MMU, it is the host virtual address.
* For each VM's EPT, it is the guest physical address.
*
* @return A pointer to the PML4E.
*
* @pre pml4_page != NULL
*
* @post N/A
*/
static inline uint64_t *pml4e_offset(uint64_t *pml4_page, uint64_t addr)
{
return pml4_page + pml4e_index(addr);
}
/**
* @brief Calculate the page directory pointer table entry(PDPTE) for a specified input address.
*
* The page directory pointer table(PDPT) is referenced by a page map level-4 table entry(PML4E) and echo entry(PDPTE)
* in PDPT points to a page directory table(PDT). Address has the index to the PDPTE in PDPT. This function is used to
* calculate the address of PDPTE. It is typically used during the page translation process.
*
* It will return a pointer to the page directory pointer table entry(PDPTE).
*
* @param[in] pml4e A pointer to a page map level-4 table entry(PML4E).
* @param[in] addr The address for which the page directory pointer table entry(PDPTE) address is to be calculated.
* For hypervisor's MMU, it is the host virtual address.
* For each VM's EPT, it is the guest physical address.
*
* @return A pointer to the PDPTE.
*
* @pre pml4e != NULL
*
* @post N/A
*/
static inline uint64_t *pdpte_offset(const uint64_t *pml4e, uint64_t addr)
{
return pml4e_page_vaddr(*pml4e) + pdpte_index(addr);
}
/**
* @brief Calculate the page directory table entry(PDE) for a specified input address.
*
* The page directory table(PDT) is referenced by a page directory pointer table entry(PDPTE) and echo entry(PDE) in PDT
* points to a page table(PT). Address has the index to the PDE in PDT. This function is used to calculate the address
* of PDE. It is typically used during the page translation process.
*
* It will return a pointer to the page directory table entry(PDE).
*
* @param[in] pdpte A pointer to a page directory pointer table entry(PDPTE).
* @param[in] addr The address for which the page directory table entry(PDE) address is to be calculated.
* For hypervisor's MMU, it is the host virtual address.
* For each VM's EPT, it is the guest physical address.
*
* @return A pointer to the PDE.
*
* @pre pdpte != NULL
*
* @post N/A
*/
static inline uint64_t *pde_offset(const uint64_t *pdpte, uint64_t addr)
{
return pdpte_page_vaddr(*pdpte) + pde_index(addr);
}
/**
* @brief Calculate the page table entry(PTE) for a specified input address.
*
* The page table entry(PTE) is the entry that maps a page. This function is used to calculate the address of the PTE.
* It is typically used during the page translation process. The function is essential for managing memory access
* permissions and for implementing memory systems.
*
* It will return the address of a page table entry(PTE).
*
* @param[in] pde A pointer to a page directory entry(PDE).
* @param[in] addr The address for which the page table entry(PTE) address is to be calculated.
* For hypervisor's MMU, it is the host virtual address.
* For each VM's EPT, it is the guest physical address.
*
* @return A pointer to the page table entry(PTE).
*
* @pre pde != NULL
*
* @post N/A
*/
static inline uint64_t *pte_offset(const uint64_t *pde, uint64_t addr)
{
return pde_page_vaddr(*pde) + pte_index(addr);
@ -308,11 +486,51 @@ static inline void set_pgentry(uint64_t *ptep, uint64_t pte, const struct pgtabl
table->clflush_pagewalk(ptep);
}
/**
* @brief Check whether the PS flag of the specified page directory table entry(PDE) is 1 or not.
*
* PS(Page Size) flag in PDE indicates whether maps a 2-MByte page or references a page table. This function checks this
* flag. This function is typically used in the context of setting up or modifying page tables where it's necessary to
* distinguish between large and regular page mappings.
*
* It returns the value that bit 7 is 1 if the specified PDE maps a 2-MByte page, or 0 if references a page table.
*
* @param[in] pde The page directory table entry(PDE) to check.
*
* @return The value of PS flag in the PDE.
*
* @retval PAGE_PSE indicating mapping to a 2-MByte page.
* @retval 0 indicating reference to a page table.
*
* @pre N/A
*
* @post N/A
*/
static inline uint64_t pde_large(uint64_t pde)
{
return pde & PAGE_PSE;
}
/**
* @brief Check whether the PS flag of the specified page directory pointer table entry(PDPTE) is 1 or not.
*
* PS(Page Size) flag in PDPTE indicates whether maps a 1-GByte page or references a page directory table. This function
* checks this flag. This function is typically used in the context of setting up or modifying page tables where it's
* necessary to distinguish between large and regular page mappings.
*
* It returns the value that bit 7 is 1 if the specified PDPTE maps a 1-GByte page, and 0 if references a page table.
*
* @param[in] pdpte The page directory pointer table entry(PDPTE) to check.
*
* @return The value of PS flag in the PDPTE.
*
* @retval PAGE_PSE indicating mapping to a 1-GByte page.
* @retval 0 indicating reference to a page directory table.
*
* @pre N/A
*
* @post N/A
*/
static inline uint64_t pdpte_large(uint64_t pdpte)
{
return pdpte & PAGE_PSE;
@ -335,7 +553,8 @@ void pgtable_add_map(uint64_t *pml4_page, uint64_t paddr_base,
void pgtable_modify_or_del_map(uint64_t *pml4_page, uint64_t vaddr_base,
uint64_t size, uint64_t prot_set, uint64_t prot_clr,
const struct pgtable *table, uint32_t type);
#endif /* PGTABLE_H */
/**
* @}
*/
#endif /* PGTABLE_H */
*/

View File

@ -473,7 +473,7 @@ static inline uint16_t dma_frcd_up_sid(uint64_t up_sid)
}
#define MAX_DRHDS DRHD_COUNT
#define MAX_DRHD_DEVSCOPES 16U
#define MAX_DRHD_DEVSCOPES DRHD_MAX_DEVSCOPE_COUNT
#define DMAR_CONTEXT_TRANSLATION_TYPE_TRANSLATED 0x00U
#define DMAR_CONTEXT_TRANSLATION_TYPE_RESERVED 0x01U

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022 Intel Corporation.
* Copyright (C) 2024 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,6 +7,25 @@
#ifndef VRTC_H
#define VRTC_H
/**
* @defgroup vp-dm_vperipheral vp-dm.vperipheral
* @ingroup vp-dm
* @brief Implementation of virtual peripheral devices in hypervisor.
*
* This module implements the virtualization of all peripheral devices in hypervisor. The virtual device initial
* function is usually called by the VM initialization function and registers their port IO and memory IO access
* functions. So when a guest VM accesses its peripheral device by port IO or memory IO, it would cause VM exit and then
* call their registered functions.
* @{
*/
/**
* @file
* @brief Definitions for the virtual RTC device.
*
* This file defines types and data structure for the virtual RTC device.
*/
typedef int32_t time_t;
/* Register layout of the RTC */
@ -29,17 +48,34 @@ struct rtcdev {
uint8_t century;
};
/**
* @brief Data structure to illustrate a virtual RTC device.
*
* This structure contains the information of a virtual RTC device.
*
* @consistency self.vm->vrtc == self
* @alignment N/A
*
* @remark N/A
*/
struct acrn_vrtc {
struct acrn_vm *vm;
uint32_t addr; /* RTC register to read or write */
time_t base_rtctime; /* Base time calulated from physical rtc register. */
time_t offset_rtctime; /* RTC offset against base time. */
time_t last_rtctime; /* Last RTC time, to keep monotonicity. */
uint64_t base_tsc; /* Base tsc value */
struct rtcdev rtcdev; /* RTC register */
struct acrn_vm *vm; /**< Pointer to the VM that owns the virtual RTC device. */
/**
* @brief The RTC register to read or write.
*
* To access RTC registers, the guest writes the register index to the RTC address port and then reads/writes
* the register value from/to the RTC data port. This field is used to store the register index.
*/
uint32_t addr;
time_t base_rtctime; /**< Base time calculated from physical RTC register. */
time_t offset_rtctime; /**< RTC offset against base time. */
time_t last_rtctime; /**< Last RTC time, to keep monotonicity. */
uint64_t base_tsc; /**< Base TSC value. */
struct rtcdev rtcdev; /**< Register layout of RTC. */
};
#endif /* VRTC_H */
/**
* @}
*/

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 2013 Neel Natu <neel@freebsd.org>
* Copyright (c) 2018-2022 Intel Corporation.
* Copyright (c) 2018-2024 Intel Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -32,6 +32,19 @@
#include <asm/lib/spinlock.h>
#include <asm/vm_config.h>
/**
* @addtogroup vp-dm_vperipheral
*
* @{
*/
/**
* @file
* @brief All APIs to support virtual UART device.
*
* This file defines macros, structures and function declarations for emulating virtual UART device.
*/
#define RX_BUF_SIZE CONFIG_VUART_RX_BUF_SIZE
#define TX_BUF_SIZE CONFIG_VUART_TX_BUF_SIZE
#define VUART_TIMER_CPU CONFIG_VUART_TIMER_PCPU
@ -56,31 +69,41 @@ struct vuart_fifo {
uint32_t size; /* size of the fifo */
};
/**
* @brief Data structure to illustrate a virtual UART device.
*
* This structure contains the information of a virtual UART device.
*
* @consistency self.vm->vuart[X] == self
* @alignment N/A
*
* @remark N/A
*/
struct acrn_vuart {
uint8_t data; /* Data register (R/W) */
uint8_t ier; /* Interrupt enable register (R/W) */
uint8_t lcr; /* Line control register (R/W) */
uint8_t mcr; /* Modem control register (R/W) */
uint8_t lsr; /* Line status register (R/W) */
uint8_t msr; /* Modem status register (R/W) */
uint8_t fcr; /* FIFO control register (W) */
uint8_t scr; /* Scratch register (R/W) */
uint8_t dll; /* Baudrate divisor latch LSB */
uint8_t dlh; /* Baudrate divisor latch MSB */
uint8_t data; /**< Data register (R/W). */
uint8_t ier; /**< Interrupt enable register (R/W). */
uint8_t lcr; /**< Line control register (R/W). */
uint8_t mcr; /**< Modem control register (R/W). */
uint8_t lsr; /**< Line status register (R/W). */
uint8_t msr; /**< Modem status register (R/W). */
uint8_t fcr; /**< FIFO control register (W). */
uint8_t scr; /**< Scratch register (R/W). */
uint8_t dll; /**< Baudrate divisor latch LSB. */
uint8_t dlh; /**< Baudrate divisor latch MSB. */
struct vuart_fifo rxfifo;
struct vuart_fifo txfifo;
uint16_t port_base;
uint32_t irq;
char vuart_rx_buf[RX_BUF_SIZE];
char vuart_tx_buf[TX_BUF_SIZE];
bool thre_int_pending; /* THRE interrupt pending */
bool active;
bool escaping; /* in escaping sequence, for console vuarts */
struct acrn_vuart *target_vu; /* Pointer to target vuart */
struct acrn_vm *vm;
struct pci_vdev *vdev; /* pci vuart */
spinlock_t lock; /* protects all softc elements */
struct vuart_fifo rxfifo; /**< FIFO queue for received data. */
struct vuart_fifo txfifo; /**< FIFO queue for transmitted data. */
uint16_t port_base; /**< Base port address of the virtual UART device. */
uint32_t irq; /**< IRQ number of the virtual UART device. */
char vuart_rx_buf[RX_BUF_SIZE]; /**< Buffer for received data. */
char vuart_tx_buf[TX_BUF_SIZE]; /**< Buffer for transmitted data. */
bool thre_int_pending; /**< Whether Transmitter Holding Register Empty(THRE) interrupt is pending. */
bool active; /**< Whether the vuart is active. */
bool escaping; /**< Whether in escaping sequence, only for console vuarts. */
struct acrn_vuart *target_vu; /**< Pointer to target vuart */
struct acrn_vm *vm; /**< Pointer to the VM that owns the virtual UART device. */
struct pci_vdev *vdev; /**< Pointer to the PCI device, only for a PCI vuart. */
spinlock_t lock; /**< The spinlock to protect simultaneous access of all elements. */
};
void init_legacy_vuarts(struct acrn_vm *vm, const struct vuart_config *vu_config);
@ -97,3 +120,7 @@ bool is_vuart_intx(const struct acrn_vm *vm, uint32_t intx_gsi);
uint8_t vuart_read_reg(struct acrn_vuart *vu, uint16_t offset);
void vuart_write_reg(struct acrn_vuart *vu, uint16_t offset, uint8_t value);
#endif /* VUART_H */
/**
* @}
*/

View File

@ -65,6 +65,7 @@
#define GUEST_FLAG_PMU_PASSTHROUGH (1UL << 11U) /* Whether PMU is passed through */
#define GUEST_FLAG_VHWP (1UL << 12U) /* Whether the VM supports vHWP */
#define GUEST_FLAG_VTM (1UL << 13U) /* Whether the VM supports virtual thermal monitor */
#define GUEST_FLAG_STATELESS (1UL << 14U) /* Whether the VM is stateless (can be forcefully shutdown with no data loss) */
/* TODO: We may need to get this addr from guest ACPI instead of hardcode here */
#define VIRTUAL_SLEEP_CTL_ADDR 0x400U /* Pre-launched VM uses ACPI reduced HW mode and sleep control register */

View File

@ -11,6 +11,6 @@ void uart16550_init(__unused bool early_boot) {}
bool is_pci_dbg_uart(__unused union pci_bdf bdf_value) { return false; }
bool get_pio_dbg_uart_cfg(__unused uint64_t *pio_address, __unused uint64_t *nbytes) {
bool get_pio_dbg_uart_cfg(__unused uint16_t *pio_address, __unused uint32_t *nbytes) {
return false;
}

View File

@ -3,6 +3,8 @@
# SPDX-License-Identifier: BSD-3-Clause
#
import logging
import board_cfg_lib
import acrn_config_utilities
@ -190,7 +192,7 @@ def drhd_info_parser(config):
Parse DRHD information
:param config: it is a file pointer to write acpi information
"""
prev_num = 0
has_drhd_max_devscope_count = False
drhd_lines = board_cfg_lib.get_info(
acrn_config_utilities.BOARD_INFO_FILE, "<DRHD_INFO>", "</DRHD_INFO>")
@ -200,7 +202,18 @@ def drhd_info_parser(config):
if not drhd_lines:
print("\n#define DRHD_COUNT\t\t8U", file=config)
print("\n#define DRHD_MAX_DEVSCOPE_COUNT\t16U", file=config)
return
for drhd in drhd_lines:
if "DRHD_MAX_DEVSCOPE_COUNT" in drhd:
has_drhd_max_devscope_count = True
break
if not has_drhd_max_devscope_count:
logging.warning("DRHD_MAX_DEVSCOPE_COUNT is not defined in board.xml, using default 16U. "
"Generate board.xml with latest board inspector to remove this warning.")
print("\n#define DRHD_MAX_DEVSCOPE_COUNT\t16U", file=config)
for drhd in drhd_lines:
print(drhd.strip(), file=config)

View File

@ -360,6 +360,7 @@ def write_dmar_data(sysnode, config):
dmar_tbl, dmar_hw_list, dmar_dev_list, sysnode)
print("\t#define DRHD_COUNT {0}U".format(drhd_cnt), file=config)
print("\t#define DRHD_MAX_DEVSCOPE_COUNT {0}U".format(max(dmar_dev_list.dev_scope_cnt_list)), file=config)
print("", file=config)
prev_dev_scope_num = 0
for drhd_hw_i in range(drhd_cnt):

View File

@ -40,12 +40,17 @@
"chokidar": {
"braces": "3.0.3"
}
},
"vue": {
"postcss": {
"nanoid": "3.3.8"
}
}
},
"devDependencies": {
"@tauri-apps/cli": "^1.0.0-rc.10",
"@types/node": "^16.11.33",
"@vitejs/plugin-vue": "^2.3.1",
"vite": "^2.9.16"
"vite": ">=3.2.11"
}
}

View File

@ -6,14 +6,19 @@ version = 3
name = "acrn-configurator"
version = "0.1.0"
dependencies = [
"crossbeam-channel",
"dirs",
"glob",
"idna",
"itertools",
"log",
"openssl",
"serde",
"serde_json",
"tauri",
"tauri-build",
"tokio",
"url",
]
[[package]]
@ -159,7 +164,7 @@ dependencies = [
"polling",
"rustix",
"slab",
"socket2",
"socket2 0.4.9",
"waker-fn",
]
@ -609,22 +614,18 @@ dependencies = [
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.16"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294"
dependencies = [
"cfg-if",
]
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crypto-common"
@ -800,6 +801,17 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
[[package]]
name = "displaydoc"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.26",
]
[[package]]
name = "downcast-rs"
version = "1.2.1"
@ -1004,9 +1016,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.2.0"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
dependencies = [
"percent-encoding",
]
@ -1568,7 +1580,7 @@ dependencies = [
"httpdate",
"itoa 1.0.9",
"pin-project-lite",
"socket2",
"socket2 0.4.9",
"tokio",
"tower-service",
"tracing",
@ -1621,6 +1633,124 @@ dependencies = [
"png",
]
[[package]]
name = "icu_collections"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
dependencies = [
"displaydoc",
"yoke",
"zerofrom",
"zerovec",
]
[[package]]
name = "icu_locid"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
dependencies = [
"displaydoc",
"litemap",
"tinystr",
"writeable",
"zerovec",
]
[[package]]
name = "icu_locid_transform"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
dependencies = [
"displaydoc",
"icu_locid",
"icu_locid_transform_data",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
name = "icu_locid_transform_data"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
[[package]]
name = "icu_normalizer"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
dependencies = [
"displaydoc",
"icu_collections",
"icu_normalizer_data",
"icu_properties",
"icu_provider",
"smallvec",
"utf16_iter",
"utf8_iter",
"write16",
"zerovec",
]
[[package]]
name = "icu_normalizer_data"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
[[package]]
name = "icu_properties"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
dependencies = [
"displaydoc",
"icu_collections",
"icu_locid_transform",
"icu_properties_data",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
name = "icu_properties_data"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
[[package]]
name = "icu_provider"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
dependencies = [
"displaydoc",
"icu_locid",
"icu_provider_macros",
"stable_deref_trait",
"tinystr",
"writeable",
"yoke",
"zerofrom",
"zerovec",
]
[[package]]
name = "icu_provider_macros"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.26",
]
[[package]]
name = "ident_case"
version = "1.0.1"
@ -1629,12 +1759,14 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.4.0"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed"
dependencies = [
"unicode-bidi",
"unicode-normalization",
"icu_normalizer",
"icu_properties",
"smallvec",
"utf8_iter",
]
[[package]]
@ -1836,9 +1968,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.153"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "line-wrap"
@ -1855,6 +1987,12 @@ version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
[[package]]
name = "litemap"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
[[package]]
name = "lock_api"
version = "0.4.10"
@ -2000,13 +2138,13 @@ dependencies = [
[[package]]
name = "mio"
version = "0.8.11"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
@ -2155,16 +2293,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "num_enum"
version = "0.5.11"
@ -2252,9 +2380,9 @@ dependencies = [
[[package]]
name = "openssl"
version = "0.10.60"
version = "0.10.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800"
checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da"
dependencies = [
"bitflags 2.4.1",
"cfg-if",
@ -2284,9 +2412,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.96"
version = "0.9.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f"
checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07"
dependencies = [
"cc",
"libc",
@ -2393,9 +2521,9 @@ checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
[[package]]
name = "percent-encoding"
version = "2.3.0"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "petgraph"
@ -2543,9 +2671,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.10"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pin-utils"
@ -3249,9 +3377,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.11.0"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
@ -3263,6 +3391,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "socket2"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "soup2"
version = "0.2.1"
@ -3372,6 +3510,17 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "synstructure"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.26",
]
[[package]]
name = "sys-locale"
version = "0.2.4"
@ -3796,35 +3945,28 @@ dependencies = [
]
[[package]]
name = "tinyvec"
version = "1.6.0"
name = "tinystr"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
dependencies = [
"tinyvec_macros",
"displaydoc",
"zerovec",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.29.1"
version = "1.43.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
checksum = "492a604e2fd7f814268a378409e6c92b5525d747d10db9a229723f55a417958c"
dependencies = [
"autocfg",
"backtrace",
"bytes",
"libc",
"mio",
"num_cpus",
"pin-project-lite",
"socket2",
"windows-sys 0.48.0",
"socket2 0.5.9",
"windows-sys 0.52.0",
]
[[package]]
@ -3998,27 +4140,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "unicode-bidi"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
[[package]]
name = "unicode-ident"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.10.1"
@ -4027,9 +4154,9 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
name = "url"
version = "2.4.0"
version = "2.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56"
dependencies = [
"form_urlencoded",
"idna",
@ -4043,6 +4170,18 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "utf16_iter"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
[[package]]
name = "utf8_iter"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "uuid"
version = "1.4.1"
@ -4821,6 +4960,18 @@ dependencies = [
"wayland-protocols",
]
[[package]]
name = "write16"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
[[package]]
name = "writeable"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "wry"
version = "0.24.10"
@ -4927,6 +5078,30 @@ version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193"
[[package]]
name = "yoke"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
dependencies = [
"serde",
"stable_deref_trait",
"yoke-derive",
"zerofrom",
]
[[package]]
name = "yoke-derive"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.26",
"synstructure",
]
[[package]]
name = "zbus"
version = "3.14.1"
@ -4993,6 +5168,49 @@ dependencies = [
"zvariant",
]
[[package]]
name = "zerofrom"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
dependencies = [
"zerofrom-derive",
]
[[package]]
name = "zerofrom-derive"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.26",
"synstructure",
]
[[package]]
name = "zerovec"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
dependencies = [
"yoke",
"zerofrom",
"zerovec-derive",
]
[[package]]
name = "zerovec-derive"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.26",
]
[[package]]
name = "zvariant"
version = "3.15.0"

View File

@ -15,6 +15,11 @@ rust-version = "1.57"
tauri-build = { version = "1.5.2", features = [] }
[dependencies]
openssl = "0.10.72" # fix vulnerability only
idna = "=1.0.0" # fix vulnerability only
url = "=2.5.1" # fix vulnerability only
tokio = "=1.43.1" # fix vulnerability only
crossbeam-channel = "=0.5.15" # fix vulnerability only
serde_json = "1.0.81"
serde = { version = "1.0.137", features = ["derive"] }
tauri = { version = "1.6.7", features = ["api-all", "devtools"] }

File diff suppressed because it is too large Load Diff

View File

@ -303,12 +303,18 @@ def generate_for_one_vm(board_etree, hv_scenario_etree, vm_scenario_etree, vm_id
for ivshmem in eval_xpath_all(vm_scenario_etree, f"//IVSHMEM_REGION[PROVIDED_BY = 'Device Model' and .//VM_NAME = '{vm_name}']"):
vbdf = eval_xpath(ivshmem, f".//VBDF/text()")
slot = get_slot_by_vbdf(vbdf)
script.add_virtual_device("ivshmem", slot, options=f"dm:/{ivshmem.find('NAME').text},{ivshmem.find('IVSHMEM_SIZE').text}")
if ivshmem.find('IVSHMEM_REGION_ID') is not None:
script.add_virtual_device("ivshmem", slot, options=f"dm:/{ivshmem.find('NAME').text},{ivshmem.find('IVSHMEM_SIZE').text},{ivshmem.find('IVSHMEM_REGION_ID').text}")
else:
script.add_virtual_device("ivshmem", slot, options=f"dm:/{ivshmem.find('NAME').text},{ivshmem.find('IVSHMEM_SIZE').text},{0}")
for ivshmem in eval_xpath_all(vm_scenario_etree, f"//IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor' and .//VM_NAME = '{vm_name}']"):
vbdf = eval_xpath(ivshmem, f".//VBDF/text()")
slot = get_slot_by_vbdf(vbdf)
script.add_virtual_device("ivshmem", slot, options=f"hv:/{ivshmem.find('NAME').text},{ivshmem.find('IVSHMEM_SIZE').text}")
if ivshmem.find('IVSHMEM_REGION_ID') is not None:
script.add_virtual_device("ivshmem", slot, options=f"hv:/{ivshmem.find('NAME').text},{ivshmem.find('IVSHMEM_SIZE').text},{ivshmem.find('IVSHMEM_REGION_ID').text}")
else:
script.add_virtual_device("ivshmem", slot, options=f"hv:/{ivshmem.find('NAME').text},{ivshmem.find('IVSHMEM_SIZE').text},{0}")
if eval_xpath(vm_scenario_etree, ".//console_vuart/text()") == "PCI":
script.add_virtual_device("uart", options="vuart_idx:0")

View File

@ -216,7 +216,7 @@ If your VM is not a security VM, leave this option unchecked. </xs:documentation
<xs:documentation>Maximum number of User VMs allowed.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="MAX_IOAPIC_NUM" default="1">
<xs:element name="MAX_IOAPIC_NUM" minOccurs="0">
<xs:annotation acrn:views="">
<xs:documentation>Maximum number of IOAPICs.</xs:documentation>
</xs:annotation>
@ -250,7 +250,7 @@ If your VM is not a security VM, leave this option unchecked. </xs:documentation
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="MAX_IOAPIC_LINES" default="120">
<xs:element name="MAX_IOAPIC_LINES" minOccurs="0">
<xs:annotation acrn:views="">
<xs:documentation>Maximum number of interrupt lines per IOAPIC.</xs:documentation>
</xs:annotation>
@ -487,6 +487,11 @@ These settings can only be changed at build time.</xs:documentation>
<xs:documentation>Specify TPM2 FIXUP for VM.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="stateless" type="Boolean" default="n" minOccurs="0">
<xs:annotation acrn:title="Stateless VM" acrn:applicable-vms="pre-launched" acrn:views="advanced">
<xs:documentation>Indicate the VM is running a stateless operating system and it can be shutdown forcefully with no data loss.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="epc_section" type="EPCSection" minOccurs="0">
<xs:annotation acrn:title="SGX Enclave Page Cache" acrn:views="advanced" acrn:applicable-vms="pre-launched">
<xs:documentation>Specify the Intel Software Guard Extensions (SGX) enclave page cache (EPC) section settings.</xs:documentation>

View File

@ -286,7 +286,7 @@ in megabytes. The value should be a power of 2
and no more than 512.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="IVSHMEM_REGION_ID" type="xs:integer" default="0">
<xs:element name="IVSHMEM_REGION_ID" type="xs:string" default="0">
<xs:annotation acrn:title="IVSHMEM Region ID">
<xs:documentation>A stable identification when multiple shared memory regions are provided.</xs:documentation>
</xs:annotation>

View File

@ -27,6 +27,7 @@ policies = [
GuestFlagPolicy(".//vm_type = 'RTVM' and .//load_order = 'PRE_LAUNCHED_VM' and //hv/BUILD_TYPE= 'debug'", "GUEST_FLAG_PMU_PASSTHROUGH"),
GuestFlagPolicy(".//vm_type = 'TEE_VM'", "GUEST_FLAG_TEE"),
GuestFlagPolicy(".//vm_type = 'REE_VM'", "GUEST_FLAG_REE"),
GuestFlagPolicy("(.//load_order = 'PRE_LAUNCHED_VM' and .//stateless = 'y') or (.//vm_type = 'TEE_VM')", "GUEST_FLAG_STATELESS"),
]
def fn(board_etree, scenario_etree, allocation_etree):

View File

@ -18,12 +18,12 @@
<xsl:call-template name="integer-by-key-value">
<xsl:with-param name="key" select="'MAX_IOAPIC_NUM'" />
<xsl:with-param name="value" select="//config-data//MAX_IOAPIC_NUM/text()" />
<xsl:with-param name="default" select="count(.//ioapic)" />
<xsl:with-param name="default" select="acrn:max(1, count(.//ioapic))" />
</xsl:call-template>
<xsl:call-template name="integer-by-key-value">
<xsl:with-param name="key" select="'MAX_IOAPIC_LINES'" />
<xsl:with-param name="value" select="//config-data//MAX_IOAPIC_LINES/text()" />
<xsl:with-param name="default" select="math:max(.//ioapic/gsi_number/text() | exslt:node-set(0))" />
<xsl:with-param name="default" select="math:max(.//ioapic/gsi_number/text() | exslt:node-set(48))" />
</xsl:call-template>
<xsl:call-template name="msi-msix-max" />
</xsl:template>