Skip to content

Commit

Permalink
Merge branch 'projectacrn:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangckid committed Apr 28, 2024
2 parents 14f9cc5 + 629808c commit e50f227
Show file tree
Hide file tree
Showing 23 changed files with 233 additions and 96 deletions.
21 changes: 16 additions & 5 deletions devicemodel/hw/pci/ivshmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#define IVSHMEM_DEVICE_ID 0x1110
#define IVSHMEM_CLASS 0x05
#define IVSHMEM_REV 0x01
#define IVSHMEM_INTEL_SUBVENDOR_ID 0x8086U


/* IVSHMEM MMIO Registers */
Expand Down Expand Up @@ -249,13 +250,13 @@ pci_ivshmem_read(struct vmctx *ctx, int vcpu, struct pci_vdev *dev,
static int
pci_ivshmem_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
{
uint32_t size;
char *tmp, *name, *orig;
uint32_t size, region_id = 0;
char *tmp, *name, *size_str, *orig;
struct pci_ivshmem_vdev *ivshmem_vdev = NULL;
bool is_hv_land;
int rc;

/* ivshmem device usage: "-s N,ivshmem,shm_name,shm_size" */
/* ivshmem device usage: "-s N,ivshmem,shm_name,shm_size,region_id" */
tmp = orig = strdup(opts);
if (!orig) {
pr_warn("No memory for strdup\n");
Expand All @@ -277,8 +278,9 @@ pci_ivshmem_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
goto err;
}

if (dm_strtoui(tmp, &tmp, 10, &size) != 0) {
pr_warn("the shared memory size is incorrect, %s\n", tmp);
size_str = strsep(&tmp, ",");
if (dm_strtoui(size_str, &size_str, 10, &size) != 0) {
pr_warn("the shared memory size is incorrect, %s\n", size_str);
goto err;
}
size *= 0x100000; /* convert to megabytes */
Expand All @@ -289,6 +291,13 @@ pci_ivshmem_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
goto err;
}

if (tmp) {
if (dm_strtoui(tmp, &tmp, 10, &region_id) != 0) {
pr_warn("shared memory region ID is incorrect, %s, 0 will used.\n", tmp);
region_id = 0;
}
}

ivshmem_vdev = calloc(1, sizeof(struct pci_ivshmem_vdev));
if (!ivshmem_vdev) {
pr_warn("failed to allocate ivshmem device\n");
Expand All @@ -304,6 +313,8 @@ pci_ivshmem_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
pci_set_cfgdata16(dev, PCIR_DEVICE, IVSHMEM_DEVICE_ID);
pci_set_cfgdata16(dev, PCIR_REVID, IVSHMEM_REV);
pci_set_cfgdata8(dev, PCIR_CLASS, IVSHMEM_CLASS);
pci_set_cfgdata16(dev, PCIR_SUBDEV_0, (uint16_t)region_id);
pci_set_cfgdata16(dev, PCIR_SUBVEND_0, IVSHMEM_INTEL_SUBVENDOR_ID);

pci_emul_alloc_bar(dev, IVSHMEM_MMIO_BAR, PCIBAR_MEM32, IVSHMEM_REG_SIZE);
pci_emul_alloc_bar(dev, IVSHMEM_MSIX_BAR, PCIBAR_MEM32, IVSHMEM_MSIX_PBA_SIZE);
Expand Down
4 changes: 1 addition & 3 deletions devicemodel/hw/pci/lpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static struct lpc_uart_vdev {
const char *opts;
int iobase;
int irq;
int enabled;
int enabled; /* enabled/configured by user */
} lpc_uart_vdev[LPC_UART_NUM];

static const char *lpc_uart_names[LPC_UART_NUM] = { "COM1", "COM2", "COM3", "COM4" };
Expand Down Expand Up @@ -185,7 +185,6 @@ lpc_deinit(struct vmctx *ctx)
uart_release_backend(lpc_uart->uart, lpc_uart->opts);
uart_legacy_dealloc(unit);
lpc_uart->uart = NULL;
lpc_uart->enabled = 0;
}
}

Expand Down Expand Up @@ -233,7 +232,6 @@ lpc_init(struct vmctx *ctx)
error = register_inout(&iop);
if (error)
goto init_failed;
lpc_uart->enabled = 1;
}

