Date   

Re: [PATCH] HV: hv_main: Add #ifdef HV_DEBUG before debug specific code #ifdef

Eddie Dong
 


On 08-13 Mon 07:59, Eddie Dong wrote:
This is part of SBUF component, what kind of compile option do we use?
Let us use same one.
shell command "vmexit" is the only one user of vmexit_time/cnt and we use
the get_vmexit_profile, enclosed by HV_DEBUG, to access these variables.
Ok then.


BTW, hcall side also needs this kind of compile option.
I can't follow here. Can you make it more clear.
The sbuf has a hypercall, we need compile option to cover all sbuf code...


Re: [PATCH] HV: handle trusty on vm reset

Eddie Dong
 

LGTM, with one issue to fix.

-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...] On Behalf Of Victor Sun
Sent: Monday, August 13, 2018 3:47 PM
To: acrn-dev@...
Subject: [acrn-dev] [PATCH] HV: handle trusty on vm reset

- clear run context when reset vcpu;

- destroy trusty without erase trusty memory when reset vm;

Signed-off-by: Sun Victor <victor.sun@...>
Signed-off-by: Yin Fengwei <fengwei.yin@...>
---
hypervisor/arch/x86/guest/vcpu.c | 7 +++++++
hypervisor/arch/x86/guest/vm.c | 2 ++
2 files changed, 9 insertions(+)

diff --git a/hypervisor/arch/x86/guest/vcpu.c
b/hypervisor/arch/x86/guest/vcpu.c
index 9dc0241..a8a9f0e 100644
--- a/hypervisor/arch/x86/guest/vcpu.c
+++ b/hypervisor/arch/x86/guest/vcpu.c
@@ -396,6 +396,7 @@ void destroy_vcpu(struct vcpu *vcpu)
*/
void reset_vcpu(struct vcpu *vcpu)
{
+ int i;
struct acrn_vlapic *vlapic;

pr_dbg("vcpu%hu reset", vcpu->vcpu_id); @@ -419,6 +420,12 @@ void
reset_vcpu(struct vcpu *vcpu)
vcpu->arch_vcpu.inject_event_pending = false;
(void)memset(vcpu->arch_vcpu.vmcs, 0U, CPU_PAGE_SIZE);

+ for (i = 0; i < NR_WORLD; i++) {
+ memset(&vcpu->arch_vcpu.contexts[i], 0,
+ sizeof(struct run_context));
+ }
+ vcpu->arch_vcpu.cur_context = NORMAL_WORLD;
+
vlapic = vcpu->arch_vcpu.vlapic;
vlapic_reset(vlapic);
}
diff --git a/hypervisor/arch/x86/guest/vm.c
b/hypervisor/arch/x86/guest/vm.c index 4bfda8e..f2efbf9 100644
--- a/hypervisor/arch/x86/guest/vm.c
+++ b/hypervisor/arch/x86/guest/vm.c
@@ -366,6 +366,8 @@ int reset_vm(struct vm *vm)
}

vioapic_reset(vm->arch_vm.virt_ioapic);
+ destroy_secure_world(vm, false);
+ vm->sworld_control.flag.active = 0UL;

start_vm(vm);
return 0;
--
2.7.4



[PATCH v3 1/1] vbs: fix virtio_vq_index_get func handling of multi VQ concurrent request.

Ong Hock Yu <ong.hock.yu@...>
 

Under multiple VQ use case, it is possible to have concurrent requests.
Added support to return multiple vq index from all vcpu.

Signed-off-by: Ong Hock Yu <ong.hock.yu@...>
---
drivers/vbs/vbs.c | 14 ++++++++------
drivers/vbs/vbs_rng.c | 2 +-
include/linux/vbs/vbs.h | 8 ++++++--
3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/vbs/vbs.c b/drivers/vbs/vbs.c
index 65b8a0bbe3d3..a2f263cb91c0 100644
--- a/drivers/vbs/vbs.c
+++ b/drivers/vbs/vbs.c
@@ -148,9 +148,11 @@ long virtio_dev_deregister(struct virtio_dev_info *dev)
return 0;
}

-int virtio_vq_index_get(struct virtio_dev_info *dev, unsigned long *ioreqs_map)
+int virtio_vqs_index_get(struct virtio_dev_info *dev,
+ unsigned long *ioreqs_map,
+ int *vqs_index, int max_vqs_index)
{
- int val = -1;
+ int idx = 0;
struct vhm_request *req;
int vcpu;

@@ -159,7 +161,7 @@ int virtio_vq_index_get(struct virtio_dev_info *dev, unsigned long *ioreqs_map)
return -EINVAL;
}

- while (1) {
+ while (idx < max_vqs_index) {
vcpu = find_first_bit(ioreqs_map, dev->_ctx.max_vcpu);
if (vcpu == dev->_ctx.max_vcpu)
break;
@@ -179,9 +181,9 @@ int virtio_vq_index_get(struct virtio_dev_info *dev, unsigned long *ioreqs_map)
pr_debug("%s: write request! type %d\n",
__func__, req->type);
if (dev->io_range_type == PIO_RANGE)
- val = req->reqs.pio_request.value;
+ vqs_index[idx++] = req->reqs.pio_request.value;
else
- val = req->reqs.mmio_request.value;
+ vqs_index[idx++] = req->reqs.mmio_request.value;
}
smp_mb();
atomic_set(&req->processed, REQ_STATE_COMPLETE);
@@ -189,7 +191,7 @@ int virtio_vq_index_get(struct virtio_dev_info *dev, unsigned long *ioreqs_map)
}
}

- return val;
+ return idx;
}

static long virtio_vqs_info_set(struct virtio_dev_info *dev,
diff --git a/drivers/vbs/vbs_rng.c b/drivers/vbs/vbs_rng.c
index fd2bb27af66e..c5e28cc12c55 100644
--- a/drivers/vbs/vbs_rng.c
+++ b/drivers/vbs/vbs_rng.c
@@ -268,7 +268,7 @@ static int handle_kick(int client_id, unsigned long *ioreqs_map)
return -EINVAL;
}

- val = virtio_vq_index_get(&rng->dev, ioreqs_map);
+ virtio_vqs_index_get(&rng->dev, ioreqs_map, &val, 1);

if (val >= 0)
handle_vq_kick(rng, val);
diff --git a/include/linux/vbs/vbs.h b/include/linux/vbs/vbs.h
index 30df8ebf68a0..964bacac865c 100644
--- a/include/linux/vbs/vbs.h
+++ b/include/linux/vbs/vbs.h
@@ -262,7 +262,7 @@ long virtio_dev_register(struct virtio_dev_info *dev);
long virtio_dev_deregister(struct virtio_dev_info *dev);

/**
- * virtio_vq_index_get - get virtqueue index that frontend kicks
+ * virtio_vqs_index_get - get virtqueue indexes that frontend kicks
*
* This API is normally called in the VBS-K device's callback
* function, to get value write to the "kick" register from
@@ -270,10 +270,14 @@ long virtio_dev_deregister(struct virtio_dev_info *dev);
*
* @dev: Pointer to VBS-K device data struct
* @ioreqs_map: requests bitmap need to handle, provided by VHM
+ * @vqs_index: array to store the vq indexes
+ * @max_vqs_index: size of vqs_index array
*
* Return: >=0 on virtqueue index, <0 on error
*/
-int virtio_vq_index_get(struct virtio_dev_info *dev, unsigned long *ioreqs_map);
+int virtio_vqs_index_get(struct virtio_dev_info *dev,
+ unsigned long *ioreqs_map,
+ int *vqs_index, int max_vqs_index);

/**
* virtio_dev_reset - reset a VBS-K device
--
2.17.0


[PATCH] tools: acrntrace: Add ring buffer mode

Zhipeng Gong <zhipeng.gong@...>
 

When running longevity test and capture acrntrace, generated acrntrace
files sizes are too big.
Sometimes we don't care very old trace. This patch adds ring buffer
mode, fixes acrntrace file size and overwrites old trace with new trace.

Signed-off-by: Zhipeng Gong <zhipeng.gong@...>
---
tools/acrntrace/acrntrace.c | 44 +++++++++++++++++++++++++++++++++++++++++---
tools/acrntrace/acrntrace.h | 1 +
2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/tools/acrntrace/acrntrace.c b/tools/acrntrace/acrntrace.c
index 39fda35..371ffaa 100644
--- a/tools/acrntrace/acrntrace.c
+++ b/tools/acrntrace/acrntrace.c
@@ -37,16 +37,19 @@ static char trace_file_dir[TRACE_FILE_DIR_LEN];

static reader_struct *reader;
static int pcpu_num = 0;
+static int ring_buffer_size = 0;

static void display_usage(void)
{
printf("acrntrace - tool to collect ACRN trace data\n"
- "[Usage] acrntrace [-i] [period in msec] [-ch]\n\n"
+ "[Usage] acrntrace [-i] [period in msec] [-r] [ring buffer size] [-ch]\n\n"
"[Options]\n"
"\t-h: print this message\n"
"\t-i: period_in_ms: specify polling interval [1-999]\n"
"\t-t: max time to capture trace data (in second)\n"
- "\t-c: clear the buffered old data\n");
+ "\t-c: clear the buffered old data\n"
+ "\t-r: ring_buffer_size (in MB): enable ring buffer mode,"
+ " where new trace overwrites old trace when full\n");
}

static void timer_handler(union sigval sv)
@@ -113,6 +116,15 @@ static int parse_opt(int argc, char *argv[])
timeout = ret;
pr_dbg("Capture trace data for at most %ds\n", ret);
break;
+ case 'r':
+ ret = atoi(optarg);
+ if (ret <= 0) {
+ pr_err("'-r' require integer greater than 0\n");
+ return -EINVAL;
+ }
+ ring_buffer_size = ret * 1024 * 1024;
+ pr_dbg("Ring buffer size is %dM\n", ret);
+ break;
case 'c':
flags |= FLAG_CLEAR_BUF;
break;
@@ -206,6 +218,15 @@ static void reader_fn(param_t * param)
trace_ev_t e;
struct statvfs stat;
uint64_t freespace;
+ int pos = 0;
+
+ if (ring_buffer_size != 0) {
+ param->buffer = malloc(ring_buffer_size);
+ if (!param->buffer) {
+ perror("Failed to allocate ring buffer\n");
+ return;
+ }
+ }

pr_dbg("reader thread[%lu] created for FILE*[0x%p]\n",
pthread_self(), fp);
@@ -219,7 +240,13 @@ static void reader_fn(param_t * param)

while (1) {
do {
- ret = sbuf_write(fd, sbuf);
+ if (ring_buffer_size != 0) {
+ ret = sbuf_get(sbuf, param->buffer + pos);
+ pos += sbuf->ele_size;
+ if (pos + sbuf->ele_size > ring_buffer_size)
+ pos = 0;
+ } else
+ ret = sbuf_write(fd, sbuf);
} while (ret > 0);

usleep(period);
@@ -284,6 +311,17 @@ static void destory_reader(reader_struct * reader)
reader->thrd = 0;
}

+ if (ring_buffer_size != 0 && reader->param.buffer) {
+ int ret;
+
+ ret = write(reader->param.trace_fd, reader->param.buffer,
+ ring_buffer_size);
+ if (ret != ring_buffer_size) {
+ perror("Failed to write ring buffer\n");
+ }
+ free(reader->param.buffer);
+ }
+
if (reader->param.sbuf) {
munmap(reader->param.sbuf, MMAP_SIZE);
reader->param.sbuf = NULL;
diff --git a/tools/acrntrace/acrntrace.h b/tools/acrntrace/acrntrace.h
index ea54f4d..6615157 100644
--- a/tools/acrntrace/acrntrace.h
+++ b/tools/acrntrace/acrntrace.h
@@ -76,6 +76,7 @@ typedef struct {
int trace_fd;
shared_buf_t *sbuf;
pthread_mutex_t *sbuf_lock;
+ uint8_t *buffer;
} param_t;

typedef struct {
--
2.7.4


[PATCH v2] HV: handle trusty on vm reset

Victor Sun
 

- clear run context when reset vcpu;

- destroy trusty without erase trusty memory when reset vm;

changelog:
v1 -> v2: fix misra violation on calling memset();

Signed-off-by: Sun Victor <victor.sun@...>
Signed-off-by: Yin Fengwei <fengwei.yin@...>
---
hypervisor/arch/x86/guest/vcpu.c | 7 +++++++
hypervisor/arch/x86/guest/vm.c | 2 ++
2 files changed, 9 insertions(+)

diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c
index 9dc0241..a6746d2 100644
--- a/hypervisor/arch/x86/guest/vcpu.c
+++ b/hypervisor/arch/x86/guest/vcpu.c
@@ -396,6 +396,7 @@ void destroy_vcpu(struct vcpu *vcpu)
*/
void reset_vcpu(struct vcpu *vcpu)
{
+ int i;
struct acrn_vlapic *vlapic;

pr_dbg("vcpu%hu reset", vcpu->vcpu_id);
@@ -419,6 +420,12 @@ void reset_vcpu(struct vcpu *vcpu)
vcpu->arch_vcpu.inject_event_pending = false;
(void)memset(vcpu->arch_vcpu.vmcs, 0U, CPU_PAGE_SIZE);

+ for (i = 0; i < NR_WORLD; i++) {
+ (void)memset(&vcpu->arch_vcpu.contexts[i], 0U,
+ sizeof(struct run_context));
+ }
+ vcpu->arch_vcpu.cur_context = NORMAL_WORLD;
+
vlapic = vcpu->arch_vcpu.vlapic;
vlapic_reset(vlapic);
}
diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c
index 4bfda8e..f2efbf9 100644
--- a/hypervisor/arch/x86/guest/vm.c
+++ b/hypervisor/arch/x86/guest/vm.c
@@ -366,6 +366,8 @@ int reset_vm(struct vm *vm)
}

vioapic_reset(vm->arch_vm.virt_ioapic);
+ destroy_secure_world(vm, false);
+ vm->sworld_control.flag.active = 0UL;

start_vm(vm);
return 0;
--
2.7.4


Re: [PATCH] HV: hv_main: Add #ifdef HV_DEBUG before debug specific code #ifdef

Kaige Fu
 

On 08-13 Mon 07:59, Eddie Dong wrote:
This is part of SBUF component, what kind of compile option do we use? Let us use same one.
shell command "vmexit" is the only one user of vmexit_time/cnt and we use the
get_vmexit_profile, enclosed by HV_DEBUG, to access these variables.

BTW, hcall side also needs this kind of compile option.
I can't follow here. Can you make it more clear.

--
Thanks
Kaige Fu



-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...] On Behalf Of Kaige Fu
Sent: Monday, August 13, 2018 1:28 PM
To: acrn-dev@...
Subject: [acrn-dev] [PATCH] HV: hv_main: Add #ifdef HV_DEBUG before
debug specific code

vmexit_time and vmexit_cnt is used for debuging only.
This patch encloses these debug specific code using #ifdef HV_DEBUG.

Signed-off-by: Kaige Fu <kaige.fu@...>
---
hypervisor/common/hv_main.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hypervisor/common/hv_main.c b/hypervisor/common/hv_main.c
index 15f1d9d..e3657f9 100644
--- a/hypervisor/common/hv_main.c
+++ b/hypervisor/common/hv_main.c
@@ -59,11 +59,13 @@ void vcpu_thread(struct vcpu *vcpu)
continue;
}

+#ifdef HV_DEBUG
vmexit_end = rdtsc();
if (vmexit_begin != 0UL) {
per_cpu(vmexit_time, vcpu->pcpu_id)[basic_exit_reason]
+= (vmexit_end - vmexit_begin);
}
+#endif
TRACE_2L(TRACE_VM_ENTER, 0UL, 0UL);

/* Restore guest TSC_AUX */
@@ -79,7 +81,9 @@ void vcpu_thread(struct vcpu *vcpu)
continue;
}

+#ifdef HV_DEBUG
vmexit_begin = rdtsc();
+#endif

vcpu->arch_vcpu.nrexits++;
/* Save guest TSC_AUX */
@@ -90,16 +94,18 @@ void vcpu_thread(struct vcpu *vcpu)
CPU_IRQ_ENABLE();
/* Dispatch handler */
ret = vmexit_handler(vcpu);
+ basic_exit_reason = vcpu->arch_vcpu.exit_reason & 0xFFFFU;
if (ret < 0) {
pr_fatal("dispatch VM exit handler failed for reason"
- " %d, ret = %d!",
- vcpu->arch_vcpu.exit_reason & 0xFFFFU, ret);
+ " %d, ret = %d!", basic_exit_reason, ret);
vcpu_inject_gp(vcpu, 0U);
continue;
}

- basic_exit_reason = vcpu->arch_vcpu.exit_reason & 0xFFFFU;
+#ifdef HV_DEBUG
per_cpu(vmexit_cnt, vcpu->pcpu_id)[basic_exit_reason]++;
+#endif
+
TRACE_2L(TRACE_VM_EXIT, basic_exit_reason,
vcpu_get_rip(vcpu));
} while (1);
}
--
2.7.4





Re: [PATCH] HV: handle trusty on vm reset

Victor Sun
 

On 8/13/2018 3:55 PM, Mingqiang Chi wrote:

-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...] On Behalf Of Victor Sun
Sent: Monday, August 13, 2018 3:47 PM
To: acrn-dev@...
Subject: [acrn-dev] [PATCH] HV: handle trusty on vm reset

- clear run context when reset vcpu;

- destroy trusty without erase trusty memory when reset vm;

Signed-off-by: Sun Victor <victor.sun@...>
Signed-off-by: Yin Fengwei <fengwei.yin@...>
---
hypervisor/arch/x86/guest/vcpu.c | 7 +++++++
hypervisor/arch/x86/guest/vm.c | 2 ++
2 files changed, 9 insertions(+)