return 0;
Expand Down
15 changes: 9 additions & 6 deletions hypervisor/arch/x86/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,14 +233,17 @@ void set_paging_x(uint64_t base, uint64_t size)

void allocate_ppt_pages(void)
{
uint64_t page_base;
uint64_t page_base;
uint64_t bitmap_size = get_ppt_page_num() / 8;

page_base = e820_alloc_memory(sizeof(struct page) * get_ppt_page_num(), MEM_4G);
ppt_page_pool.bitmap = (uint64_t *)e820_alloc_memory(get_ppt_page_num()/8, MEM_4G);
page_base = e820_alloc_memory(sizeof(struct page) * get_ppt_page_num(), MEM_4G);
ppt_page_pool.bitmap = (uint64_t *)e820_alloc_memory(bitmap_size, MEM_4G);

ppt_page_pool.start_page = (struct page *)(void *)page_base;
ppt_page_pool.bitmap_size = get_ppt_page_num() / 64;
ppt_page_pool.dummy_page = NULL;
ppt_page_pool.start_page = (struct page *)(void *)page_base;
ppt_page_pool.bitmap_size = bitmap_size / sizeof(uint64_t);
ppt_page_pool.dummy_page = NULL;

memset(ppt_page_pool.bitmap, 0, bitmap_size);
}