diff --git a/hypervisor/arch/x86/guest/vcpu.c
b/hypervisor/arch/x86/guest/vcpu.c
index 9dc0241..a8a9f0e 100644
--- a/hypervisor/arch/x86/guest/vcpu.c
+++ b/hypervisor/arch/x86/guest/vcpu.c
@@ -396,6 +396,7 @@ void destroy_vcpu(struct vcpu *vcpu)
*/
void reset_vcpu(struct vcpu *vcpu)
{
+ int i;
struct acrn_vlapic *vlapic;

pr_dbg("vcpu%hu reset", vcpu->vcpu_id); @@ -419,6 +420,12 @@ void
reset_vcpu(struct vcpu *vcpu)
vcpu->arch_vcpu.inject_event_pending = false;
(void)memset(vcpu->arch_vcpu.vmcs, 0U, CPU_PAGE_SIZE);

+ for (i = 0; i < NR_WORLD; i++) {
+ memset(&vcpu->arch_vcpu.contexts[i], 0,
+ sizeof(struct run_context));
(void)memset(&vcpu->arch_vcpu.contexts[i], 0U,
sizeof(struct run_context));
Thanks Mingqiang, I will update it soon.

BR,
Victor
+ }
+ vcpu->arch_vcpu.cur_context = NORMAL_WORLD;
+
vlapic = vcpu->arch_vcpu.vlapic;
vlapic_reset(vlapic);
}
diff --git a/hypervisor/arch/x86/guest/vm.c
b/hypervisor/arch/x86/guest/vm.c index 4bfda8e..f2efbf9 100644
--- a/hypervisor/arch/x86/guest/vm.c
+++ b/hypervisor/arch/x86/guest/vm.c
@@ -366,6 +366,8 @@ int reset_vm(struct vm *vm)
}

vioapic_reset(vm->arch_vm.virt_ioapic);
+ destroy_secure_world(vm, false);
+ vm->sworld_control.flag.active = 0UL;

start_vm(vm);
return 0;
--
2.7.4




Re: [PATCH v2 1/3] HV: Add the emulation of CPUID with 0x16 leaf

Eddie Dong
 

Hi Yakui,

ACRN doesn't emulate CPUID >=0x80000000U at all.
So for CPUID >=0x80000000U, ACRN just read from hardware in
guest_cpuid().
init_vcpuid_entry doesn't need to handle CPUID >=0x80000000U.
After Eddie's suggestion is followed to add the limit check(>=0x15 CPUID),
the mentioned check is not needed any more.

I keep them so that the init_vcpuid_entry still can return the zero entry for
the out-of-range CPUID input.

If you think that the check is redundant, I can remove them.
If it is physical out of ranger, returning what hardware returns is better than fixed-zero.

We want the code to be slim to save FuSa effort.

Thx Eddie


Re: [PATCH 3/4] HV: Merge hypervisor debug header files

Eddie Dong
 

The series are fine.
Please go PR with my ACK.

-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...] On Behalf Of Yonghua Huang
Sent: Monday, August 13, 2018 10:12 PM
To: acrn-dev@...
Cc: Huang, Yonghua <yonghua.huang@...>
Subject: [acrn-dev] [PATCH 3/4] HV: Merge hypervisor debug header files

-- merge 'assert.h' & 'printf.h' into 'logmsg.h'
-- merge 'shell.h' into 'console.h'

Signed-off-by: Yonghua Huang <yonghua.huang@...>
---
hypervisor/include/debug/assert.h | 21 ----------------
hypervisor/include/debug/console.h | 9 +++++++
hypervisor/include/debug/logmsg.h | 45
++++++++++++++++++++++++++++++++++
hypervisor/include/debug/printf.h | 49 --------------------------------------
hypervisor/include/debug/shell.h | 21 ----------------
hypervisor/include/hv_debug.h | 3 ---
6 files changed, 54 insertions(+), 94 deletions(-) delete mode 100644
hypervisor/include/debug/assert.h delete mode 100644
hypervisor/include/debug/printf.h delete mode 100644
hypervisor/include/debug/shell.h

diff --git a/hypervisor/include/debug/assert.h
b/hypervisor/include/debug/assert.h
deleted file mode 100644
index b5f170d..0000000
--- a/hypervisor/include/debug/assert.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2018 Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef ASSERT_H
-#define ASSERT_H
-
-#ifdef HV_DEBUG
-void asm_assert(int32_t line, const char *file, const char *txt);
-
-#define ASSERT(x, ...) \
- if (!(x)) {\
- asm_assert(__LINE__, __FILE__, "fatal error");\
- }
-#else
-#define ASSERT(x, ...) do { } while(0)
-#endif
-
-#endif /* ASSERT_H */
diff --git a/hypervisor/include/debug/console.h
b/hypervisor/include/debug/console.h
index 6c491bc..706f5b1 100644
--- a/hypervisor/include/debug/console.h
+++ b/hypervisor/include/debug/console.h
@@ -7,6 +7,9 @@
#ifndef CONSOLE_H
#define CONSOLE_H

+/* Switching key combinations for shell and uart console */
+#define GUEST_CONSOLE_TO_HV_SWITCH_KEY 0 /* CTRL +
SPACE */
+
#ifdef HV_DEBUG
extern struct hv_timer console_timer;

@@ -52,6 +55,9 @@ static inline void resume_console(void) } void
uart16550_set_property(bool enabled, bool port_mapped, uint64_t
base_addr);

+void shell_init(void);
+void shell_kick(void);
+
#else
static inline void console_init(void)
{
@@ -70,6 +76,9 @@ static inline void suspend_console(void) {} static
inline void resume_console(void) {} static inline void
uart16550_set_property(__unused bool enabled,
__unused bool port_mapped, __unused uint64_t base_addr) {}
+
+static inline void shell_init(void) {}
+static inline void shell_kick(void) {}
#endif

#endif /* CONSOLE_H */
diff --git a/hypervisor/include/debug/logmsg.h
b/hypervisor/include/debug/logmsg.h
index 7e1ed70..c8de4c5 100644
--- a/hypervisor/include/debug/logmsg.h
+++ b/hypervisor/include/debug/logmsg.h
@@ -33,6 +33,39 @@ void init_logmsg(__unused uint32_t mem_size,
uint32_t flags); void print_logmsg_buffer(uint16_t pcpu_id); void
do_logmsg(uint32_t severity, const char *fmt, ...);

+void asm_assert(int32_t line, const char *file, const char *txt);
+
+#define ASSERT(x, ...) \
+ do { \
+ if (!(x)) {\
+ asm_assert(__LINE__, __FILE__, "fatal error");\
+ } \
+ } while (0)
+
+/** The well known printf() function.
+ *
+ * Formats a string and writes it to the console output.
+ *
+ * @param fmt A pointer to the NUL terminated format string.
+ *
+ * @return The number of characters actually written or a negative
+ * number if an error occurred.
+ */
+
+int printf(const char *fmt, ...);
+
+/** The well known vprintf() function.
+ *
+ * Formats a string and writes it to the console output.
+ *
+ * @param fmt A pointer to the NUL terminated format string.
+ * @param args The variable long argument list as va_list.
+ * @return The number of characters actually written or a negative
+ * number if an error occurred.
+ */
+
+int vprintf(const char *fmt, va_list args);
+
#else /* HV_DEBUG */

static inline void init_logmsg(__unused uint32_t mem_size, @@ -49,6
+82,18 @@ static inline void print_logmsg_buffer(__unused uint16_t
pcpu_id) { }

+#define ASSERT(x, ...) do { } while (0)
+
+static inline int printf(__unused const char *fmt, ...) {
+ return 0;
+}
+
+static inline int vprintf(__unused const char *fmt, __unused va_list
+args) {
+ return 0;
+}
+
#endif /* HV_DEBUG */

#ifndef pr_prefix
diff --git a/hypervisor/include/debug/printf.h
b/hypervisor/include/debug/printf.h
deleted file mode 100644
index 6e6c911..0000000
--- a/hypervisor/include/debug/printf.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2018 Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PRINTF_H
-#define PRINTF_H
-
-#ifdef HV_DEBUG
-/** The well known printf() function.
- *
- * Formats a string and writes it to the console output.
- *
- * @param fmt A pointer to the NUL terminated format string.
- *
- * @return The number of characters actually written or a negative
- * number if an error occurred.
- */
-
-int printf(const char *fmt, ...);
-
-/** The well known vprintf() function.
- *
- * Formats a string and writes it to the console output.
- *
- * @param fmt A pointer to the NUL terminated format string.
- * @param args The variable long argument list as va_list.
- * @return The number of characters actually written or a negative
- * number if an error occurred.
- */
-
-int vprintf(const char *fmt, va_list args);
-
-#else /* HV_DEBUG */
-
-static inline int printf(__unused const char *fmt, ...) -{
- return 0;
-}
-
-static inline int vprintf(__unused const char *fmt, __unused va_list args) -{
- return 0;
-}
-
-#endif /* HV_DEBUG */
-
-#endif /* PRINTF_H */
diff --git a/hypervisor/include/debug/shell.h
b/hypervisor/include/debug/shell.h
deleted file mode 100644
index 829e0ac..0000000
--- a/hypervisor/include/debug/shell.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2018 Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SHELL_H
-#define SHELL_H
-
-/* Switching key combinations for shell and uart console */
-#define GUEST_CONSOLE_TO_HV_SWITCH_KEY 0 /* CTRL +
SPACE */
-
-#ifdef HV_DEBUG
-void shell_init(void);
-void shell_kick(void);
-#else
-static inline void shell_init(void) {}
-static inline void shell_kick(void) {}
-#endif
-
-#endif /* SHELL_H */
diff --git a/hypervisor/include/hv_debug.h b/hypervisor/include/hv_debug.h
index ff41e32..7198132 100644
--- a/hypervisor/include/hv_debug.h
+++ b/hypervisor/include/hv_debug.h
@@ -12,9 +12,6 @@
#include <console.h>
#include <dump.h>
#include <trace.h>
-#include <shell.h>
#include <sbuf.h>
-#include <assert.h>
-#include <printf.h>

#endif /* HV_DEBUG_H */
--
2.7.4



Re: [PATCH] HV: hv_main: Add #ifdef HV_DEBUG before debug specific code #ifdef

Eddie Dong
 

This is part of SBUF component, what kind of compile option do we use? Let us use same one.

BTW, hcall side also needs this kind of compile option.

-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...] On Behalf Of Kaige Fu
Sent: Monday, August 13, 2018 1:28 PM
To: acrn-dev@...
Subject: [acrn-dev] [PATCH] HV: hv_main: Add #ifdef HV_DEBUG before
debug specific code

vmexit_time and vmexit_cnt is used for debuging only.
This patch encloses these debug specific code using #ifdef HV_DEBUG.

Signed-off-by: Kaige Fu <kaige.fu@...>
---
hypervisor/common/hv_main.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/hypervisor/common/hv_main.c b/hypervisor/common/hv_main.c
index 15f1d9d..e3657f9 100644
--- a/hypervisor/common/hv_main.c
+++ b/hypervisor/common/hv_main.c
@@ -59,11 +59,13 @@ void vcpu_thread(struct vcpu *vcpu)
continue;
}

+#ifdef HV_DEBUG
vmexit_end = rdtsc();
if (vmexit_begin != 0UL) {
per_cpu(vmexit_time, vcpu->pcpu_id)[basic_exit_reason]
+= (vmexit_end - vmexit_begin);
}
+#endif
TRACE_2L(TRACE_VM_ENTER, 0UL, 0UL);

/* Restore guest TSC_AUX */
@@ -79,7 +81,9 @@ void vcpu_thread(struct vcpu *vcpu)
continue;
}

+#ifdef HV_DEBUG
vmexit_begin = rdtsc();
+#endif

vcpu->arch_vcpu.nrexits++;
/* Save guest TSC_AUX */
@@ -90,16 +94,18 @@ void vcpu_thread(struct vcpu *vcpu)
CPU_IRQ_ENABLE();
/* Dispatch handler */
ret = vmexit_handler(vcpu);
+ basic_exit_reason = vcpu->arch_vcpu.exit_reason & 0xFFFFU;
if (ret < 0) {
pr_fatal("dispatch VM exit handler failed for reason"
- " %d, ret = %d!",
- vcpu->arch_vcpu.exit_reason & 0xFFFFU, ret);
+ " %d, ret = %d!", basic_exit_reason, ret);
vcpu_inject_gp(vcpu, 0U);
continue;
}

- basic_exit_reason = vcpu->arch_vcpu.exit_reason & 0xFFFFU;
+#ifdef HV_DEBUG
per_cpu(vmexit_cnt, vcpu->pcpu_id)[basic_exit_reason]++;
+#endif
+
TRACE_2L(TRACE_VM_EXIT, basic_exit_reason,
vcpu_get_rip(vcpu));
} while (1);
}
--
2.7.4



Re: [PATCH] HV: handle trusty on vm reset

Mingqiang Chi
 

-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...] On Behalf Of Victor Sun
Sent: Monday, August 13, 2018 3:47 PM
To: acrn-dev@...
Subject: [acrn-dev] [PATCH] HV: handle trusty on vm reset

- clear run context when reset vcpu;

- destroy trusty without erase trusty memory when reset vm;

Signed-off-by: Sun Victor <victor.sun@...>
Signed-off-by: Yin Fengwei <fengwei.yin@...>
---
hypervisor/arch/x86/guest/vcpu.c | 7 +++++++
hypervisor/arch/x86/guest/vm.c | 2 ++
2 files changed, 9 insertions(+)

diff --git a/hypervisor/arch/x86/guest/vcpu.c
b/hypervisor/arch/x86/guest/vcpu.c
index 9dc0241..a8a9f0e 100644
--- a/hypervisor/arch/x86/guest/vcpu.c
+++ b/hypervisor/arch/x86/guest/vcpu.c
@@ -396,6 +396,7 @@ void destroy_vcpu(struct vcpu *vcpu)
*/
void reset_vcpu(struct vcpu *vcpu)
{
+ int i;
struct acrn_vlapic *vlapic;

pr_dbg("vcpu%hu reset", vcpu->vcpu_id); @@ -419,6 +420,12 @@ void
reset_vcpu(struct vcpu *vcpu)
vcpu->arch_vcpu.inject_event_pending = false;
(void)memset(vcpu->arch_vcpu.vmcs, 0U, CPU_PAGE_SIZE);

+ for (i = 0; i < NR_WORLD; i++) {
+ memset(&vcpu->arch_vcpu.contexts[i], 0,
+ sizeof(struct run_context));
(void)memset(&vcpu->arch_vcpu.contexts[i], 0U,
sizeof(struct run_context));

+ }
+ vcpu->arch_vcpu.cur_context = NORMAL_WORLD;
+
vlapic = vcpu->arch_vcpu.vlapic;
vlapic_reset(vlapic);
}
diff --git a/hypervisor/arch/x86/guest/vm.c
b/hypervisor/arch/x86/guest/vm.c index 4bfda8e..f2efbf9 100644
--- a/hypervisor/arch/x86/guest/vm.c
+++ b/hypervisor/arch/x86/guest/vm.c
@@ -366,6 +366,8 @@ int reset_vm(struct vm *vm)
}

vioapic_reset(vm->arch_vm.virt_ioapic);
+ destroy_secure_world(vm, false);
+ vm->sworld_control.flag.active = 0UL;

start_vm(vm);
return 0;
--
2.7.4



[PATCH] HV: handle trusty on vm reset

Victor Sun
 

- clear run context when reset vcpu;

- destroy trusty without erase trusty memory when reset vm;

Signed-off-by: Sun Victor <victor.sun@...>
Signed-off-by: Yin Fengwei <fengwei.yin@...>
---
hypervisor/arch/x86/guest/vcpu.c | 7 +++++++
hypervisor/arch/x86/guest/vm.c | 2 ++
2 files changed, 9 insertions(+)

diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c
index 9dc0241..a8a9f0e 100644
--- a/hypervisor/arch/x86/guest/vcpu.c
+++ b/hypervisor/arch/x86/guest/vcpu.c
@@ -396,6 +396,7 @@ void destroy_vcpu(struct vcpu *vcpu)
*/
void reset_vcpu(struct vcpu *vcpu)
{
+ int i;
struct acrn_vlapic *vlapic;

pr_dbg("vcpu%hu reset", vcpu->vcpu_id);
@@ -419,6 +420,12 @@ void reset_vcpu(struct vcpu *vcpu)
vcpu->arch_vcpu.inject_event_pending = false;
(void)memset(vcpu->arch_vcpu.vmcs, 0U, CPU_PAGE_SIZE);

+ for (i = 0; i < NR_WORLD; i++) {
+ memset(&vcpu->arch_vcpu.contexts[i], 0,
+ sizeof(struct run_context));
+ }
+ vcpu->arch_vcpu.cur_context = NORMAL_WORLD;
+
vlapic = vcpu->arch_vcpu.vlapic;
vlapic_reset(vlapic);
}
diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c
index 4bfda8e..f2efbf9 100644
--- a/hypervisor/arch/x86/guest/vm.c
+++ b/hypervisor/arch/x86/guest/vm.c
@@ -366,6 +366,8 @@ int reset_vm(struct vm *vm)
}

vioapic_reset(vm->arch_vm.virt_ioapic);
+ destroy_secure_world(vm, false);
+ vm->sworld_control.flag.active = 0UL;

start_vm(vm);
return 0;
--
2.7.4


[PATCH] hv:Fix misra-c return value violations for vioapic APIs

Mingqiang Chi
 