void init_paging(void)
Expand Down
15 changes: 14 additions & 1 deletion hypervisor/arch/x86/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,22 @@ uint64_t get_random_value(void)
#ifdef STACK_PROTECTOR
void set_fs_base(void)
{
int retry;
struct stack_canary *psc = &get_cpu_var(stk_canary);

psc->canary = get_random_value();
/*
* 1) Leave initialized canary untouched when this function
* is called again such as on resuming from S3.
* 2) Do some retries in case 'get_random_value()' returns 0.
*/
for (retry = 0; (retry < 5) && (psc->canary == 0UL); retry++) {
psc->canary = get_random_value();
}

if (psc->canary == 0UL) {
panic("Failed to setup stack protector!");
}

msr_write(MSR_IA32_FS_BASE, (uint64_t)psc);
}
#endif
Expand Down
5 changes: 3 additions & 2 deletions hypervisor/common/hypercall.c
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,8 @@ int32_t hcall_vm_intr_monitor(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,
intr_hdr = (struct acrn_intr_monitor *)hpa2hva(hpa);
stac();
if (intr_hdr->buf_cnt <= (MAX_PTDEV_NUM * 2U)) {
status = 0;

switch (intr_hdr->cmd) {
case INTR_CMD_GET_DATA:
intr_hdr->buf_cnt = ptirq_get_intr_data(target_vm,
Expand All @@ -1222,10 +1224,9 @@ int32_t hcall_vm_intr_monitor(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm,

default:
/* if cmd wrong it goes here should not happen */
status = -EINVAL;
break;
}

status = 0;
}
clac();
}
Expand Down
59 changes: 47 additions & 12 deletions hypervisor/common/sbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ uint32_t sbuf_next_ptr(uint32_t pos_arg,

/**
* The high caller should guarantee each time there must have
* sbuf->ele_size data can be write form data and this function
* should guarantee execution atomically.
* sbuf->ele_size data can be write form data.
*
* As sbuf->ele_size is possibly setup by some sources outside of the
* HV (e.g. the service VM), it is not meant to be trusted. So caller
* should provide the max length of the data for safety reason.
*
* And this function should guarantee execution atomically.
*
* flag:
* If OVERWRITE_EN set, buf can store (ele_num - 1) elements at most.
Expand All @@ -40,44 +45,48 @@ uint32_t sbuf_next_ptr(uint32_t pos_arg,
* return:
* ele_size: write succeeded.
* 0: no write, buf is full
* negative: failed.
* UINT32_MAX: failed, sbuf corrupted.
*/

uint32_t sbuf_put(struct shared_buf *sbuf, uint8_t *data)
uint32_t sbuf_put(struct shared_buf *sbuf, uint8_t *data, uint32_t max_len)
{
void *to;
uint32_t next_tail;
uint32_t ele_size;
uint32_t ele_size, ret;
bool trigger_overwrite = false;

stac();
next_tail = sbuf_next_ptr(sbuf->tail, sbuf->ele_size, sbuf->size);
ele_size = sbuf->ele_size;
next_tail = sbuf_next_ptr(sbuf->tail, ele_size, sbuf->size);

if ((next_tail == sbuf->head) && ((sbuf->flags & OVERWRITE_EN) == 0U)) {
/* if overrun is not enabled, return 0 directly */
ele_size = 0U;
} else {
ret = 0U;
} else if (ele_size <= max_len) {
if (next_tail == sbuf->head) {
/* accumulate overrun count if necessary */
sbuf->overrun_cnt += sbuf->flags & OVERRUN_CNT_EN;
trigger_overwrite = true;
}
to = (void *)sbuf + SBUF_HEAD_SIZE + sbuf->tail;

(void)memcpy_s(to, sbuf->ele_size, data, sbuf->ele_size);
(void)memcpy_s(to, ele_size, data, max_len);
/* make sure write data before update head */
cpu_write_memory_barrier();

if (trigger_overwrite) {
sbuf->head = sbuf_next_ptr(sbuf->head,
sbuf->ele_size, sbuf->size);
ele_size, sbuf->size);
}
sbuf->tail = next_tail;
ele_size = sbuf->ele_size;
ret = ele_size;
} else {
/* there must be something wrong */
ret = UINT32_MAX;
}
clac();

return ele_size;
return ret;
}

int32_t sbuf_setup_common(struct acrn_vm *vm, uint16_t cpu_id, uint32_t sbuf_id, uint64_t *hva)
Expand All @@ -104,3 +113,29 @@ int32_t sbuf_setup_common(struct acrn_vm *vm, uint16_t cpu_id, uint32_t sbuf_id,

return ret;
}

/* try put a batch of elememts from data to sbuf
* data_size should be equel to n*elem_size, data not enough to fill the elem_size will be ignored.
*
* return:
* elem_size * n: bytes put in sbuf
* UINT32_MAX: failed, sbuf corrupted.
*/
uint32_t sbuf_put_many(struct shared_buf *sbuf, uint32_t elem_size, uint8_t *data, uint32_t data_size)
{
uint32_t ret, sent = 0U;
uint32_t i;

for (i = 0U; i < (data_size / elem_size); i++) {
ret = sbuf_put(sbuf, data + i * elem_size, elem_size);
if (ret == elem_size) {
sent += ret;
} else {
if (ret == UINT32_MAX) {
sent = UINT32_MAX;
}
break;
}
}
return sent;
}
2 changes: 1 addition & 1 deletion hypervisor/common/vm_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ int32_t send_vm_event(struct acrn_vm *vm, struct vm_event *event)

if (sbuf != NULL) {
spinlock_obtain(&vm->vm_event_lock);
size_sent = sbuf_put(sbuf, (uint8_t *)event);
size_sent = sbuf_put(sbuf, (uint8_t *)event, sizeof(*event));
spinlock_release(&vm->vm_event_lock);
if (size_sent == sizeof(struct vm_event)) {
arch_fire_hsm_interrupt();
Expand Down
53 changes: 40 additions & 13 deletions hypervisor/debug/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ struct hv_timer console_timer;

#define CONSOLE_KICK_TIMER_TIMEOUT 40UL /* timeout is 40ms*/
/* Switching key combinations for shell and uart console */
#define GUEST_CONSOLE_TO_HV_SWITCH_KEY 0 /* CTRL + SPACE */
uint16_t console_vmid = ACRN_INVALID_VMID;
#define GUEST_CONSOLE_ESCAPE_KEY 0x0 /* the "break", put twice to send "break" to guest */
#define GUEST_CONSOLE_TO_HV_SWITCH_KEY 'e' /* escape + e to switch back to hv console */
uint16_t console_vmid = CONFIG_CONSOLE_DEFAULT_VM;

/* if use INIT to kick pcpu only, if not notification IPI still is used for sharing CPU */
static bool use_init_ipi = false;
Expand Down Expand Up @@ -104,20 +105,46 @@ struct acrn_vuart *vm_console_vuart(struct acrn_vm *vm)
static void vuart_console_rx_chars(struct acrn_vuart *vu)
{
char ch = -1;

/* Get data from physical uart */
ch = uart16550_getc();

if (ch == GUEST_CONSOLE_TO_HV_SWITCH_KEY) {
/* Switch the console */
console_vmid = ACRN_INVALID_VMID;
printf("\r\n\r\n ---Entering ACRN SHELL---\r\n");
bool recv = false;

while (1) {
/* Get data from physical uart */
ch = uart16550_getc();
if (ch == -1)
break;

if (vu->escaping) {
vu->escaping = false;
switch (ch) {
case GUEST_CONSOLE_ESCAPE_KEY:
vuart_putchar(vu, ch);
vu->lsr |= LSR_BI;
recv = true;
break;
case GUEST_CONSOLE_TO_HV_SWITCH_KEY:
/* Switch the console */
console_vmid = ACRN_INVALID_VMID;
printf("\r\n\r\n ---Entering ACRN SHELL---\r\n");
/* following inputs are for hv, don't handle in this loop */
goto exit;
default:
printf("Unknown escaping key: '%c'\r\n", ch);
break;
}
} else {
if (ch == GUEST_CONSOLE_ESCAPE_KEY) {
vu->escaping = true;
} else {
vuart_putchar(vu, ch);
recv = true;
}
}
}
if (ch != -1) {
vuart_putchar(vu, ch);

exit:
if (recv) {
vuart_toggle_intr(vu);
}

}

/**
Expand Down
10 changes: 3 additions & 7 deletions hypervisor/debug/logmsg.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,14 @@ void do_logmsg(uint32_t severity, const char *fmt, ...)

/* Check whether output to memory */
if (do_mem_log) {
uint32_t i, msg_len;
uint32_t msg_len;
struct shared_buf *sbuf = per_cpu(sbuf, pcpu_id)[ACRN_HVLOG];

/* If sbuf is not ready, we just drop the massage */
if (sbuf != NULL) {
msg_len = strnlen_s(buffer, LOG_MESSAGE_MAX_SIZE);

for (i = 0U; i < (((msg_len - 1U) / LOG_ENTRY_SIZE) + 1U);
i++) {
(void)sbuf_put(sbuf, (uint8_t *)buffer +
(i * LOG_ENTRY_SIZE));
}
(void)sbuf_put_many(sbuf, LOG_ENTRY_SIZE, (uint8_t *)buffer,
LOG_ENTRY_SIZE * (((msg_len - 1U) / LOG_ENTRY_SIZE) + 1));
}
}
}
10 changes: 2 additions & 8 deletions hypervisor/debug/profiling.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ static int32_t profiling_sbuf_put_variable(struct shared_buf *sbuf,
*/
static int32_t profiling_generate_data(int32_t collector, uint32_t type)
{
uint64_t i;
uint32_t remaining_space = 0U;
int32_t ret = 0;
struct data_header pkt_header;
Expand Down Expand Up @@ -380,13 +379,8 @@ static int32_t profiling_generate_data(int32_t collector, uint32_t type)
return 0;
}

for (i = 0U; i < (((DATA_HEADER_SIZE - 1U) / SEP_BUF_ENTRY_SIZE) + 1U); i++) {
(void)sbuf_put(sbuf, (uint8_t *)&pkt_header + i * SEP_BUF_ENTRY_SIZE);
}

for (i = 0U; i < (((payload_size - 1U) / SEP_BUF_ENTRY_SIZE) + 1U); i++) {
(void)sbuf_put(sbuf, (uint8_t *)payload + i * SEP_BUF_ENTRY_SIZE);
}
(void)sbuf_put_many(sbuf, SEP_BUF_ENTRY_SIZE, (uint8_t *)&pkt_header, sizeof(pkt_header));
(void)sbuf_put_many(sbuf, SEP_BUF_ENTRY_SIZE, (uint8_t *)payload, payload_size);

ss->samples_logged++;
}
Expand Down
2 changes: 1 addition & 1 deletion hypervisor/debug/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ static inline void trace_put(uint16_t cpu_id, uint32_t evid, uint32_t n_data, st
entry->id = evid;
entry->n_data = (uint8_t)n_data;
entry->cpu = (uint8_t)cpu_id;
(void)sbuf_put(sbuf, (uint8_t *)entry);
(void)sbuf_put(sbuf, (uint8_t *)entry, sizeof(*entry));
}

void TRACE_2L(uint32_t evid, uint64_t e, uint64_t f)
Expand Down

0 comments on commit e50f227

Please sign in to comment.