From: Mingqiang Chi <mingqiang.chi@...>

--Changed 4 APIs to void type
vioapic_set_irqstate
vioapic_assert_irq
vioapic_deassert_irq
vioapic_pulse_irq

Signed-off-by: Mingqiang Chi <mingqiang.chi@...>
---
hypervisor/common/hypercall.c | 6 +++---
hypervisor/dm/vioapic.c | 20 +++++++++-----------
hypervisor/include/arch/x86/guest/vioapic.h | 6 +++---
3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c
index f8efb35..110b3b1 100644
--- a/hypervisor/common/hypercall.c
+++ b/hypervisor/common/hypercall.c
@@ -109,13 +109,13 @@ handle_vioapic_irqline(struct vm *vm, uint32_t irq, enum irq_mode mode)

switch (mode) {
case IRQ_ASSERT:
- ret = vioapic_assert_irq(vm, irq);
+ vioapic_assert_irq(vm, irq);
break;
case IRQ_DEASSERT:
- ret = vioapic_deassert_irq(vm, irq);
+ vioapic_deassert_irq(vm, irq);
break;
case IRQ_PULSE:
- ret = vioapic_pulse_irq(vm, irq);
+ vioapic_pulse_irq(vm, irq);
break;
default:
/*
diff --git a/hypervisor/dm/vioapic.c b/hypervisor/dm/vioapic.c
index 4692094..3724be0 100644
--- a/hypervisor/dm/vioapic.c
+++ b/hypervisor/dm/vioapic.c
@@ -150,14 +150,15 @@ enum irqstate {
IRQSTATE_PULSE
};

-static int
+static void
vioapic_set_irqstate(struct vm *vm, uint32_t irq, enum irqstate irqstate)
{
struct vioapic *vioapic;
uint32_t pin = irq;

if (pin >= vioapic_pincount(vm)) {
- return -EINVAL;
+ pr_err("invalid vioapic pin number %hhu", pin);
+ return;
}

vioapic = vm_ioapic(vm);
@@ -178,26 +179,23 @@ vioapic_set_irqstate(struct vm *vm, uint32_t irq, enum irqstate irqstate)
panic("vioapic_set_irqstate: invalid irqstate %d", irqstate);
}
VIOAPIC_UNLOCK(vioapic);
-
- return 0;
}

-int
+void
vioapic_assert_irq(struct vm *vm, uint32_t irq)
{
- return vioapic_set_irqstate(vm, irq, IRQSTATE_ASSERT);
+ vioapic_set_irqstate(vm, irq, IRQSTATE_ASSERT);
}

-int
-vioapic_deassert_irq(struct vm *vm, uint32_t irq)
+void vioapic_deassert_irq(struct vm *vm, uint32_t irq)
{
- return vioapic_set_irqstate(vm, irq, IRQSTATE_DEASSERT);
+ vioapic_set_irqstate(vm, irq, IRQSTATE_DEASSERT);
}

-int
+void
vioapic_pulse_irq(struct vm *vm, uint32_t irq)
{
- return vioapic_set_irqstate(vm, irq, IRQSTATE_PULSE);
+ vioapic_set_irqstate(vm, irq, IRQSTATE_PULSE);
}

/*
diff --git a/hypervisor/include/arch/x86/guest/vioapic.h b/hypervisor/include/arch/x86/guest/vioapic.h
index 98ffc9e..29bb540 100644
--- a/hypervisor/include/arch/x86/guest/vioapic.h
+++ b/hypervisor/include/arch/x86/guest/vioapic.h
@@ -41,9 +41,9 @@ struct vioapic *vioapic_init(struct vm *vm);
void vioapic_cleanup(struct vioapic *vioapic);
void vioapic_reset(struct vioapic *vioapic);

-int vioapic_assert_irq(struct vm *vm, uint32_t irq);
-int vioapic_deassert_irq(struct vm *vm, uint32_t irq);
-int vioapic_pulse_irq(struct vm *vm, uint32_t irq);
+void vioapic_assert_irq(struct vm *vm, uint32_t irq);
+void vioapic_deassert_irq(struct vm *vm, uint32_t irq);
+void vioapic_pulse_irq(struct vm *vm, uint32_t irq);
void vioapic_update_tmr(struct vcpu *vcpu);

void vioapic_mmio_write(struct vm *vm, uint64_t gpa, uint32_t wval);
--
2.7.4


Re: [PATCH V3 0/3] Tools: fixed issues for S3 feature

Yan, Like
 

Reviewed-by: Yan, Like <like.yan@...>

On Mon, Aug 13, 2018 at 10:28:47PM +0800, Tao, Yuhong wrote:
With these changes, S3 feature works.

changes in V2:
1.fixed get_sos_wakeup_reason() in acrnd.c
2.fixed handle_resume() in monitor.c
changes in V3:
1.wakeup reason is unsigned int

yuhong.tao@... (3):
tools: vm_resume() requires wakeup reason
tools: acrnd: Fixed get_sos_wakeup_reason()
dm: monotor: bugfix: update wakeup reason before call recume()
callback

devicemodel/core/monitor.c | 4 ++--
tools/acrn-manager/acrn_mngr.h | 2 +-
tools/acrn-manager/acrn_vm_ops.c | 4 +++-
tools/acrn-manager/acrnctl.c | 34 +++++++++++++++++++---------------
tools/acrn-manager/acrnctl.h | 2 +-
tools/acrn-manager/acrnd.c | 11 ++++++++---
6 files changed, 34 insertions(+), 23 deletions(-)

--
2.7.4




Re: [PATCH] drm/i915/gvt: fix display messy issue which is introduced by plane pvmmio

Fei Jiang
 

Got it. Will simplify the description when submit PR.

-----Original Message-----
From: He, Min
Sent: Monday, August 13, 2018 3:13 PM
To: acrn-dev@...
Cc: Jiang, Fei <fei.jiang@...>
Subject: RE: [acrn-dev] [PATCH] drm/i915/gvt: fix display messy issue which is introduced by plane pvmmio

LGTM. But I don't think we need to talk about the reason of why it's missed in previous patch.

Reviewed-by: He, Min <min.he@...>


-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...]
On Behalf Of Fei Jiang
Sent: Monday, August 13, 2018 2:36 PM
To: acrn-dev@...
Cc: Jiang, Fei <fei.jiang@...>
Subject: [acrn-dev] [PATCH] drm/i915/gvt: fix display messy issue
which is introduced by plane pvmmio

For plane pvmmio optimization, we need cache all plane related
registers, in previous commit 9c3e8b1a3f15 ("drm/i915/gvt: handling
pvmmio update of plane registers in GVT-g"), due to PLANE_AUX_DIST and
PLANE_AUX_OFFSET are trapped with _REG_701C0 and _REG_701C4, then they
are missing by only checking PLANE_AUX_DIST and PLANE_AUX_OFFSET.

Signed-off-by: Fei Jiang <fei.jiang@...>
---
drivers/gpu/drm/i915/gvt/handlers.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/gvt/handlers.c
b/drivers/gpu/drm/i915/gvt/handlers.c
index c33c771..6001127 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -777,6 +777,12 @@ static void pvmmio_update_plane_register(struct
intel_vgpu *vgpu,
skl_plane_mmio_write(vgpu,
i915_mmio_reg_offset(PLANE_SIZE(pipe, plane)),
&pv_plane->plane_size, 4);
+ skl_plane_mmio_write(vgpu,
+ i915_mmio_reg_offset(PLANE_AUX_DIST(pipe, plane)),
+ &pv_plane.plane_aux_dist, 4);
+ skl_plane_mmio_write(vgpu,
+ i915_mmio_reg_offset(PLANE_AUX_OFFSET(pipe, plane)),
+ &pv_plane.plane_aux_offset, 4);

if (pv_plane->flags & PLANE_SCALER_BIT) {
skl_ps_mmio_write(vgpu,
--
2.7.4



Re: [PATCH] drm/i915/gvt: fix display messy issue which is introduced by plane pvmmio

He, Min <min.he@...>
 

LGTM. But I don't think we need to talk about the reason of why it's missed in
previous patch.

Reviewed-by: He, Min <min.he@...>

-----Original Message-----
From: acrn-dev@... [mailto:acrn-dev@...]
On Behalf Of Fei Jiang
Sent: Monday, August 13, 2018 2:36 PM
To: acrn-dev@...
Cc: Jiang, Fei <fei.jiang@...>
Subject: [acrn-dev] [PATCH] drm/i915/gvt: fix display messy issue which is
introduced by plane pvmmio

For plane pvmmio optimization, we need cache all plane related registers,
in previous commit 9c3e8b1a3f15 ("drm/i915/gvt: handling pvmmio update
of
plane registers in GVT-g"), due to PLANE_AUX_DIST and PLANE_AUX_OFFSET
are
trapped with _REG_701C0 and _REG_701C4, then they are missing by only
checking PLANE_AUX_DIST and PLANE_AUX_OFFSET.

Signed-off-by: Fei Jiang <fei.jiang@...>
---
drivers/gpu/drm/i915/gvt/handlers.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/gvt/handlers.c
b/drivers/gpu/drm/i915/gvt/handlers.c
index c33c771..6001127 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -777,6 +777,12 @@ static void pvmmio_update_plane_register(struct
intel_vgpu *vgpu,
skl_plane_mmio_write(vgpu,
i915_mmio_reg_offset(PLANE_SIZE(pipe, plane)),
&pv_plane->plane_size, 4);
+ skl_plane_mmio_write(vgpu,
+ i915_mmio_reg_offset(PLANE_AUX_DIST(pipe, plane)),
+ &pv_plane.plane_aux_dist, 4);
+ skl_plane_mmio_write(vgpu,
+ i915_mmio_reg_offset(PLANE_AUX_OFFSET(pipe, plane)),
+ &pv_plane.plane_aux_offset, 4);

if (pv_plane->flags & PLANE_SCALER_BIT) {
skl_ps_mmio_write(vgpu,
--
2.7.4



Re: [PATCH] drm/i915/gvt: fix display messy issue which is introduced by plane pvmmio

Zhao, Yakui
 

-----Original Message-----
From: acrn-dev@... [mailto:acrn-dev@...]
On Behalf Of Fei Jiang
Sent: Monday, August 13, 2018 2:36 PM
To: acrn-dev@...
Cc: Jiang, Fei <fei.jiang@...>
Subject: [acrn-dev] [PATCH] drm/i915/gvt: fix display messy issue which is
introduced by plane pvmmio

For plane pvmmio optimization, we need cache all plane related registers, in
previous commit 9c3e8b1a3f15 ("drm/i915/gvt: handling pvmmio update of
plane registers in GVT-g"), due to PLANE_AUX_DIST and PLANE_AUX_OFFSET
are trapped with _REG_701C0 and _REG_701C4, then they are missing by only
checking PLANE_AUX_DIST and PLANE_AUX_OFFSET.
LGTM.

Add: Reviewed-by: Zhao Yakui <yakui.zhao@...>


Signed-off-by: Fei Jiang <fei.jiang@...>
---
drivers/gpu/drm/i915/gvt/handlers.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/gvt/handlers.c
b/drivers/gpu/drm/i915/gvt/handlers.c
index c33c771..6001127 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -777,6 +777,12 @@ static void pvmmio_update_plane_register(struct
intel_vgpu *vgpu,
skl_plane_mmio_write(vgpu,
i915_mmio_reg_offset(PLANE_SIZE(pipe, plane)),
&pv_plane->plane_size, 4);
+ skl_plane_mmio_write(vgpu,
+ i915_mmio_reg_offset(PLANE_AUX_DIST(pipe, plane)),
+ &pv_plane.plane_aux_dist, 4);
+ skl_plane_mmio_write(vgpu,
+ i915_mmio_reg_offset(PLANE_AUX_OFFSET(pipe, plane)),
+ &pv_plane.plane_aux_offset, 4);

if (pv_plane->flags & PLANE_SCALER_BIT) {
skl_ps_mmio_write(vgpu,
--
2.7.4



Re: [PATCH v2 2/3] HV: Use the pre-defined value to calculate tsc when cpuid(0x15) returns zero ecx

Zhao, Yakui
 

-----Original Message-----
From: acrn-dev@... [mailto:acrn-dev@...]
On Behalf Of Xu, Anthony
Sent: Saturday, August 11, 2018 5:29 AM
To: acrn-dev@...; Dong, Eddie <eddie.dong@...>
Subject: Re: [acrn-dev] [PATCH v2 2/3] HV: Use the pre-defined value to
calculate tsc when cpuid(0x15) returns zero ecx

Subject: RE: [acrn-dev] [PATCH v2 2/3] HV: Use the pre-defined value
to calculate tsc when cpuid(0x15) returns zero ecx


The CPUID (0x15) can be used to calculate the tsc. It is faster and accurate.
The ecx indicates the nominal frequency of core crystal in HZ.
But on some platforms the zero ecx is returned by the 0x15 CPUID.
In fact it should use the pre-defined crystal ref to calculate the tsc_hz.
Hi Yakui:
On what platform, do we see this case? How popular is it?
My thinking is that, if it is not often, we may prefer to fall back
to tsc calibration to keep the code simple.
We see this issue on KBL NUC machine.
If we check 0x16 first , do we still need this patch?
As the pre-defined value is too hack, this patch is removed.

Instead after it fails on CPUID 0x15, it will try the CPUID 0x16 to calculate the tsc.




Anthony



Thx Eddie


Signed-off-by: Zhao Yakui <yakui.zhao@...>
---
hypervisor/arch/x86/timer.c | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/hypervisor/arch/x86/timer.c
b/hypervisor/arch/x86/timer.c index cd88df7..2f0d53c 100644
--- a/hypervisor/arch/x86/timer.c
+++ b/hypervisor/arch/x86/timer.c
@@ -289,6 +289,18 @@ static uint64_t native_calibrate_tsc(void)
&ecx_hz, &reserved);

if (eax_denominator != 0U && ebx_numerator != 0U) {
+ if (ecx_hz == 0) {
+ /* ecx is the nominal frequency of core
+ * crystal in Hz.
+ * If it is zero, use the pre-defined value.
+ */
+ ecx_hz = 24000000U;
+ if (boot_cpu_data.model == 0x5FU) {
+ ecx_hz = 25000000U;
+ } else if (boot_cpu_data.model == 0x5CU) {
+ ecx_hz = 19200000U;
+ }
+ }
return ((uint64_t) ecx_hz *
ebx_numerator) / eax_denominator;
}
--
2.7.4





Re: [PATCH v2 1/3] HV: Add the emulation of CPUID with 0x16 leaf

Zhao, Yakui
 

-----Original Message-----
From: Xu, Anthony
Sent: Saturday, August 11, 2018 5:47 AM
To: acrn-dev@...
Cc: Zhao, Yakui <yakui.zhao@...>
Subject: RE: [acrn-dev] [PATCH v2 1/3] HV: Add the emulation of CPUID with
0x16 leaf

Hi Yakui,

ACRN doesn't emulate CPUID >=0x80000000U at all.
So for CPUID >=0x80000000U, ACRN just read from hardware in guest_cpuid().
init_vcpuid_entry doesn't need to handle CPUID >=0x80000000U.
After Eddie's suggestion is followed to add the limit check(>=0x15 CPUID), the mentioned check is not needed any more.

I keep them so that the init_vcpuid_entry still can return the zero entry for the out-of-range CPUID input.

If you think that the check is redundant, I can remove them.



Anthony



-----Original Message-----
From: acrn-dev@...
[mailto:acrn-dev@...]
On Behalf Of Zhao, Yakui
Sent: Thursday, August 9, 2018 11:44 PM
To: acrn-dev@...
Cc: Zhao, Yakui <yakui.zhao@...>
Subject: [acrn-dev] [PATCH v2 1/3] HV: Add the emulation of CPUID with
0x16 leaf

The CPUID with 0x16 leaf can report the CPU khz and it is faster. And
this mechanism is widely used in Linux kernel.(native_calibrate_cpu).
As this is not supported on APL, currently sos adds the cpu_khz
callback in pv_cpu_ops to read the cpu frequency. This is quite hack.
(In fact HV leverages the cpuid with 0x40000010 leaf).
If it is emulated, the sos and guest os can use the cpuid to obtain
the corresponding cpu_khz. Then the cpu_khz in pv_cpu_ops can be
removed.

V2: Simple the logic of adding unsupported cpuid level entry after the
CPUID 0x16 is emulated. Initialize the vcpuid_entry explicitly with
zero for the unsupported cpuid.

Signed-off-by: Zhao Yakui <yakui.zhao@...>
---
hypervisor/arch/x86/cpuid.c | 53
++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/hypervisor/arch/x86/cpuid.c b/hypervisor/arch/x86/cpuid.c
index 18ebfcc..6d53a30 100644
--- a/hypervisor/arch/x86/cpuid.c
+++ b/hypervisor/arch/x86/cpuid.c
@@ -119,6 +119,21 @@ static void init_vcpuid_entry(__unused struct vm
*vm,
entry->ecx = 0U;
entry->edx = 0U;
break;
+ case 0x16U:
+ if (boot_cpu_data.cpuid_level >= 0x16U) {
+ /* call the cpuid when 0x16 is supported */
+ cpuid_subleaf(leaf, subleaf,
+ &entry->eax, &entry->ebx,
+ &entry->ecx, &entry->edx);
+ } else {
+ /* Use the tsc to derive the emulated 0x16U cpuid.
*/
+ entry->eax = (uint32_t) (tsc_khz / 1000U);
+ entry->ebx = entry->eax;
+ /* Bus frequency: hard coded to 100M */
+ entry->ecx = 100U;
+ entry->edx = 0U;
+ }
+ break;

/*
* Leaf 0x40000000
@@ -158,9 +173,36 @@ static void init_vcpuid_entry(__unused struct vm
*vm,
break;

default:
- cpuid_subleaf(leaf, subleaf,
- &entry->eax, &entry->ebx,
- &entry->ecx, &entry->edx);
+ if (leaf >= 0x80000000U) {
+ /* unsupported extended cpuid level */
+ if (leaf > boot_cpu_data.extended_cpuid_level) {
+ entry->eax = 0U;
+ entry->ebx = 0U;
+ entry->ecx = 0U;
+ entry->edx = 0U;
+ } else {
+ cpuid_subleaf(leaf, subleaf,
+ &entry->eax, &entry->ebx,
+ &entry->ecx, &entry->edx);
+ }
+ } else if (leaf >= 0x40000000U) {
+ entry->eax = 0U;
+ entry->ebx = 0U;
+ entry->ecx = 0U;
+ entry->edx = 0U;
+ } else {
+ /* unsupported cpuid level */
+ if (leaf > boot_cpu_data.cpuid_level) {
+ entry->eax = 0U;
+ entry->ebx = 0U;
+ entry->ecx = 0U;
+ entry->edx = 0U;
+ } else {
+ cpuid_subleaf(leaf, subleaf,
+ &entry->eax, &entry->ebx,
+ &entry->ecx, &entry->edx);
+ }
+ }
break;
}
}
@@ -173,6 +215,11 @@ int set_vcpuid_entries(struct vm *vm)
uint32_t i, j;

init_vcpuid_entry(vm, 0U, 0U, 0U, &entry);
+ if (boot_cpu_data.cpuid_level < 0x16U) {
+ /* The cpuid with zero leaf returns the max level.
+ * Emulate that the 0x16U is supported */
+ entry.eax = 0x16U;
+ }
result = set_vcpuid_entry(vm, &entry);
if (result != 0) {
return result;
--
2.7.4



[PATCH 2/2] vhm: add irqfd support for ACRN hypervisor service module

Shuo A Liu
 

irqfd which is based on eventfd, provides a pipe for injecting guest
interrupt through a file description writing operation.

Each irqfd registered by userspace can map a interrupt of the guest
to eventfd, and a writing operation on one side of the eventfd will
trigger the interrupt injection on vhm side.

Signed-off-by: Shuo Liu <shuo.a.liu@...>
---
drivers/char/vhm/vhm_dev.c | 11 ++
drivers/vhm/Makefile | 2 +-
drivers/vhm/vhm_irqfd.c | 320 +++++++++++++++++++++++++++++++++++++
include/linux/vhm/vhm_eventfd.h | 6 +
include/linux/vhm/vhm_ioctl_defs.h | 8 +
5 files changed, 346 insertions(+), 1 deletion(-)
create mode 100644 drivers/vhm/vhm_irqfd.c

diff --git a/drivers/char/vhm/vhm_dev.c b/drivers/char/vhm/vhm_dev.c
index 0ffd3b9..9e0a6e4 100644
--- a/drivers/char/vhm/vhm_dev.c
+++ b/drivers/char/vhm/vhm_dev.c
@@ -235,6 +235,7 @@ static long vhm_dev_ioctl(struct file *filep,
}

acrn_ioeventfd_init(vm->vmid);
+ acrn_irqfd_init(vm->vmid);

pr_info("vhm: VM %d created\n", created_vm.vmid);
break;
@@ -276,6 +277,7 @@ static long vhm_dev_ioctl(struct file *filep,

case IC_DESTROY_VM: {
acrn_ioeventfd_deinit(vm->vmid);
+ acrn_irqfd_deinit(vm->vmid);
if (vm->trusty_host_gpa)
deinit_trusty(vm);
ret = hcall_destroy_vm(vm->vmid);
@@ -634,6 +636,15 @@ static long vhm_dev_ioctl(struct file *filep,
break;
}

+ case IC_EVENT_IRQFD: {
+ struct acrn_irqfd args;
+
+ if (copy_from_user(&args, (void *)ioctl_param, sizeof(args)))
+ return -EFAULT;
+ ret = acrn_irqfd(vm->vmid, &args);
+ break;
+ }
+
default:
pr_warn("Unknown IOCTL 0x%x\n", ioctl_num);
ret = 0;
diff --git a/drivers/vhm/Makefile b/drivers/vhm/Makefile
index a25c65d..67a2243 100644
--- a/drivers/vhm/Makefile
+++ b/drivers/vhm/Makefile
@@ -1 +1 @@
-obj-y += vhm_mm.o vhm_hugetlb.o vhm_ioreq.o vhm_vm_mngt.o vhm_msi.o vhm_hypercall.o vhm_ioeventfd.o
+obj-y += vhm_mm.o vhm_hugetlb.o vhm_ioreq.o vhm_vm_mngt.o vhm_msi.o vhm_hypercall.o vhm_ioeventfd.o vhm_irqfd.o
diff --git a/drivers/vhm/vhm_irqfd.c b/drivers/vhm/vhm_irqfd.c
new file mode 100644
index 0000000..9795893
--- /dev/null
+++ b/drivers/vhm/vhm_irqfd.c
@@ -0,0 +1,320 @@
+#include <linux/syscalls.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/file.h>
+#include <linux/list.h>
+#include <linux/eventfd.h>
+#include <linux/kernel.h>
+#include <linux/async.h>
+#include <linux/slab.h>
+
+#include <linux/vhm/acrn_common.h>
+#include <linux/vhm/acrn_vhm_ioreq.h>
+#include <linux/vhm/vhm_vm_mngt.h>
+#include <linux/vhm/vhm_ioctl_defs.h>
+#include <linux/vhm/vhm_hypercall.h>
+
+static LIST_HEAD(vhm_irqfd_clients);
+static DEFINE_MUTEX(vhm_irqfds_mutex);
+static ASYNC_DOMAIN_EXCLUSIVE(irqfd_domain);
+
+struct acrn_vhm_irqfd {
+ struct vhm_irqfd_info *info;
+ wait_queue_entry_t wait;
+ struct work_struct shutdown;
+ struct eventfd_ctx *eventfd;
+ struct list_head list;
+ poll_table pt;
+ struct acrn_msi_entry msi;
+};
+
+struct vhm_irqfd_info {
+ struct list_head list;
+ int refcnt;
+ uint16_t vmid;
+ struct workqueue_struct *wq;
+
+ struct list_head irqfds;
+ spinlock_t irqfds_lock;
+};
+
+static struct vhm_irqfd_info *find_get_irqfd_info_by_vm(uint16_t vmid)
+{
+ struct vhm_irqfd_info *info = NULL;
+
+ mutex_lock(&vhm_irqfds_mutex);
+ list_for_each_entry(info, &vhm_irqfd_clients, list) {
+ if (info->vmid == vmid) {
+ info->refcnt++;
+ mutex_unlock(&vhm_irqfds_mutex);
+ return info;
+ }
+ }
+ mutex_unlock(&vhm_irqfds_mutex);
+ return NULL;
+}
+
+static void put_irqfd_info(struct vhm_irqfd_info *info)
+{
+ mutex_lock(&vhm_irqfds_mutex);
+ info->refcnt--;
+ if (info->refcnt == 0) {
+ list_del(&info->list);
+ kfree(info);
+ }
+ mutex_unlock(&vhm_irqfds_mutex);
+}
+
+static void vhm_irqfd_inject(struct acrn_vhm_irqfd *irqfd)
+{
+ struct vhm_irqfd_info *info = irqfd->info;
+
+ vhm_inject_msi(info->vmid, irqfd->msi.msi_addr,
+ irqfd->msi.msi_data);
+}
+
+/*
+ * Try to find if the irqfd still in list info->irqfds
+ *
+ * assumes info->irqfds_lock is held
+ */
+static bool vhm_irqfd_is_active(struct vhm_irqfd_info *info,
+ struct acrn_vhm_irqfd *irqfd)
+{
+ struct acrn_vhm_irqfd *_irqfd;
+
+ list_for_each_entry(_irqfd, &info->irqfds, list)
+ if (_irqfd == irqfd)
+ return true;
+
+ return false;
+}
+
+/*
+ * Remove irqfd and free it.
+ *
+ * assumes info->irqfds_lock is held
+ */
+static void vhm_irqfd_shutdown(struct acrn_vhm_irqfd *irqfd)
+{
+ u64 cnt;
+
+ /* remove from wait queue */
+ list_del_init(&irqfd->list);
+ eventfd_ctx_remove_wait_queue(irqfd->eventfd, &irqfd->wait, &cnt);
+ eventfd_ctx_put(irqfd->eventfd);
+ kfree(irqfd);
+}
+
+static void vhm_irqfd_shutdown_work(struct work_struct *work)
+{
+ unsigned long flags;
+ struct acrn_vhm_irqfd *irqfd =
+ container_of(work, struct acrn_vhm_irqfd, shutdown);
+ struct vhm_irqfd_info *info = irqfd->info;
+
+ spin_lock_irqsave(&info->irqfds_lock, flags);
+ if (vhm_irqfd_is_active(info, irqfd))
+ vhm_irqfd_shutdown(irqfd);
+ spin_unlock_irqrestore(&info->irqfds_lock, flags);
+}
+
+/*
+ * Called with wqh->lock held and interrupts disabled
+ */
+static int vhm_irqfd_wakeup(wait_queue_entry_t *wait, unsigned mode,
+ int sync, void *key)
+{
+ struct acrn_vhm_irqfd *irqfd =
+ container_of(wait, struct acrn_vhm_irqfd, wait);
+ unsigned long poll_bits = (unsigned long)key;
+ struct vhm_irqfd_info *info = irqfd->info;
+
+ if (poll_bits & POLLIN)
+ /* An event has been signaled, inject an interrupt */
+ vhm_irqfd_inject(irqfd);
+
+ if (poll_bits & POLLHUP)
+ /* async close eventfd as shutdown need hold wqh->lock */
+ queue_work(info->wq, &irqfd->shutdown);
+
+ return 0;
+}
+
+static void vhm_irqfd_poll_func(struct file *file,
+ wait_queue_head_t *wqh, poll_table *pt)
+{
+ struct acrn_vhm_irqfd *irqfd =
+ container_of(pt, struct acrn_vhm_irqfd, pt);
+ add_wait_queue(wqh, &irqfd->wait);
+}
+
+static int acrn_irqfd_assign(struct vhm_irqfd_info *info,
+ struct acrn_irqfd *args)
+{
+ struct acrn_vhm_irqfd *irqfd, *tmp;
+ struct fd f;
+ struct eventfd_ctx *eventfd = NULL;
+ int ret = 0;
+ unsigned int events;
+
+ irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
+ if (!irqfd)
+ return -ENOMEM;
+
+ irqfd->info = info;
+ memcpy(&irqfd->msi, &args->msi, sizeof(args->msi));
+ INIT_LIST_HEAD(&irqfd->list);
+ INIT_WORK(&irqfd->shutdown, vhm_irqfd_shutdown_work);
+
+ f = fdget(args->fd);
+ if (!f.file) {
+ ret = -EBADF;
+ goto out;
+ }
+
+ eventfd = eventfd_ctx_fileget(f.file);
+ if (IS_ERR(eventfd)) {
+ ret = PTR_ERR(eventfd);
+ goto fail;
+ }
+
+ irqfd->eventfd = eventfd;
+
+ /*
+ * Install our own custom wake-up handling so we are notified via
+ * a callback whenever someone signals the underlying eventfd
+ */
+ init_waitqueue_func_entry(&irqfd->wait, vhm_irqfd_wakeup);
+ init_poll_funcptr(&irqfd->pt, vhm_irqfd_poll_func);
+
+ spin_lock_irq(&info->irqfds_lock);
+
+ list_for_each_entry(tmp, &info->irqfds, list) {
+ if (irqfd->eventfd != tmp->eventfd)
+ continue;
+ /* This fd is used for another irq already. */
+ ret = -EBUSY;
+ spin_unlock_irq(&info->irqfds_lock);
+ goto fail;
+ }
+ list_add_tail(&irqfd->list, &info->irqfds);
+
+ spin_unlock_irq(&info->irqfds_lock);
+
+ /* Check the pending event in this stage */
+ events = f.file->f_op->poll(f.file, &irqfd->pt);
+
+ if (events & POLLIN)
+ vhm_irqfd_inject(irqfd);
+
+ fdput(f);
+
+ return 0;
+fail:
+ if (eventfd && !IS_ERR(eventfd))
+ eventfd_ctx_put(eventfd);
+
+ fdput(f);
+out:
+ kfree(irqfd);
+ return ret;
+}
+
+static int acrn_irqfd_deassign(struct vhm_irqfd_info *info,
+ struct acrn_irqfd *args)
+{
+ struct acrn_vhm_irqfd *irqfd, *tmp;
+ struct eventfd_ctx *eventfd;
+
+ eventfd = eventfd_ctx_fdget(args->fd);
+ if (IS_ERR(eventfd))
+ return PTR_ERR(eventfd);
+
+ spin_lock_irq(&info->irqfds_lock);
+
+ list_for_each_entry_safe(irqfd, tmp, &info->irqfds, list) {
+ if (irqfd->eventfd == eventfd) {
+ vhm_irqfd_shutdown(irqfd);
+ break;
+ }
+ }
+
+ spin_unlock_irq(&info->irqfds_lock);
+ eventfd_ctx_put(eventfd);
+
+ return 0;
+}
+
+int acrn_irqfd(uint16_t vmid, struct acrn_irqfd *args)
+{
+ struct vhm_irqfd_info *info;
+ int ret;
+
+ info = find_get_irqfd_info_by_vm(vmid);
+ if (!info)
+ return -ENOENT;
+
+ if (args->flags & ACRN_IRQFD_FLAG_DEASSIGN)
+ ret = acrn_irqfd_deassign(info, args);
+ else
+ ret = acrn_irqfd_assign(info, args);
+
+ put_irqfd_info(info);
+ return ret;
+}
+
+int acrn_irqfd_init(uint16_t vmid)
+{
+ struct vhm_irqfd_info *info;
+
+ info = find_get_irqfd_info_by_vm(vmid);
+ if (info) {
+ put_irqfd_info(info);
+ return -EEXIST;
+ }
+
+ info = kzalloc(sizeof(struct vhm_irqfd_info), GFP_KERNEL);
+ if (!info) {
+ pr_err("ACRN vhm irqfd init fail!\n");
+ return -ENOMEM;
+ }
+ info->vmid = vmid;
+ info->refcnt = 1;
+ INIT_LIST_HEAD(&info->irqfds);
+ spin_lock_init(&info->irqfds_lock);
+
+ info->wq = alloc_workqueue("acrn_irqfd-%d", 0, 0, vmid);
+ if (!info->wq) {
+ kfree(info);
+ return -ENOMEM;
+ }
+
+ mutex_lock(&vhm_irqfds_mutex);
+ list_add(&info->list, &vhm_irqfd_clients);
+ mutex_unlock(&vhm_irqfds_mutex);
+
+ pr_info("ACRN vhm irqfd init done!\n");
+ return 0;
+}
+
+void acrn_irqfd_deinit(uint16_t vmid)
+{
+ struct acrn_vhm_irqfd *irqfd, *tmp;
+ struct vhm_irqfd_info *info;
+
+ info = find_get_irqfd_info_by_vm(vmid);
+ if (!info)
+ return;
+ put_irqfd_info(info);
+
+ destroy_workqueue(info->wq);
+
+ spin_lock_irq(&info->irqfds_lock);
+ list_for_each_entry_safe(irqfd, tmp, &info->irqfds, list)
+ vhm_irqfd_shutdown(irqfd);
+ spin_unlock_irq(&info->irqfds_lock);
+
+ /* put one more to release it */
+ put_irqfd_info(info);
+}
diff --git a/include/linux/vhm/vhm_eventfd.h b/include/linux/vhm/vhm_eventfd.h
index 3c73194..7ee5843 100644
--- a/include/linux/vhm/vhm_eventfd.h
+++ b/include/linux/vhm/vhm_eventfd.h
@@ -7,4 +7,10 @@ int acrn_ioeventfd_init(int vmid);
int acrn_ioeventfd(int vmid, struct acrn_ioeventfd *args);
void acrn_ioeventfd_deinit(int vmid);

+/* irqfd APIs */
+struct acrn_irqfd;
+int acrn_irqfd_init(uint16_t vmid);
+int acrn_irqfd(uint16_t vmid, struct acrn_irqfd *args);
+void acrn_irqfd_deinit(uint16_t vmid);
+
#endif
diff --git a/include/linux/vhm/vhm_ioctl_defs.h b/include/linux/vhm/vhm_ioctl_defs.h
index ac62f1a..3cd0a00 100644
--- a/include/linux/vhm/vhm_ioctl_defs.h
+++ b/include/linux/vhm/vhm_ioctl_defs.h
@@ -111,6 +111,7 @@
/* VHM eventfd */
#define IC_ID_EVENT_BASE 0x70UL
#define IC_EVENT_IOEVENTFD _IC_ID(IC_ID, IC_ID_EVENT_BASE + 0x00)
+#define IC_EVENT_IRQFD _IC_ID(IC_ID, IC_ID_EVENT_BASE + 0x01)

/**
* struct vm_memseg - memory segment info for guest
@@ -228,4 +229,11 @@ struct acrn_ioeventfd {
uint32_t len;
uint64_t data;
};
+
+#define ACRN_IRQFD_FLAG_DEASSIGN 0x01
+struct acrn_irqfd {
+ int32_t fd;
+ uint32_t flags;
+ struct acrn_msi_entry msi;
+};
#endif /* __VHM_IOCTL_DEFS_H__ */
--
2.8.3