Re: [RFC PATCH 08/15] drivers/acrn: add VM memory management for ACRN char device

2019-08-19 Thread Zhao, Yakui




On 2019年08月19日 15:39, Dan Carpenter wrote:

On Mon, Aug 19, 2019 at 01:32:54PM +0800, Zhao, Yakui wrote:

In fact as this driver is mainly used for embedded IOT usage, it doesn't
handle the complex cleanup when such error is encountered. Instead the clean
up is handled in free_guest_vm.


A use after free here seems like a potential security problem.  Security
matters for IoT...  :(


Thanks for pointing out the issue.
The cleanup will be considered carefully.



regards,
dan carpenter



Re: [RFC PATCH 15/15] drivers/acrn: add the support of offline SOS cpu

2019-08-19 Thread Zhao, Yakui




On 2019年08月19日 18:34, Dan Carpenter wrote:

On Fri, Aug 16, 2019 at 10:25:56AM +0800, Zhao Yakui wrote:

diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index 0602125..6868003 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -588,6 +588,41 @@ static const struct file_operations fops = {
  #define SUPPORT_HV_API_VERSION_MAJOR  1
  #define SUPPORT_HV_API_VERSION_MINOR  0
  
+static ssize_t

+offline_cpu_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+#ifdef CONFIG_X86
+   u64 cpu, lapicid;
+
+   if (kstrtoull(buf, 0, &cpu) < 0)
+   return -EINVAL;




Thanks for the review.

Make sense.
The error code will be preserved.


Preserve the error code.

ret = kstrtoull(buf, 0, &cpu);
if (ret)
return ret;






+
+   if (cpu_possible(cpu)) {


You can't pass unchecked cpu values to cpu_possible() or it results in
an out of bounds read if cpu is >= than nr_cpu_ids.



OK. It will add the check of "cpu < num_possibles_cpu()" to avoid the 
out of bounds.



regards,
dan carpenter



Re: [RFC PATCH 00/15] acrn: add the ACRN driver module

2019-08-18 Thread Zhao, Yakui




On 2019年08月19日 13:25, Greg KH wrote:

On Mon, Aug 19, 2019 at 09:44:25AM +0800, Zhao, Yakui wrote:



On 2019年08月16日 14:39, Borislav Petkov wrote:

On Fri, Aug 16, 2019 at 10:25:41AM +0800, Zhao Yakui wrote:

The first three patches are the changes under x86/acrn, which adds the
required APIs for the driver and reports the X2APIC caps.
The remaining patches add the ACRN driver module, which accepts the ioctl
from user-space and then communicate with the low-level ACRN hypervisor
by using hypercall.


I have a problem with that: you're adding interfaces to arch/x86/ and
its users go into staging. Why? Why not directly put the driver where
it belongs, clean it up properly and submit it like everything else is
submitted?


Thanks for your reply and the concern.

After taking a look at several driver examples(gma500, android), it seems
that they are firstly added into drivers/staging/XXX and then moved to
drivers/XXX after the driver becomes mature.
So we refer to this method to upstream ACRN driver part.


Those two examples are probably the worst examples to ever look at :)

The code quality of those submissions was horrible, gma500 took a very
long time to clean up and there are parts of the android code that are
still in staging to this day.


If the new driver can also be added by skipping the staging approach,
we will refine it and then submit it in normal process.


That is the normal process, staging should not be needed at all for any
code.  It is a fall-back for when the company involved has no idea of
how to upstream their code, which should NOT be the case here.


Thanks for your explanation.

OK. We will submit it in normal process.



thanks,

greg k-h



Re: [RFC PATCH 08/15] drivers/acrn: add VM memory management for ACRN char device

2019-08-18 Thread Zhao, Yakui




On 2019年08月16日 20:58, Dan Carpenter wrote:

On Fri, Aug 16, 2019 at 10:25:49AM +0800, Zhao Yakui wrote:

+int hugepage_map_guest(struct acrn_vm *vm, struct vm_memmap *memmap)
+{
+   struct page *page = NULL, *regions_buf_pg = NULL;
+   unsigned long len, guest_gpa, vma;
+   struct vm_memory_region *region_array;
+   struct set_regions *regions;
+   int max_size = PAGE_SIZE / sizeof(struct vm_memory_region);
+   int ret;
+
+   if (!vm || !memmap)
+   return -EINVAL;
+
+   len = memmap->len;
+   vma = memmap->vma_base;
+   guest_gpa = memmap->gpa;
+
+   /* prepare set_memory_regions info */
+   regions_buf_pg = alloc_page(GFP_KERNEL);
+   if (!regions_buf_pg)
+   return -ENOMEM;
+
+   regions = kzalloc(sizeof(*regions), GFP_KERNEL);
+   if (!regions) {
+   __free_page(regions_buf_pg);
+   return -ENOMEM;


It's better to do a goto err_free_regions_buf here.  More comments
below.


+   }
+   regions->mr_num = 0;
+   regions->vmid = vm->vmid;
+   regions->regions_gpa = page_to_phys(regions_buf_pg);
+   region_array = page_to_virt(regions_buf_pg);
+
+   while (len > 0) {
+   unsigned long vm0_gpa, pagesize;
+
+   ret = get_user_pages_fast(vma, 1, 1, &page);
+   if (unlikely(ret != 1) || (!page)) {
+   pr_err("failed to pin huge page!\n");
+   ret = -ENOMEM;
+   goto err;


goto err is a red flag.  It's better if error labels do one specific
named thing like:

err_regions:
kfree(regions);
err_free_regions_buf:
__free_page(regions_buf_pg);

We should unwind in the opposite/mirror order from how things were
allocated.  Then we can remove the if statements in the error handling.


Thanks for the review.

Will follow your suggestion to unwind the error handling.



In this situation, say the user triggers an -EFAULT in
get_user_pages_fast() in the second iteration through the loop.  That
means that "page" is the non-NULL page from the previous iteration.  We
have already added it to add_guest_map().  But now we're freeing it
without removing it from the map so probably it leads to a use after
free.

The best way to write the error handling in a loop like this is to
clean up the partial iteration that has succeed (nothing here), and then
unwind all the successful iterations at the bottom of the function.
"goto unwind_loop;"



In theory we should cleanup the previous success iteration if it 
encounters one error in the current iteration.

But it will be quite complex to cleanup up the previous iteration.
call the set_memory_regions for MR_DEL op.
call the remove_guest_map for the added hash item
call the put_page for returned page in get_user_pages_fast.

In fact as this driver is mainly used for embedded IOT usage, it doesn't 
handle the complex cleanup when such error is encountered. Instead the 
clean up is handled in free_guest_vm.



+   }
+
+   vm0_gpa = page_to_phys(page);
+   pagesize = PAGE_SIZE << compound_order(page);
+
+   ret = add_guest_map(vm, vm0_gpa, guest_gpa, pagesize);
+   if (ret < 0) {
+   pr_err("failed to add memseg for huge page!\n");
+   goto err;


So then here, it would be:

pr_err("failed to add memseg for huge page!\n");
put_page(page);
goto unwind_loop;

regards,
dan carpenter


+   }
+
+   /* fill each memory region into region_array */
+   region_array[regions->mr_num].type = MR_ADD;
+   region_array[regions->mr_num].gpa = guest_gpa;
+   region_array[regions->mr_num].vm0_gpa = vm0_gpa;
+   region_array[regions->mr_num].size = pagesize;
+   region_array[regions->mr_num].prot =
+   (MEM_TYPE_WB & MEM_TYPE_MASK) |
+   (memmap->prot & MEM_ACCESS_RIGHT_MASK);
+   regions->mr_num++;
+   if (regions->mr_num == max_size) {
+   pr_debug("region buffer full, set & renew regions!\n");
+   ret = set_memory_regions(regions);
+   if (ret < 0) {
+   pr_err("failed to set regions,ret=%d!\n", ret);
+   goto err;
+   }
+   regions->mr_num = 0;
+   }
+
+   len -= pagesize;
+   vma += pagesize;
+   guest_gpa += pagesize;
+   }
+
+   ret = set_memory_regions(regions);
+   if (ret < 0) {
+   pr_err("failed to set r

Re: [RFC PATCH 10/15] drivers/acrn: add interrupt injection support

2019-08-18 Thread Zhao, Yakui




On 2019年08月16日 21:12, Dan Carpenter wrote:

On Fri, Aug 16, 2019 at 10:25:51AM +0800, Zhao Yakui wrote:

+   case IC_VM_INTR_MONITOR: {
+   struct page *page;
+
+   ret = get_user_pages_fast(ioctl_param, 1, 1, &page);
+   if (unlikely(ret != 1) || !page) {


Not required.


Do you mean that it is enough to check the condition of "ret != 1"?
OK. It will be removed.





+   pr_err("acrn-dev: failed to pin intr hdr buffer!\n");
+   return -ENOMEM;
+   }
+
+   ret = hcall_vm_intr_monitor(vm->vmid, page_to_phys(page));
+   if (ret < 0) {
+   pr_err("acrn-dev: monitor intr data err=%ld\n", ret);
+   return -EFAULT;
+   }
+   break;
+   }
+


regards,
dan carpenter



Re: [RFC PATCH 11/15] drivers/acrn: add the support of handling emulated ioreq

2019-08-18 Thread Zhao, Yakui




On 2019年08月16日 21:39, Dan Carpenter wrote:

On Fri, Aug 16, 2019 at 10:25:52AM +0800, Zhao Yakui wrote:

+int acrn_ioreq_create_client(unsigned short vmid,
+ioreq_handler_t handler,
+void *client_priv,
+char *name)
+{
+   struct acrn_vm *vm;
+   struct ioreq_client *client;
+   int client_id;
+
+   might_sleep();
+
+   vm = find_get_vm(vmid);
+   if (unlikely(!vm || !vm->req_buf)) {
+   pr_err("acrn-ioreq: failed to find vm from vmid %d\n", vmid);
+   put_vm(vm);
+   return -EINVAL;
+   }
+
+   client_id = alloc_client();
+   if (unlikely(client_id < 0)) {
+   pr_err("acrn-ioreq: vm[%d] failed to alloc ioreq client\n",
+  vmid);
+   put_vm(vm);
+   return -EINVAL;
+   }
+
+   client = acrn_ioreq_get_client(client_id);
+   if (unlikely(!client)) {
+   pr_err("failed to get the client.\n");
+   put_vm(vm);
+   return -EINVAL;


Do we need to clean up the alloc_client() allocation?


Thanks for the review.

The function of acrn_iocreq_get_client is used to return the client for 
the given client_id. (The ref_count of client is also added). If it is 
NULL, it indicates that it is already released in another place.


In the function of acrn_ioreq_create_client, we don't need to clean up 
the alloc_client as it always exists in course of creating_client.




regards,
dan carpenter


+   }
+
+   if (handler) {
+   client->handler = handler;
+   client->acrn_create_kthread = true;
+   }
+
+   client->ref_vm = vm;
+   client->vmid = vmid;
+   client->client_priv = client_priv;
+   if (name)
+   strncpy(client->name, name, sizeof(client->name) - 1);
+   rwlock_init(&client->range_lock);
+   INIT_LIST_HEAD(&client->range_list);
+   init_waitqueue_head(&client->wq);
+
+   /* When it is added to ioreq_client_list, the refcnt is increased */
+   spin_lock_bh(&vm->ioreq_client_lock);
+   list_add(&client->list, &vm->ioreq_client_list);
+   spin_unlock_bh(&vm->ioreq_client_lock);
+
+   pr_info("acrn-ioreq: created ioreq client %d\n", client_id);
+
+   return client_id;
+}




Re: [RFC PATCH 04/15] drivers/acrn: add the basic framework of acrn char device driver

2019-08-18 Thread Zhao, Yakui




On 2019年08月16日 15:05, Greg KH wrote:

On Fri, Aug 16, 2019 at 10:25:45AM +0800, Zhao Yakui wrote:

ACRN hypervisor service module is the important middle layer that allows
the Linux kernel to communicate with the ACRN hypervisor. It includes
the management of virtualized CPU/memory/device/interrupt for other ACRN
guest. The user-space applications can use the provided ACRN ioctls to
interact with ACRN hypervisor through different hypercalls.

Add one basic framework firstly and the following patches will
add the corresponding implementations, which includes the management of
virtualized CPU/memory/interrupt and the emulation of MMIO/IO/PCI access.
The device file of /dev/acrn_hsm can be accessed in user-space to
communicate with ACRN module.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Jack Ren 
Signed-off-by: Jack Ren 
Co-developed-by: Mingqiang Chi 
Signed-off-by: Mingqiang Chi 
Co-developed-by: Liu Shuo 
Signed-off-by: Liu Shuo 
Signed-off-by: Zhao Yakui 
---
  drivers/staging/Kconfig |   2 +


Also, your subject line for all of these patches are wrong, it is not
drivers/acrn :(


Thanks for the pointing out it.

It will be fixed.



And you forgot to cc: the staging maintainer :(


Do you mean that the maintainer of staging subsystem is also added in 
the patch commit log?





As I have said with NUMEROUS Intel patches in the past, I now refuse to
take patches from you all WITHOUT having it signed-off-by someone from
the Intel "OTC" group (or whatever the Intel Linux group is called these
days).  They are a resource you can not ignore, and if you do, you just
end up making the rest of the kernel community grumpy by having us do
their work for them :(

Please work with them.


OK. I will work with some peoples in OTC group to prepare the better 
ACRN driver.




greg k-h



Re: [RFC PATCH 00/15] acrn: add the ACRN driver module

2019-08-18 Thread Zhao, Yakui




On 2019年08月16日 15:03, Greg KH wrote:

On Fri, Aug 16, 2019 at 08:39:25AM +0200, Borislav Petkov wrote:

On Fri, Aug 16, 2019 at 10:25:41AM +0800, Zhao Yakui wrote:

The first three patches are the changes under x86/acrn, which adds the
required APIs for the driver and reports the X2APIC caps.
The remaining patches add the ACRN driver module, which accepts the ioctl
from user-space and then communicate with the low-level ACRN hypervisor
by using hypercall.


I have a problem with that: you're adding interfaces to arch/x86/ and
its users go into staging. Why? Why not directly put the driver where
it belongs, clean it up properly and submit it like everything else is
submitted?

I don't want to have stuff in arch/x86/ which is used solely by code in
staging and the latter is lingering there indefinitely because no one is
cleaning it up...


I agree, stuff in drivers/staging/ must be self-contained, with no
changes outside of the code's subdirectory needed in order for it to
work.  That way it is trivial for us to delete it when it never gets
cleaned up :)


Thanks for pointing out the rule of drivers/staging.
The acrn staging driver is one self-contained driver. But it has some 
dependency on arch/x86/acrn and need to call the APIs in arch/x86/acrn.


If there is no driver,  the API without user had better not be added.
If API is not added,  the driver can't be compiled correctly.
The ACRN driver is one new driver. Maybe it will have some bugs and not 
be mature. So we want to add the driver as the staging.


What is the better approach to handle such scenario?



You never say _why_ this should go into drivers/staging/, nor do you
have a TODO file like all other staging code that explains exactly what
needs to be done to get it out of there.


Ok. The TODO file will be added in next version.




thanks,

greg k-h



Re: [RFC PATCH 00/15] acrn: add the ACRN driver module

2019-08-18 Thread Zhao, Yakui




On 2019年08月16日 14:39, Borislav Petkov wrote:

On Fri, Aug 16, 2019 at 10:25:41AM +0800, Zhao Yakui wrote:

The first three patches are the changes under x86/acrn, which adds the
required APIs for the driver and reports the X2APIC caps.
The remaining patches add the ACRN driver module, which accepts the ioctl
from user-space and then communicate with the low-level ACRN hypervisor
by using hypercall.


I have a problem with that: you're adding interfaces to arch/x86/ and
its users go into staging. Why? Why not directly put the driver where
it belongs, clean it up properly and submit it like everything else is
submitted?


Thanks for your reply and the concern.

After taking a look at several driver examples(gma500, android), it 
seems that they are firstly added into drivers/staging/XXX and then 
moved to drivers/XXX after the driver becomes mature.

So we refer to this method to upstream ACRN driver part.

If the new driver can also be added by skipping the staging approach,
we will refine it and then submit it in normal process.


I don't want to have stuff in arch/x86/ which is used solely by code in
staging and the latter is lingering there indefinitely because no one is
cleaning it up...



The ACRN driver will be the only user of the added APIs in x86/acrn. 
Without the APIs in x86/acrn, the driver can't add the driver-specifc 
upcall notification ISR or call the hypercall.


Not sure whether it can be sent in two patch sets?
The first is to add the required APIs for ACRN driver.
The second is to add the ACRN driver

Thanks
   Yakui


[RFC PATCH 14/15] drivers/acrn: add the support of irqfd and eventfd

2019-08-15 Thread Zhao Yakui
The ioventfd/irqfd based on eventfd is one mechanism that is widely used
to implement virtio kernel backend driver. After the ioreq is trigged from
virtio front driver, the eventfd_signal is called to notify the eventfd so
that the virtio kernel backend driver is waked up to handle the request.
After it is done, it will wake up the irqfd to inject the interrupt to
virtio front driver.

Each ioeventfd registered by userspace can map a PIO/MMIO range of the
guest to eventfd, and response to signal the eventfd when get the
in-range IO write from guest. Then the other side of eventfd can be
notified to process the IO request.

As we only use the ioeventfd to listen virtqueue's kick register, some
limitations are added:
  1) Length support can only be 1, 2, 4 or 8
  2) Only support write operation, read will get 0
  3) Same address, shorter length writing can be handled with the
 integral data matching

The irqfd 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 acrn_hsm side.

Co-developed-by: Shuo Liu 
Signed-off-by: Shuo Liu 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/Makefile |   4 +-
 drivers/staging/acrn/acrn_dev.c   |  19 ++
 drivers/staging/acrn/acrn_drv_internal.h  |  10 +
 drivers/staging/acrn/acrn_ioeventfd.c | 407 ++
 drivers/staging/acrn/acrn_irqfd.c | 339 +
 drivers/staging/acrn/acrn_vm_mngt.c   |   9 +-
 include/uapi/linux/acrn/acrn_ioctl_defs.h |  25 ++
 7 files changed, 811 insertions(+), 2 deletions(-)
 create mode 100644 drivers/staging/acrn/acrn_ioeventfd.c
 create mode 100644 drivers/staging/acrn/acrn_irqfd.c

diff --git a/drivers/staging/acrn/Makefile b/drivers/staging/acrn/Makefile
index a381944..f8d8ee2 100644
--- a/drivers/staging/acrn/Makefile
+++ b/drivers/staging/acrn/Makefile
@@ -4,4 +4,6 @@ acrn-y := acrn_dev.o \
  acrn_vm_mngt.o \
  acrn_mm.o \
  acrn_mm_hugetlb.o \
- acrn_ioreq.o
+ acrn_ioreq.o  \
+ acrn_ioeventfd.o \
+ acrn_irqfd.o
diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index ef0ec50..0602125 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -141,6 +141,8 @@ long acrn_dev_ioctl(struct file *filep,
if (ret < 0)
goto ioreq_buf_fail;
 
+   acrn_ioeventfd_init(vm->vmid);
+   acrn_irqfd_init(vm->vmid);
pr_info("acrn: VM %d created\n", created_vm->vmid);
kfree(created_vm);
break;
@@ -506,6 +508,23 @@ long acrn_dev_ioctl(struct file *filep,
 
break;
}
+   case IC_EVENT_IOEVENTFD: {
+   struct acrn_ioeventfd args;
+
+   if (copy_from_user(&args, (void *)ioctl_param, sizeof(args)))
+   return -EFAULT;
+   ret = acrn_ioeventfd_config(vm->vmid, &args);
+   break;
+   }
+
+   case IC_EVENT_IRQFD: {
+   struct acrn_irqfd args;
+
+   if (copy_from_user(&args, (void *)ioctl_param, sizeof(args)))
+   return -EFAULT;
+   ret = acrn_irqfd_config(vm->vmid, &args);
+   break;
+   }
 
default:
pr_warn("Unknown IOCTL 0x%x\n", ioctl_num);
diff --git a/drivers/staging/acrn/acrn_drv_internal.h 
b/drivers/staging/acrn/acrn_drv_internal.h
index 7813387..b9ded9a 100644
--- a/drivers/staging/acrn/acrn_drv_internal.h
+++ b/drivers/staging/acrn/acrn_drv_internal.h
@@ -173,4 +173,14 @@ void acrn_ioreq_driver_init(void);
 void acrn_ioreq_clear_request(struct acrn_vm *vm);
 int acrn_ioreq_distribute_request(struct acrn_vm *vm);
 
+/* ioeventfd APIs */
+int acrn_ioeventfd_init(unsigned short vmid);
+int acrn_ioeventfd_config(unsigned short vmid, struct acrn_ioeventfd *args);
+void acrn_ioeventfd_deinit(unsigned short vmid);
+
+/* irqfd APIs */
+int acrn_irqfd_init(unsigned short vmid);
+int acrn_irqfd_config(unsigned short vmid, struct acrn_irqfd *args);
+void acrn_irqfd_deinit(unsigned short vmid);
+
 #endif
diff --git a/drivers/staging/acrn/acrn_ioeventfd.c 
b/drivers/staging/acrn/acrn_ioeventfd.c
new file mode 100644
index 000..b330625
--- /dev/null
+++ b/drivers/staging/acrn/acrn_ioeventfd.c
@@ -0,0 +1,407 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * ACRN hyperviosr service module (SRV): ioeventfd based on eventfd
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * Liu Shuo 
+ * Zhao Yakui 
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "acrn_

[RFC PATCH 13/15] drivers/acrn: add service to obtain Power data transition

2019-08-15 Thread Zhao Yakui
The px/cx data is critical to support the power transition. DM will get
these data to build DSDT for UOS. With this DSDT, UOS would have the
capability on power control if acpi-cpufreq/idle driver is enabled in
kernel.
Add the PM ioctl that is used to obtain the info of power state
so that the DM can construct the DSDT with Power frequence/C-state idle
for guest system.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Victor Sun 
Signed-off-by: Victor Sun 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/acrn_dev.c   | 75 +++
 include/uapi/linux/acrn/acrn_ioctl_defs.h | 36 +++
 2 files changed, 111 insertions(+)

diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index 93f45e3..ef0ec50 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -432,6 +432,81 @@ long acrn_dev_ioctl(struct file *filep,
break;
}
 
+   case IC_PM_GET_CPU_STATE: {
+   u64 cmd;
+
+   if (copy_from_user(&cmd, (void *)ioctl_param, sizeof(cmd)))
+   return -EFAULT;
+
+   switch (cmd & PMCMD_TYPE_MASK) {
+   case PMCMD_GET_PX_CNT:
+   case PMCMD_GET_CX_CNT: {
+   u64 *pm_info;
+
+   pm_info = kmalloc(sizeof(u64), GFP_KERNEL);
+   if (!pm_info)
+   return -ENOMEM;
+
+   ret = hcall_get_cpu_state(cmd, virt_to_phys(pm_info));
+   if (ret < 0) {
+   kfree(pm_info);
+   return -EFAULT;
+   }
+
+   if (copy_to_user((void *)ioctl_param,
+pm_info, sizeof(u64)))
+   ret = -EFAULT;
+
+   kfree(pm_info);
+   break;
+   }
+   case PMCMD_GET_PX_DATA: {
+   struct cpu_px_data *px_data;
+
+   px_data = kmalloc(sizeof(*px_data), GFP_KERNEL);
+   if (!px_data)
+   return -ENOMEM;
+
+   ret = hcall_get_cpu_state(cmd, virt_to_phys(px_data));
+   if (ret < 0) {
+   kfree(px_data);
+   return -EFAULT;
+   }
+
+   if (copy_to_user((void *)ioctl_param,
+px_data, sizeof(*px_data)))
+   ret = -EFAULT;
+
+   kfree(px_data);
+   break;
+   }
+   case PMCMD_GET_CX_DATA: {
+   struct cpu_cx_data *cx_data;
+
+   cx_data = kmalloc(sizeof(*cx_data), GFP_KERNEL);
+   if (!cx_data)
+   return -ENOMEM;
+
+   ret = hcall_get_cpu_state(cmd, virt_to_phys(cx_data));
+   if (ret < 0) {
+   kfree(cx_data);
+   return -EFAULT;
+   }
+
+   if (copy_to_user((void *)ioctl_param,
+cx_data, sizeof(*cx_data)))
+   ret = -EFAULT;
+   kfree(cx_data);
+   break;
+   }
+   default:
+   ret = -EFAULT;
+   break;
+   }
+
+   break;
+   }
+
default:
pr_warn("Unknown IOCTL 0x%x\n", ioctl_num);
ret = -EFAULT;
diff --git a/include/uapi/linux/acrn/acrn_ioctl_defs.h 
b/include/uapi/linux/acrn/acrn_ioctl_defs.h
index c3c4f98..c762bd2 100644
--- a/include/uapi/linux/acrn/acrn_ioctl_defs.h
+++ b/include/uapi/linux/acrn/acrn_ioctl_defs.h
@@ -234,6 +234,39 @@ struct ioreq_notify {
uint32_t vcpu;
 };
 
+struct acrn_generic_address {
+   uint8_t space_id;
+   uint8_t bit_width;
+   uint8_t bit_offset;
+   uint8_t access_size;
+   uint64_taddress;
+};
+
+struct cpu_cx_data {
+   struct acrn_generic_address cx_reg;
+   uint8_t type;
+   uint32_tlatency;
+   uint64_tpower;
+};
+
+struct cpu_px_data {
+   uint64_t core_frequency;/* megahertz */
+   uint64_t power; /* milliWatts */
+   uint64_t transition_latency;/* microseconds */
+   uint64_t bus_master_latency;/* microseconds */
+   uint64_t control;   /* control value */
+   uint64_t status;/* success indicator */
+};
+
+#define PMCMD_TYPE_MASK0x00ff
+
+enum pm_cmd_type {
+   PMCMD_GET_PX_CNT

[RFC PATCH 01/15] x86/acrn: Report X2APIC for ACRN guest

2019-08-15 Thread Zhao Yakui
After lapic is switched from xapic to x2apic mode, it can use the APIC
MSR register to access local apic register in ACRN guest. This will
help to remove some traps of lapic access in ACRN guest.
Report the X2APIC so that the ACRN guest can be switched to x2apic mode.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 arch/x86/kernel/cpu/acrn.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index 676022e..95db5c4 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -29,12 +30,7 @@ static void __init acrn_init_platform(void)
 
 static bool acrn_x2apic_available(void)
 {
-   /*
-* x2apic is not supported for now. Future enablement will have to check
-* X86_FEATURE_X2APIC to determine whether x2apic is supported in the
-* guest.
-*/
-   return false;
+   return boot_cpu_has(X86_FEATURE_X2APIC);
 }
 
 static void (*acrn_intr_handler)(void);
-- 
2.7.4



[RFC PATCH 06/15] drivers/acrn: add the support of querying ACRN api version

2019-08-15 Thread Zhao Yakui
In order to assure that the ACRN module can work with the required ACRN
hypervisor, it needs to check whether the required version is consistent
with the queried version from ACRN ypervisor. If it is inconsistent, it
won't coninue the initialization of ACRN_HSM module.
Similarly the user-space module also needs to check the driver version.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Liu Shuo 
Signed-off-by: Liu Shuo 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/acrn_dev.c   | 47 +++
 include/uapi/linux/acrn/acrn_ioctl_defs.h | 32 +
 2 files changed, 79 insertions(+)
 create mode 100644 include/uapi/linux/acrn/acrn_ioctl_defs.h

diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index 55a7612..57cd2bb 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -18,13 +18,22 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
+#include 
 #include 
 #include 
+#include 
+
+#include "acrn_hypercall.h"
 
 #define  DEVICE_NAME "acrn_hsm"
 #define  CLASS_NAME  "acrn"
 
+#define ACRN_API_VERSION_MAJOR 1
+#define ACRN_API_VERSION_MINOR 0
+
 static int acrn_hsm_inited;
 static int major;
 static struct class*acrn_class;
@@ -44,6 +53,19 @@ long acrn_dev_ioctl(struct file *filep,
 {
long ret = 0;
 
+   if (ioctl_num == IC_GET_API_VERSION) {
+   struct api_version api_version;
+
+   api_version.major_version = ACRN_API_VERSION_MAJOR;
+   api_version.minor_version = ACRN_API_VERSION_MINOR;
+
+   if (copy_to_user((void *)ioctl_param, &api_version,
+sizeof(api_version)))
+   return -EFAULT;
+
+   return 0;
+   }
+
return ret;
 }
 
@@ -59,9 +81,12 @@ static const struct file_operations fops = {
 };
 
 #define EAX_PRIVILEGE_VM   BIT(0)
+#define SUPPORT_HV_API_VERSION_MAJOR   1
+#define SUPPORT_HV_API_VERSION_MINOR   0
 
 static int __init acrn_init(void)
 {
+   struct api_version *api_version;
acrn_hsm_inited = 0;
if (x86_hyper_type != X86_HYPER_ACRN)
return -ENODEV;
@@ -69,6 +94,28 @@ static int __init acrn_init(void)
if (!(cpuid_eax(0x4001) & EAX_PRIVILEGE_VM))
return -EPERM;
 
+   api_version = kmalloc(sizeof(*api_version), GFP_KERNEL);
+   if (!api_version)
+   return -ENOMEM;
+
+   if (hcall_get_api_version(virt_to_phys(api_version)) < 0) {
+   pr_err("acrn: failed to get api version from Hypervisor !\n");
+   kfree(api_version);
+   return -EINVAL;
+   }
+
+   if (api_version->major_version >= SUPPORT_HV_API_VERSION_MAJOR &&
+   api_version->minor_version >= SUPPORT_HV_API_VERSION_MINOR) {
+   pr_info("acrn: hv api version %d.%d\n",
+   api_version->major_version, api_version->minor_version);
+   kfree(api_version);
+   } else {
+   pr_err("acrn: not support hv api version %d.%d!\n",
+  api_version->major_version, api_version->minor_version);
+   kfree(api_version);
+   return -EINVAL;
+   }
+
/* Try to dynamically allocate a major number for the device */
major = register_chrdev(0, DEVICE_NAME, &fops);
if (major < 0) {
diff --git a/include/uapi/linux/acrn/acrn_ioctl_defs.h 
b/include/uapi/linux/acrn/acrn_ioctl_defs.h
new file mode 100644
index 000..8dbf69a
--- /dev/null
+++ b/include/uapi/linux/acrn/acrn_ioctl_defs.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/**
+ * @file acrn_ioctl_defs.h
+ *
+ * ACRN definition for ioctl to user space
+ */
+
+#ifndef __ACRN_IOCTL_DEFS_H__
+#define __ACRN_IOCTL_DEFS_H__
+
+/**
+ * struct api_version - data structure to track ACRN_SRV API version
+ *
+ * @major_version: major version of ACRN_SRV API
+ * @minor_version: minor version of ACRN_SRV API
+ */
+struct api_version {
+   uint32_t major_version;
+   uint32_t minor_version;
+};
+
+/*
+ * Common IOCTL ID definition for DM
+ */
+#define _IC_ID(x, y) (((x) << 24) | (y))
+#define IC_ID 0x43UL
+
+/* General */
+#define IC_ID_GEN_BASE  0x0UL
+#define IC_GET_API_VERSION _IC_ID(IC_ID, IC_ID_GEN_BASE + 0x00)
+
+#endif /* __ACRN_IOCTL_DEFS_H__ */
-- 
2.7.4



[RFC PATCH 04/15] drivers/acrn: add the basic framework of acrn char device driver

2019-08-15 Thread Zhao Yakui
ACRN hypervisor service module is the important middle layer that allows
the Linux kernel to communicate with the ACRN hypervisor. It includes
the management of virtualized CPU/memory/device/interrupt for other ACRN
guest. The user-space applications can use the provided ACRN ioctls to
interact with ACRN hypervisor through different hypercalls.

Add one basic framework firstly and the following patches will
add the corresponding implementations, which includes the management of
virtualized CPU/memory/interrupt and the emulation of MMIO/IO/PCI access.
The device file of /dev/acrn_hsm can be accessed in user-space to
communicate with ACRN module.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Jack Ren 
Signed-off-by: Jack Ren 
Co-developed-by: Mingqiang Chi 
Signed-off-by: Mingqiang Chi 
Co-developed-by: Liu Shuo 
Signed-off-by: Liu Shuo 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/Kconfig |   2 +
 drivers/staging/Makefile|   1 +
 drivers/staging/acrn/Kconfig|  18 ++
 drivers/staging/acrn/Makefile   |   2 +
 drivers/staging/acrn/acrn_dev.c | 123 
 5 files changed, 146 insertions(+)
 create mode 100644 drivers/staging/acrn/Kconfig
 create mode 100644 drivers/staging/acrn/Makefile
 create mode 100644 drivers/staging/acrn/acrn_dev.c

diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 7c96a01..0766de5 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -120,4 +120,6 @@ source "drivers/staging/kpc2000/Kconfig"
 
 source "drivers/staging/isdn/Kconfig"
 
+source "drivers/staging/acrn/Kconfig"
+
 endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index fcaac96..f927eb0 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -49,4 +49,5 @@ obj-$(CONFIG_XIL_AXIS_FIFO)   += axis-fifo/
 obj-$(CONFIG_EROFS_FS) += erofs/
 obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/
 obj-$(CONFIG_KPC2000)  += kpc2000/
+obj-$(CONFIG_ACRN_HSM) += acrn/
 obj-$(CONFIG_ISDN_CAPI)+= isdn/
diff --git a/drivers/staging/acrn/Kconfig b/drivers/staging/acrn/Kconfig
new file mode 100644
index 000..a047d5f
--- /dev/null
+++ b/drivers/staging/acrn/Kconfig
@@ -0,0 +1,18 @@
+config ACRN_HSM
+   tristate "Intel ACRN Hypervisor service Module"
+   depends on ACRN_GUEST
+   depends on HUGETLBFS
+   depends on PCI_MSI
+   default n
+   help
+ This is the Hypervisor service Module (ACRN.ko) for ACRN guest
+ to communicate with ACRN hypervisor. It includes the management
+ of virtualized CPU/memory/device/interrupt for other ACRN guest.
+
+ It is required if it needs to manage other ACRN guests. User-guest
+ OS does not need it.
+
+ If unsure, say N.
+ If you wish to work on this driver, to help improve it, or to
+ report problems you have with them, please use the
+ acrn-...@lists.projectacrn.org mailing list.
diff --git a/drivers/staging/acrn/Makefile b/drivers/staging/acrn/Makefile
new file mode 100644
index 000..48fca38
--- /dev/null
+++ b/drivers/staging/acrn/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_ACRN_HSM) := acrn.o
+acrn-y := acrn_dev.o
diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
new file mode 100644
index 000..55a7612
--- /dev/null
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * ACRN hyperviosr service module (HSM): main framework
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ * Jack Ren 
+ * Mingqiang Chi 
+ * Liu Shuo 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define  DEVICE_NAME "acrn_hsm"
+#define  CLASS_NAME  "acrn"
+
+static int acrn_hsm_inited;
+static int major;
+static struct class*acrn_class;
+static struct device   *acrn_device;
+
+static
+int acrn_dev_open(struct inode *inodep, struct file *filep)
+{
+   pr_info("%s: opening device node\n", __func__);
+
+   return 0;
+}
+
+static
+long acrn_dev_ioctl(struct file *filep,
+   unsigned int ioctl_num, unsigned long ioctl_param)
+{
+   long ret = 0;
+
+   return ret;
+}
+
+static int acrn_dev_release(struct inode *inodep, struct file *filep)
+{
+   return 0;
+}
+
+static const struct file_operations fops = {
+   .open = acrn_dev_open,
+   .release = acrn_dev_release,
+   .unlocked_ioctl = acrn_dev_ioctl,
+};
+
+#define EAX_PRIVILEGE_VM   BIT(0)
+
+static int __init acrn_init(void)
+{
+   acrn_hsm_inited = 0;
+   if (x86_hyper_type != X86_HYPER_ACRN)
+   return -ENODEV;
+
+   if (!(cpuid_eax(0x4001) & EAX_PRIVILEGE_VM))
+   return -EPERM;
+
+   /* 

[RFC PATCH 09/15] drivers/acrn: add passthrough device support

2019-08-15 Thread Zhao Yakui
Pass-through device plays an important role for guest OS when it is
accessed exclusively by guest OS. This is critical for the performance
scenario. After one PCI device is assigned to guest OS, it can be
accessed exclusively by guest system. It can avoid the device emulation
and provide the better performance.
It provides the following operations for supporting pass-through device.
- assign, pass-through device
   ACRN_ASSIGN_PTDEV: Assign one PCI device to one guest OS
- deassign pass-through device
   ACRN_DEASSIGN_PTDEV: Return the assigned PCI device from
the guest OS so that it can be assigned to another guest OS.
- set, reset pass-through device intr info
   ACRN_SET_PTDEV_INTR_INFO
   ACRN_RESET_PTDEV_INTR_INFO : This is used to configure
the interrupt info for the assigned pass-through device so that
ACRN hypervisor can inject the interrupt into guest system after
the device interrupt is triggered.

Co-developed-by: Gao, Shiqing 
Signed-off-by: Gao, Shiqing 
Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/acrn_dev.c   | 77 +++
 drivers/staging/acrn/acrn_drv_internal.h  | 25 ++
 include/uapi/linux/acrn/acrn_ioctl_defs.h | 47 +++
 3 files changed, 149 insertions(+)

diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index cb62819..28bbd78 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -239,6 +239,83 @@ long acrn_dev_ioctl(struct file *filep,
break;
}
 
+   case IC_ASSIGN_PTDEV: {
+   unsigned short bdf;
+
+   if (copy_from_user(&bdf, (void *)ioctl_param,
+  sizeof(unsigned short)))
+   return -EFAULT;
+
+   ret = hcall_assign_ptdev(vm->vmid, bdf);
+   if (ret < 0) {
+   pr_err("acrn: failed to assign ptdev!\n");
+   return -EFAULT;
+   }
+   break;
+   }
+   case IC_DEASSIGN_PTDEV: {
+   unsigned short bdf;
+
+   if (copy_from_user(&bdf, (void *)ioctl_param,
+  sizeof(unsigned short)))
+   return -EFAULT;
+
+   ret = hcall_deassign_ptdev(vm->vmid, bdf);
+   if (ret < 0) {
+   pr_err("acrn: failed to deassign ptdev!\n");
+   return -EFAULT;
+   }
+   break;
+   }
+
+   case IC_SET_PTDEV_INTR_INFO: {
+   struct ic_ptdev_irq ic_pt_irq;
+   struct hc_ptdev_irq *hc_pt_irq;
+
+   if (copy_from_user(&ic_pt_irq, (void *)ioctl_param,
+  sizeof(ic_pt_irq)))
+   return -EFAULT;
+
+   hc_pt_irq = kmalloc(sizeof(*hc_pt_irq), GFP_KERNEL);
+   if (!hc_pt_irq)
+   return -ENOMEM;
+
+   memcpy(hc_pt_irq, &ic_pt_irq, sizeof(*hc_pt_irq));
+
+   ret = hcall_set_ptdev_intr_info(vm->vmid,
+   virt_to_phys(hc_pt_irq));
+   kfree(hc_pt_irq);
+   if (ret < 0) {
+   pr_err("acrn: failed to set intr info for ptdev!\n");
+   return -EFAULT;
+   }
+
+   break;
+   }
+   case IC_RESET_PTDEV_INTR_INFO: {
+   struct ic_ptdev_irq ic_pt_irq;
+   struct hc_ptdev_irq *hc_pt_irq;
+
+   if (copy_from_user(&ic_pt_irq, (void *)ioctl_param,
+  sizeof(ic_pt_irq)))
+   return -EFAULT;
+
+   hc_pt_irq = kmalloc(sizeof(*hc_pt_irq), GFP_KERNEL);
+   if (!hc_pt_irq)
+   return -ENOMEM;
+
+   memcpy(hc_pt_irq, &ic_pt_irq, sizeof(*hc_pt_irq));
+
+   ret = hcall_reset_ptdev_intr_info(vm->vmid,
+ virt_to_phys(hc_pt_irq));
+   kfree(hc_pt_irq);
+   if (ret < 0) {
+   pr_err("acrn: failed to reset intr info for ptdev!\n");
+   return -EFAULT;
+   }
+   break;
+   }
+
default:
pr_warn("Unknown IOCTL 0x%x\n", ioctl_num);
ret = -EFAULT;
diff --git a/drivers/staging/acrn/acrn_drv_internal.h 
b/drivers/staging/acrn/acrn_drv_internal.h
index 5098765..3e633cd 100644
--- a/drivers/staging/acrn/acrn_drv_internal.h
+++ b/drivers/staging/acrn/acrn_drv_internal.h
@@ -115,4 +115,29 @@ void hugepage_free_guest(struct acrn_vm *vm);
 void *hugepage_map_guest_phys(struct acrn_vm *vm, u64 guest_phys, size_t size);
 int hugepage_unmap_guest_phys(struct acrn_vm *vm, u64 guest_phys);
 int set_

[RFC PATCH 12/15] drivers/acrn: add driver-specific IRQ handle to dispatch IO_REQ request

2019-08-15 Thread Zhao Yakui
After ACRN hypervisor captures the io_request(mmio, IO, PCI access) from
guest OS, it will send the IRQ interrupt to SOS system.
The HYPERVISOR_CALLBACK_VECTOR ISR handler will be executed and it
needs to call the driver-specific ISR handler to dispatch emulated
io_request.
After the emulation of ioreq request is finished, the ACRN hypervisor
is notified and then can resume the execution of guest OS.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Mingqiang Chi 
Signed-off-by: Mingqiang Chi 
Co-developed-by: Liu Shuo 
Signed-off-by: Liu Shuo 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/acrn_dev.c | 41 +
 1 file changed, 41 insertions(+)

diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index 28258fb..93f45e3 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -41,6 +42,7 @@ static intacrn_hsm_inited;
 static int major;
 static struct class*acrn_class;
 static struct device   *acrn_device;
+static struct tasklet_struct acrn_io_req_tasklet;
 
 static
 int acrn_dev_open(struct inode *inodep, struct file *filep)
@@ -416,6 +418,16 @@ long acrn_dev_ioctl(struct file *filep,
break;
}
case IC_CLEAR_VM_IOREQ: {
+   /*
+* we need to flush the current pending ioreq dispatch
+* tasklet and finish it before clearing all ioreq of this VM.
+* With tasklet_kill, there still be a very rare race which
+* might lost one ioreq tasklet for other VMs. So arm one after
+* the clearing. It's harmless.
+*/
+   tasklet_schedule(&acrn_io_req_tasklet);
+   tasklet_kill(&acrn_io_req_tasklet);
+   tasklet_schedule(&acrn_io_req_tasklet);
acrn_ioreq_clear_request(vm);
break;
}
@@ -449,6 +461,28 @@ static int acrn_dev_release(struct inode *inodep, struct 
file *filep)
return 0;
 }
 
+static void io_req_tasklet(unsigned long data)
+{
+   struct acrn_vm *vm;
+   /* This is already in tasklet. Use read_lock for list_lock */
+
+   read_lock(&acrn_vm_list_lock);
+   list_for_each_entry(vm, &acrn_vm_list, list) {
+   if (!vm || !vm->req_buf)
+   break;
+
+   get_vm(vm);
+   acrn_ioreq_distribute_request(vm);
+   put_vm(vm);
+   }
+   read_unlock(&acrn_vm_list_lock);
+}
+
+static void acrn_intr_handler(void)
+{
+   tasklet_schedule(&acrn_io_req_tasklet);
+}
+
 static const struct file_operations fops = {
.open = acrn_dev_open,
.release = acrn_dev_release,
@@ -462,6 +496,7 @@ static const struct file_operations fops = {
 
 static int __init acrn_init(void)
 {
+   unsigned long flag;
struct api_version *api_version;
acrn_hsm_inited = 0;
if (x86_hyper_type != X86_HYPER_ACRN)
@@ -518,6 +553,10 @@ static int __init acrn_init(void)
return PTR_ERR(acrn_device);
}
 
+   tasklet_init(&acrn_io_req_tasklet, io_req_tasklet, 0);
+   local_irq_save(flag);
+   acrn_setup_intr_irq(acrn_intr_handler);
+   local_irq_restore(flag);
acrn_ioreq_driver_init();
pr_info("acrn: ACRN Hypervisor service module initialized\n");
acrn_hsm_inited = 1;
@@ -529,6 +568,8 @@ static void __exit acrn_exit(void)
if (!acrn_hsm_inited)
return;
 
+   tasklet_kill(&acrn_io_req_tasklet);
+   acrn_remove_intr_irq();
device_destroy(acrn_class, MKDEV(major, 0));
class_unregister(acrn_class);
class_destroy(acrn_class);
-- 
2.7.4



[RFC PATCH 08/15] drivers/acrn: add VM memory management for ACRN char device

2019-08-15 Thread Zhao Yakui
In order to launch the ACRN guest system, it needs to setup the mapping
between GPA (guest physical address) and HPA (host physical address).
This is based on memory virtualization and configured in EPT table.
The ioctl related with memory management is added and then the hypercall
is called so that the ACRN hypervisor can help to setup the memory
mapping for ACRN guest.
The 1G/2M huge page is used to optimize the EPT table for guest VM. This
will simplify the memory allocation and also optimizes the TLB.
For the MMIO mapping: It can support 4K/2M page.

IC_SET_MEMSEG: This is used to setup the memory mapping for the memory
of guest system by using hugetlb(Guest physical address and host virtual
addr).It is also used to setup the device MMIO mapping for PCI device.
IC_UNSET_MEMSEG: This is used to remove the device MMIO mapping for PCI
device. This is used with updating the MMIO mapping together. As the
acrn hypervisor is mainly used for embedded IOT device, it doesn't support
the dynamica removal of memory mapping.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Li, Fei 
Signed-off-by: Li, Fei 
Co-developed-by: Liu Shuo 
Signed-off-by: Liu Shuo 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/Makefile |   4 +-
 drivers/staging/acrn/acrn_dev.c   |  27 +++
 drivers/staging/acrn/acrn_drv_internal.h  |  90 +++---
 drivers/staging/acrn/acrn_mm.c| 227 
 drivers/staging/acrn/acrn_mm_hugetlb.c| 281 ++
 drivers/staging/acrn/acrn_vm_mngt.c   |   2 +
 include/linux/acrn/acrn_drv.h |  86 +
 include/uapi/linux/acrn/acrn_common_def.h |  25 +++
 include/uapi/linux/acrn/acrn_ioctl_defs.h |  41 +
 9 files changed, 759 insertions(+), 24 deletions(-)
 create mode 100644 drivers/staging/acrn/acrn_mm.c
 create mode 100644 drivers/staging/acrn/acrn_mm_hugetlb.c
 create mode 100644 include/linux/acrn/acrn_drv.h
 create mode 100644 include/uapi/linux/acrn/acrn_common_def.h

diff --git a/drivers/staging/acrn/Makefile b/drivers/staging/acrn/Makefile
index 426d6e8..ec62afe 100644
--- a/drivers/staging/acrn/Makefile
+++ b/drivers/staging/acrn/Makefile
@@ -1,4 +1,6 @@
 obj-$(CONFIG_ACRN_HSM) := acrn.o
 acrn-y := acrn_dev.o \
  acrn_hypercall.o \
- acrn_vm_mngt.o
+ acrn_vm_mngt.o \
+ acrn_mm.o \
+ acrn_mm_hugetlb.o
diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index 7372316..cb62819 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -44,6 +44,7 @@ static
 int acrn_dev_open(struct inode *inodep, struct file *filep)
 {
struct acrn_vm *vm;
+   int i;
 
vm = kzalloc(sizeof(*vm), GFP_KERNEL);
if (!vm)
@@ -53,6 +54,10 @@ int acrn_dev_open(struct inode *inodep, struct file *filep)
vm->vmid = ACRN_INVALID_VMID;
vm->dev = acrn_device;
 
+   for (i = 0; i < HUGEPAGE_HLIST_ARRAY_SIZE; i++)
+   INIT_HLIST_HEAD(&vm->hugepage_hlist[i]);
+   mutex_init(&vm->hugepage_lock);
+
write_lock_bh(&acrn_vm_list_lock);
vm_list_add(&vm->list);
write_unlock_bh(&acrn_vm_list_lock);
@@ -212,6 +217,28 @@ long acrn_dev_ioctl(struct file *filep,
return ret;
}
 
+   case IC_SET_MEMSEG: {
+   struct vm_memmap memmap;
+
+   if (copy_from_user(&memmap, (void *)ioctl_param,
+  sizeof(memmap)))
+   return -EFAULT;
+
+   ret = map_guest_memseg(vm, &memmap);
+   break;
+   }
+
+   case IC_UNSET_MEMSEG: {
+   struct vm_memmap memmap;
+
+   if (copy_from_user(&memmap, (void *)ioctl_param,
+  sizeof(memmap)))
+   return -EFAULT;
+
+   ret = unmap_guest_memseg(vm, &memmap);
+   break;
+   }
+
default:
pr_warn("Unknown IOCTL 0x%x\n", ioctl_num);
ret = -EFAULT;
diff --git a/drivers/staging/acrn/acrn_drv_internal.h 
b/drivers/staging/acrn/acrn_drv_internal.h
index 6758dea..5098765 100644
--- a/drivers/staging/acrn/acrn_drv_internal.h
+++ b/drivers/staging/acrn/acrn_drv_internal.h
@@ -11,6 +11,57 @@
 #include 
 #include 
 
+struct vm_memory_region {
+#define MR_ADD 0
+#define MR_DEL 2
+   u32 type;
+
+   /* IN: mem attr */
+   u32 prot;
+
+   /* IN: beginning guest GPA to map */
+   u64 gpa;
+
+   /* IN: VM0's GPA which foreign gpa will be mapped to */
+   u64 vm0_gpa;
+
+   /* IN: size of the region */
+   u64 size;
+};
+
+struct set_regions {
+   /*IN: vmid for this hypercall */
+   u16 vmid;
+
+   /** Reserved */
+   u16 reserved[3];
+
+   /* IN: multi memmaps numbers */
+   u32 mr_num;
+
+   /** Reser

[RFC PATCH 11/15] drivers/acrn: add the support of handling emulated ioreq

2019-08-15 Thread Zhao Yakui
After guest UOS is booted, the MMIO/IO access will cause that
it exits from VMX non-root env into ACRN hypervisor. Then the ACRN
hypervisor will inject virtual irq into the Linux guest with ACRN HSM
module. The ACRN_HSM handles this virtual irq (which is based on
HYPERVISOR_CALLBACK_VECTOR), parses corresponding IO request from shared
IOReq buffer and distributes it to different ioreq client. After the
ioreq emulation is finished, it will notify ACRN hypervisor and then
hypervisor will resume the execution of guest UOS.

ACRN HSM module will group some range of emulated MMIO/IO addr as
one ioreq_client. It will determine which ioreq_client should handle
the emulated MMIO/IO request based on the address and then dispatch it
into the ioreq_client thread. User-space device model will create one
default ioreq_client, which is used to handle the emulated MMIO/IO in
user-space thread.

Add ioreq service and defines IOReq APIs like below:
   int acrn_ioreq_create_client(unsigned long vmid,
ioreq_handler_t handler,
void *client_priv,
char *name);
   void acrn_ioreq_destroy_client(int client_id);
   int acrn_ioreq_add_iorange(int client_id, enum request_type type,
   long start, long end);
   int acrn_ioreq_del_iorange(int client_id, enum request_type type,
   long start, long end);
   struct acrn_request * acrn_ioreq_get_reqbuf(int client_id);
   int acrn_ioreq_attach_client(int client_id);
   int acrn_ioreq_complete_request(int client_id);

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Yin FengWei 
Signed-off-by: Yin FengWei 
Co-developed-by: Liu Shuo 
Signed-off-by: Liu Shuo 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/Makefile |   3 +-
 drivers/staging/acrn/acrn_dev.c   |  58 ++
 drivers/staging/acrn/acrn_drv_internal.h  |  33 ++
 drivers/staging/acrn/acrn_ioreq.c | 937 ++
 drivers/staging/acrn/acrn_vm_mngt.c   |   7 +
 include/linux/acrn/acrn_drv.h | 102 
 include/uapi/linux/acrn/acrn_common_def.h | 176 ++
 include/uapi/linux/acrn/acrn_ioctl_defs.h |  20 +
 8 files changed, 1335 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/acrn/acrn_ioreq.c

diff --git a/drivers/staging/acrn/Makefile b/drivers/staging/acrn/Makefile
index ec62afe..a381944 100644
--- a/drivers/staging/acrn/Makefile
+++ b/drivers/staging/acrn/Makefile
@@ -3,4 +3,5 @@ acrn-y := acrn_dev.o \
  acrn_hypercall.o \
  acrn_vm_mngt.o \
  acrn_mm.o \
- acrn_mm_hugetlb.o
+ acrn_mm_hugetlb.o \
+ acrn_ioreq.o
diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index 1476817..28258fb 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "acrn_hypercall.h"
 #include "acrn_drv_internal.h"
@@ -59,6 +60,9 @@ int acrn_dev_open(struct inode *inodep, struct file *filep)
INIT_HLIST_HEAD(&vm->hugepage_hlist[i]);
mutex_init(&vm->hugepage_lock);
 
+   INIT_LIST_HEAD(&vm->ioreq_client_list);
+   spin_lock_init(&vm->ioreq_client_lock);
+
write_lock_bh(&acrn_vm_list_lock);
vm_list_add(&vm->list);
write_unlock_bh(&acrn_vm_list_lock);
@@ -131,9 +135,20 @@ long acrn_dev_ioctl(struct file *filep,
vm->vmid = created_vm->vmid;
atomic_set(&vm->vcpu_num, 0);
 
+   ret = acrn_ioreq_init(vm, created_vm->req_buf);
+   if (ret < 0)
+   goto ioreq_buf_fail;
+
pr_info("acrn: VM %d created\n", created_vm->vmid);
kfree(created_vm);
break;
+
+ioreq_buf_fail:
+   hcall_destroy_vm(created_vm->vmid);
+   vm->vmid = ACRN_INVALID_VMID;
+   kfree(created_vm);
+   break;
+
}
 
case IC_START_VM: {
@@ -364,6 +379,47 @@ long acrn_dev_ioctl(struct file *filep,
break;
}
 
+   case IC_CREATE_IOREQ_CLIENT: {
+   int client_id;
+
+   client_id = acrn_ioreq_create_fallback_client(vm->vmid,
+ "acrndm");
+   if (client_id < 0)
+   return -EFAULT;
+   return client_id;
+   }
+
+   case IC_DESTROY_IOREQ_CLIENT: {
+   int client = ioctl_param;
+
+   acrn_ioreq_destroy_client(client);
+   break;
+   }
+
+   case IC_ATTACH_IOREQ_CLIENT: {
+   int client = ioctl_param;
+
+   return acrn_ioreq_attach_client(client);
+   }
+
+   case IC_NOTIFY_REQUEST_FINISH: {
+   struct ioreq_notify notify;
+
+   if (copy_from_user(

[RFC PATCH 10/15] drivers/acrn: add interrupt injection support

2019-08-15 Thread Zhao Yakui
After ACRN devicemodel finishes the emulation of trapped MMIO/IO/PCICFG
access, it needs to inject one interrupt to notify that the guest can be
resumed.
IC_SET_IRQLINE: This is used to inject virtual IOAPIC gsi interrupt
IC_INJECT_MSI: Inject virtual MSI interrupt to guest OS
IC_VM_INTR_MONITOR: monitor the interrupt info for one guest OS

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Mingqiang Chi 
Signed-off-by: Mingqiang Chi 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/acrn_dev.c   | 48 +++
 drivers/staging/acrn/acrn_vm_mngt.c   | 28 ++
 include/linux/acrn/acrn_drv.h | 12 
 include/uapi/linux/acrn/acrn_ioctl_defs.h | 18 
 4 files changed, 106 insertions(+)

diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index 28bbd78..1476817 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -316,6 +317,53 @@ long acrn_dev_ioctl(struct file *filep,
break;
}
 
+   case IC_SET_IRQLINE: {
+   ret = hcall_set_irqline(vm->vmid, ioctl_param);
+   if (ret < 0) {
+   pr_err("acrn: failed to set irqline!\n");
+   return -EFAULT;
+   }
+   break;
+   }
+
+   case IC_INJECT_MSI: {
+   struct acrn_msi_entry *msi;
+
+   msi = kmalloc(sizeof(*msi), GFP_KERNEL);
+   if (!msi)
+   return -ENOMEM;
+
+   if (copy_from_user(msi, (void *)ioctl_param, sizeof(*msi))) {
+   kfree(msi);
+   return -EFAULT;
+   }
+
+   ret = hcall_inject_msi(vm->vmid, virt_to_phys(msi));
+   kfree(msi);
+   if (ret < 0) {
+   pr_err("acrn: failed to inject!\n");
+   return -EFAULT;
+   }
+   break;
+   }
+
+   case IC_VM_INTR_MONITOR: {
+   struct page *page;
+
+   ret = get_user_pages_fast(ioctl_param, 1, 1, &page);
+   if (unlikely(ret != 1) || !page) {
+   pr_err("acrn-dev: failed to pin intr hdr buffer!\n");
+   return -ENOMEM;
+   }
+
+   ret = hcall_vm_intr_monitor(vm->vmid, page_to_phys(page));
+   if (ret < 0) {
+   pr_err("acrn-dev: monitor intr data err=%ld\n", ret);
+   return -EFAULT;
+   }
+   break;
+   }
+
default:
pr_warn("Unknown IOCTL 0x%x\n", ioctl_num);
ret = -EFAULT;
diff --git a/drivers/staging/acrn/acrn_vm_mngt.c 
b/drivers/staging/acrn/acrn_vm_mngt.c
index 9c6dd6d..4287595 100644
--- a/drivers/staging/acrn/acrn_vm_mngt.c
+++ b/drivers/staging/acrn/acrn_vm_mngt.c
@@ -11,8 +11,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
 
 #include "acrn_hypercall.h"
 #include "acrn_drv_internal.h"
@@ -72,3 +74,29 @@ int acrn_vm_destroy(struct acrn_vm *vm)
vm->vmid = ACRN_INVALID_VMID;
return 0;
 }
+
+int acrn_inject_msi(unsigned short vmid, unsigned long msi_addr,
+   unsigned long msi_data)
+{
+   struct acrn_msi_entry *msi;
+   int ret;
+
+   msi = kzalloc(sizeof(*msi), GFP_KERNEL);
+
+   if (!msi)
+   return -ENOMEM;
+
+   /* msi_addr: addr[19:12] with dest vcpu id */
+   /* msi_data: data[7:0] with vector */
+   msi->msi_addr = msi_addr;
+   msi->msi_data = msi_data;
+   ret = hcall_inject_msi(vmid, virt_to_phys(msi));
+   kfree(msi);
+   if (ret < 0) {
+   pr_err("acrn: failed to inject MSI for vmid %d, msi_addr %lx 
msi_data%lx!\n",
+  vmid, msi_addr, msi_data);
+   return -EFAULT;
+   }
+   return 0;
+}
+EXPORT_SYMBOL_GPL(acrn_inject_msi);
diff --git a/include/linux/acrn/acrn_drv.h b/include/linux/acrn/acrn_drv.h
index 62b03f0..bcdfcaf 100644
--- a/include/linux/acrn/acrn_drv.h
+++ b/include/linux/acrn/acrn_drv.h
@@ -83,4 +83,16 @@ extern int acrn_del_memory_region(unsigned short vmid, 
unsigned long gpa,
 extern int acrn_write_protect_page(unsigned short vmid, unsigned long gpa,
   unsigned char set);
 
+/**
+ * acrn_inject_msi() - inject MSI interrupt to guest
+ *
+ * @vmid: guest vmid
+ * @msi_addr: MSI addr matches MSI spec
+ * @msi_data: MSI data matches MSI spec
+ *
+ * Return: 0 on success, <0 on error
+ */
+extern int acrn_inject_msi(unsigned short vmid, unsigned long msi_addr,
+  unsigned long msi_data);
+
 #endif
diff --git a/include/uapi/

[RFC PATCH 03/15] x86/acrn: Add hypercall for ACRN guest

2019-08-15 Thread Zhao Yakui
When ACRN hypervisor is detected, the hypercall is needed so that the
ACRN guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for guest operating system.

On x86 it is implemented with the VMCALL instruction.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 arch/x86/include/asm/acrn.h | 54 +
 1 file changed, 54 insertions(+)

diff --git a/arch/x86/include/asm/acrn.h b/arch/x86/include/asm/acrn.h
index 857e6244..ab97c3d 100644
--- a/arch/x86/include/asm/acrn.h
+++ b/arch/x86/include/asm/acrn.h
@@ -11,4 +11,58 @@ extern void acrn_hv_vector_handler(struct pt_regs *regs);
 
 extern void acrn_setup_intr_irq(void (*handler)(void));
 extern void acrn_remove_intr_irq(void);
+
+/*
+ * Hypercalls for ACRN guest
+ *
+ * Hypercall number is passed in R8 register.
+ * Up to 2 arguments are passed in RDI, RSI.
+ * Return value will be placed in RAX.
+ */
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   long result;
+
+   /* the hypercall is implemented with the VMCALL instruction.
+* volatile qualifier is added to avoid that it is dropped
+* because of compiler optimization.
+*/
+   asm volatile("movq %[hcall_id], %%r8\n\t"
+"vmcall\n\t"
+: "=a" (result)
+: [hcall_id] "g" (hcall_id)
+: "r8");
+
+   return result;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   long result;
+
+   asm volatile("movq %[hcall_id], %%r8\n\t"
+"vmcall\n\t"
+: "=a" (result)
+: [hcall_id] "g" (hcall_id), "D" (param1)
+: "r8");
+
+   return result;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   long result;
+
+   asm volatile("movq %[hcall_id], %%r8\n\t"
+"vmcall\n\t"
+: "=a" (result)
+: [hcall_id] "g" (hcall_id), "D" (param1), "S" (param2)
+: "r8");
+
+   return result;
+}
+
 #endif /* _ASM_X86_ACRN_H */
-- 
2.7.4



[RFC PATCH 15/15] drivers/acrn: add the support of offline SOS cpu

2019-08-15 Thread Zhao Yakui
The ACRN-hypervisor works in partition mode. In such case the guest OS
and domain0 kernel will run in the different CPUs.  In course of booting
domain0 kernel, it can use all the available CPUs,which can accelerate
the booting. But after the booting is finished, it needs to offline the
other CPUs so that they can be allocated to the guest OS.

add sysfs with attr "offline_cpu", use
echo cpu_id > /sys/class/acrn/acrn_hsm/offline_cpu
to do the hypercall offline/destroy according vcpu.
before doing it, It will offline cpu by using the below cmd:
echo 0 > /sys/devices/system/cpu/cpuX/online

Currently this is mainly used in user-space device model before
booting other ACRN guest.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/acrn_dev.c | 45 +
 1 file changed, 45 insertions(+)

diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index 0602125..6868003 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -588,6 +588,41 @@ static const struct file_operations fops = {
 #define SUPPORT_HV_API_VERSION_MAJOR   1
 #define SUPPORT_HV_API_VERSION_MINOR   0
 
+static ssize_t
+offline_cpu_store(struct device *dev,
+   struct device_attribute *attr,
+   const char *buf, size_t count)
+{
+#ifdef CONFIG_X86
+   u64 cpu, lapicid;
+
+   if (kstrtoull(buf, 0, &cpu) < 0)
+   return -EINVAL;
+
+   if (cpu_possible(cpu)) {
+   lapicid = cpu_data(cpu).apicid;
+   pr_info("acrn: try to offline cpu %lld with lapicid %lld\n",
+   cpu, lapicid);
+   if (hcall_sos_offline_cpu(lapicid) < 0) {
+   pr_err("acrn: failed to offline cpu from 
Hypervisor!\n");
+   return -EINVAL;
+   }
+   }
+#endif
+   return count;
+}
+
+static DEVICE_ATTR(offline_cpu, 00200, NULL, offline_cpu_store);
+
+static struct attribute *acrn_attrs[] = {
+   &dev_attr_offline_cpu.attr,
+   NULL
+};
+
+static struct attribute_group acrn_attr_group = {
+   .attrs = acrn_attrs,
+};
+
 static int __init acrn_init(void)
 {
unsigned long flag;
@@ -647,6 +682,15 @@ static int __init acrn_init(void)
return PTR_ERR(acrn_device);
}
 
+   if (sysfs_create_group(&acrn_device->kobj, &acrn_attr_group)) {
+   pr_warn("acrn: sysfs create failed\n");
+   device_destroy(acrn_class, MKDEV(major, 0));
+   class_unregister(acrn_class);
+   class_destroy(acrn_class);
+   unregister_chrdev(major, DEVICE_NAME);
+   return -EINVAL;
+   }
+
tasklet_init(&acrn_io_req_tasklet, io_req_tasklet, 0);
local_irq_save(flag);
acrn_setup_intr_irq(acrn_intr_handler);
@@ -664,6 +708,7 @@ static void __exit acrn_exit(void)
 
tasklet_kill(&acrn_io_req_tasklet);
acrn_remove_intr_irq();
+   sysfs_remove_group(&acrn_device->kobj, &acrn_attr_group);
device_destroy(acrn_class, MKDEV(major, 0));
class_unregister(acrn_class);
class_destroy(acrn_class);
-- 
2.7.4



[RFC PATCH 02/15] x86/acrn: Add two APIs to add/remove driver-specific upcall ISR handler

2019-08-15 Thread Zhao Yakui
After the ACRN hypervisor sends the upcall notify interrupt, the upcall ISR
handler will be served. Now almost nothing is handled in upcall ISR handler
except acking EOI.
The driver-specific ISR handler is registered by the driver, which helps to
handle the real notification from ACRN hypervisor.
This is similar to that in XEN/HyperV.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 arch/x86/include/asm/acrn.h |  3 +++
 arch/x86/kernel/cpu/acrn.c  | 12 
 2 files changed, 15 insertions(+)

diff --git a/arch/x86/include/asm/acrn.h b/arch/x86/include/asm/acrn.h
index 4adb13f..857e6244 100644
--- a/arch/x86/include/asm/acrn.h
+++ b/arch/x86/include/asm/acrn.h
@@ -8,4 +8,7 @@ extern void acrn_hv_callback_vector(void);
 #endif
 
 extern void acrn_hv_vector_handler(struct pt_regs *regs);
+
+extern void acrn_setup_intr_irq(void (*handler)(void));
+extern void acrn_remove_intr_irq(void);
 #endif /* _ASM_X86_ACRN_H */
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index 95db5c4..a1ce52a 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -56,6 +56,18 @@ __visible void __irq_entry acrn_hv_vector_handler(struct 
pt_regs *regs)
set_irq_regs(old_regs);
 }
 
+void acrn_setup_intr_irq(void (*handler)(void))
+{
+   acrn_intr_handler = handler;
+}
+EXPORT_SYMBOL_GPL(acrn_setup_intr_irq);
+
+void acrn_remove_intr_irq(void)
+{
+   acrn_intr_handler = NULL;
+}
+EXPORT_SYMBOL_GPL(acrn_remove_intr_irq);
+
 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
.name   = "ACRN",
.detect = acrn_detect,
-- 
2.7.4



[RFC PATCH 00/15] acrn: add the ACRN driver module

2019-08-15 Thread Zhao Yakui
ACRN is a flexible, lightweight reference hypervisor, built with real-time
and safety-criticality in mind, optimized to streamline embedded development
through an open source platform. It is built for embedded IOT with small
footprint and real-time features. More details can be found
in https://projectacrn.org/

This is the patch set that add the ACRN driver module on ACRN guest, which
acts as the router to communciate with ACRN hypervisor.
The user-space applications can use the provided ACRN ioctls to
interact with ACRN hypervisor through different hypercalls. After the ACRN
module is loaded, the device file of /dev/acrn_hsm can be accessed in
user-space. It includes the management of virtualized CPU/memory/
device/interrupt/MMIO emulation for other ACRN guest. 
 
The first three patches are the changes under x86/acrn, which adds the
required APIs for the driver and reports the X2APIC caps. 
The remaining patches add the ACRN driver module, which accepts the ioctl
from user-space and then communicate with the low-level ACRN hypervisor
by using hypercall.


Zhao Yakui (15):
  x86/acrn: Report X2APIC for ACRN guest
  x86/acrn: Add two APIs to add/remove driver-specific upcall ISR handler
  x86/acrn: Add hypercall for ACRN guest
  drivers/acrn: add the basic framework of acrn char device driver
  drivers/acrn: add driver-specific hypercall for ACRN_HSM
  drivers/acrn: add the support of querying ACRN api version
  drivers/acrn: add acrn vm/vcpu management for ACRN_HSM char device
  drivers/acrn: add VM memory management for ACRN char device
  drivers/acrn: add passthrough device support
  drivers/acrn: add interrupt injection support
  drivers/acrn: add the support of handling emulated ioreq
  drivers/acrn: add driver-specific IRQ handle to dispatch IO_REQ request
  drivers/acrn: add service to obtain Power data transition
  drivers/acrn: add the support of irqfd and eventfd
  drivers/acrn: add the support of offline SOS cpu

 arch/x86/include/asm/acrn.h   |  57 ++
 arch/x86/kernel/cpu/acrn.c|  20 +-
 drivers/staging/Kconfig   |   2 +
 drivers/staging/Makefile  |   1 +
 drivers/staging/acrn/Kconfig  |  18 +
 drivers/staging/acrn/Makefile |   9 +
 drivers/staging/acrn/acrn_dev.c   | 727 +++
 drivers/staging/acrn/acrn_drv_internal.h  | 186 ++
 drivers/staging/acrn/acrn_hv_defs.h   |  65 +++
 drivers/staging/acrn/acrn_hypercall.c | 136 +
 drivers/staging/acrn/acrn_hypercall.h | 132 +
 drivers/staging/acrn/acrn_ioeventfd.c | 407 +
 drivers/staging/acrn/acrn_ioreq.c | 937 ++
 drivers/staging/acrn/acrn_irqfd.c | 339 +++
 drivers/staging/acrn/acrn_mm.c| 227 
 drivers/staging/acrn/acrn_mm_hugetlb.c| 281 +
 drivers/staging/acrn/acrn_vm_mngt.c   | 116 
 include/linux/acrn/acrn_drv.h | 200 +++
 include/uapi/linux/acrn/acrn_common_def.h | 201 +++
 include/uapi/linux/acrn/acrn_ioctl_defs.h | 345 +++
 20 files changed, 4400 insertions(+), 6 deletions(-)
 create mode 100644 drivers/staging/acrn/Kconfig
 create mode 100644 drivers/staging/acrn/Makefile
 create mode 100644 drivers/staging/acrn/acrn_dev.c
 create mode 100644 drivers/staging/acrn/acrn_drv_internal.h
 create mode 100644 drivers/staging/acrn/acrn_hv_defs.h
 create mode 100644 drivers/staging/acrn/acrn_hypercall.c
 create mode 100644 drivers/staging/acrn/acrn_hypercall.h
 create mode 100644 drivers/staging/acrn/acrn_ioeventfd.c
 create mode 100644 drivers/staging/acrn/acrn_ioreq.c
 create mode 100644 drivers/staging/acrn/acrn_irqfd.c
 create mode 100644 drivers/staging/acrn/acrn_mm.c
 create mode 100644 drivers/staging/acrn/acrn_mm_hugetlb.c
 create mode 100644 drivers/staging/acrn/acrn_vm_mngt.c
 create mode 100644 include/linux/acrn/acrn_drv.h
 create mode 100644 include/uapi/linux/acrn/acrn_common_def.h
 create mode 100644 include/uapi/linux/acrn/acrn_ioctl_defs.h

-- 
2.7.4



[RFC PATCH 05/15] drivers/acrn: add driver-specific hypercall for ACRN_HSM

2019-08-15 Thread Zhao Yakui
After the user-space calls the ioctls, the module will then call the
defined hypercall so that the ACRN hypervisor can take the corresponding
action. It includes the management of creating vcpu, guest memory
management and interrupt injection, pass-through device management.
The available driver-specific hypercalls for ACRN HSM module are added
so that the ACRN_HSM module can communicate with the low-level
ACRN hypervisor.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Jack Ren 
Signed-off-by: Jack Ren 
Co-developed-by: Yin FengWei 
Signed-off-by: Yin FengWei 
Co-developed-by: Liu Shuo 
Signed-off-by: Liu Shuo 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/Makefile |   3 +-
 drivers/staging/acrn/acrn_hv_defs.h   |  65 
 drivers/staging/acrn/acrn_hypercall.c | 136 ++
 drivers/staging/acrn/acrn_hypercall.h | 132 +
 4 files changed, 335 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/acrn/acrn_hv_defs.h
 create mode 100644 drivers/staging/acrn/acrn_hypercall.c
 create mode 100644 drivers/staging/acrn/acrn_hypercall.h

diff --git a/drivers/staging/acrn/Makefile b/drivers/staging/acrn/Makefile
index 48fca38..a58b0d1 100644
--- a/drivers/staging/acrn/Makefile
+++ b/drivers/staging/acrn/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_ACRN_HSM) := acrn.o
-acrn-y := acrn_dev.o
+acrn-y := acrn_dev.o \
+ acrn_hypercall.o
diff --git a/drivers/staging/acrn/acrn_hv_defs.h 
b/drivers/staging/acrn/acrn_hv_defs.h
new file mode 100644
index 000..55417d2
--- /dev/null
+++ b/drivers/staging/acrn/acrn_hv_defs.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * hypercall ID definition
+ *
+ */
+
+#ifndef _ACRN_HV_DEFS_H
+#define _ACRN_HV_DEFS_H
+
+/*
+ * Common structures for HV/HSM
+ */
+
+#define _HC_ID(x, y) (((x) << 24) | (y))
+
+#define HC_ID 0x80UL
+
+/* general */
+#define HC_ID_GEN_BASE   0x0UL
+#define HC_GET_API_VERSION  _HC_ID(HC_ID, HC_ID_GEN_BASE + 0x00)
+#define HC_SOS_OFFLINE_CPU  _HC_ID(HC_ID, HC_ID_GEN_BASE + 0x01)
+#define HC_GET_PLATFORM_INFO_HC_ID(HC_ID, HC_ID_GEN_BASE + 0x03)
+
+/* VM management */
+#define HC_ID_VM_BASE   0x10UL
+#define HC_CREATE_VM_HC_ID(HC_ID, HC_ID_VM_BASE + 0x00)
+#define HC_DESTROY_VM   _HC_ID(HC_ID, HC_ID_VM_BASE + 0x01)
+#define HC_START_VM _HC_ID(HC_ID, HC_ID_VM_BASE + 0x02)
+#define HC_PAUSE_VM _HC_ID(HC_ID, HC_ID_VM_BASE + 0x03)
+#define HC_CREATE_VCPU  _HC_ID(HC_ID, HC_ID_VM_BASE + 0x04)
+#define HC_RESET_VM _HC_ID(HC_ID, HC_ID_VM_BASE + 0x05)
+#define HC_SET_VCPU_REGS_HC_ID(HC_ID, HC_ID_VM_BASE + 0x06)
+
+/* IRQ and Interrupts */
+#define HC_ID_IRQ_BASE  0x20UL
+#define HC_INJECT_MSI   _HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x03)
+#define HC_VM_INTR_MONITOR  _HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x04)
+#define HC_SET_IRQLINE  _HC_ID(HC_ID, HC_ID_IRQ_BASE + 0x05)
+
+/* DM ioreq management */
+#define HC_ID_IOREQ_BASE0x30UL
+#define HC_SET_IOREQ_BUFFER _HC_ID(HC_ID, HC_ID_IOREQ_BASE + 0x00)
+#define HC_NOTIFY_REQUEST_FINISH_HC_ID(HC_ID, HC_ID_IOREQ_BASE + 0x01)
+
+/* Guest memory management */
+#define HC_ID_MEM_BASE  0x40UL
+#define HC_VM_SET_MEMORY_REGIONS_HC_ID(HC_ID, HC_ID_MEM_BASE + 0x02)
+#define HC_VM_WRITE_PROTECT_PAGE_HC_ID(HC_ID, HC_ID_MEM_BASE + 0x03)
+
+/* PCI assignment*/
+#define HC_ID_PCI_BASE  0x50UL
+#define HC_ASSIGN_PTDEV _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x00)
+#define HC_DEASSIGN_PTDEV   _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x01)
+#define HC_SET_PTDEV_INTR_INFO  _HC_ID(HC_ID, HC_ID_PCI_BASE + 0x03)
+#define HC_RESET_PTDEV_INTR_INFO_HC_ID(HC_ID, HC_ID_PCI_BASE + 0x04)
+
+/* DEBUG */
+#define HC_ID_DBG_BASE  0x60UL
+
+/* Power management */
+#define HC_ID_PM_BASE   0x80UL
+#define HC_PM_GET_CPU_STATE _HC_ID(HC_ID, HC_ID_PM_BASE + 0x00)
+#define HC_PM_SET_SSTATE_DATA   _HC_ID(HC_ID, HC_ID_PM_BASE + 0x01)
+
+#endif /* __ACRN_HV_DEFS_H */
diff --git a/drivers/staging/acrn/acrn_hypercall.c 
b/drivers/staging/acrn/acrn_hypercall.c
new file mode 100644
index 000..6d83475
--- /dev/null
+++ b/drivers/staging/acrn/acrn_hypercall.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * ACRN hyperviosr service module (HSM): driver-specific hypercall
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ * Jack Ren 
+ * Yin FengWei 
+ * Liu Shuo 
+ */
+
+#include 
+#include 
+#include 
+#include "acrn_hv_defs.h"
+#include "acrn_hypercall.h"
+
+/* General */
+long hcall_get_api_version(unsigned long api_version)
+{
+   return acrn_hypercall1(HC_GET_API_VERSION, api_version);
+}
+
+long hcall_sos_off

[RFC PATCH 07/15] drivers/acrn: add acrn vm/vcpu management for ACRN_HSM char device

2019-08-15 Thread Zhao Yakui
The VM management is one important role of acrn module. It is used to
manage another VM based on the user-space ioctls. It includes the
following VM operation: CREATE/START/PAUSE/DESTROY VM, CREATE_VCPU,
IC_SET_VCPU_REGS.
acrn_ioctl is provided so that the user of /dev/acrn_hsm can manage
the VM for the given guest. After the ioctl is called, the hypercall
is then called so that the ACRN hypervisor can help to manage the
corresponding VM and create the required VCPU.

As ACRN is mainly used for embedded IOT usage, no interface is provided
to destroy the vcpu explicitly. When the VM is destroyed, the low-level
ACRN hypervisor will free the corresponding vcpu implicitly.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Co-developed-by: Liu Shuo 
Signed-off-by: Liu Shuo 
Signed-off-by: Zhao Yakui 
---
 drivers/staging/acrn/Makefile |   3 +-
 drivers/staging/acrn/acrn_dev.c   | 169 +-
 drivers/staging/acrn/acrn_drv_internal.h  |  74 +
 drivers/staging/acrn/acrn_vm_mngt.c   |  72 +
 include/uapi/linux/acrn/acrn_ioctl_defs.h | 126 ++
 5 files changed, 442 insertions(+), 2 deletions(-)
 create mode 100644 drivers/staging/acrn/acrn_drv_internal.h
 create mode 100644 drivers/staging/acrn/acrn_vm_mngt.c

diff --git a/drivers/staging/acrn/Makefile b/drivers/staging/acrn/Makefile
index a58b0d1..426d6e8 100644
--- a/drivers/staging/acrn/Makefile
+++ b/drivers/staging/acrn/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_ACRN_HSM) := acrn.o
 acrn-y := acrn_dev.o \
- acrn_hypercall.o
+ acrn_hypercall.o \
+ acrn_vm_mngt.o
diff --git a/drivers/staging/acrn/acrn_dev.c b/drivers/staging/acrn/acrn_dev.c
index 57cd2bb..7372316 100644
--- a/drivers/staging/acrn/acrn_dev.c
+++ b/drivers/staging/acrn/acrn_dev.c
@@ -27,6 +27,7 @@
 #include 
 
 #include "acrn_hypercall.h"
+#include "acrn_drv_internal.h"
 
 #define  DEVICE_NAME "acrn_hsm"
 #define  CLASS_NAME  "acrn"
@@ -42,8 +43,22 @@ static struct device *acrn_device;
 static
 int acrn_dev_open(struct inode *inodep, struct file *filep)
 {
-   pr_info("%s: opening device node\n", __func__);
+   struct acrn_vm *vm;
+
+   vm = kzalloc(sizeof(*vm), GFP_KERNEL);
+   if (!vm)
+   return -ENOMEM;
+
+   refcount_set(&vm->refcnt, 1);
+   vm->vmid = ACRN_INVALID_VMID;
+   vm->dev = acrn_device;
 
+   write_lock_bh(&acrn_vm_list_lock);
+   vm_list_add(&vm->list);
+   write_unlock_bh(&acrn_vm_list_lock);
+   filep->private_data = vm;
+
+   pr_info("%s: opening device node\n", __func__);
return 0;
 }
 
@@ -52,6 +67,15 @@ long acrn_dev_ioctl(struct file *filep,
unsigned int ioctl_num, unsigned long ioctl_param)
 {
long ret = 0;
+   struct acrn_vm *vm;
+
+   pr_debug("[%s] ioctl_num=0x%x\n", __func__, ioctl_num);
+
+   vm = (struct acrn_vm *)filep->private_data;
+   if (!vm) {
+   pr_err("acrn: invalid VM !\n");
+   return -EFAULT;
+   }
 
if (ioctl_num == IC_GET_API_VERSION) {
struct api_version api_version;
@@ -66,11 +90,154 @@ long acrn_dev_ioctl(struct file *filep,
return 0;
}
 
+   if ((vm->vmid == ACRN_INVALID_VMID) && (ioctl_num != IC_CREATE_VM)) {
+   pr_err("acrn: invalid VM ID for IOCTL %x!\n", ioctl_num);
+   return -EFAULT;
+   }
+
+   switch (ioctl_num) {
+   case IC_CREATE_VM: {
+   struct acrn_create_vm *created_vm;
+
+   created_vm = kmalloc(sizeof(*created_vm), GFP_KERNEL);
+   if (!created_vm)
+   return -ENOMEM;
+
+   if (copy_from_user(created_vm, (void *)ioctl_param,
+  sizeof(struct acrn_create_vm))) {
+   kfree(created_vm);
+   return -EFAULT;
+   }
+
+   ret = hcall_create_vm(virt_to_phys(created_vm));
+   if ((ret < 0) || (created_vm->vmid == ACRN_INVALID_VMID)) {
+   pr_err("acrn: failed to create VM from Hypervisor !\n");
+   kfree(created_vm);
+   return -EFAULT;
+   }
+
+   if (copy_to_user((void *)ioctl_param, created_vm,
+sizeof(struct acrn_create_vm))) {
+   kfree(created_vm);
+   return -EFAULT;
+   }
+
+   vm->vmid = created_vm->vmid;
+   atomic_set(&vm->vcpu_num, 0);
+
+   pr_info("acrn: VM %d created\n", created_vm->vmid);
+   kfree(created_vm);
+   break;
+   }
+
+   case IC_START_VM: {
+   

[tip:x86/platform] x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

2019-06-11 Thread tip-bot for Zhao Yakui
Commit-ID:  498ad39368865dfdbf15d3516c43694947074b88
Gitweb: https://git.kernel.org/tip/498ad39368865dfdbf15d3516c43694947074b88
Author: Zhao Yakui 
AuthorDate: Tue, 30 Apr 2019 11:45:25 +0800
Committer:  Borislav Petkov 
CommitDate: Tue, 11 Jun 2019 21:31:31 +0200

x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

Use the HYPERVISOR_CALLBACK_VECTOR to notify an ACRN guest.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
Signed-off-by: Borislav Petkov 
Reviewed-by: Thomas Gleixner 
Cc: Andy Lutomirski 
Cc: "H. Peter Anvin" 
Cc: Ingo Molnar 
Cc: Thomas Gleixner 
Cc: x86-ml 
Link: 
https://lkml.kernel.org/r/1559108037-18813-4-git-send-email-yakui.z...@intel.com
---
 arch/x86/Kconfig|  1 +
 arch/x86/entry/entry_64.S   |  5 +
 arch/x86/include/asm/acrn.h | 11 +++
 arch/x86/kernel/cpu/acrn.c  | 30 ++
 4 files changed, 47 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 8a95c50e5c12..0ddcce78f85c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -838,6 +838,7 @@ config JAILHOUSE_GUEST
 config ACRN_GUEST
bool "ACRN Guest support"
depends on X86_64
+   select X86_HV_CALLBACK_VECTOR
help
  This option allows to run Linux as guest in the ACRN hypervisor. ACRN 
is
  a flexible, lightweight reference open-source hypervisor, built with
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 11aa3b2afa4d..2fe62893bbdf 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1142,6 +1142,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
+#if IS_ENABLED(CONFIG_ACRN_GUEST)
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+   acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
 idtentry debug do_debughas_error_code=0
paranoid=1 shift_ist=IST_INDEX_DB ist_offset=DB_STACK_OFFSET
 idtentry int3  do_int3 has_error_code=0
create_gap=1
 idtentry stack_segment do_stack_segmenthas_error_code=1
diff --git a/arch/x86/include/asm/acrn.h b/arch/x86/include/asm/acrn.h
new file mode 100644
index ..4adb13f08af7
--- /dev/null
+++ b/arch/x86/include/asm/acrn.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRN_H
+#define _ASM_X86_ACRN_H
+
+extern void acrn_hv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_acrn_hv_callback_vector acrn_hv_callback_vector
+#endif
+
+extern void acrn_hv_vector_handler(struct pt_regs *regs);
+#endif /* _ASM_X86_ACRN_H */
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index 6d365e97cce6..676022e71791 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -9,7 +9,12 @@
  *
  */
 
+#include 
+#include 
+#include 
+#include 
 #include 
+#include 
 
 static uint32_t __init acrn_detect(void)
 {
@@ -18,6 +23,8 @@ static uint32_t __init acrn_detect(void)
 
 static void __init acrn_init_platform(void)
 {
+   /* Setup the IDT for ACRN hypervisor callback */
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, acrn_hv_callback_vector);
 }
 
 static bool acrn_x2apic_available(void)
@@ -30,6 +37,29 @@ static bool acrn_x2apic_available(void)
return false;
 }
 
+static void (*acrn_intr_handler)(void);
+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   /*
+* The hypervisor requires that the APIC EOI should be acked.
+* If the APIC EOI is not acked, the APIC ISR bit for the
+* HYPERVISOR_CALLBACK_VECTOR will not be cleared and then it
+* will block the interrupt whose vector is lower than
+* HYPERVISOR_CALLBACK_VECTOR.
+*/
+   entering_ack_irq();
+   inc_irq_stat(irq_hv_callback_count);
+
+   if (acrn_intr_handler)
+   acrn_intr_handler();
+
+   exiting_irq();
+   set_irq_regs(old_regs);
+}
+
 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
.name   = "ACRN",
.detect = acrn_detect,


[tip:x86/platform] x86: Add support for Linux guests on an ACRN hypervisor

2019-06-11 Thread tip-bot for Zhao Yakui
Commit-ID:  ec7972c99fffb4d2739f286ce9b544a71aa1d05f
Gitweb: https://git.kernel.org/tip/ec7972c99fffb4d2739f286ce9b544a71aa1d05f
Author: Zhao Yakui 
AuthorDate: Tue, 30 Apr 2019 11:45:24 +0800
Committer:  Borislav Petkov 
CommitDate: Tue, 11 Jun 2019 21:29:22 +0200

x86: Add support for Linux guests on an ACRN hypervisor

ACRN is an open-source hypervisor maintained by The Linux Foundation. It
is built for embedded IOT with small footprint and real-time features.
Add ACRN guest support so that it allows Linux to be booted under the
ACRN hypervisor. This adds only the barebones implementation.

 [ bp: Massage commit message and help text. ]

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
Signed-off-by: Borislav Petkov 
Reviewed-by: Thomas Gleixner 
Cc: "H. Peter Anvin" 
Cc: Ingo Molnar 
Cc: Thomas Gleixner 
Cc: x86-ml 
Link: 
https://lkml.kernel.org/r/1559108037-18813-3-git-send-email-yakui.z...@intel.com
---
 arch/x86/Kconfig  | 10 ++
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 39 +++
 arch/x86/kernel/cpu/hypervisor.c  |  4 
 5 files changed, 55 insertions(+)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c9ab09004b16..8a95c50e5c12 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -835,6 +835,16 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
 
+config ACRN_GUEST
+   bool "ACRN Guest support"
+   depends on X86_64
+   help
+ This option allows to run Linux as guest in the ACRN hypervisor. ACRN 
is
+ a flexible, lightweight reference open-source hypervisor, built with
+ real-time and safety-criticality in mind. It is built for embedded
+ IOT with small footprint and real-time features. More details can be
+ found in https://projectacrn.org/.
+
 endif #HYPERVISOR_GUEST
 
 source "arch/x86/Kconfig.cpu"
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 8c5aaba6633f..50a30f6c668b 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -29,6 +29,7 @@ enum x86_hypervisor_type {
X86_HYPER_XEN_HVM,
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
+   X86_HYPER_ACRN,
 };
 
 #ifdef CONFIG_HYPERVISOR_GUEST
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 5102bf7c8192..3ffe1b0b7516 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_X86_CPU_RESCTRL) += resctrl/
 obj-$(CONFIG_X86_LOCAL_APIC)   += perfctr-watchdog.o
 
 obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
+obj-$(CONFIG_ACRN_GUEST)   += acrn.o
 
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
new file mode 100644
index ..6d365e97cce6
--- /dev/null
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACRN detection support
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ *
+ */
+
+#include 
+
+static uint32_t __init acrn_detect(void)
+{
+   return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+}
+
+static void __init acrn_init_platform(void)
+{
+}
+
+static bool acrn_x2apic_available(void)
+{
+   /*
+* x2apic is not supported for now. Future enablement will have to check
+* X86_FEATURE_X2APIC to determine whether x2apic is supported in the
+* guest.
+*/
+   return false;
+}
+
+const __initconst struct hypervisor_x86 x86_hyper_acrn = {
+   .name   = "ACRN",
+   .detect = acrn_detect,
+   .type   = X86_HYPER_ACRN,
+   .init.init_platform = acrn_init_platform,
+   .init.x2apic_available  = acrn_x2apic_available,
+};
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 479ca4728de0..87e39ad8d873 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -32,6 +32,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
 extern const struct hypervisor_x86 x86_hyper_xen_hvm;
 extern const struct hypervisor_x86 x86_hyper_kvm;
 extern const struct hypervisor_x86 x86_hyper_jailhouse;
+extern const struct hypervisor_x86 x86_hyper_acrn;
 
 static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
@@ -49,6 +50,9 @@ static const __initconst struct hypervisor_x86 * const 
hypervisors[] =
 #ifdef CONFIG_JAILHOUSE_GUEST
&x86_hyper_jailhouse,
 #endif
+#ifdef CONFIG_ACRN_GUEST
+   &x86_hyper_acrn,
+#endif
 };
 
 enum x86_hypervisor_type x86_hyper_type;


[tip:x86/platform] x86/Kconfig: Add new X86_HV_CALLBACK_VECTOR config symbol

2019-06-11 Thread tip-bot for Zhao Yakui
Commit-ID:  ecca25029473bee6e98ce062e76b7310904bbdd1
Gitweb: https://git.kernel.org/tip/ecca25029473bee6e98ce062e76b7310904bbdd1
Author: Zhao Yakui 
AuthorDate: Tue, 30 Apr 2019 11:45:23 +0800
Committer:  Borislav Petkov 
CommitDate: Tue, 11 Jun 2019 21:21:11 +0200

x86/Kconfig: Add new X86_HV_CALLBACK_VECTOR config symbol

Add a special Kconfig symbol X86_HV_CALLBACK_VECTOR so that the guests
using the hypervisor interrupt callback counter can select and thus
enable that counter. Select it when xen or hyperv support is enabled. No
functional changes.

Signed-off-by: Zhao Yakui 
Signed-off-by: Borislav Petkov 
Reviewed-by: Borislav Petkov 
Reviewed-by: Thomas Gleixner 
Cc: Boris Ostrovsky 
Cc: Frederic Weisbecker 
Cc: Haiyang Zhang 
Cc: "H. Peter Anvin" 
Cc: Ingo Molnar 
Cc: Juergen Gross 
Cc: "K. Y. Srinivasan" 
Cc: linux-hyp...@vger.kernel.org
Cc: Nicolai Stange 
Cc: Paolo Bonzini 
Cc: Peter Zijlstra 
Cc: Sasha Levin 
Cc: Stefano Stabellini 
Cc: Stephen Hemminger 
Cc: Thomas Gleixner 
Cc: x86-ml 
Cc: xen-de...@lists.xenproject.org
Link: 
https://lkml.kernel.org/r/1559108037-18813-2-git-send-email-yakui.z...@intel.com
---
 arch/x86/Kconfig   | 3 +++
 arch/x86/include/asm/hardirq.h | 2 +-
 arch/x86/kernel/irq.c  | 2 +-
 arch/x86/xen/Kconfig   | 1 +
 drivers/hv/Kconfig | 1 +
 5 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2bbbd4d1ba31..c9ab09004b16 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -781,6 +781,9 @@ config PARAVIRT_SPINLOCKS
 
  If you are unsure how to answer this question, answer Y.
 
+config X86_HV_CALLBACK_VECTOR
+   def_bool n
+
 source "arch/x86/xen/Kconfig"
 
 config KVM_GUEST
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d9069bb26c7f..07533795b8d2 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -37,7 +37,7 @@ typedef struct {
 #ifdef CONFIG_X86_MCE_AMD
unsigned int irq_deferred_error_count;
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
unsigned int irq_hv_callback_count;
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 9b68b5b00ac9..4e8f193ad81f 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -135,7 +135,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_puts(p, "  Machine check polls\n");
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j)
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index e07abefd3d26..ba5a41828e9d 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,6 +7,7 @@ config XEN
bool "Xen guest support"
depends on PARAVIRT
select PARAVIRT_CLOCK
+   select X86_HV_CALLBACK_VECTOR
depends on X86_64 || (X86_32 && X86_PAE)
depends on X86_LOCAL_APIC && X86_TSC
help
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 1c1a2514d6f3..cafcb974dcfe 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -6,6 +6,7 @@ config HYPERV
tristate "Microsoft Hyper-V client drivers"
depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
select PARAVIRT
+   select X86_HV_CALLBACK_VECTOR
help
  Select this option to run Linux as a Hyper-V client operating
  system.


[PATCH v7 3/3] x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

2019-05-28 Thread Zhao Yakui
Linux kernel uses the HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall
vector. It is already used for Xen and HyperV.
After the ACRN hypervisor is detected, it will also use this defined
vector to notify the ACRN guest.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
Reviewed-by: Thomas Gleixner 
---
V1->V2: Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.

v2->v3: No change
v3->v4: Refine the file name of acrnhyper.h to acrn.h
v5->v6: Add the "extern" for the function declarations in header file
Add some comments for calling entering_ack_irq
Some other minor changes(unnecessary spliting two lines.
and minor change in commit log)
v6->v7: Include the header file of asm/apic.h to fix the buidling error
when enabling cflags="-Werror=implict-function-declaration".
---
 arch/x86/Kconfig|  1 +
 arch/x86/entry/entry_64.S   |  5 +
 arch/x86/include/asm/acrn.h | 11 +++
 arch/x86/kernel/cpu/acrn.c  | 30 ++
 4 files changed, 47 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 3020bc7..170d5cf 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -838,6 +838,7 @@ config JAILHOUSE_GUEST
 config ACRN_GUEST
bool "ACRN Guest support"
depends on X86_64
+   select X86_HV_CALLBACK_VECTOR
help
  This option allows to run Linux as guest in ACRN hypervisor. Enabling
  this will allow the kernel to boot in virtualized environment under
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 11aa3b2..2fe6289 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1142,6 +1142,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
+#if IS_ENABLED(CONFIG_ACRN_GUEST)
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+   acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
 idtentry debug do_debughas_error_code=0
paranoid=1 shift_ist=IST_INDEX_DB ist_offset=DB_STACK_OFFSET
 idtentry int3  do_int3 has_error_code=0
create_gap=1
 idtentry stack_segment do_stack_segmenthas_error_code=1
diff --git a/arch/x86/include/asm/acrn.h b/arch/x86/include/asm/acrn.h
new file mode 100644
index 000..4adb13f
--- /dev/null
+++ b/arch/x86/include/asm/acrn.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRN_H
+#define _ASM_X86_ACRN_H
+
+extern void acrn_hv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_acrn_hv_callback_vector acrn_hv_callback_vector
+#endif
+
+extern void acrn_hv_vector_handler(struct pt_regs *regs);
+#endif /* _ASM_X86_ACRN_H */
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index f556640..a110c8b 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -9,7 +9,12 @@
  *
  */
 
+#include 
+#include 
+#include 
+#include 
 #include 
+#include 
 
 static uint32_t __init acrn_detect(void)
 {
@@ -18,6 +23,8 @@ static uint32_t __init acrn_detect(void)
 
 static void __init acrn_init_platform(void)
 {
+   /* Setup the IDT for ACRN hypervisor callback */
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, acrn_hv_callback_vector);
 }
 
 static bool acrn_x2apic_available(void)
@@ -30,6 +37,29 @@ static bool acrn_x2apic_available(void)
return false;
 }
 
+static void (*acrn_intr_handler)(void);
+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   /*
+* The hypervisor requires that the APIC EOI should be acked.
+* If the APIC EOI is not acked, the APIC ISR bit for the
+* HYPERVISOR_CALLBACK_VECTOR will not be cleared and then it
+* will block the interrupt whose vector is lower than
+* HYPERVISOR_CALLBACK_VECTOR.
+*/
+   entering_ack_irq();
+   inc_irq_stat(irq_hv_callback_count);
+
+   if (acrn_intr_handler)
+   acrn_intr_handler();
+
+   exiting_irq();
+   set_irq_regs(old_regs);
+}
+
 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
.name   = "ACRN",
.detect = acrn_detect,
-- 
2.7.4



[PATCH v7 1/3] x86/Kconfig: Add new config symbol to unify conditional definition of hv_irq_callback_count

2019-05-28 Thread Zhao Yakui
Add a special Kconfig symbol X86_HV_CALLBACK_VECTOR so that the guests
using the hypervisor interrupt callback counter can select and thus
enable that counter. Select it when xen or hyperv support is enabled.
No functional changes.

Signed-off-by: Zhao Yakui 
Reviewed-by: Borislav Petkov 
Reviewed-by: Thomas Gleixner 
---
v3->v4: Follow the comments to refine the commit log.
---
 arch/x86/Kconfig   | 3 +++
 arch/x86/include/asm/hardirq.h | 2 +-
 arch/x86/kernel/irq.c  | 2 +-
 arch/x86/xen/Kconfig   | 1 +
 drivers/hv/Kconfig | 1 +
 5 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2bbbd4d..c9ab090 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -781,6 +781,9 @@ config PARAVIRT_SPINLOCKS
 
  If you are unsure how to answer this question, answer Y.
 
+config X86_HV_CALLBACK_VECTOR
+   def_bool n
+
 source "arch/x86/xen/Kconfig"
 
 config KVM_GUEST
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d9069bb..0753379 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -37,7 +37,7 @@ typedef struct {
 #ifdef CONFIG_X86_MCE_AMD
unsigned int irq_deferred_error_count;
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
unsigned int irq_hv_callback_count;
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 9b68b5b..4e8f193 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -135,7 +135,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_puts(p, "  Machine check polls\n");
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j)
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index e07abef..ba5a418 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,6 +7,7 @@ config XEN
bool "Xen guest support"
depends on PARAVIRT
select PARAVIRT_CLOCK
+   select X86_HV_CALLBACK_VECTOR
depends on X86_64 || (X86_32 && X86_PAE)
depends on X86_LOCAL_APIC && X86_TSC
help
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 1c1a251..cafcb97 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -6,6 +6,7 @@ config HYPERV
tristate "Microsoft Hyper-V client drivers"
depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
select PARAVIRT
+   select X86_HV_CALLBACK_VECTOR
help
  Select this option to run Linux as a Hyper-V client operating
  system.
-- 
2.7.4



[PATCH v7 2/3] x86: Add the support of Linux guest on ACRN hypervisor

2019-05-28 Thread Zhao Yakui
ACRN is an open-source hypervisor maintained by Linux Foundation.
It is built for embedded IOT with small footprint and real-time features.
Add the ACRN guest support so that it allows linux to be booted under the
ACRN hypervisor. Following this patch it will setup the upcall
notification vector, enable hypercall and provide the interface that is
used to manage the virtualized CPU/memory/device/interrupt for other
guest OS.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
Reviewed-by: Thomas Gleixner 
---
v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.

v2->v3: Remove the unnecessary dependency of PARAVIRT
v3->v4: Refine the commit log and add more meaningful description in Kconfig
v4->v5: No change
v5->v6: No change
v6->v7: No change
---
 arch/x86/Kconfig  | 12 
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 39 +++
 arch/x86/kernel/cpu/hypervisor.c  |  4 
 5 files changed, 57 insertions(+)
 create mode 100644 arch/x86/kernel/cpu/acrn.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c9ab090..3020bc7 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -835,6 +835,18 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
 
+config ACRN_GUEST
+   bool "ACRN Guest support"
+   depends on X86_64
+   help
+ This option allows to run Linux as guest in ACRN hypervisor. Enabling
+ this will allow the kernel to boot in virtualized environment under
+ the ACRN hypervisor.
+ ACRN is a flexible, lightweight reference open-source hypervisor, 
built
+ with real-time and safety-criticality in mind. It is built for 
embedded
+ IOT with small footprint and real-time features. More details can be
+ found in https://projectacrn.org/
+
 endif #HYPERVISOR_GUEST
 
 source "arch/x86/Kconfig.cpu"
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 8c5aaba..50a30f6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -29,6 +29,7 @@ enum x86_hypervisor_type {
X86_HYPER_XEN_HVM,
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
+   X86_HYPER_ACRN,
 };
 
 #ifdef CONFIG_HYPERVISOR_GUEST
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 1796d2b..b9b3017 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_X86_CPU_RESCTRL) += resctrl/
 obj-$(CONFIG_X86_LOCAL_APIC)   += perfctr-watchdog.o
 
 obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
+obj-$(CONFIG_ACRN_GUEST)   += acrn.o
 
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
new file mode 100644
index 000..f556640
--- /dev/null
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACRN detection support
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ *
+ */
+
+#include 
+
+static uint32_t __init acrn_detect(void)
+{
+   return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+}
+
+static void __init acrn_init_platform(void)
+{
+}
+
+static bool acrn_x2apic_available(void)
+{
+   /* x2apic is not supported now.
+* Later it needs to check the X86_FEATURE_X2APIC bit of cpu info
+* returned by CPUID to determine whether the x2apic is
+* supported in Linux guest.
+*/
+   return false;
+}
+
+const __initconst struct hypervisor_x86 x86_hyper_acrn = {
+   .name   = "ACRN",
+   .detect = acrn_detect,
+   .type   = X86_HYPER_ACRN,
+   .init.init_platform = acrn_init_platform,
+   .init.x2apic_available  = acrn_x2apic_available,
+};
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 479ca47..87e39ad 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -32,6 +32,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
 extern const struct hypervisor_x86 x86_hyper_xen_hvm;
 extern const struct hypervisor_x86 x86_hyper_kvm;
 extern const struct hypervisor_x86 x86_hyper_jailhouse;
+extern const struct hypervisor_x86 x86_hyper_acrn;
 
 static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
@@ -49,6 +50,9 @@ static const __initconst struct hypervisor_x86 * const 
hypervisors[] =
 #ifdef CONFIG_JAILHOUSE_GUEST
&x86_hyper_jailhouse,
 #endif
+#ifdef CONFIG_ACRN_GUEST
+ 

[PATCH v7 0/3] x86: Add the support of ACRN guest under x86

2019-05-28 Thread Zhao Yakui
ACRN is a flexible, lightweight reference hypervisor, built with real-time
and safety-criticality in mind, optimized to streamline embedded development
through an open source platform. It is built for embedded IOT with small
footprint and real-time features. More details can be found
in https://projectacrn.org/

This is the patch set that allows the Linux to work on ACRN hypervisor and it 
can
work with the following patch set to manage the Linux guest on ACRN hypervisor. 
It
includes the detection of ACRN hypervisor, upcall notification vector from
hypervisor, hypercall. The hypervisor detection is similar to Xen/VMWARE/Hyperv.
ACRN also uses the upcall notification mechanism similar to that in 
Xen/Microsoft
HyperV when it needs to send the notification to Linux guest. The hypercall 
provides
the mechanism that can be used to query/configure the ACRN hypervisor by Linux 
guest.

Following this patch set, we will send acrn driver part, which provides the 
interface
that can be used to manage the virtualized CPU/memory/device/interrupt for 
other guest
OS after the ACRN hypervisor is detected.

v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.
Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.
Refine the comments for the function of acrn_hypercall0/1/2

v2-v3:  Add one new config symbol to unify the conditional definition
of hv_irq_callback_count
Use the "vmcall" mnemonic to replace the hard-code byte definition
Remove the unnecessary dependency of CONFIG_PARAVIRT for ACRN_GUEST

v3-v4:  Rename the file name of acrnhyper.h to acrn.h
Refine the commit log and some other minor changes(more comments and 
redundant ifdef in acrn.h, sorting the header file in acrn.c)

v4->v5: Minor changes of comments/commit log in patch 04
Use _ASM_X86_ACRN_HYPERCALL_H instead of _ASM_X86_ACRNHYPERCALL_H.
Use the "VMCALL" mnemonic in comment/commit log.
Uppercase r8/rdi/rsi/rax for hypercall parameter register in comment.

v5->v6: Remove the explicit register variable for inline assembly
Add the "extern" for the function declaration in acrn.h
Add comments about acking ACPI EOI in acrn_hv_callback_handler
Minor changes for comments/commit log in patch 03/04

v6->v7: Add the missing header file of asm/apic.h in acrn.c
Remove the definition of ACRN hypercall as it is not used in this
patch set.


Zhao Yakui (3):
  x86/Kconfig: Add new config symbol to unify conditional definition of
hv_irq_callback_count
  x86: Add the support of Linux guest on ACRN hypervisor
  x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

 arch/x86/Kconfig  | 16 +
 arch/x86/entry/entry_64.S |  5 +++
 arch/x86/include/asm/acrn.h   | 11 +++
 arch/x86/include/asm/hardirq.h|  2 +-
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 69 +++
 arch/x86/kernel/cpu/hypervisor.c  |  4 +++
 arch/x86/kernel/irq.c |  2 +-
 arch/x86/xen/Kconfig  |  1 +
 drivers/hv/Kconfig|  1 +
 11 files changed, 111 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/acrn.h
 create mode 100644 arch/x86/kernel/cpu/acrn.c

-- 
2.7.4



Re: [PATCH v6 4/4] x86/acrn: Add hypercall for ACRN guest

2019-05-27 Thread Zhao, Yakui




On 2019年05月28日 06:46, Borislav Petkov wrote:

On Mon, May 27, 2019 at 10:57:09AM +0800, Zhao, Yakui wrote:

I refer to the Xen/KVM hypercall to add the ACRN hypercall in one separate
header.


And?


The ACRN hypercall is defined in one separate acrn_hypercall.h and can be
included explicitly by the *.c that needs the hypercall.


Sure but what else will need the hypercall definition except stuff which
already needs acrn.h? I.e., why is the separate header needed?


In fact there is no much difference that it is defined in acrn.h or one 
separate header file.
When it is sent with the driver stuff, I will add the hypercall into 
acrn.h. If the further extension is needed, we can then consider whether 
it is necessary to be moved into the separate header file.


My initial thought is that the acrn.h/acrn_hypercall.h defines the 
different contents.  Then the each source file in ACRN driver part can 
include "acrn.h" or "acrn_hypercall.h" based on its requirement.
Of course it is also ok that they are added in one header file. Then it 
is always included.





The hypercall will be used in driver part. Before the driver part is added,
it seems that the defined ACRN hypercall functions are not used.
Do I need to add these functions together with driver part?


Yes, send functions together with the stuff which uses them pls.


Sure.



Thx.



Re: [PATCH v6 4/4] x86/acrn: Add hypercall for ACRN guest

2019-05-26 Thread Zhao, Yakui




On 2019年05月15日 15:37, Borislav Petkov wrote:

On Tue, Apr 30, 2019 at 11:45:26AM +0800, Zhao Yakui wrote:

When the ACRN hypervisor is detected, the hypercall is needed so that the
ACRN guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for guest operating system.

Add the hypercall so that the ACRN guest can communicate with the
low-level ACRN hypervisor. On x86 it is implemented with the VMCALL
instruction.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
Reviewed-by: Thomas Gleixner 
---
V1->V2: Refine the comments for the function of acrn_hypercall0/1/2
v2->v3: Use the "vmcall" mnemonic to replace hard-code byte definition
v4->v5: Use _ASM_X86_ACRN_HYPERCALL_H instead of _ASM_X86_ACRNHYPERCALL_H.
 Use the "VMCALL" mnemonic in comment/commit log.
 Uppercase r8/rdi/rsi/rax for hypercall parameter register in comment.
v5->v6: Remove explicit local register variable for inline assembly
---
  arch/x86/include/asm/acrn_hypercall.h | 84 +++
  1 file changed, 84 insertions(+)
  create mode 100644 arch/x86/include/asm/acrn_hypercall.h

diff --git a/arch/x86/include/asm/acrn_hypercall.h 
b/arch/x86/include/asm/acrn_hypercall.h
new file mode 100644
index 000..5cb438e
--- /dev/null
+++ b/arch/x86/include/asm/acrn_hypercall.h


Questions:

* why isn't this in acrn.h and needs to be a separate header?


I refer to the Xen/KVM hypercall to add the ACRN hypercall in one 
separate header.


The ACRN hypercall is defined in one separate acrn_hypercall.h and can 
be included explicitly by the *.c that needs the hypercall.





* why aren't those functions used anywhere?


The hypercall will be used in driver part. Before the driver part is 
added, it seems that the defined ACRN hypercall functions are not used.

Do I need to add these functions together with driver part?

Thanks
   Yakui




Re: [PATCH v6 3/4] x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

2019-05-26 Thread Zhao, Yakui




On 2019年05月16日 01:23, Borislav Petkov wrote:

On Tue, Apr 30, 2019 at 11:45:25AM +0800, Zhao Yakui wrote:

@@ -30,6 +36,29 @@ static bool acrn_x2apic_available(void)
return false;
  }
  
+static void (*acrn_intr_handler)(void);

+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   /*
+* The hypervisor requires that the APIC EOI should be acked.
+* If the APIC EOI is not acked, the APIC ISR bit for the
+* HYPERVISOR_CALLBACK_VECTOR will not be cleared and then it
+* will block the interrupt whose vector is lower than
+* HYPERVISOR_CALLBACK_VECTOR.
+*/
+   entering_ack_irq();


Sorry for the late response.

You are right. The "asm/apic.h" is missing.
It will be added.
Very sorry that this issue is not triggered as the used .config in my 
test doesn't enable the check of "-Werror=implict-function-declaration".




arch/x86/kernel/cpu/acrn.c: In function ‘acrn_hv_vector_handler’:
arch/x86/kernel/cpu/acrn.c:52:2: error: implicit declaration of function 
‘entering_ack_irq’; did you mean ‘spin_lock_irq’? 
[-Werror=implicit-function-declaration]
   entering_ack_irq();
   ^~~~
   spin_lock_irq
arch/x86/kernel/cpu/acrn.c:58:2: error: implicit declaration of function 
‘exiting_irq’; did you mean ‘in_irq’? [-Werror=implicit-function-declaration]
   exiting_irq();
   ^~~
   in_irq
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:278: arch/x86/kernel/cpu/acrn.o] Error 1
make[3]: *** Waiting for unfinished jobs
make[2]: *** [scripts/Makefile.build:489: arch/x86/kernel/cpu] Error 2
make[1]: *** [scripts/Makefile.build:489: arch/x86/kernel] Error 2
make: *** [Makefile:1073: arch/x86] Error 2
make: *** Waiting for unfinished jobs

Looks like it needs

+#include 

config attached.



[PATCH v6 0/4] x86: Add the support of ACRN guest under x86

2019-04-29 Thread Zhao Yakui
ACRN is a flexible, lightweight reference hypervisor, built with real-time
and safety-criticality in mind, optimized to streamline embedded development
through an open source platform. It is built for embedded IOT with small
footprint and real-time features. More details can be found
in https://projectacrn.org/

This is the patch set that allows the Linux to work on ACRN hypervisor and it 
can
work with the following patch set to manage the Linux guest on ACRN hypervisor. 
It
includes the detection of ACRN hypervisor, upcall notification vector from
hypervisor, hypercall. The hypervisor detection is similar to Xen/VMWARE/Hyperv.
ACRN also uses the upcall notification mechanism similar to that in 
Xen/Microsoft
HyperV when it needs to send the notification to Linux guest. The hypercall 
provides
the mechanism that can be used to query/configure the ACRN hypervisor by Linux 
guest.

Following this patch set, we will send acrn driver part, which provides the 
interface
that can be used to manage the virtualized CPU/memory/device/interrupt for 
other guest
OS after the ACRN hypervisor is detected.

v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.
Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.
Refine the comments for the function of acrn_hypercall0/1/2

v2-v3:  Add one new config symbol to unify the conditional definition
of hv_irq_callback_count
Use the "vmcall" mnemonic to replace the hard-code byte definition
Remove the unnecessary dependency of CONFIG_PARAVIRT for ACRN_GUEST

v3-v4:  Rename the file name of acrnhyper.h to acrn.h
Refine the commit log and some other minor changes(more comments and 
redundant ifdef in acrn.h, sorting the header file in acrn.c)

v4->v5: Minor changes of comments/commit log in patch 04
Use _ASM_X86_ACRN_HYPERCALL_H instead of _ASM_X86_ACRNHYPERCALL_H.
Use the "VMCALL" mnemonic in comment/commit log.
Uppercase r8/rdi/rsi/rax for hypercall parameter register in comment.

v5->v6: Remove the explicit register variable for inline assembly
Add the "extern" for the function declaration in acrn.h
Add comments about acking ACPI EOI in acrn_hv_callback_handler
Minor changes for comments/commit log in patch 03/04


Zhao Yakui (4):
  x86/Kconfig: Add new config symbol to unify conditional definition of
hv_irq_callback_count
  x86: Add the support of Linux guest on ACRN hypervisor
  x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector
  x86/acrn: Add hypercall for ACRN guest

 arch/x86/Kconfig  | 16 +++
 arch/x86/entry/entry_64.S |  5 +++
 arch/x86/include/asm/acrn.h   | 11 +
 arch/x86/include/asm/acrn_hypercall.h | 84 +++
 arch/x86/include/asm/hardirq.h|  2 +-
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 68 
 arch/x86/kernel/cpu/hypervisor.c  |  4 ++
 arch/x86/kernel/irq.c |  2 +-
 arch/x86/xen/Kconfig  |  1 +
 drivers/hv/Kconfig|  1 +
 12 files changed, 194 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/acrn.h
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h
 create mode 100644 arch/x86/kernel/cpu/acrn.c

-- 
2.7.4



[PATCH v6 1/4] x86/Kconfig: Add new config symbol to unify conditional definition of hv_irq_callback_count

2019-04-29 Thread Zhao Yakui
Add a special Kconfig symbol X86_HV_CALLBACK_VECTOR so that the guests
using the hypervisor interrupt callback counter can select and thus
enable that counter. Select it when xen or hyperv support is enabled.
No functional changes.

Signed-off-by: Zhao Yakui 
Reviewed-by: Borislav Petkov 
Reviewed-by: Thomas Gleixner 
---
v3->v4: Follow the comments to refine the commit log.
---
 arch/x86/Kconfig   | 3 +++
 arch/x86/include/asm/hardirq.h | 2 +-
 arch/x86/kernel/irq.c  | 2 +-
 arch/x86/xen/Kconfig   | 1 +
 drivers/hv/Kconfig | 1 +
 5 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 62fc3fd..2fc9297 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -791,6 +791,9 @@ config QUEUED_LOCK_STAT
  behavior of paravirtualized queued spinlocks and report
  them on debugfs.
 
+config X86_HV_CALLBACK_VECTOR
+   def_bool n
+
 source "arch/x86/xen/Kconfig"
 
 config KVM_GUEST
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d9069bb..0753379 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -37,7 +37,7 @@ typedef struct {
 #ifdef CONFIG_X86_MCE_AMD
unsigned int irq_deferred_error_count;
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
unsigned int irq_hv_callback_count;
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 59b5f2e..a147826 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -134,7 +134,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_puts(p, "  Machine check polls\n");
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j)
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index e07abef..ba5a418 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,6 +7,7 @@ config XEN
bool "Xen guest support"
depends on PARAVIRT
select PARAVIRT_CLOCK
+   select X86_HV_CALLBACK_VECTOR
depends on X86_64 || (X86_32 && X86_PAE)
depends on X86_LOCAL_APIC && X86_TSC
help
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 1c1a251..cafcb97 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -6,6 +6,7 @@ config HYPERV
tristate "Microsoft Hyper-V client drivers"
depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
select PARAVIRT
+   select X86_HV_CALLBACK_VECTOR
help
  Select this option to run Linux as a Hyper-V client operating
  system.
-- 
2.7.4



[PATCH v6 4/4] x86/acrn: Add hypercall for ACRN guest

2019-04-29 Thread Zhao Yakui
When the ACRN hypervisor is detected, the hypercall is needed so that the
ACRN guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for guest operating system.

Add the hypercall so that the ACRN guest can communicate with the
low-level ACRN hypervisor. On x86 it is implemented with the VMCALL
instruction.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
Reviewed-by: Thomas Gleixner 
---
V1->V2: Refine the comments for the function of acrn_hypercall0/1/2
v2->v3: Use the "vmcall" mnemonic to replace hard-code byte definition
v4->v5: Use _ASM_X86_ACRN_HYPERCALL_H instead of _ASM_X86_ACRNHYPERCALL_H.
Use the "VMCALL" mnemonic in comment/commit log.
Uppercase r8/rdi/rsi/rax for hypercall parameter register in comment.
v5->v6: Remove explicit local register variable for inline assembly
---
 arch/x86/include/asm/acrn_hypercall.h | 84 +++
 1 file changed, 84 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h

diff --git a/arch/x86/include/asm/acrn_hypercall.h 
b/arch/x86/include/asm/acrn_hypercall.h
new file mode 100644
index 000..5cb438e
--- /dev/null
+++ b/arch/x86/include/asm/acrn_hypercall.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_X86_ACRN_HYPERCALL_H
+#define _ASM_X86_ACRN_HYPERCALL_H
+
+#include 
+
+#ifdef CONFIG_ACRN_GUEST
+
+/*
+ * Hypercalls for ACRN guest
+ *
+ * Hypercall number is passed in R8 register.
+ * Up to 2 arguments are passed in RDI, RSI.
+ * Return value will be placed in RAX.
+ */
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   long result;
+
+   /* the hypercall is implemented with the VMCALL instruction.
+* volatile qualifier is added to avoid that it is dropped
+* because of compiler optimization.
+*/
+   asm volatile("movq %[hcall_id], %%r8\n\t"
+"vmcall\n\t"
+: "=a" (result)
+: [hcall_id] "g" (hcall_id)
+: "r8");
+
+   return result;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   long result;
+
+   asm volatile("movq %[hcall_id], %%r8\n\t"
+"vmcall\n\t"
+: "=a" (result)
+: [hcall_id] "g" (hcall_id), "D" (param1)
+: "r8");
+
+   return result;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   long result;
+
+   asm volatile("movq %[hcall_id], %%r8\n\t"
+"vmcall\n\t"
+: "=a" (result)
+: [hcall_id] "g" (hcall_id), "D" (param1), "S" (param2)
+: "r8");
+
+   return result;
+}
+
+#else
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   return -ENOTSUPP;
+}
+#endif /* CONFIG_ACRN_GUEST */
+#endif /* _ASM_X86_ACRN_HYPERCALL_H */
-- 
2.7.4



[PATCH v6 2/4] x86: Add the support of Linux guest on ACRN hypervisor

2019-04-29 Thread Zhao Yakui
ACRN is an open-source hypervisor maintained by Linux Foundation.
It is built for embedded IOT with small footprint and real-time features.
Add the ACRN guest support so that it allows linux to be booted under the
ACRN hypervisor. Following this patch it will setup the upcall
notification vector, enable hypercall and provide the interface that is
used to manage the virtualized CPU/memory/device/interrupt for other
guest OS.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
Reviewed-by: Thomas Gleixner 
---
v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.

v2->v3: Remove the unnecessary dependency of PARAVIRT
v3->v4: Refine the commit log and add more meaningful description in Kconfig
v4->v5: No change
v5->v6: No change
---
 arch/x86/Kconfig  | 12 
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 39 +++
 arch/x86/kernel/cpu/hypervisor.c  |  4 
 5 files changed, 57 insertions(+)
 create mode 100644 arch/x86/kernel/cpu/acrn.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2fc9297..8dc4200 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -845,6 +845,18 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
 
+config ACRN_GUEST
+   bool "ACRN Guest support"
+   depends on X86_64
+   help
+ This option allows to run Linux as guest in ACRN hypervisor. Enabling
+ this will allow the kernel to boot in virtualized environment under
+ the ACRN hypervisor.
+ ACRN is a flexible, lightweight reference open-source hypervisor, 
built
+ with real-time and safety-criticality in mind. It is built for 
embedded
+ IOT with small footprint and real-time features. More details can be
+ found in https://projectacrn.org/
+
 endif #HYPERVISOR_GUEST
 
 source "arch/x86/Kconfig.cpu"
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 8c5aaba..50a30f6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -29,6 +29,7 @@ enum x86_hypervisor_type {
X86_HYPER_XEN_HVM,
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
+   X86_HYPER_ACRN,
 };
 
 #ifdef CONFIG_HYPERVISOR_GUEST
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index cfd24f9..17a7cdf 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_X86_CPU_RESCTRL) += resctrl/
 obj-$(CONFIG_X86_LOCAL_APIC)   += perfctr-watchdog.o
 
 obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
+obj-$(CONFIG_ACRN_GUEST)   += acrn.o
 
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
new file mode 100644
index 000..f556640
--- /dev/null
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACRN detection support
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ *
+ */
+
+#include 
+
+static uint32_t __init acrn_detect(void)
+{
+   return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+}
+
+static void __init acrn_init_platform(void)
+{
+}
+
+static bool acrn_x2apic_available(void)
+{
+   /* x2apic is not supported now.
+* Later it needs to check the X86_FEATURE_X2APIC bit of cpu info
+* returned by CPUID to determine whether the x2apic is
+* supported in Linux guest.
+*/
+   return false;
+}
+
+const __initconst struct hypervisor_x86 x86_hyper_acrn = {
+   .name   = "ACRN",
+   .detect = acrn_detect,
+   .type   = X86_HYPER_ACRN,
+   .init.init_platform = acrn_init_platform,
+   .init.x2apic_available  = acrn_x2apic_available,
+};
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 479ca47..87e39ad 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -32,6 +32,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
 extern const struct hypervisor_x86 x86_hyper_xen_hvm;
 extern const struct hypervisor_x86 x86_hyper_kvm;
 extern const struct hypervisor_x86 x86_hyper_jailhouse;
+extern const struct hypervisor_x86 x86_hyper_acrn;
 
 static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
@@ -49,6 +50,9 @@ static const __initconst struct hypervisor_x86 * const 
hypervisors[] =
 #ifdef CONFIG_JAILHOUSE_GUEST
&x86_hyper_jailhouse,
 #endif
+#ifdef CONFIG_ACRN_GUEST
+   &x86_hyp

[PATCH v6 3/4] x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

2019-04-29 Thread Zhao Yakui
Linux kernel uses the HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall
vector. It is already used for Xen and HyperV.
After the ACRN hypervisor is detected, it will also use this defined
vector to notify the ACRN guest.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
Reviewed-by: Thomas Gleixner 
---
V1->V2: Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.

v2->v3: No change
v3->v4: Refine the file name of acrnhyper.h to acrn.h
v5->v6: Add the "extern" for the function declarations in header file
Add some comments for calling entering_ack_irq
Some other minor changes(unnecessary spliting two lines.
and minor change in commit log)
---
 arch/x86/Kconfig|  1 +
 arch/x86/entry/entry_64.S   |  5 +
 arch/x86/include/asm/acrn.h | 11 +++
 arch/x86/kernel/cpu/acrn.c  | 29 +
 4 files changed, 46 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 8dc4200..d7a10f6 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -848,6 +848,7 @@ config JAILHOUSE_GUEST
 config ACRN_GUEST
bool "ACRN Guest support"
depends on X86_64
+   select X86_HV_CALLBACK_VECTOR
help
  This option allows to run Linux as guest in ACRN hypervisor. Enabling
  this will allow the kernel to boot in virtualized environment under
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 1f0efdb..d1b8ad3 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1129,6 +1129,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
+#if IS_ENABLED(CONFIG_ACRN_GUEST)
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+   acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
 idtentry debug do_debughas_error_code=0
paranoid=1 shift_ist=DEBUG_STACK
 idtentry int3  do_int3 has_error_code=0
 idtentry stack_segment do_stack_segmenthas_error_code=1
diff --git a/arch/x86/include/asm/acrn.h b/arch/x86/include/asm/acrn.h
new file mode 100644
index 000..4adb13f
--- /dev/null
+++ b/arch/x86/include/asm/acrn.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRN_H
+#define _ASM_X86_ACRN_H
+
+extern void acrn_hv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_acrn_hv_callback_vector acrn_hv_callback_vector
+#endif
+
+extern void acrn_hv_vector_handler(struct pt_regs *regs);
+#endif /* _ASM_X86_ACRN_H */
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index f556640..ce88d2d 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -9,7 +9,11 @@
  *
  */
 
+#include 
+#include 
+#include 
 #include 
+#include 
 
 static uint32_t __init acrn_detect(void)
 {
@@ -18,6 +22,8 @@ static uint32_t __init acrn_detect(void)
 
 static void __init acrn_init_platform(void)
 {
+   /* Setup the IDT for ACRN hypervisor callback */
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, acrn_hv_callback_vector);
 }
 
 static bool acrn_x2apic_available(void)
@@ -30,6 +36,29 @@ static bool acrn_x2apic_available(void)
return false;
 }
 
+static void (*acrn_intr_handler)(void);
+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   /*
+* The hypervisor requires that the APIC EOI should be acked.
+* If the APIC EOI is not acked, the APIC ISR bit for the
+* HYPERVISOR_CALLBACK_VECTOR will not be cleared and then it
+* will block the interrupt whose vector is lower than
+* HYPERVISOR_CALLBACK_VECTOR.
+*/
+   entering_ack_irq();
+   inc_irq_stat(irq_hv_callback_count);
+
+   if (acrn_intr_handler)
+   acrn_intr_handler();
+
+   exiting_irq();
+   set_irq_regs(old_regs);
+}
+
 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
.name   = "ACRN",
.detect = acrn_detect,
-- 
2.7.4



Re: [RFC PATCH v5 4/4] x86/acrn: Add hypercall for ACRN guest

2019-04-29 Thread Zhao, Yakui




On 2019年04月29日 15:36, Borislav Petkov wrote:

On Mon, Apr 29, 2019 at 09:24:12AM +0800, Zhao, Yakui wrote:

Yes. "movq" only indicates explicitly that it is 64-bit mov as ACRN guest
only works under 64-bit mode.
I also check the usage of "mov" and "movq" in this scenario. There is no
difference except that the movq is an explicit 64-op.


Damn, I'm tired of explaining this: it is explicit only to the code
reader. gcc generates the *same* instruction no matter whether it has a
"q" suffix or not as long as the destination register is a 64-bit one.

If you prefer to have it explicit, sure, use "movq".


Hi, Borislav

Thanks for the detailed explanation.
"movq" will be used so that it is explicit to the code reader 
although the same binary is generated for "movq" and "mov" in this scenario.


And thank you again for giving a lot of helps about removing the 
usage of explicit register variable.


Best regards
   Yakui




Re: [RFC PATCH v5 4/4] x86/acrn: Add hypercall for ACRN guest

2019-04-28 Thread Zhao, Yakui




On 2019年04月28日 18:03, Borislav Petkov wrote:

On Sun, Apr 28, 2019 at 09:56:35AM +0800, Zhao, Yakui wrote:

Thanks for the reminder about the access width.
It is 64-bit register. What I said is the "movq", not "movl".
(I understand that movl is incorrect for 64-bit register).


I didn't say anything about movl. I think what you're trying to say is
that because your inputs like hcall_id and param1/2 are unsigned longs,
you want a 64-bit move.


Yes. "movq" only indicates explicitly that it is 64-bit mov as ACRN 
guest only works under 64-bit mode.
I also check the usage of "mov" and "movq" in this scenario. There is no 
difference except that the movq is an explicit 64-op.

Of course "mov" is also ok to me that if you prefer the "mov".

Thanks
  Yakui




Re: [RFC PATCH v5 4/4] x86/acrn: Add hypercall for ACRN guest

2019-04-27 Thread Zhao, Yakui




On 2019年04月27日 16:58, Borislav Petkov wrote:

On Fri, Apr 26, 2019 at 11:18:48AM +0800, Zhao, Yakui wrote:

It seems that it is seldom used in kernel although the explicit register
variable is supported by GCC and makes the code look simpler. And it seems
that the explicit register variable is not suppoorted by CLAG.


The more reason not to do it this way. Also, the "register" variable
specification is not very widespread in x86 when you look at

$ git grep -E "register\s.*asm" arch/x86/

output.


Yes.  The explicit register variable is not very videspread for arch/x86.
So the register variable will be removed for ACRN hypercall.




So the explicit register variable will be removed. I will follow the asm
code from Borislav. Of course one minor change is that the "movq" is used
instead of "mov".


Does that matter if your destination register is 64-bit?


Thanks for the reminder about the access width.
It is 64-bit register. What I said is the "movq", not "movl".
(I understand that movl is incorrect for 64-bit register).


Thanks
Yakui



Re: [RFC PATCH v5 4/4] x86/acrn: Add hypercall for ACRN guest

2019-04-25 Thread Zhao, Yakui




On 2019年04月25日 19:00, Borislav Petkov wrote:

On Thu, Apr 25, 2019 at 06:16:02PM +0800, Zhao, Yakui wrote:

The parameter register for the VMCALL is predefined in ACRN hypervisor. Now
the R8 is used to pass the hcall_id.
It seems that there is no special constraint for R8~R15.
So the explicit register variable is used so that the R8 can be passed.


If you're going to use the constraint "D" for param1, you can just as
well do

"=a" (result)

everywhere since you have the letter constraint for %rax instead of
declaring it with "register".

Also, you can completely get rid of those "register" declarations
and let gcc have all the freedom to pass in hcall_id and the other
parameters:

Thanks Borislav for providing the code.

It seems that it is seldom used in kernel although the explicit register 
variable is supported by GCC and makes the code look simpler. And it 
seems that the explicit register variable is not suppoorted by CLAG.



So the explicit register variable will be removed. I will follow the asm 
code from Borislav. Of course one minor change is that the "movq" is 
used instead of "mov".


Is this ok?

Thanks



unsigned long result;

 asm volatile("mov %[hcall_id], %%r8\n\t"
  "vmcall\n\t"
  : "=a" (result)
  : [hcall_id] "g" (hcall_id)
  : "r8");

 return result;

and %r8 will be in the clobber list so gcc will reload it if needed.

gcc turns it into

1040 :
 1040:   4c 8b 05 e1 2f 00 00mov0x2fe1(%rip),%r8# 4028 

 1047:   0f 01 c1vmcall
 104a:   c3  retq
 104b:   0f 1f 44 00 00  nopl   0x0(%rax,%rax,1)

here.



Re: [RFC PATCH v5 3/4] x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

2019-04-25 Thread Zhao, Yakui




On 2019年04月26日 03:45, Ingo Molnar wrote:


* Zhao, Yakui  wrote:


+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
+   acrn_hv_callback_vector);


Why is this on two lines, not a single line?


At first it used the long function name for acrn_hv_callback_vector.
As it exceeds 80 columns, it is split into two lines.


No, it doesn't exceed 80 columns - the last character of that line is on
column 71.


Thanks for the helps.
It will be fixed.



Does the hypervisor model the APIC EOI command, i.e. does it require the
APIC to be acked? I.e. would not acking the APIC create an IRQ storm?


The hypervisor requires that the APIC EOI should be acked. If the EOI APIC
is not acked, the APIC ISR bit for the HYPERVISOR_CALLBACK_VECTOR will not
be cleared and then it will block the interrupt whose vector is lower than
HYPERVISOR_CALLBACK_VECTOR.


Ok!



I will add some comments for calling entering_ack_irq in 
acrn_hv_callback_handler. Is this ok to you?



Thanks,

Ingo



Re: [RFC PATCH v5 3/4] x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

2019-04-25 Thread Zhao, Yakui




On 2019年04月25日 15:17, Ingo Molnar wrote:


* Zhao Yakui  wrote:


Linux kernel uses the HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall
vector. And it is already used for Xen and HyperV.


English sentences should not be started with 'and'.


OK. I will remove it.




After ACRN hypervisor is detected, it will also use this defined vector
to notify ACRN guest.


Missing 'the', twice.


OK. It will be added.




+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRN_H
+#define _ASM_X86_ACRN_H
+
+void acrn_hv_callback_vector(void);


Please mark these with 'extern', as customary in x86 headers.


OK. The "extern" will be added.



  
+#include 

+#include 
+#include 
  #include 
+#include 
  
  static uint32_t __init acrn_detect(void)

  {
@@ -18,6 +22,8 @@ static uint32_t __init acrn_detect(void)
  
  static void __init acrn_init_platform(void)

  {
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
+   acrn_hv_callback_vector);


Why is this on two lines, not a single line?


At first it used the long function name for acrn_hv_callback_vector.
As it exceeds 80 columns, it is split into two lines.
I will check it and see whether it can be fit into one single line.
If it is ok, it will be in one single line.




+static void (*acrn_intr_handler)(void);
+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   entering_ack_irq();


Does the hypervisor model the APIC EOI command, i.e. does it require the
APIC to be acked? I.e. would not acking the APIC create an IRQ storm?


The hypervisor requires that the APIC EOI should be acked. If the EOI 
APIC is not acked, the APIC ISR bit for the HYPERVISOR_CALLBACK_VECTOR 
will not be cleared and then it will block the interrupt whose vector is 
lower than HYPERVISOR_CALLBACK_VECTOR.





+   inc_irq_stat(irq_hv_callback_count);
+
+   if (acrn_intr_handler)
+   acrn_intr_handler();


Nothing appears to be setting acrn_intr_handler, so this will never
execute anything? Is more code relying on this?


Nothing will be done in this patch.
Later the driver part code will be added and it needs to add/remove the 
corresponding driver handler. It is similar to vmbus_handler in 
hyperv_vector_handler.




Thanks,

Ingo



Re: [RFC PATCH v5 4/4] x86/acrn: Add hypercall for ACRN guest

2019-04-25 Thread Zhao, Yakui




On 2019年04月25日 15:07, Ingo Molnar wrote:

Thanks for the review.


* Zhao Yakui  wrote:


When ACRN hypervisor is detected, the hypercall is needed so that the
ACRN guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for the guest operating system.

So add the hypercall so that ACRN guest can communicate with the
low-level ACRN hypervisor. It is implemented with the VMCALL instruction.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
V1->V2: Refine the comments for the function of acrn_hypercall0/1/2
v2->v3: Use the "vmcall" mnemonic to replace hard-code byte definition
v4->v5: Use _ASM_X86_ACRN_HYPERCALL_H instead of _ASM_X86_ACRNHYPERCALL_H to
align the header file of acrn_hypercall.h
 Use the "VMCALL" mnemonic in comment/commit log.
 Uppercase r8/rdi/rsi/rax for hypercall parameter registers in comment.
---
  arch/x86/include/asm/acrn_hypercall.h | 82 +++
  1 file changed, 82 insertions(+)
  create mode 100644 arch/x86/include/asm/acrn_hypercall.h

diff --git a/arch/x86/include/asm/acrn_hypercall.h 
b/arch/x86/include/asm/acrn_hypercall.h
new file mode 100644
index 000..3594436
--- /dev/null
+++ b/arch/x86/include/asm/acrn_hypercall.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_X86_ACRN_HYPERCALL_H
+#define _ASM_X86_ACRN_HYPERCALL_H




+
+#include 
+
+#ifdef CONFIG_ACRN_GUEST
+
+/*
+ * Hypercalls for ACRN guest
+ *
+ * Hypercall number is passed in R8 register.
+ * Up to 2 arguments are passed in RDI, RSI.
+ * Return value will be placed in RAX.
+ */
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   /* the hypercall is implemented with the VMCALL instruction.
+* asm indicates that inline assembler instruction is used.
+* volatile qualifier is added to avoid that it is dropped
+* because of compiler optimization.
+*/


Non-standard comment style.

asm statements are volatile by default I believe.


For the basic asm:  it is volatile by default.
For the extend asm:  The volatile is needed to disable the certain 
optimization.
The below info is copied from: 
https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm


The typical use of extended asm statements is to manipulate input values 
to produce output values. However, your asm statements may also produce 
side effects. If so, you may need to use the volatile qualifier to 
disable certain optimizations. See Volatile.





I.e. the second and third sentences are partly obvious, superfluous and
bogus.


+   asm volatile("vmcall"
+   : "=r"(result)
+   : "r"(r8));
+
+   return result;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "D"(param1), "r"(r8));


Why are register variables used? Doesn't GCC figure it out correctly by
default?


The parameter register for the VMCALL is predefined in ACRN hypervisor. 
Now the R8 is used to pass the hcall_id.

It seems that there is no special constraint for R8~R15.
So the explicit register variable is used so that the R8 can be passed.




+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "D"(param1), "S"(param2), "r"(r8));


Ditto.

Thanks,

Ingo



Re: [RFC PATCH v5 0/4] x86: Add the support of ACRN guest under x86

2019-04-24 Thread Zhao, Yakui




On 2019年04月25日 06:20, Thomas Gleixner wrote:

On Wed, 24 Apr 2019, Zhao Yakui wrote:


ACRN is a flexible, lightweight reference hypervisor, built with real-time
and safety-criticality in mind, optimized to streamline embedded development
through an open source platform. It is built for embedded IOT with small
footprint and real-time features. More details can be found
in https://projectacrn.org/

This is the patch set that allows the Linux to work on ACRN hypervisor and it 
can
work with the following patch set to manage the Linux guest on ACRN hypervisor. 
It
includes the detection of ACRN hypervisor, upcall notification vector from
hypervisor, hypercall. The hypervisor detection is similar to Xen/VMWARE/Hyperv.
ACRN also uses the upcall notification mechanism similar to that in 
Xen/Microsoft
HyperV when it needs to send the notification to Linux OS. The hypercall 
provides
the mechanism that can be used to query/configure the ACRN hypervisor by Linux 
guest.


Reviewed-by: Thomas Gleixner 


Thanks for the review.
I will remove the RFC in the next version.

Thanks
   Yakui





[RFC PATCH v5 4/4] x86/acrn: Add hypercall for ACRN guest

2019-04-23 Thread Zhao Yakui
When ACRN hypervisor is detected, the hypercall is needed so that the
ACRN guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for the guest operating system.

So add the hypercall so that ACRN guest can communicate with the
low-level ACRN hypervisor. It is implemented with the VMCALL instruction.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
V1->V2: Refine the comments for the function of acrn_hypercall0/1/2
v2->v3: Use the "vmcall" mnemonic to replace hard-code byte definition
v4->v5: Use _ASM_X86_ACRN_HYPERCALL_H instead of _ASM_X86_ACRNHYPERCALL_H to
align the header file of acrn_hypercall.h
Use the "VMCALL" mnemonic in comment/commit log.
Uppercase r8/rdi/rsi/rax for hypercall parameter registers in comment.
---
 arch/x86/include/asm/acrn_hypercall.h | 82 +++
 1 file changed, 82 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h

diff --git a/arch/x86/include/asm/acrn_hypercall.h 
b/arch/x86/include/asm/acrn_hypercall.h
new file mode 100644
index 000..3594436
--- /dev/null
+++ b/arch/x86/include/asm/acrn_hypercall.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_X86_ACRN_HYPERCALL_H
+#define _ASM_X86_ACRN_HYPERCALL_H
+
+#include 
+
+#ifdef CONFIG_ACRN_GUEST
+
+/*
+ * Hypercalls for ACRN guest
+ *
+ * Hypercall number is passed in R8 register.
+ * Up to 2 arguments are passed in RDI, RSI.
+ * Return value will be placed in RAX.
+ */
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   /* the hypercall is implemented with the VMCALL instruction.
+* asm indicates that inline assembler instruction is used.
+* volatile qualifier is added to avoid that it is dropped
+* because of compiler optimization.
+*/
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "r"(r8));
+
+   return result;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "D"(param1), "r"(r8));
+
+   return result;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "D"(param1), "S"(param2), "r"(r8));
+
+   return result;
+}
+
+#else
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   return -ENOTSUPP;
+}
+#endif /* CONFIG_ACRN_GUEST */
+#endif /* _ASM_X86_ACRN_HYPERCALL_H */
-- 
2.7.4



[RFC PATCH v5 1/4] x86/Kconfig: Add new config symbol to unify conditional definition of hv_irq_callback_count

2019-04-23 Thread Zhao Yakui
Add a special Kconfig symbol X86_HV_CALLBACK_VECTOR so that the guests
using the hypervisor interrupt callback counter can select and thus
enable that counter. Select it when xen or hyperv support is enabled.
No functional changes.

Signed-off-by: Zhao Yakui 
Reviewed-by: Borislav Petkov 
---
v3->v4: Follow the comments to refine the commit log.
v4->v5: No change
---
 arch/x86/Kconfig   | 3 +++
 arch/x86/include/asm/hardirq.h | 2 +-
 arch/x86/kernel/irq.c  | 2 +-
 arch/x86/xen/Kconfig   | 1 +
 drivers/hv/Kconfig | 1 +
 5 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 62fc3fd..2fc9297 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -791,6 +791,9 @@ config QUEUED_LOCK_STAT
  behavior of paravirtualized queued spinlocks and report
  them on debugfs.
 
+config X86_HV_CALLBACK_VECTOR
+   def_bool n
+
 source "arch/x86/xen/Kconfig"
 
 config KVM_GUEST
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d9069bb..0753379 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -37,7 +37,7 @@ typedef struct {
 #ifdef CONFIG_X86_MCE_AMD
unsigned int irq_deferred_error_count;
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
unsigned int irq_hv_callback_count;
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 59b5f2e..a147826 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -134,7 +134,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_puts(p, "  Machine check polls\n");
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j)
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index e07abef..ba5a418 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,6 +7,7 @@ config XEN
bool "Xen guest support"
depends on PARAVIRT
select PARAVIRT_CLOCK
+   select X86_HV_CALLBACK_VECTOR
depends on X86_64 || (X86_32 && X86_PAE)
depends on X86_LOCAL_APIC && X86_TSC
help
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 1c1a251..cafcb97 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -6,6 +6,7 @@ config HYPERV
tristate "Microsoft Hyper-V client drivers"
depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
select PARAVIRT
+   select X86_HV_CALLBACK_VECTOR
help
  Select this option to run Linux as a Hyper-V client operating
  system.
-- 
2.7.4



[RFC PATCH v5 3/4] x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

2019-04-23 Thread Zhao Yakui
Linux kernel uses the HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall
vector. And it is already used for Xen and HyperV.
After ACRN hypervisor is detected, it will also use this defined vector
to notify ACRN guest.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
V1->V2: Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.

v2->v3: Select the X86_HV_CALLBACK_VECTOR for ACRN guest
v3->v4: Refine the file name of acrnhyper.h to acrn.h
v4->v5: no change
---
 arch/x86/Kconfig|  1 +
 arch/x86/entry/entry_64.S   |  5 +
 arch/x86/include/asm/acrn.h | 11 +++
 arch/x86/kernel/cpu/acrn.c  | 22 ++
 4 files changed, 39 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 8dc4200..d7a10f6 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -848,6 +848,7 @@ config JAILHOUSE_GUEST
 config ACRN_GUEST
bool "ACRN Guest support"
depends on X86_64
+   select X86_HV_CALLBACK_VECTOR
help
  This option allows to run Linux as guest in ACRN hypervisor. Enabling
  this will allow the kernel to boot in virtualized environment under
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 1f0efdb..d1b8ad3 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1129,6 +1129,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
+#if IS_ENABLED(CONFIG_ACRN_GUEST)
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+   acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
 idtentry debug do_debughas_error_code=0
paranoid=1 shift_ist=DEBUG_STACK
 idtentry int3  do_int3 has_error_code=0
 idtentry stack_segment do_stack_segmenthas_error_code=1
diff --git a/arch/x86/include/asm/acrn.h b/arch/x86/include/asm/acrn.h
new file mode 100644
index 000..43ab032
--- /dev/null
+++ b/arch/x86/include/asm/acrn.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRN_H
+#define _ASM_X86_ACRN_H
+
+void acrn_hv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_acrn_hv_callback_vector acrn_hv_callback_vector
+#endif
+
+void acrn_hv_vector_handler(struct pt_regs *regs);
+#endif /* _ASM_X86_ACRN_H */
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index f556640..d8072bf 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -9,7 +9,11 @@
  *
  */
 
+#include 
+#include 
+#include 
 #include 
+#include 
 
 static uint32_t __init acrn_detect(void)
 {
@@ -18,6 +22,8 @@ static uint32_t __init acrn_detect(void)
 
 static void __init acrn_init_platform(void)
 {
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
+   acrn_hv_callback_vector);
 }
 
 static bool acrn_x2apic_available(void)
@@ -30,6 +36,22 @@ static bool acrn_x2apic_available(void)
return false;
 }
 
+static void (*acrn_intr_handler)(void);
+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   entering_ack_irq();
+   inc_irq_stat(irq_hv_callback_count);
+
+   if (acrn_intr_handler)
+   acrn_intr_handler();
+
+   exiting_irq();
+   set_irq_regs(old_regs);
+}
+
 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
.name   = "ACRN",
.detect = acrn_detect,
-- 
2.7.4



[RFC PATCH v5 2/4] x86: Add the support of Linux guest on ACRN hypervisor

2019-04-23 Thread Zhao Yakui
ACRN is an open-source hypervisor maintained by Linux Foundation.
It is built for embedded IOT with small footprint and real-time features.
Add the ACRN guest support so that it allows Linux to be booted under
ACRN hypervisor. Following this patch it will setup the upcall
notification vector and enable hypercall. And after ACRN guest is
supported, the ACRN driver part can add the interface that is used to
manage the virtualized CPU/memory/device/interrupt for other guest system.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.

v2->v3: Remove the unnecessary dependency of PARAVIRT
v3->v4: Refine the commit log and add meaningful description in Kconfig
v4->v5: Minor change for the commit log.
---
 arch/x86/Kconfig  | 12 
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 39 +++
 arch/x86/kernel/cpu/hypervisor.c  |  4 
 5 files changed, 57 insertions(+)
 create mode 100644 arch/x86/kernel/cpu/acrn.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2fc9297..8dc4200 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -845,6 +845,18 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
 
+config ACRN_GUEST
+   bool "ACRN Guest support"
+   depends on X86_64
+   help
+ This option allows to run Linux as guest in ACRN hypervisor. Enabling
+ this will allow the kernel to boot in virtualized environment under
+ the ACRN hypervisor.
+ ACRN is a flexible, lightweight reference open-source hypervisor, 
built
+ with real-time and safety-criticality in mind. It is built for 
embedded
+ IOT with small footprint and real-time features. More details can be
+ found in https://projectacrn.org/
+
 endif #HYPERVISOR_GUEST
 
 source "arch/x86/Kconfig.cpu"
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 8c5aaba..50a30f6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -29,6 +29,7 @@ enum x86_hypervisor_type {
X86_HYPER_XEN_HVM,
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
+   X86_HYPER_ACRN,
 };
 
 #ifdef CONFIG_HYPERVISOR_GUEST
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index cfd24f9..17a7cdf 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_X86_CPU_RESCTRL) += resctrl/
 obj-$(CONFIG_X86_LOCAL_APIC)   += perfctr-watchdog.o
 
 obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
+obj-$(CONFIG_ACRN_GUEST)   += acrn.o
 
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
new file mode 100644
index 000..f556640
--- /dev/null
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACRN detection support
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ *
+ */
+
+#include 
+
+static uint32_t __init acrn_detect(void)
+{
+   return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+}
+
+static void __init acrn_init_platform(void)
+{
+}
+
+static bool acrn_x2apic_available(void)
+{
+   /* x2apic is not supported now.
+* Later it needs to check the X86_FEATURE_X2APIC bit of cpu info
+* returned by CPUID to determine whether the x2apic is
+* supported in Linux guest.
+*/
+   return false;
+}
+
+const __initconst struct hypervisor_x86 x86_hyper_acrn = {
+   .name   = "ACRN",
+   .detect = acrn_detect,
+   .type   = X86_HYPER_ACRN,
+   .init.init_platform = acrn_init_platform,
+   .init.x2apic_available  = acrn_x2apic_available,
+};
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 479ca47..87e39ad 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -32,6 +32,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
 extern const struct hypervisor_x86 x86_hyper_xen_hvm;
 extern const struct hypervisor_x86 x86_hyper_kvm;
 extern const struct hypervisor_x86 x86_hyper_jailhouse;
+extern const struct hypervisor_x86 x86_hyper_acrn;
 
 static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
@@ -49,6 +50,9 @@ static const __initconst struct hypervisor_x86 * const 
hypervisors[] =
 #ifdef CONFIG_JAILHOUSE_GUEST
&x86_hyper_jailhouse,
 #endif
+#ifdef CONFIG

[RFC PATCH v5 0/4] x86: Add the support of ACRN guest under x86

2019-04-23 Thread Zhao Yakui
ACRN is a flexible, lightweight reference hypervisor, built with real-time
and safety-criticality in mind, optimized to streamline embedded development
through an open source platform. It is built for embedded IOT with small
footprint and real-time features. More details can be found
in https://projectacrn.org/

This is the patch set that allows the Linux to work on ACRN hypervisor and it 
can
work with the following patch set to manage the Linux guest on ACRN hypervisor. 
It
includes the detection of ACRN hypervisor, upcall notification vector from
hypervisor, hypercall. The hypervisor detection is similar to Xen/VMWARE/Hyperv.
ACRN also uses the upcall notification mechanism similar to that in 
Xen/Microsoft
HyperV when it needs to send the notification to Linux OS. The hypercall 
provides
the mechanism that can be used to query/configure the ACRN hypervisor by Linux 
guest.

Following this patch set, we will send acrn driver part, which provides the 
interface
that can be used to manage the virtualized CPU/memory/device/interrupt for 
other guest
OS after the ACRN hypervisor is detected.

v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.
Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.
Refine the comments for the function of acrn_hypercall0/1/2

v2-v3:  Add one new config symbol to unify the conditional definition
of hv_irq_callback_count
Use the "vmcall" mnemonic to replace the hard-code byte definition
Remove the unnecessary dependency of CONFIG_PARAVIRT for ACRN_GUEST

v3-v4:  Rename the file name of acrnhyper.h to acrn.h
Refine the commit log and some other minor changes(more comments and 
redundant ifdef in acrn.h, sorting the header file in acrn.c)

v4->v5: Minor changes of comments/commit log in patch 04
Use _ASM_X86_ACRN_HYPERCALL_H instead of _ASM_X86_ACRNHYPERCALL_H.
Use the "VMCALL" mnemonic in comment/commit log.
Uppercase r8/rdi/rsi/rax for hypercall parameter register in comment.

Zhao Yakui (4):
  x86/Kconfig: Add new config symbol to unify conditional definition of
hv_irq_callback_count
  x86: Add the support of Linux guest on ACRN hypervisor
  x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector
  x86/acrn: Add hypercall for ACRN guest

 arch/x86/Kconfig  | 16 +++
 arch/x86/entry/entry_64.S |  5 +++
 arch/x86/include/asm/acrn.h   | 11 +
 arch/x86/include/asm/acrn_hypercall.h | 81 +++
 arch/x86/include/asm/hardirq.h|  2 +-
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 61 ++
 arch/x86/kernel/cpu/hypervisor.c  |  4 ++
 arch/x86/kernel/irq.c |  2 +-
 arch/x86/xen/Kconfig  |  1 +
 drivers/hv/Kconfig|  1 +
 12 files changed, 184 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/acrn.h
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h
 create mode 100644 arch/x86/kernel/cpu/acrn.c

-- 
2.7.4



[RFC PATCH v4 4/4] x86/acrn: Add hypercall for ACRN guest

2019-04-14 Thread Zhao Yakui
When ACRN hypervisor is detected, the hypercall is needed so that the
ACRN guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for guest operating system.

Add the hypercall so that the kernel can communicate with the low-level
ACRN hypervisor. It is implemented with vmacll instruction.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
V1->V2: Refine the comments for the function of acrn_hypercall0/1/2
v2->v3: Use the "vmcall" mnemonic to replace hard-code byte definition
v3->v4: refine the commit log(minor change)
---
 arch/x86/include/asm/acrn_hypercall.h | 81 +++
 1 file changed, 81 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h

diff --git a/arch/x86/include/asm/acrn_hypercall.h 
b/arch/x86/include/asm/acrn_hypercall.h
new file mode 100644
index 000..30e256e
--- /dev/null
+++ b/arch/x86/include/asm/acrn_hypercall.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_X86_ACRNHYPERCALL_H
+#define _ASM_X86_ACRNHYPERCALL_H
+
+#include 
+
+#ifdef CONFIG_ACRN_GUEST
+
+/*
+ * Hypercalls for ACRN Guest
+ *
+ * Hypercall number is passed in r8 register.
+ * Return value will be placed in rax.
+ * Up to 2 arguments are passed in rdi, rsi.
+ */
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   /* the hypercall is implemented with vmcall instruction.
+* asm volatile is used to avoid that it is dropped because of
+* compiler optimization.
+*/
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "r"(r8));
+
+   return result;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "D"(param1), "r"(r8));
+
+   return result;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "D"(param1), "S"(param2), "r"(r8));
+
+   return result;
+}
+
+#else
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   return -ENOTSUPP;
+}
+#endif /* CONFIG_ACRN_GUEST */
+#endif /* _ASM_X86_ACRNHYPERCALL_H */
-- 
2.7.4



[RFC PATCH v4 3/4] x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector

2019-04-14 Thread Zhao Yakui
Linux kernel uses the HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall
vector. And it is already used for Xen and HyperV.
After ACRN hypervisor is detected, it will also use this defined vector
to notify kernel.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
V1->V2: Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.

v2->v3: Select the X86_HV_CALLBACK_VECTOR for ACRN guest
v3->v4: Refine the file name of acrnhyper.h to acrn.h
---
 arch/x86/Kconfig|  1 +
 arch/x86/entry/entry_64.S   |  5 +
 arch/x86/include/asm/acrn.h | 11 +++
 arch/x86/kernel/cpu/acrn.c  | 22 ++
 4 files changed, 39 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b33bfe5..4bad72c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -848,6 +848,7 @@ config JAILHOUSE_GUEST
 config ACRN_GUEST
bool "ACRN Guest support"
depends on X86_64
+   select X86_HV_CALLBACK_VECTOR
help
  This option allows to run Linux as guest in ACRN hypervisor. Enabling
  this will allow the kernel to boot in virtualized environment under
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 1f0efdb..d1b8ad3 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1129,6 +1129,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
+#if IS_ENABLED(CONFIG_ACRN_GUEST)
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+   acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
 idtentry debug do_debughas_error_code=0
paranoid=1 shift_ist=DEBUG_STACK
 idtentry int3  do_int3 has_error_code=0
 idtentry stack_segment do_stack_segmenthas_error_code=1
diff --git a/arch/x86/include/asm/acrn.h b/arch/x86/include/asm/acrn.h
new file mode 100644
index 000..43ab032
--- /dev/null
+++ b/arch/x86/include/asm/acrn.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRN_H
+#define _ASM_X86_ACRN_H
+
+void acrn_hv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_acrn_hv_callback_vector acrn_hv_callback_vector
+#endif
+
+void acrn_hv_vector_handler(struct pt_regs *regs);
+#endif /* _ASM_X86_ACRN_H */
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index f556640..d8072bf 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -9,7 +9,11 @@
  *
  */
 
+#include 
+#include 
+#include 
 #include 
+#include 
 
 static uint32_t __init acrn_detect(void)
 {
@@ -18,6 +22,8 @@ static uint32_t __init acrn_detect(void)
 
 static void __init acrn_init_platform(void)
 {
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
+   acrn_hv_callback_vector);
 }
 
 static bool acrn_x2apic_available(void)
@@ -30,6 +36,22 @@ static bool acrn_x2apic_available(void)
return false;
 }
 
+static void (*acrn_intr_handler)(void);
+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   entering_ack_irq();
+   inc_irq_stat(irq_hv_callback_count);
+
+   if (acrn_intr_handler)
+   acrn_intr_handler();
+
+   exiting_irq();
+   set_irq_regs(old_regs);
+}
+
 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
.name   = "ACRN",
.detect = acrn_detect,
-- 
2.7.4



[PATCH v4 2/4] x86: Add the support of Linux guest on ACRN hypervisor

2019-04-14 Thread Zhao Yakui
ACRN is an open-source hypervisor maintained by Linux Foundation.
It is built for embedded IOT with small footprint and real-time features.
Add the ACRN guest support so that it allows linux to be booted under
ACRN hypervisor. Following this patch it will setup the upcall
notification vector, enable hypercall and provide the interface that is
used to manage the virtualized CPU/memory/device/interrupt for other
guest OS.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.

v2->v3: Remove the unnecessary dependency of PARAVIRT
v3->v4: Refine the commit log and add meaningful description
in Kconfig
---
 arch/x86/Kconfig  | 12 
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 39 +++
 arch/x86/kernel/cpu/hypervisor.c  |  4 
 5 files changed, 57 insertions(+)
 create mode 100644 arch/x86/kernel/cpu/acrn.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 54d1fbc..b33bfe5 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -845,6 +845,18 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
 
+config ACRN_GUEST
+   bool "ACRN Guest support"
+   depends on X86_64
+   help
+ This option allows to run Linux as guest in ACRN hypervisor. Enabling
+ this will allow the kernel to boot in virtualized environment under
+ the ACRN hypervisor.
+ ACRN is a flexible, lightweight reference open-source hypervisor, 
built
+ with real-time and safety-criticality in mind. It is built for 
embedded
+ IOT with small footprint and real-time features. More details can be
+ found in https://projectacrn.org/
+
 endif #HYPERVISOR_GUEST
 
 source "arch/x86/Kconfig.cpu"
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 8c5aaba..50a30f6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -29,6 +29,7 @@ enum x86_hypervisor_type {
X86_HYPER_XEN_HVM,
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
+   X86_HYPER_ACRN,
 };
 
 #ifdef CONFIG_HYPERVISOR_GUEST
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index cfd24f9..17a7cdf 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_X86_CPU_RESCTRL) += resctrl/
 obj-$(CONFIG_X86_LOCAL_APIC)   += perfctr-watchdog.o
 
 obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
+obj-$(CONFIG_ACRN_GUEST)   += acrn.o
 
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
new file mode 100644
index 000..f556640
--- /dev/null
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACRN detection support
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ *
+ */
+
+#include 
+
+static uint32_t __init acrn_detect(void)
+{
+   return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+}
+
+static void __init acrn_init_platform(void)
+{
+}
+
+static bool acrn_x2apic_available(void)
+{
+   /* x2apic is not supported now.
+* Later it needs to check the X86_FEATURE_X2APIC bit of cpu info
+* returned by CPUID to determine whether the x2apic is
+* supported in Linux guest.
+*/
+   return false;
+}
+
+const __initconst struct hypervisor_x86 x86_hyper_acrn = {
+   .name   = "ACRN",
+   .detect = acrn_detect,
+   .type   = X86_HYPER_ACRN,
+   .init.init_platform = acrn_init_platform,
+   .init.x2apic_available  = acrn_x2apic_available,
+};
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 479ca47..87e39ad 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -32,6 +32,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
 extern const struct hypervisor_x86 x86_hyper_xen_hvm;
 extern const struct hypervisor_x86 x86_hyper_kvm;
 extern const struct hypervisor_x86 x86_hyper_jailhouse;
+extern const struct hypervisor_x86 x86_hyper_acrn;
 
 static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
@@ -49,6 +50,9 @@ static const __initconst struct hypervisor_x86 * const 
hypervisors[] =
 #ifdef CONFIG_JAILHOUSE_GUEST
&x86_hyper_jailhouse,
 #endif
+#ifdef CONFIG_ACRN_GUEST
+   &x86_hyper_acrn,
+#endif
 };
 
 enum x86_hypervisor_type x86_hyper_type;
-- 
2.7.4



[RFC PATCH v4 0/4] x86: Add the support of ACRN guest under arch/x86

2019-04-14 Thread Zhao Yakui
ACRN is a flexible, lightweight reference hypervisor, built with real-time
and safety-criticality in mind, optimized to streamline embedded development
through an open source platform. It is built for embedded IOT with small
footprint and real-time features. More details can be found
in https://projectacrn.org/

This is the patch set that allows the Linux to work on ACRN hypervisor and it 
can
work with the following patch set to manage the Linux guest on acrn-hypervisor. 
It
includes the detection of acrn_hypervisor, upcall notification vector from
hypervisor, hypercall. The hypervisor detection is similar to Xen/VMWARE/Hyperv.
ACRN also uses the upcall notification mechanism similar to that in 
Xen/Microsoft
HyperV when it needs to send the notification to Linux OS. The hypercall 
provides
the mechanism that can be used to query/configure the acrn-hypervisor by Linux 
guest.

Following this patch set, we will send acrn driver part, which provides the 
interface
that can be used to manage the virtualized CPU/memory/device/interrupt for 
other guest
OS after the acrn hypervisor is detected.


v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.
Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.
Refine the comments for the function of acrn_hypercall0/1/2

v2-v3:  Add one new config symbol to unify the conditional definition
of hv_irq_callback_count
Use the "vmcall" mnemonic to replace the hard-code byte definition
Remove the unnecessary dependency of CONFIG_PARAVIRT for ACRN_GUEST

v3-v4:  Rename the file name of acrnhyper.h to acrn.h
Refine the commit log and some other minor changes(more comments and 
redundant ifdef in acrn.h, sorting the header file in acrn.c)

Zhao Yakui (4):
  x86/Kconfig: Add new config symbol to unify conditional definition of
hv_irq_callback_count
  x86: Add the support of Linux guest on ACRN hypervisor
  x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for ACRN guest upcall vector
  x86/acrn: Add hypercall for ACRN guest

 arch/x86/Kconfig  | 16 +++
 arch/x86/entry/entry_64.S |  5 +++
 arch/x86/include/asm/acrn.h   | 11 +
 arch/x86/include/asm/acrn_hypercall.h | 81 +++
 arch/x86/include/asm/hardirq.h|  2 +-
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 61 ++
 arch/x86/kernel/cpu/hypervisor.c  |  4 ++
 arch/x86/kernel/irq.c |  2 +-
 arch/x86/xen/Kconfig  |  1 +
 drivers/hv/Kconfig|  1 +
 12 files changed, 184 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/acrn.h
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h
 create mode 100644 arch/x86/kernel/cpu/acrn.c

-- 
2.7.4



[RFC PATCH v4 1/4] x86/Kconfig: Add new config symbol to unify conditional definition of hv_irq_callback_count

2019-04-14 Thread Zhao Yakui
Add a special Kconfig symbol X86_HV_CALLBACK_VECTOR so that the guests
using the hypervisor interrupt callback counter can select and thus
enable that counter. Select it when xen or hyperv support is enabled.
No functional changes.

Signed-off-by: Zhao Yakui 
Reviewed-by: Borislav Petkov 
---
v3->v4: Follow the comments to refine the commit log.
---
 arch/x86/Kconfig   | 3 +++
 arch/x86/include/asm/hardirq.h | 2 +-
 arch/x86/kernel/irq.c  | 2 +-
 arch/x86/xen/Kconfig   | 1 +
 drivers/hv/Kconfig | 1 +
 5 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5ad9241..54d1fbc 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -791,6 +791,9 @@ config QUEUED_LOCK_STAT
  behavior of paravirtualized queued spinlocks and report
  them on debugfs.
 
+config X86_HV_CALLBACK_VECTOR
+   def_bool n
+
 source "arch/x86/xen/Kconfig"
 
 config KVM_GUEST
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d9069bb..0753379 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -37,7 +37,7 @@ typedef struct {
 #ifdef CONFIG_X86_MCE_AMD
unsigned int irq_deferred_error_count;
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
unsigned int irq_hv_callback_count;
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 59b5f2e..a147826 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -134,7 +134,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_puts(p, "  Machine check polls\n");
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j)
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index e07abef..ba5a418 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,6 +7,7 @@ config XEN
bool "Xen guest support"
depends on PARAVIRT
select PARAVIRT_CLOCK
+   select X86_HV_CALLBACK_VECTOR
depends on X86_64 || (X86_32 && X86_PAE)
depends on X86_LOCAL_APIC && X86_TSC
help
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 1c1a251..cafcb97 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -6,6 +6,7 @@ config HYPERV
tristate "Microsoft Hyper-V client drivers"
depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
select PARAVIRT
+   select X86_HV_CALLBACK_VECTOR
help
  Select this option to run Linux as a Hyper-V client operating
  system.
-- 
2.7.4



Re: [RFC PATCH v3 3/4] x86: Use HYPERVISOR_CALLBACK_VECTOR for acrn_guest upcall vector

2019-04-11 Thread Zhao, Yakui




On 2019年04月11日 21:55, Borislav Petkov wrote:

On Wed, Apr 10, 2019 at 03:57:08PM +0800, Zhao, Yakui wrote:

It is used to avoid that one function declaration has no definition
when asm/acrnhyper.h is included and ACRN_GUEST is not enabled.


And that is a problem because...?


This is not a problem.
I take a look at the header file of mshyperv.h and xen/events.h.
It seems that they have no such extra conditional definition.
To follow the same style, I will remove it.




Do you have any suggestion about the header order?


linux/ path includes still need to come first, of course.


As said above:

linux/ path first, then asm/

Feel free to look around the tree for inspiration :)


I take a look at the file of vwmare.c/mshyperv.c under the directory of 
arch/x86/kernel/cpu. It seems that the header file only follows the 
order of: linux/ path first and then asm/.


Anyway, I will follow your idea in previous email and use the alphabetic 
order.


Thanks




Re: [RFC PATCH v3 2/4] x86: Add the support of ACRN guest

2019-04-11 Thread Zhao, Yakui




On 2019年04月11日 21:49, Borislav Petkov wrote:

On Wed, Apr 10, 2019 at 05:15:48PM +0800, Zhao, Yakui wrote:

Currently the x2apic is not enabled in the first step.
Next step it needs to check the cpu info reported by ACRN hypervisor to
determine whether the x2apic should be supported.


What "cpu info"? CPUID or something ACRN-specific?


It is based on CPUID.
The low-level ACRN hypervisor can return the different output of CPUID 
when several linux guests executes the CPUID instruction. Then it can 
control whether x2apic is supported in one linux guest.


So we will leverage the X86_FEATURE_X2APIC bit from CPUID to indicate 
whether the x2apic is supported in linux guest when ACRN hypervisor is 
detected.

Is this fine to you?

Thanks




Re: [RFC PATCH v3 2/4] x86: Add the support of ACRN guest

2019-04-10 Thread Zhao, Yakui




On 2019年04月08日 22:39, Borislav Petkov wrote:

On Mon, Apr 08, 2019 at 04:12:09PM +0800, Zhao Yakui wrote:

ACRN is an open-source hypervisor maintained by Linuxfoundation.


I think tglx wanted to say "by the Linux Foundation" here.


Sure. It will be fixed.



This is to add the Linux guest support on acrn-hypervisor.


I think you were told already:

"Please do not use 'This is to add' or 'This adds'. Just say:

Add "

So please take your time, work in *all* review feedback instead of
hurrying the next version out without addressing all review comments.


Add x86_hyper_acrn into supported hypervisors array, which enables
Linux ACRN guest running on ACRN hypervisor. It is restricted to X86_64.


So this all talks about *what* the patch does. But that is visible from
the diff below and doesn't belong in the commit message.

Rather, your commit message should talk about *why* a change is being
done.


I will refine the commit log and only talk about "why" a changed is added.




Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
 Remove the export of x86_hyper_acrn.

v2->v3: Remove the unnecessary dependency of PARAVIRT
---
  arch/x86/Kconfig  |  8 
  arch/x86/include/asm/hypervisor.h |  1 +
  arch/x86/kernel/cpu/Makefile  |  1 +
  arch/x86/kernel/cpu/acrn.c| 35 +++
  arch/x86/kernel/cpu/hypervisor.c  |  4 
  5 files changed, 49 insertions(+)
  create mode 100644 arch/x86/kernel/cpu/acrn.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 54d1fbc..d77d215 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -845,6 +845,14 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
  
+config ACRN_GUEST

+   bool "ACRN Guest support"
+   depends on X86_64
+   help
+ This option allows to run Linux as guest in ACRN hypervisor. Enabling
+ this will allow the kernel to boot in virtualized environment under
+ the ACRN hypervisor.


WARNING: please write a paragraph that describes the config symbol fully
#47: FILE: arch/x86/Kconfig:848:
+config ACRN_GUEST

That help text above could use some of the explanation what ACRN is from
your 0/4 message.



Make sense. I will add some description in patch 0 for the Kconfig 
description.



+
  endif #HYPERVISOR_GUEST
  
  source "arch/x86/Kconfig.cpu"

diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 8c5aaba..50a30f6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -29,6 +29,7 @@ enum x86_hypervisor_type {
X86_HYPER_XEN_HVM,
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
+   X86_HYPER_ACRN,
  };
  
  #ifdef CONFIG_HYPERVISOR_GUEST

diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index cfd24f9..17a7cdf 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_X86_CPU_RESCTRL) += resctrl/
  obj-$(CONFIG_X86_LOCAL_APIC)  += perfctr-watchdog.o
  
  obj-$(CONFIG_HYPERVISOR_GUEST)		+= vmware.o hypervisor.o mshyperv.o

+obj-$(CONFIG_ACRN_GUEST)   += acrn.o
  
  ifdef CONFIG_X86_FEATURE_NAMES

  quiet_cmd_mkcapflags = MKCAP   $@
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
new file mode 100644
index 000..3956567
--- /dev/null
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACRN detection support
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ *
+ */
+
+#include 
+
+static uint32_t __init acrn_detect(void)
+{
+   return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+}
+
+static void __init acrn_init_platform(void)
+{
+}
+
+static bool acrn_x2apic_available(void)
+{
+   /* do not support x2apic */


Why?

This comment could explain why that choice has been made.



Currently the x2apic is not enabled in the first step.
Next step it needs to check the cpu info reported by ACRN hypervisor to 
determine whether the x2apic should be supported.

How about using the below comments?
" x2apic is not supported now. Later it will check the cpu info to 
determine whether the x2apic can be supported or not."


Thanks



Re: [RFC PATCH v3 4/4] x86: Add hypercall for acrn_guest

2019-04-10 Thread Zhao, Yakui




On 2019年04月08日 23:10, Borislav Petkov wrote:

On Mon, Apr 08, 2019 at 04:12:11PM +0800, Zhao Yakui wrote:

When acrn_hypervisor is detected, the hypercall is needed so that the
acrn guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for Guest system.


Good example.

What is "Guest system" and why is capitalized? Do you mean "the guest
operating system" or simply "the guest"?


it means the "guest operating system".
It will be changed to "guest operating system".




So the hypercall is added so that the kernel can communicate with the


"So add the hypercall so that..."


low-level acrn-hypervisor.


Is it acrn_hypervisor or acrn-hypervisor or the ACRN hypervisor or ...?

Unify the naming pls.


Sure. They will be unified to "ACRN hypervisor" in next version.




On x86 it is implemented by using vmacll when


During last review Thomas said:

"is implemented with the VMCALL instruction"

You still have it wrong. Which makes me think you haven't even gone over
*all* review comments as this is the second missed review comment in a
4-patches set.

So I'm going to stop reviewing here and won't look at your patches until
you incorporate *all* review comments from all people.



Re: [RFC PATCH v3 3/4] x86: Use HYPERVISOR_CALLBACK_VECTOR for acrn_guest upcall vector

2019-04-10 Thread Zhao, Yakui




On 2019年04月08日 23:00, Borislav Petkov wrote:

You can prefix your subject now like this:

x86/acrn: Use ...


Thanks for suggestion.
It will be updated in next version.



On Mon, Apr 08, 2019 at 04:12:10PM +0800, Zhao Yakui wrote:

Linux kernel uses the HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall
vector. And it is already used for Xen and HyperV.
After Acrn hypervisor is detected, it will also use this defined vector
to notify kernel.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
V1->V2: Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
 Adjust the order of header file
 Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.
---
  arch/x86/Kconfig |  1 +
  arch/x86/entry/entry_64.S|  5 +
  arch/x86/include/asm/acrnhyper.h | 19 +++
  arch/x86/kernel/cpu/acrn.c   | 22 ++
  4 files changed, 47 insertions(+)
  create mode 100644 arch/x86/include/asm/acrnhyper.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index d77d215..ae4d38b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -848,6 +848,7 @@ config JAILHOUSE_GUEST
  config ACRN_GUEST
bool "ACRN Guest support"
depends on X86_64
+   select X86_HV_CALLBACK_VECTOR
help
  This option allows to run Linux as guest in ACRN hypervisor. Enabling
  this will allow the kernel to boot in virtualized environment under
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 1f0efdb..d1b8ad3 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1129,6 +1129,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler
  #endif /* CONFIG_HYPERV */
  
+#if IS_ENABLED(CONFIG_ACRN_GUEST)

+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+   acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
  idtentry debugdo_debug
has_error_code=0paranoid=1 shift_ist=DEBUG_STACK
  idtentry int3 do_int3 has_error_code=0
  idtentry stack_segmentdo_stack_segmenthas_error_code=1
diff --git a/arch/x86/include/asm/acrnhyper.h b/arch/x86/include/asm/acrnhyper.h
new file mode 100644
index 000..9f9c239
--- /dev/null
+++ b/arch/x86/include/asm/acrnhyper.h


Simply

.../acrn.h

I'd say.


OK. The simplifed file name(acrn.h) will be used in next version.




@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRNHYPER_H
+#define _ASM_X86_ACRNHYPER_H
+
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_ACRN_GUEST


Why is that ifdef needed?


It is used to avoid that one function declaration has no definition when 
asm/acrnhyper.h is included and ACRN_GUEST is not enabled.





+void acrn_hv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_acrn_hv_callback_vector acrn_hv_callback_vector
+#endif
+
+void acrn_hv_vector_handler(struct pt_regs *regs);


end marker:

#endif /* _ASM_X86_ACRNHYPER_H */


It will be added in next version.




diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index 3956567..7a233b5 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -9,7 +9,11 @@
   *
   */
  
+#include 

  #include 
+#include 
+#include 
+#include 


What's the sorting order here? Length or alphabetic? Or none? :)


Sorry that I don't consider the oder.
The required new header file is appended one by one. Of course linux/ 
path and asm / are appended separately.

Do you have any suggestion about the header order?



linux/ path includes still need to come first, of course.



Re: [RFC PATCH v3 1/4] x86: Add new config symbol to unify conditional definition of hv_irq_callback_count

2019-04-10 Thread Zhao, Yakui




On 2019年04月08日 17:35, Borislav Petkov wrote:

Subject: x86/kconfig: Add ...

On Mon, Apr 08, 2019 at 04:12:08PM +0800, Zhao Yakui wrote:

Now the CONFIG_HYPERV and CONFIG_XEN can be used to control the definition
/usage of hv_irq_callback_count. If another linux guest also needs to use
the hv_irq_callback_count, current conditional definition looks unreadable.


Rewrite that to:

"Add a special Kconfig symbol X86_HV_CALLBACK_VECTOR which guests using
the hypervisor interrupt callback counter can select and thus enable
that counter. Select it when xen or hyperv support is enabled.

No functional changes."

with that fixed you can add:

Reviewed-by: Borislav Petkov 


Thanks for your review.
Will update the title and commit log as you suggested.

Thanks



Thx.



[RFC PATCH v3 2/4] x86: Add the support of ACRN guest

2019-04-08 Thread Zhao Yakui
ACRN is an open-source hypervisor maintained by Linuxfoundation.
This is to add the Linux guest support on acrn-hypervisor.

Add x86_hyper_acrn into supported hypervisors array, which enables
Linux ACRN guest running on ACRN hypervisor. It is restricted to X86_64.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.

v2->v3: Remove the unnecessary dependency of PARAVIRT
---
 arch/x86/Kconfig  |  8 
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 35 +++
 arch/x86/kernel/cpu/hypervisor.c  |  4 
 5 files changed, 49 insertions(+)
 create mode 100644 arch/x86/kernel/cpu/acrn.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 54d1fbc..d77d215 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -845,6 +845,14 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
 
+config ACRN_GUEST
+   bool "ACRN Guest support"
+   depends on X86_64
+   help
+ This option allows to run Linux as guest in ACRN hypervisor. Enabling
+ this will allow the kernel to boot in virtualized environment under
+ the ACRN hypervisor.
+
 endif #HYPERVISOR_GUEST
 
 source "arch/x86/Kconfig.cpu"
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 8c5aaba..50a30f6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -29,6 +29,7 @@ enum x86_hypervisor_type {
X86_HYPER_XEN_HVM,
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
+   X86_HYPER_ACRN,
 };
 
 #ifdef CONFIG_HYPERVISOR_GUEST
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index cfd24f9..17a7cdf 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_X86_CPU_RESCTRL) += resctrl/
 obj-$(CONFIG_X86_LOCAL_APIC)   += perfctr-watchdog.o
 
 obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
+obj-$(CONFIG_ACRN_GUEST)   += acrn.o
 
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
new file mode 100644
index 000..3956567
--- /dev/null
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACRN detection support
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ *
+ */
+
+#include 
+
+static uint32_t __init acrn_detect(void)
+{
+   return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+}
+
+static void __init acrn_init_platform(void)
+{
+}
+
+static bool acrn_x2apic_available(void)
+{
+   /* do not support x2apic */
+   return false;
+}
+
+const __initconst struct hypervisor_x86 x86_hyper_acrn = {
+   .name   = "ACRN",
+   .detect = acrn_detect,
+   .type   = X86_HYPER_ACRN,
+   .init.init_platform = acrn_init_platform,
+   .init.x2apic_available  = acrn_x2apic_available,
+};
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 479ca47..87e39ad 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -32,6 +32,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
 extern const struct hypervisor_x86 x86_hyper_xen_hvm;
 extern const struct hypervisor_x86 x86_hyper_kvm;
 extern const struct hypervisor_x86 x86_hyper_jailhouse;
+extern const struct hypervisor_x86 x86_hyper_acrn;
 
 static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
@@ -49,6 +50,9 @@ static const __initconst struct hypervisor_x86 * const 
hypervisors[] =
 #ifdef CONFIG_JAILHOUSE_GUEST
&x86_hyper_jailhouse,
 #endif
+#ifdef CONFIG_ACRN_GUEST
+   &x86_hyper_acrn,
+#endif
 };
 
 enum x86_hypervisor_type x86_hyper_type;
-- 
2.7.4



[RFC PATCH v3 3/4] x86: Use HYPERVISOR_CALLBACK_VECTOR for acrn_guest upcall vector

2019-04-08 Thread Zhao Yakui
Linux kernel uses the HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall
vector. And it is already used for Xen and HyperV.
After Acrn hypervisor is detected, it will also use this defined vector
to notify kernel.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
V1->V2: Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.
---
 arch/x86/Kconfig |  1 +
 arch/x86/entry/entry_64.S|  5 +
 arch/x86/include/asm/acrnhyper.h | 19 +++
 arch/x86/kernel/cpu/acrn.c   | 22 ++
 4 files changed, 47 insertions(+)
 create mode 100644 arch/x86/include/asm/acrnhyper.h

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index d77d215..ae4d38b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -848,6 +848,7 @@ config JAILHOUSE_GUEST
 config ACRN_GUEST
bool "ACRN Guest support"
depends on X86_64
+   select X86_HV_CALLBACK_VECTOR
help
  This option allows to run Linux as guest in ACRN hypervisor. Enabling
  this will allow the kernel to boot in virtualized environment under
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 1f0efdb..d1b8ad3 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1129,6 +1129,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
+#if IS_ENABLED(CONFIG_ACRN_GUEST)
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+   acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
 idtentry debug do_debughas_error_code=0
paranoid=1 shift_ist=DEBUG_STACK
 idtentry int3  do_int3 has_error_code=0
 idtentry stack_segment do_stack_segmenthas_error_code=1
diff --git a/arch/x86/include/asm/acrnhyper.h b/arch/x86/include/asm/acrnhyper.h
new file mode 100644
index 000..9f9c239
--- /dev/null
+++ b/arch/x86/include/asm/acrnhyper.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRNHYPER_H
+#define _ASM_X86_ACRNHYPER_H
+
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_ACRN_GUEST
+void acrn_hv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_acrn_hv_callback_vector acrn_hv_callback_vector
+#endif
+
+void acrn_hv_vector_handler(struct pt_regs *regs);
+#endif
+
+#endif
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index 3956567..7a233b5 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -9,7 +9,11 @@
  *
  */
 
+#include 
 #include 
+#include 
+#include 
+#include 
 
 static uint32_t __init acrn_detect(void)
 {
@@ -18,6 +22,8 @@ static uint32_t __init acrn_detect(void)
 
 static void __init acrn_init_platform(void)
 {
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
+   acrn_hv_callback_vector);
 }
 
 static bool acrn_x2apic_available(void)
@@ -26,6 +32,22 @@ static bool acrn_x2apic_available(void)
return false;
 }
 
+static void (*acrn_intr_handler)(void);
+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   entering_ack_irq();
+   inc_irq_stat(irq_hv_callback_count);
+
+   if (acrn_intr_handler)
+   acrn_intr_handler();
+
+   exiting_irq();
+   set_irq_regs(old_regs);
+}
+
 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
.name   = "ACRN",
.detect = acrn_detect,
-- 
2.7.4



[RFC PATCH v3 4/4] x86: Add hypercall for acrn_guest

2019-04-08 Thread Zhao Yakui
When acrn_hypervisor is detected, the hypercall is needed so that the
acrn guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for Guest system.

So the hypercall is added so that the kernel can communicate with the
low-level acrn-hypervisor. On x86 it is implemented by using vmacll when
the acrn hypervisor is enabled.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
V1->V2: Refine the comments for the function of acrn_hypercall0/1/2
v2->v3: Use the "vmcall" mnemonic to replace hard-code byte definition
---
 arch/x86/include/asm/acrn_hypercall.h | 82 +++
 1 file changed, 82 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h

diff --git a/arch/x86/include/asm/acrn_hypercall.h 
b/arch/x86/include/asm/acrn_hypercall.h
new file mode 100644
index 000..82c1577
--- /dev/null
+++ b/arch/x86/include/asm/acrn_hypercall.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_X86_ACRNHYPERCALL_H
+#define _ASM_X86_ACRNHYPERCALL_H
+
+#include 
+
+#ifdef CONFIG_ACRN_GUEST
+
+/*
+ * Hypercalls for ACRN Guest
+ *
+ * Hypercall number is passed in r8 register.
+ * Return value will be placed in rax.
+ * Up to 2 arguments are passed in rdi, rsi.
+ */
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   /* vmcall is used to implment the hypercall.
+* asm volatile is used to avoid that it is dropped because of
+* compiler optimization.
+*/
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "r"(r8));
+
+   return result;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "D"(param1), "r"(r8));
+
+   return result;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   register unsigned long r8 asm("r8") = hcall_id;
+   register long result asm("rax");
+
+   asm volatile("vmcall"
+   : "=r"(result)
+   : "D"(param1), "S"(param2), "r"(r8));
+
+   return result;
+}
+
+#else
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   return -ENOTSUPP;
+}
+#endif
+
+#endif /* _ASM_X86_ACRNHYPERCALL_H */
-- 
2.7.4



[RFC PATCH v3 0/4] x86: Add the support of ACRN guest under arch/x86

2019-04-08 Thread Zhao Yakui
ACRN is a flexible, lightweight reference hypervisor, built with real-time
and safety-criticality in mind, optimized to streamline embedded development
through an open source platform. It is built for embedded IOT with small
footprint and real-time features. More details can be found
in https://projectacrn.org/

This is the patch set that allows the Linux to work on ACRN hypervisor and it 
can
work with the following patch set to manage the Linux guest on acrn-hypervisor. 
It
includes the detection of acrn_hypervisor, upcall notification vector from
hypervisor, hypercall. The hypervisor detection is similar to Xen/VMWARE/Hyperv.
ACRN also uses the upcall notification mechanism similar to that in 
Xen/Microsoft
HyperV when it needs to send the notification to Linux OS. The hypercall 
provides
the mechanism that can be used to query/configure the acrn-hypervisor by Linux 
guest.

Following this patch set, we will send acrn driver part, which provides the 
interface
that can be used to manage the virtualized CPU/memory/device/interrupt for 
other guest
OS after the acrn hypervisor is detected.


v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.
Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.
Refine the comments for the function of acrn_hypercall0/1/2

v2-v3:  Add one new config symbol to unify the conditional definition
of hv_irq_callback_count
Use the "vmcall" mnemonic to replace the hard-code byte definition
Remove the unnecessary dependency of CONFIG_PARAVIRT for ACRN_GUEST

Zhao Yakui (4):
  x86: Add new config symbol to unify conditional definition of
hv_irq_callback_count
  x86: Add the support of ACRN guest
  x86: Use HYPERVISOR_CALLBACK_VECTOR for acrn_guest upcall vector
  x86: Add hypercall for acrn_guest

 arch/x86/Kconfig  | 12 +
 arch/x86/entry/entry_64.S |  5 +++
 arch/x86/include/asm/acrn_hypercall.h | 82 +++
 arch/x86/include/asm/acrnhyper.h  | 19 
 arch/x86/include/asm/hardirq.h|  2 +-
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 57 
 arch/x86/kernel/cpu/hypervisor.c  |  4 ++
 arch/x86/kernel/irq.c |  2 +-
 arch/x86/xen/Kconfig  |  1 +
 drivers/hv/Kconfig|  1 +
 12 files changed, 185 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h
 create mode 100644 arch/x86/include/asm/acrnhyper.h
 create mode 100644 arch/x86/kernel/cpu/acrn.c

-- 
2.7.4



[RFC PATCH v3 1/4] x86: Add new config symbol to unify conditional definition of hv_irq_callback_count

2019-04-08 Thread Zhao Yakui
Now the CONFIG_HYPERV and CONFIG_XEN can be used to control the definition
/usage of hv_irq_callback_count. If another linux guest also needs to use
the hv_irq_callback_count, current conditional definition looks unreadable.

Signed-off-by: Zhao Yakui 
---
 arch/x86/Kconfig   | 3 +++
 arch/x86/include/asm/hardirq.h | 2 +-
 arch/x86/kernel/irq.c  | 2 +-
 arch/x86/xen/Kconfig   | 1 +
 drivers/hv/Kconfig | 1 +
 5 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5ad9241..54d1fbc 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -791,6 +791,9 @@ config QUEUED_LOCK_STAT
  behavior of paravirtualized queued spinlocks and report
  them on debugfs.
 
+config X86_HV_CALLBACK_VECTOR
+   def_bool n
+
 source "arch/x86/xen/Kconfig"
 
 config KVM_GUEST
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d9069bb..0753379 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -37,7 +37,7 @@ typedef struct {
 #ifdef CONFIG_X86_MCE_AMD
unsigned int irq_deferred_error_count;
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
unsigned int irq_hv_callback_count;
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 59b5f2e..a147826 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -134,7 +134,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_puts(p, "  Machine check polls\n");
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#ifdef CONFIG_X86_HV_CALLBACK_VECTOR
if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j)
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index e07abef..ba5a418 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -7,6 +7,7 @@ config XEN
bool "Xen guest support"
depends on PARAVIRT
select PARAVIRT_CLOCK
+   select X86_HV_CALLBACK_VECTOR
depends on X86_64 || (X86_32 && X86_PAE)
depends on X86_LOCAL_APIC && X86_TSC
help
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 1c1a251..cafcb97 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -6,6 +6,7 @@ config HYPERV
tristate "Microsoft Hyper-V client drivers"
depends on X86 && ACPI && X86_LOCAL_APIC && HYPERVISOR_GUEST
select PARAVIRT
+   select X86_HV_CALLBACK_VECTOR
help
  Select this option to run Linux as a Hyper-V client operating
  system.
-- 
2.7.4



Re: [RFC PATCH v2 1/3] arch/x86: add the support of ACRN guest

2019-04-07 Thread Zhao, Yakui




On 2019年04月06日 03:01, Thomas Gleixner wrote:

Zhao,

On Tue, 26 Mar 2019, Zhao Yakui wrote:

Vs. the Subject line: arch/x86: add the support of ACRN guest

The proper prefix for x86 is surprisingly 'x86:' not 'arch/x86:'. Also
please start the first word after the colon with an upper case letter.


ACRN is one open-source hypervisour, which is maintained by Linux


s/one/an/


foundation.


by the Linuxfoundation.


This is to add the para-virtualization support so that
it allows the Linux guest to run on acrn-hypervisor.

This adds x86_hyper_acrn into supported hypervisors array, which enables
Linux ACRN guest running on ACRN hypervisor. It is restricted to X86_64.


Please do not use 'This is to add' or 'This adds'. Just say:

Add 
  

v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
 Remove the export of x86_hyper_acrn.


Thanks for having the version changes documented, but please put them after
the '---' line below and add another '---' before the diffstat. These
changes are not part of the final change log and if they are below then I
don't have to strip them manually.



Sure.
It will be updated.


Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
  arch/x86/Kconfig  |  8 
  arch/x86/include/asm/hypervisor.h |  1 +
  arch/x86/kernel/cpu/Makefile  |  1 +
  arch/x86/kernel/cpu/acrn.c| 35 +++
  arch/x86/kernel/cpu/hypervisor.c  |  4 
  5 files changed, 49 insertions(+)
  create mode 100644 arch/x86/kernel/cpu/acrn.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c1f9b3c..d73225e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -842,6 +842,14 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
  
+config ACRN_GUEST

+   bool "ACRN Guest support"
+   depends on X86_64 && PARAVIRT


Why does this select PARAVIRT? The current patches are not implementing
anything of the paravirt functionality. Which part of paravirtualization
are you going to provide?


Thanks for your nice and careful review.
Yes. The CONFIG_PARAVIRT is not required.
It will be removed.



Thanks,

tglx



Re: [RFC PATCH v2 2/3] arch/x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for Acrn upcall vector

2019-04-07 Thread Zhao, Yakui




On 2019年04月06日 03:07, Thomas Gleixner wrote:

On Tue, 26 Mar 2019, Zhao Yakui wrote:

diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d9069bb..a8f4d08 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -37,7 +37,8 @@ typedef struct {
  #ifdef CONFIG_X86_MCE_AMD
unsigned int irq_deferred_error_count;
  #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) ||\
+   defined(CONFIG_ACRN_GUEST)


..


@@ -134,7 +134,8 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_puts(p, "  Machine check polls\n");
  #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) ||\
+   defined(CONFIG_ACRN_GUEST)
if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j)


This starts to become unreadable. Please create a new config symbol:

  config X86_HV_CALLBACK_VECTOR
def_bool

and select if from HYPERV, XEN and your new thing. That wants to be a
separate preparatory patch at the beginning of the series please.


Thanks for the suggestion.
Sure. One new config will be added in next version.




Thanks,

tglx



Re: [RFC PATCH v2 3/3] arch/x86/acrn: add hypercall for acrn_guest

2019-04-07 Thread Zhao, Yakui




On 2019年04月06日 03:19, Thomas Gleixner wrote:

On Tue, 26 Mar 2019, Zhao Yakui wrote:


When acrn_hypervisor is detected, the hypercall is needed so that the
acrn guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for Guest system.

So the hypercall is added so that the kernel can communicate with the
low-level acrn-hypervisor. On x86 it is implemented by using vmacll when


is implemented with the VMCALL instruction


the acrn hypervisor is enabled.

+++ b/arch/x86/include/asm/acrn_hypercall.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * acrn_hypercall.h : acrn hypervisor call API


No file names in headers please. They are pointless and get out of sync
when files are renamed.


Sure. It will be removed in next vesion.




+ */
+
+#ifndef __ACRN_HYPERCALL_H__
+#define __ACRN_HYPERCALL_H__


asm headers start with

 __ASM_X86_


This will be fixed.


+
+#include 
+
+#ifdef CONFIG_ACRN_GUEST
+
+/*
+ * Hypercalls for ACRN Guest
+ *
+ * Hypercall number is passed in r8 register.
+ * Return value will be placed in rax.
+ * Up to 2 arguments are passed in rdi, rsi.
+ */
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+


Remove the empty new line please.


+   register long result asm("rax");
+   register unsigned long r8 asm("r8") = hcall_id;


Please order them the other way around, like a reverse christmas tree:

register unsigned long r8 asm("r8") = hcall_id;
register long result asm("rax");

That's way simpler to read.


This will be fixed.




+   asm volatile(".byte 0x0F,0x01,0xC1\n"
+   : "=r"(result)
+   :  "r"(r8));


Please mention in the changelog why this is implemented with bytes and not
with the proper mnemonic. I assume it depends on binutils, so please
document which version of binutils supports the mnemonic.


I check the binutils version mentioned in Document/changes.
(binutils, 2.20)
It seems that the "vmcall" is already supported.
So the "vmcall" mnemonic will be used to make it readable.



And in the first function, i.e. hypercall0, add a comment above the asm
volatile() to that effect as well.


Sure.




Thanks,

tglx



[RFC PATCH v2 1/3] arch/x86: add the support of ACRN guest

2019-03-25 Thread Zhao Yakui
ACRN is one open-source hypervisour, which is maintained by Linux
foundation. This is to add the para-virtualization support so that
it allows the Linux guest to run on acrn-hypervisor.

This adds x86_hyper_acrn into supported hypervisors array, which enables
Linux ACRN guest running on ACRN hypervisor. It is restricted to X86_64.

v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 arch/x86/Kconfig  |  8 
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 35 +++
 arch/x86/kernel/cpu/hypervisor.c  |  4 
 5 files changed, 49 insertions(+)
 create mode 100644 arch/x86/kernel/cpu/acrn.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c1f9b3c..d73225e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -842,6 +842,14 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
 
+config ACRN_GUEST
+   bool "ACRN Guest support"
+   depends on X86_64 && PARAVIRT
+   help
+ This option allows to run Linux as guest in ACRN hypervisor. Enabling
+ this will allow the kernel to boot in a paravirtualized environment
+ under the ACRN hypervisor.
+
 endif #HYPERVISOR_GUEST
 
 source "arch/x86/Kconfig.cpu"
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 8c5aaba..50a30f6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -29,6 +29,7 @@ enum x86_hypervisor_type {
X86_HYPER_XEN_HVM,
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
+   X86_HYPER_ACRN,
 };
 
 #ifdef CONFIG_HYPERVISOR_GUEST
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index cfd24f9..17a7cdf 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_X86_CPU_RESCTRL) += resctrl/
 obj-$(CONFIG_X86_LOCAL_APIC)   += perfctr-watchdog.o
 
 obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
+obj-$(CONFIG_ACRN_GUEST)   += acrn.o
 
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
new file mode 100644
index 000..3956567
--- /dev/null
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACRN detection support
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ *
+ */
+
+#include 
+
+static uint32_t __init acrn_detect(void)
+{
+   return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+}
+
+static void __init acrn_init_platform(void)
+{
+}
+
+static bool acrn_x2apic_available(void)
+{
+   /* do not support x2apic */
+   return false;
+}
+
+const __initconst struct hypervisor_x86 x86_hyper_acrn = {
+   .name   = "ACRN",
+   .detect = acrn_detect,
+   .type   = X86_HYPER_ACRN,
+   .init.init_platform = acrn_init_platform,
+   .init.x2apic_available  = acrn_x2apic_available,
+};
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 479ca47..87e39ad 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -32,6 +32,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
 extern const struct hypervisor_x86 x86_hyper_xen_hvm;
 extern const struct hypervisor_x86 x86_hyper_kvm;
 extern const struct hypervisor_x86 x86_hyper_jailhouse;
+extern const struct hypervisor_x86 x86_hyper_acrn;
 
 static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
@@ -49,6 +50,9 @@ static const __initconst struct hypervisor_x86 * const 
hypervisors[] =
 #ifdef CONFIG_JAILHOUSE_GUEST
&x86_hyper_jailhouse,
 #endif
+#ifdef CONFIG_ACRN_GUEST
+   &x86_hyper_acrn,
+#endif
 };
 
 enum x86_hypervisor_type x86_hyper_type;
-- 
2.7.4



[RFC PATCH v2 0/3] arch/x86: Add the support of ACRN guest under arch/x86

2019-03-25 Thread Zhao Yakui
ACRN is a flexible, lightweight reference hypervisor, built with real-time
and safety-criticality in mind, optimized to streamline embedded development
through an open source platform. It is built for embedded IOT with small
footprint and real-time features. More details can be found
in https://projectacrn.org/

This is the patch set that allows the Linux to work on ACRN hypervisor and it 
can
work with the following patch set to manage the Linux guest on acrn-hypervisor. 
It
includes the detection of acrn_hypervisor, upcall notification vector from
hypervisor, hypercall. The hypervisor detection is similar to Xen/VMWARE/Hyperv.
ACRN also uses the upcall notification mechanism similar to that in 
Xen/Microsoft
HyperV when it needs to send the notification to Linux OS. The hypercall 
provides
the mechanism that can be used to query/configure the acrn-hypervisor by Linux 
guest.

Following this patch set, we will send acrn driver part, which provides the 
interface
that can be used to manage the virtualized CPU/memory/device/interrupt for 
other guest
OS after the acrn hypervisor is detected.


v1->v2: Change the CONFIG_ACRN to CONFIG_ACRN_GUEST, which makes it easy to
understand.
Remove the export of x86_hyper_acrn.
Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.
Refine the comments for the function of acrn_hypercall0/1/2

Zhao Yakui (3):
  arch/x86: add the support of ACRN guest
  arch/x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for Acrn upcall vector
  arch/x86/acrn: add hypercall for acrn_guest

 arch/x86/Kconfig  |  8 
 arch/x86/entry/entry_64.S |  5 +++
 arch/x86/include/asm/acrn_hypercall.h | 84 +++
 arch/x86/include/asm/acrnhyper.h  | 19 
 arch/x86/include/asm/hardirq.h|  3 +-
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 57 
 arch/x86/kernel/cpu/hypervisor.c  |  4 ++
 arch/x86/kernel/irq.c |  3 +-
 10 files changed, 183 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h
 create mode 100644 arch/x86/include/asm/acrnhyper.h
 create mode 100644 arch/x86/kernel/cpu/acrn.c

-- 
2.7.4



[RFC PATCH v2 2/3] arch/x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for Acrn upcall vector

2019-03-25 Thread Zhao Yakui
Linux kernel uses the HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall
vector. And it is already used for Xen and HyperV.
After Acrn hypervisor is detected, it will also use this defined vector
to notify kernel.

V1->V2: Remove the unused API definition of acrn_setup_intr_handler and
acrn_remove_intr_handler.
Adjust the order of header file
Add the declaration of acrn_hv_vector_handler and tracing
definition of acrn_hv_callback_vector.

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 arch/x86/entry/entry_64.S|  5 +
 arch/x86/include/asm/acrnhyper.h | 19 +++
 arch/x86/include/asm/hardirq.h   |  3 ++-
 arch/x86/kernel/cpu/acrn.c   | 22 ++
 arch/x86/kernel/irq.c|  3 ++-
 5 files changed, 50 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/acrnhyper.h

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 1f0efdb..d1b8ad3 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1129,6 +1129,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
+#if IS_ENABLED(CONFIG_ACRN_GUEST)
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+   acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
 idtentry debug do_debughas_error_code=0
paranoid=1 shift_ist=DEBUG_STACK
 idtentry int3  do_int3 has_error_code=0
 idtentry stack_segment do_stack_segmenthas_error_code=1
diff --git a/arch/x86/include/asm/acrnhyper.h b/arch/x86/include/asm/acrnhyper.h
new file mode 100644
index 000..9f9c239
--- /dev/null
+++ b/arch/x86/include/asm/acrnhyper.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRNHYPER_H
+#define _ASM_X86_ACRNHYPER_H
+
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_ACRN_GUEST
+void acrn_hv_callback_vector(void);
+#ifdef CONFIG_TRACING
+#define trace_acrn_hv_callback_vector acrn_hv_callback_vector
+#endif
+
+void acrn_hv_vector_handler(struct pt_regs *regs);
+#endif
+
+#endif
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d9069bb..a8f4d08 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -37,7 +37,8 @@ typedef struct {
 #ifdef CONFIG_X86_MCE_AMD
unsigned int irq_deferred_error_count;
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) ||\
+   defined(CONFIG_ACRN_GUEST)
unsigned int irq_hv_callback_count;
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index 3956567..7a233b5 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -9,7 +9,11 @@
  *
  */
 
+#include 
 #include 
+#include 
+#include 
+#include 
 
 static uint32_t __init acrn_detect(void)
 {
@@ -18,6 +22,8 @@ static uint32_t __init acrn_detect(void)
 
 static void __init acrn_init_platform(void)
 {
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
+   acrn_hv_callback_vector);
 }
 
 static bool acrn_x2apic_available(void)
@@ -26,6 +32,22 @@ static bool acrn_x2apic_available(void)
return false;
 }
 
+static void (*acrn_intr_handler)(void);
+
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   entering_ack_irq();
+   inc_irq_stat(irq_hv_callback_count);
+
+   if (acrn_intr_handler)
+   acrn_intr_handler();
+
+   exiting_irq();
+   set_irq_regs(old_regs);
+}
+
 const __initconst struct hypervisor_x86 x86_hyper_acrn = {
.name   = "ACRN",
.detect = acrn_detect,
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 59b5f2e..02c6ff6 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -134,7 +134,8 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_puts(p, "  Machine check polls\n");
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) ||\
+   defined(CONFIG_ACRN_GUEST)
if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j)
-- 
2.7.4



[RFC PATCH v2 3/3] arch/x86/acrn: add hypercall for acrn_guest

2019-03-25 Thread Zhao Yakui
When acrn_hypervisor is detected, the hypercall is needed so that the
acrn guest can query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for Guest system.

So the hypercall is added so that the kernel can communicate with the
low-level acrn-hypervisor. On x86 it is implemented by using vmacll when
the acrn hypervisor is enabled.

V1->V2: Refine the comments for the function of acrn_hypercall0/1/2

Co-developed-by: Jason Chen CJ 
Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 arch/x86/include/asm/acrn_hypercall.h | 84 +++
 1 file changed, 84 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h

diff --git a/arch/x86/include/asm/acrn_hypercall.h 
b/arch/x86/include/asm/acrn_hypercall.h
new file mode 100644
index 000..3262935
--- /dev/null
+++ b/arch/x86/include/asm/acrn_hypercall.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * acrn_hypercall.h : acrn hypervisor call API
+ */
+
+#ifndef __ACRN_HYPERCALL_H__
+#define __ACRN_HYPERCALL_H__
+
+#include 
+
+#ifdef CONFIG_ACRN_GUEST
+
+/*
+ * Hypercalls for ACRN Guest
+ *
+ * Hypercall number is passed in r8 register.
+ * Return value will be placed in rax.
+ * Up to 2 arguments are passed in rdi, rsi.
+ */
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+
+   register long result asm("rax");
+   register unsigned long r8 asm("r8") = hcall_id;
+
+   asm volatile(".byte 0x0F,0x01,0xC1\n"
+   : "=r"(result)
+   :  "r"(r8));
+
+   return result;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+
+   register long result asm("rax");
+   register unsigned long r8 asm("r8") = hcall_id;
+
+   asm volatile(".byte 0x0F,0x01,0xC1\n"
+   : "=r"(result)
+   : "D"(param1), "r"(r8));
+
+   return result;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+
+   register long result asm("rax");
+   register unsigned long r8 asm("r8") = hcall_id;
+
+   asm volatile(".byte 0x0F,0x01,0xC1\n"
+   : "=r"(result)
+   : "D"(param1), "S"(param2), "r"(r8));
+
+   return result;
+}
+
+#else
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   return -ENOTSUPP;
+}
+#endif
+
+#endif /* __ACRN_HYPERCALL_H__ */
-- 
2.7.4



Re: [RFC PATCH 2/3] arch/x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for Acrn upcall vector

2019-03-25 Thread Zhao, Yakui




On 2019年03月25日 16:27, Thomas Gleixner wrote:

On Mon, 25 Mar 2019, Zhao, Yakui wrote:

+/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ACRNHYPER_H
+#define _ASM_X86_ACRNHYPER_H
+
+#include 
+#include 
+
+#ifdef CONFIG_ACRN
+/* ACRN Hypervisor callback */
+void acrn_hv_callback_vector(void);


What declares acrn_hv_vector_handler() ?


Acrn_hv_callback_vector is defined in arch/x86/entry/entry_64.S, which will be 
used as
the parameter of alloc_intr_gate

Acrn_hv_vector_handler is the real ISR handler, which is defined in acrn.c.


I know how that works and I was not asking where stuff is defined. I was
asking where it is declared. Global functions need a declaration in a
header file.


Sure. It will be declared in next version.




+void acrn_remove_intr_irq(void)
+{
+   acrn_intr_handler = NULL;
+}
+EXPORT_SYMBOL(acrn_remove_intr_irq);


Where is the code which uses these exports? We are not adding exports just
because or for consumption by out of tree modules.


Understand it.
Is it reasonable that the above two functions are added in the driver patch set?


Yes, because then we see the context.


OK. They will be removed.  And it will be included in driver patch set.



Thanks,

tglx



Re: [RFC PATCH 3/3] arch/x86/acrn: add hypercall for acrn_hypervisor

2019-03-25 Thread Zhao, Yakui




On 2019年03月25日 16:30, Thomas Gleixner wrote:

On Mon, 25 Mar 2019, Zhao, Yakui wrote:



-Original Message-
From: Thomas Gleixner [mailto:t...@linutronix.de]
Sent: Saturday, March 23, 2019 12:02 AM
To: Zhao, Yakui 
Cc: linux-kernel@vger.kernel.org; x...@kernel.org; Chen, Jason CJ

Subject: Re: [RFC PATCH 3/3] arch/x86/acrn: add hypercall for acrn_hypervisor



Can you please fix your mail client not to copy the full email headers on
the reply?

The simple: On $DATE, someone wrote: like the below is sufficient.


thanks for the reminder.




+static inline long acrn_hypercall0(unsigned long hcall_id) {
+
+   /* x86-64 System V ABI register usage */


Well, yes. But can you please provide a link to the hypercall specification in 
the
changelog?

Also instead of repeating the same comment over and over, explain the calling
convention in a top level comment.


This is the low-level implementation of low-level hypercall. It is similar to
Kvm_hypercall1/2/3 in arch/x86/include/asm/kvm_para.h.
Does it make sense that the below comments are added before acrn_hypercall0/1/2?
/*
  * Hypercalls for ACRN Guest
  *
  * Hypercall number is passed in r8 register.
  * Return value will be placed in rax.
  * Up to 2 arguments are passed in rdi, rsi.
  */


Yes, that's much more helpful.

Thanks,

tglx



RE: [RFC PATCH 3/3] arch/x86/acrn: add hypercall for acrn_hypervisor

2019-03-24 Thread Zhao, Yakui



>-Original Message-
>From: Thomas Gleixner [mailto:t...@linutronix.de]
>Sent: Saturday, March 23, 2019 12:02 AM
>To: Zhao, Yakui 
>Cc: linux-kernel@vger.kernel.org; x...@kernel.org; Chen, Jason CJ
>
>Subject: Re: [RFC PATCH 3/3] arch/x86/acrn: add hypercall for acrn_hypervisor
>
>On Thu, 7 Mar 2019, Zhao Yakui wrote:
>
>> When acrn_hypervisor is detected, the other module may communicate
>> with
>
>Which other module?
>
>> the hypervisor to query/config some settings. For example: it can be
>> used to query the resources in hypervisor and manage the
>> CPU/memory/device/ interrupt for Guest system.
>
>> +++ b/arch/x86/include/asm/acrn_hypercall.h
>> @@ -0,0 +1,85 @@
>> +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
>
>So the hypercall header is GPL-2.0+ and the acrn.c file is GPL-2.0. Not that I
>personally care, but is this intended?

Sorry for my fault. It should be GPL-2.0

>
>> +/*
>> + * acrn_hypercall.h : acrn hypervisor call API  */
>> +
>> +#ifndef __ACRN_HYPERCALL_H__
>> +#define __ACRN_HYPERCALL_H__
>> +
>> +#include 
>> +
>> +#ifdef CONFIG_ACRN
>> +
>> +static inline long acrn_hypercall0(unsigned long hcall_id) {
>> +
>> +/* x86-64 System V ABI register usage */
>
>Well, yes. But can you please provide a link to the hypercall specification in 
>the
>changelog?
>
>Also instead of repeating the same comment over and over, explain the calling
>convention in a top level comment.

This is the low-level implementation of low-level hypercall. It is similar to 
Kvm_hypercall1/2/3 in arch/x86/include/asm/kvm_para.h.
Does it make sense that the below comments are added before acrn_hypercall0/1/2?
/*
 * Hypercalls for ACRN Guest
 * 
 * Hypercall number is passed in r8 register.
 * Return value will be placed in rax. 
 * Up to 2 arguments are passed in rdi, rsi.
 */   

Of course I will also remove the redundant comments.

>
>> +register signed longresult asm("rax");
>> +register unsigned long  r8 asm("r8")  = hcall_id;
>
>I appreciate the attempt of making this tabular, but it's unreadable and has
>random white space in it. Also please use 'long' and not 'signed long'.

Ok. The type will be refined.


>
>   register unsigned long  r8  asm("r8") = hcall_id;
>   register long   result  asm("rax");
>
>> +
>> +/* Execute vmcall */
>> +asm volatile(".byte 0x0F,0x01,0xC1\n"
>> +: "=r"(result)
>> +:  "r"(r8));
>> +
>> +/* Return result to caller */
>
>Please do not comment the obvious. It's entirely clear that this returns 
>'result'
>to the caller. Comments are there to explain what's not obvious.

Thanks for pointing out the issue.
I will remove the redundant comment.

>
>> +return result;
>> +}
>
>Thanks,
>
>   tglx


RE: [RFC PATCH 2/3] arch/x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for Acrn upcall vector

2019-03-24 Thread Zhao, Yakui



>-Original Message-
>From: Thomas Gleixner [mailto:t...@linutronix.de]
>Sent: Friday, March 22, 2019 11:45 PM
>To: Zhao, Yakui 
>Cc: linux-kernel@vger.kernel.org; x...@kernel.org; Chen, Jason CJ
>
>Subject: Re: [RFC PATCH 2/3] arch/x86/acrn: Use
>HYPERVISOR_CALLBACK_VECTOR for Acrn upcall vector
>
>On Thu, 7 Mar 2019, Zhao Yakui wrote:
>
>> WHen it works in hypervisor guest mode, Linux kernel uses the
>> HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall vector. And it is
>> already used for Xen and HyperV. After Acrn hypervisor is detected, it
>> will also use this defined vector as notify vector to kernel.
>> And two APIs are added so that the other module can add/remove the
>> hypervisor callback irq handler.
>
>Which other module?
>

This work is divided into two steps. The first is to add the support of 
acrn-guest under arch/x86.
The second is to add one driver that allows the acrn-guest to communicate with 
the acrn-hypervisor.
As the second part has the dependency on the first part,  we hope that the 
acrn-guest is added firstly and the
required API is also added.

>> Signed-off-by: Jason Chen CJ 
>> Signed-off-by: Zhao Yakui 
>
>Same SOB issue.

Sure. It will be updated.

>
>> +#if IS_ENABLED(CONFIG_ACRN)
>> +apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
>> +acrn_hv_callback_vector acrn_hv_vector_handler #endif
>> +
>>  idtentry debug  do_debug
>   has_error_code=0paranoid=1 shift_ist=DEBUG_STACK
>>  idtentry int3   do_int3 has_error_code=0
>>  idtentry stack_segment  do_stack_segment
>   has_error_code=1
>> diff --git a/arch/x86/include/asm/acrnhyper.h
>> b/arch/x86/include/asm/acrnhyper.h
>> new file mode 100644
>> index 000..2562a82
>> --- /dev/null
>> +++ b/arch/x86/include/asm/acrnhyper.h
>> @@ -0,0 +1,16 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_ACRNHYPER_H
>> +#define _ASM_X86_ACRNHYPER_H
>> +
>> +#include 
>> +#include 
>> +
>> +#ifdef CONFIG_ACRN
>> +/* ACRN Hypervisor callback */
>> +void acrn_hv_callback_vector(void);
>
>What declares acrn_hv_vector_handler() ?

Acrn_hv_callback_vector is defined in arch/x86/entry/entry_64.S, which will be 
used as
the parameter of alloc_intr_gate

Acrn_hv_vector_handler is the real ISR handler, which is defined in acrn.c.

>
>>  #include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>
>First of all the include order is always:
>
> #include 
> #include 
>
> #include 
>
>Aside of that including 'linux/irq.h' should include everything you need. No
>need for gazillion of includes.

OK. The include order will be updated in next version.

>
>>  static bool acrn_x2apic_available(void) @@ -26,6 +33,37 @@ static
>> bool acrn_x2apic_available(void)
>>  return false;
>>  }
>>
>> +
>
>Stray newline
>

Sure. The extra newline will be removed.

>> +static void (*acrn_intr_handler)(void);
>> +/*
>
>Which should have been above this comment. Glueing stuff together makes it
>unreadable.
>
>> + * Handler for ACRN_HV_CALLBACK.
>
>Err? This handles the HYPERVISOR_CALLBACK_VECTOR
>

I will remove the confusing comment.
In fact this acrn_intr_handle is similar to the vmbus_handler in 
arch/x86/kernel/cpu/mshyperv.c

>> + */
>> +__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs
>> +*regs) {
>> +struct pt_regs *old_regs = set_irq_regs(regs);
>> +
>> +entering_ack_irq();
>> +inc_irq_stat(irq_hv_callback_count);
>> +
>> +if (acrn_intr_handler)
>> +acrn_intr_handler();
>> +
>> +exiting_irq();
>> +set_irq_regs(old_regs);
>> +}
>> +
>> +void acrn_setup_intr_irq(void (*handler)(void)) {
>> +acrn_intr_handler = handler;
>> +}
>> +EXPORT_SYMBOL(acrn_setup_intr_irq);
>> +
>> +void acrn_remove_intr_irq(void)
>> +{
>> +acrn_intr_handler = NULL;
>> +}
>> +EXPORT_SYMBOL(acrn_remove_intr_irq);
>
>Where is the code which uses these exports? We are not adding exports just
>because or for consumption by out of tree modules.

Understand it.
Is it reasonable that the above two functions are added in the driver patch set?


>
>Thanks,
>
>   tglx


RE: [RFC PATCH 1/3] arch/x86: add ACRN hypervisor guest

2019-03-24 Thread Zhao, Yakui
Hi,  Tglx

   Thanks for your nice review. 
>-Original Message-
>From: Thomas Gleixner [mailto:t...@linutronix.de]
>Sent: Friday, March 22, 2019 11:20 PM
>To: Zhao, Yakui 
>Cc: linux-kernel@vger.kernel.org; x...@kernel.org; Chen, Jason CJ
>
>Subject: Re: [RFC PATCH 1/3] arch/x86: add ACRN hypervisor guest
>
>Zhao,
>
>On Thu, 7 Mar 2019, Zhao Yakui wrote:
>
>> ACRN is one open-source hypervisour, which is maintained by Linux
>> foundation. This is to add the para-virtualization support so that it
>> allows to enable the Linux guest on acrn-hypervisor.
>>
>> This adds x86_hyper_acrn into supported hypervisors array, which
>> enables ACRN services guest running on ACRN hypervisor. It is
>
>What is a ACRN services guest?

It should be "ACRN guest".

>
>> restricted to X86_64.
>>
>> Signed-off-by: Jason Chen CJ 
>> Signed-off-by: Zhao Yakui 
>
>This SOB chain is wrong. If Jason wrote the patch, then there should be a
>'From: Jason ..' line at the top of the change log. If you both wrote it then
>Jason's SOB wants to be preceeded by a 'Co-developed-by: Jason'
>line. See Documentation/process/

Sure. It will be updated to "Co-developed-by: Jason" in next version.

>
>> +config ACRN
>> +bool "Enable services on ACRN hypervisor"
>> +depends on X86_64 && PARAVIRT
>> +help
>> +  This option allows to run Linux as guest in ACRN hypervisor.
>> +  It is needed if you want to run ACRN services linux on top of
>> +  ACRN hypervisor.
>
>This help text does not make any sense to me.

"Enable Services on ACRN hypervisor" is a little confusing. 
In next version it will be changed to "ACRN_GUEST". How about the below:
config ACRN_GUEST
bool "ACRN Guest Support"
depends on X86_64 && PARAVIRT
help
  This option allows to run Linux as guest in ACRN hypervisor. Enabling 
this will allow the
  kernel to boot in a paravirtualized environment under the  ACRN 
hypervisor

>
>> +const struct hypervisor_x86 x86_hyper_acrn = {
>> +.name   = "ACRN",
>> +.detect = acrn_detect,
>> +.type   = X86_HYPER_ACRN,
>> +.init.init_platform = acrn_init_platform,
>> +.init.x2apic_available  = acrn_x2apic_available, };
>> +EXPORT_SYMBOL(x86_hyper_acrn);
>
>Whay is this exported? The only user of this is hypervisor.c and that is built 
>in.
>Please remove.

You are right.
It will be removed and the x86_hyper_acrn will also be added into "__initconst" 
section.

>
>Thanks,
>
>   tglx


[RFC PATCH 2/3] arch/x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for Acrn upcall vector

2019-03-06 Thread Zhao Yakui
WHen it works in hypervisor guest mode, Linux kernel uses the
HYPERVISOR_CALLBACK_VECTOR for hypervisor upcall vector. And it is already
used for Xen and HyperV. After Acrn hypervisor is detected, it will also
use this defined vector as notify vector to kernel.
And two APIs are added so that the other module can add/remove the
hypervisor callback irq handler.

Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 arch/x86/entry/entry_64.S|  5 +
 arch/x86/include/asm/acrnhyper.h | 16 
 arch/x86/include/asm/hardirq.h   |  2 +-
 arch/x86/kernel/cpu/acrn.c   | 38 ++
 arch/x86/kernel/irq.c|  2 +-
 5 files changed, 61 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/acrnhyper.h

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 1f0efdb..23f12e8 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1129,6 +1129,11 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler
 #endif /* CONFIG_HYPERV */
 
+#if IS_ENABLED(CONFIG_ACRN)
+apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
+   acrn_hv_callback_vector acrn_hv_vector_handler
+#endif
+
 idtentry debug do_debughas_error_code=0
paranoid=1 shift_ist=DEBUG_STACK
 idtentry int3  do_int3 has_error_code=0
 idtentry stack_segment do_stack_segmenthas_error_code=1
diff --git a/arch/x86/include/asm/acrnhyper.h b/arch/x86/include/asm/acrnhyper.h
new file mode 100644
index 000..2562a82
--- /dev/null
+++ b/arch/x86/include/asm/acrnhyper.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_ACRNHYPER_H
+#define _ASM_X86_ACRNHYPER_H
+
+#include 
+#include 
+
+#ifdef CONFIG_ACRN
+/* ACRN Hypervisor callback */
+void acrn_hv_callback_vector(void);
+
+void acrn_setup_intr_irq(void (*handler)(void));
+void acrn_remove_intr_irq(void);
+#endif
+
+#endif
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index d9069bb..5aa52d2 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -37,7 +37,7 @@ typedef struct {
 #ifdef CONFIG_X86_MCE_AMD
unsigned int irq_deferred_error_count;
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) || defined(CONFIG_ACRN)
unsigned int irq_hv_callback_count;
 #endif
 #if IS_ENABLED(CONFIG_HYPERV)
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
index ddeaafb..c802fe6 100644
--- a/arch/x86/kernel/cpu/acrn.c
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -10,6 +10,11 @@
  */
 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 static uint32_t __init acrn_detect(void)
 {
@@ -18,6 +23,8 @@ static uint32_t __init acrn_detect(void)
 
 static void __init acrn_init_platform(void)
 {
+   alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR,
+   acrn_hv_callback_vector);
 }
 
 static bool acrn_x2apic_available(void)
@@ -26,6 +33,37 @@ static bool acrn_x2apic_available(void)
return false;
 }
 
+
+static void (*acrn_intr_handler)(void);
+/*
+ * Handler for ACRN_HV_CALLBACK.
+ */
+__visible void __irq_entry acrn_hv_vector_handler(struct pt_regs *regs)
+{
+   struct pt_regs *old_regs = set_irq_regs(regs);
+
+   entering_ack_irq();
+   inc_irq_stat(irq_hv_callback_count);
+
+   if (acrn_intr_handler)
+   acrn_intr_handler();
+
+   exiting_irq();
+   set_irq_regs(old_regs);
+}
+
+void acrn_setup_intr_irq(void (*handler)(void))
+{
+   acrn_intr_handler = handler;
+}
+EXPORT_SYMBOL(acrn_setup_intr_irq);
+
+void acrn_remove_intr_irq(void)
+{
+   acrn_intr_handler = NULL;
+}
+EXPORT_SYMBOL(acrn_remove_intr_irq);
+
 const struct hypervisor_x86 x86_hyper_acrn = {
.name   = "ACRN",
.detect = acrn_detect,
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 59b5f2e..6b3eaab 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -134,7 +134,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", per_cpu(mce_poll_count, j));
seq_puts(p, "  Machine check polls\n");
 #endif
-#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
+#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) || defined(CONFIG_ACRN)
if (test_bit(HYPERVISOR_CALLBACK_VECTOR, system_vectors)) {
seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j)
-- 
2.7.4



[RFC PATCH 3/3] arch/x86/acrn: add hypercall for acrn_hypervisor

2019-03-06 Thread Zhao Yakui
When acrn_hypervisor is detected, the other module may communicate with
the hypervisor to query/config some settings. For example: it can be used
to query the resources in hypervisor and manage the CPU/memory/device/
interrupt for Guest system.

So the hypercall is added so that the kernel can communicate with the
low-level acrn-hypervisor. On x86 it is implemented by using vmacll when
the acrn hypervisor is enabled.

Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 arch/x86/include/asm/acrn_hypercall.h | 85 +++
 1 file changed, 85 insertions(+)
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h

diff --git a/arch/x86/include/asm/acrn_hypercall.h 
b/arch/x86/include/asm/acrn_hypercall.h
new file mode 100644
index 000..7ffa759
--- /dev/null
+++ b/arch/x86/include/asm/acrn_hypercall.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * acrn_hypercall.h : acrn hypervisor call API
+ */
+
+#ifndef __ACRN_HYPERCALL_H__
+#define __ACRN_HYPERCALL_H__
+
+#include 
+
+#ifdef CONFIG_ACRN
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+
+   /* x86-64 System V ABI register usage */
+   register signed longresult asm("rax");
+   register unsigned long  r8 asm("r8")  = hcall_id;
+
+   /* Execute vmcall */
+   asm volatile(".byte 0x0F,0x01,0xC1\n"
+   : "=r"(result)
+   :  "r"(r8));
+
+   /* Return result to caller */
+   return result;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+
+   /* x86-64 System V ABI register usage */
+   register signed longresult asm("rax");
+   register unsigned long  r8 asm("r8")  = hcall_id;
+
+   /* Execute vmcall */
+   asm volatile(".byte 0x0F,0x01,0xC1\n"
+   : "=r"(result)
+   : "D"(param1), "r"(r8));
+
+   /* Return result to caller */
+   return result;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+
+   /* x86-64 System V ABI register usage */
+   register signed longresult asm("rax");
+   register unsigned long  r8 asm("r8")  = hcall_id;
+
+   /* Execute vmcall */
+   asm volatile(".byte 0x0F,0x01,0xC1\n"
+   : "=r"(result)
+   : "D"(param1), "S"(param2), "r"(r8));
+
+   /* Return result to caller */
+   return result;
+}
+
+#else
+
+static inline long acrn_hypercall0(unsigned long hcall_id)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall1(unsigned long hcall_id,
+  unsigned long param1)
+{
+   return -ENOTSUPP;
+}
+
+static inline long acrn_hypercall2(unsigned long hcall_id,
+  unsigned long param1,
+  unsigned long param2)
+{
+   return -ENOTSUPP;
+}
+#endif
+
+#endif /* __ACRN_HYPERCALL_H__ */
-- 
2.7.4



[RFC PATCH 1/3] arch/x86: add ACRN hypervisor guest

2019-03-06 Thread Zhao Yakui
ACRN is one open-source hypervisour, which is maintained by Linux
foundation. This is to add the para-virtualization support so that
it allows to enable the Linux guest on acrn-hypervisor.

This adds x86_hyper_acrn into supported hypervisors array, which
enables ACRN services guest running on ACRN hypervisor. It is
restricted to X86_64.

Signed-off-by: Jason Chen CJ 
Signed-off-by: Zhao Yakui 
---
 arch/x86/Kconfig  |  8 
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 36 
 arch/x86/kernel/cpu/hypervisor.c  |  4 
 5 files changed, 50 insertions(+)
 create mode 100644 arch/x86/kernel/cpu/acrn.c

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 90b562a..c7b64e7 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -843,6 +843,14 @@ config JAILHOUSE_GUEST
  cell. You can leave this option disabled if you only want to start
  Jailhouse and run Linux afterwards in the root cell.
 
+config ACRN
+   bool "Enable services on ACRN hypervisor"
+   depends on X86_64 && PARAVIRT
+   help
+ This option allows to run Linux as guest in ACRN hypervisor.
+ It is needed if you want to run ACRN services linux on top of
+ ACRN hypervisor.
+
 endif #HYPERVISOR_GUEST
 
 source "arch/x86/Kconfig.cpu"
diff --git a/arch/x86/include/asm/hypervisor.h 
b/arch/x86/include/asm/hypervisor.h
index 8c5aaba..50a30f6 100644
--- a/arch/x86/include/asm/hypervisor.h
+++ b/arch/x86/include/asm/hypervisor.h
@@ -29,6 +29,7 @@ enum x86_hypervisor_type {
X86_HYPER_XEN_HVM,
X86_HYPER_KVM,
X86_HYPER_JAILHOUSE,
+   X86_HYPER_ACRN,
 };
 
 #ifdef CONFIG_HYPERVISOR_GUEST
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index cfd24f9..cde1436 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_X86_CPU_RESCTRL) += resctrl/
 obj-$(CONFIG_X86_LOCAL_APIC)   += perfctr-watchdog.o
 
 obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o
+obj-$(CONFIG_ACRN) += acrn.o
 
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
diff --git a/arch/x86/kernel/cpu/acrn.c b/arch/x86/kernel/cpu/acrn.c
new file mode 100644
index 000..ddeaafb
--- /dev/null
+++ b/arch/x86/kernel/cpu/acrn.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ACRN hypervisor support
+ *
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ *
+ * Jason Chen CJ 
+ * Zhao Yakui 
+ *
+ */
+
+#include 
+
+static uint32_t __init acrn_detect(void)
+{
+   return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+}
+
+static void __init acrn_init_platform(void)
+{
+}
+
+static bool acrn_x2apic_available(void)
+{
+   /* do not support x2apic */
+   return false;
+}
+
+const struct hypervisor_x86 x86_hyper_acrn = {
+   .name   = "ACRN",
+   .detect = acrn_detect,
+   .type   = X86_HYPER_ACRN,
+   .init.init_platform = acrn_init_platform,
+   .init.x2apic_available  = acrn_x2apic_available,
+};
+EXPORT_SYMBOL(x86_hyper_acrn);
diff --git a/arch/x86/kernel/cpu/hypervisor.c b/arch/x86/kernel/cpu/hypervisor.c
index 479ca47..5a6f072 100644
--- a/arch/x86/kernel/cpu/hypervisor.c
+++ b/arch/x86/kernel/cpu/hypervisor.c
@@ -32,6 +32,7 @@ extern const struct hypervisor_x86 x86_hyper_xen_pv;
 extern const struct hypervisor_x86 x86_hyper_xen_hvm;
 extern const struct hypervisor_x86 x86_hyper_kvm;
 extern const struct hypervisor_x86 x86_hyper_jailhouse;
+extern const struct hypervisor_x86 x86_hyper_acrn;
 
 static const __initconst struct hypervisor_x86 * const hypervisors[] =
 {
@@ -49,6 +50,9 @@ static const __initconst struct hypervisor_x86 * const 
hypervisors[] =
 #ifdef CONFIG_JAILHOUSE_GUEST
&x86_hyper_jailhouse,
 #endif
+#ifdef CONFIG_ACRN
+   &x86_hyper_acrn,
+#endif
 };
 
 enum x86_hypervisor_type x86_hyper_type;
-- 
2.7.4



[RFC PATCH 0/3] arch/x86: Add the support of ACRN hypervisor under arch/x86

2019-03-06 Thread Zhao Yakui
ACRN is a flexible, lightweight reference hypervisor, built with real-time
and safety-criticality in mind, optimized to streamline embedded development
through an open source platform. It is built for embedded IOT with small
footprint and real-time features. More details can be found
in https://projectacrn.org/

This is the patch set that allows the Linux to work on ACRN hypervisor and it 
can
work with the following patch set to manage the Linux guest on acrn-hypervisor. 
It
includes the detection of acrn_hypervisor, upcall notification vector from
hypervisor, hypercall. The hypervisor detection is similar to Xen/VMWARE/Hyperv.
ACRN also uses the upcall notification mechanism similar to that in 
Xen/Microsoft
HyperV when it needs to send the notification to Linux OS. The hypercall 
provides
the mechanism that can be used to query/configure the acrn-hypervisor by Linux 
guest.

Following this patch set, we will send acrn driver part, which provides the 
interface
that can be used to manage the virtualized CPU/memory/device/interrupt for 
other guest
OS after the acrn hypervisor is detected.

Zhao Yakui (3):
  arch/x86: add ACRN hypervisor guest
  arch/x86/acrn: Use HYPERVISOR_CALLBACK_VECTOR for Acrn upcall vector
  arch/x86/acrn: add hypercall for acrn_hypervisor

 arch/x86/Kconfig  |  8 
 arch/x86/entry/entry_64.S |  5 +++
 arch/x86/include/asm/acrn_hypercall.h | 85 +++
 arch/x86/include/asm/acrnhyper.h  | 18 
 arch/x86/include/asm/hardirq.h|  2 +-
 arch/x86/include/asm/hypervisor.h |  1 +
 arch/x86/kernel/cpu/Makefile  |  1 +
 arch/x86/kernel/cpu/acrn.c| 75 +++
 arch/x86/kernel/cpu/hypervisor.c  |  4 ++
 arch/x86/kernel/irq.c |  2 +-
 10 files changed, 199 insertions(+), 2 deletions(-)
 create mode 100644 arch/x86/include/asm/acrn_hypercall.h
 create mode 100644 arch/x86/include/asm/acrnhyper.h
 create mode 100644 arch/x86/kernel/cpu/acrn.c

-- 
2.7.4



Re: pnpacpi: exceeded the max number of IO resources: 24

2008-01-07 Thread Zhao Yakui
On Mon, 2008-01-07 at 00:48 +0100, Frans Pop wrote:
> (Adding the kernel list back. Any reason you did not send the reply there?)
> 
> Sorry for the late reply: Christmas, New Year, the flue, etc.
Thank you for caring this problem.
> 
> On Friday 28 December 2007, Zhao Yakui wrote:
> > On Mon, 2007-12-24 at 06:12 +0100, Frans Pop wrote:
> > > During boot with v2.6.24-rc6-125-g5356f66 on my Toshiba Satellite A40
> > > laptop, I suddenly get the following message (repeated 22 times!):
> > >pnpacpi: exceeded the max number of IO resources: 24
> > >
> > > Last time I tested 2.6.24 on that box was after the initial merge, but
> > > before -rc1. Then those lines were not present.
> > >
> > > Looks like the messages originate from a7839e96 by Zhao Yakui and that
> > > patch just adds the kernel messages so it was probably a hidden issue
> > > before, but I cannot determine if I should be worried or not.
> >
> > Thanks for caring this problem.
> 
> And thank you for the reply, although I must admit that I'm still confused.
> 
> > In the patch of a7839e96 the predefined PNP constant is changed. For
> > example: IO is changed from 8 to 24, Mem is changed from 4 to 12.
> > That means that more resources will be obtained from the PNP device
> > defined in ACPI table. So the system will print more message.
> 
> OK. The change for Mem from 4 to 12 could explain the extra "iomem range" 
> messages (although I don't quite understand why resources that "could not 
> be reserved" still use a slot).
The resources of PNP device are obtained by calling the _CRS method.
Maybe some resources has been reserved. For example: Some system will
reserve the following resources.
   BIOS-e820: fec0 - fed4 (reserved)
   BIOS-e820: fed45000 - 0001 (reserved)
So the system will report that some resources can't be reserved.

> I do not yet see how the "ioport range" messages increased from 0 to 16 is 
> explained, but I'm not too worried about that.
> 
> > At the same time another problem maybe happens. If the number of
> > resources defined in BIOS still exceeds the predefined PNP constant, it
> > will report that pnpacpi: exceeded the max number of IO resources: 24.
> > Although it can be fixed by changed the pnp constant bigger, it is
> > inappropriate because it will waste a lot of memory in most cases.
> >
> > Of course the above error message is harmless.
> 
> Are the _errors_ really harmless?
The error message is harmless. It only tells us that the resource
definition of PNP device exceeds the predefined PNP constant and maybe
there will be potential problem if some important resources can't be
reserved. For example about 90 IOPORT resources are defined in some PNP
device. So it will print the message. Of course it is more appropriate
to change the message level from ERR to DEBUG. 
> Your commit message was:
> "It brings that some resources can't be reserved and resource confilicts.  
> This will cause PCI resources are assigned wrongly in some systems, and 
> cause hang. This is a regression since we deleted ACPI motherboard driver 
> and use PNP system driver."
> 
> That text seems to indicate that not reserving the remaining resources _can_ 
> cause real problems. Do we know what PCI resources are now not being 
> correctly reserved on my laptop (and other machines)? The fact that the 
> message is repeated 22 times seems to indicate that in my case quite a lot 
> of resources are being ignored.
> 
> Should the memory allocation maybe be made dynamic instead of static if the 
> memory waste is really such a problem? Apparently the number of PCI 
> resources can vary wildly from one machine to another.
> 
It is more appropriate to use dynamic memory allocation for Pnp device
than to increase the PNP constant bigger. Now Thomas is working on it.
Maybe he will submit the patch very soon.
> If the error messages really are harmless, shouldn't they be changed from 
> ERR to DEBUG? As it is, the messages are extremely ugly and will probably 
> cause a lot of people to file bug reports as it _looks_ like there is an 
> error.

> 
> Cheers,
> Frans Pop


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: pnpacpi : exceeded the max number of IO resources

2007-11-30 Thread Zhao Yakui
On Fri, 2007-11-30 at 01:40 -0500, [EMAIL PROTECTED] wrote:
> On Fri, 30 Nov 2007 10:21:28 +0800, Zhao Yakui said:
> > Thanks for the acpidump & dmesg.
> > In the acpidump there are so many IO resource definitions in the device
> > of mem2 and the number exceeds the predefined number(24).
> 
> On a semi-related note, I'm seeing 7 of these at each boot on a Dell Latitude 
> D820:
> 
> pnpacpi: exceeded the max number of mem resources: 12
> 
> 2.6.24-rc3-mm2 does it, it didn't do it for 2.6.23-mm1.
> 
> pnp-increase-the-maximum-number-of-resources.patch raised it from 4 to 12, but
> I don't understand why it didn't complain at 4 in 23-mm1, but it does at 12 
> now.
In the 23-mm1 there is no such debug info. When the number of mem
resource (for one Pnp device) defined by BIOS exceeds the predefined
constant, the mem resource can't be added. But it won't report this
case. 
In the 24-mm2 the PnP constant is raised and the debug info is added.
When the number exceeds the predifined constant, it will give the debug
info. 

Thanks.
> 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


RE: ACPI related Warning in 2.6.24-rc3-git2

2007-11-29 Thread Zhao Yakui
Subject: ACPI : Delete the IRQ operation in throttling controll via PTC
>From : Zhao Yakui <[EMAIL PROTECTED]>

The IRQ operation(enable/disable) should be avoided when throttling is
controlled via PTC method. It is replaced by the migration of task. 

Signed-off-by: Zhao Yakui <[EMAIL PROTECTED]>

---
 drivers/acpi/processor_throttling.c |   36

 1 file changed, 28 insertions(+), 8 deletions(-)

Index: linux-2.6.24-rc3-git3/drivers/acpi/processor_throttling.c
===
--- linux-2.6.24-rc3-git3.orig/drivers/acpi/processor_throttling.c
+++ linux-2.6.24-rc3-git3/drivers/acpi/processor_throttling.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -413,7 +414,7 @@ static int acpi_throttling_rdmsr(struct 
} else {
msr_low = 0;
msr_high = 0;
-   rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL,
+   rdmsr_safe(MSR_IA32_THERM_CONTROL,
(u32 *)&msr_low , (u32 *) &msr_high);
msr = (msr_high << 32) | msr_low;
*value = (acpi_integer) msr;
@@ -438,7 +439,7 @@ static int acpi_throttling_wrmsr(struct 
"HARDWARE addr space,NOT supported yet\n");
} else {
msr = value;
-   wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL,
+   wrmsr_safe(MSR_IA32_THERM_CONTROL,
msr & 0x, msr >> 32);
ret = 0;
}
@@ -572,21 +573,32 @@ static int acpi_processor_get_throttling
return -ENODEV;
 
pr->throttling.state = 0;
-   local_irq_disable();
+
value = 0;
ret = acpi_read_throttling_status(pr, &value);
if (ret >= 0) {
state = acpi_get_throttling_state(pr, value);
pr->throttling.state = state;
}
-   local_irq_enable();
 
return 0;
 }
 
 static int acpi_processor_get_throttling(struct acpi_processor *pr)
 {
-   return pr->throttling.acpi_processor_get_throttling(pr);
+   cpumask_t saved_mask;
+   int ret;
+
+   /*
+* Migrate task to the cpu pointed by pr.
+*/
+   saved_mask = current->cpus_allowed;
+   set_cpus_allowed(current, cpumask_of_cpu(pr->id));
+   ret = pr->throttling.acpi_processor_get_throttling(pr);
+   /* restore the previous state */
+   set_cpus_allowed(current, saved_mask);
+
+   return ret;
 }
 
 static int acpi_processor_get_fadt_info(struct acpi_processor *pr)
@@ -717,21 +729,29 @@ static int acpi_processor_set_throttling
if (state < pr->throttling_platform_limit)
return -EPERM;
 
-   local_irq_disable();
value = 0;
ret = acpi_get_throttling_value(pr, state, &value);
if (ret >= 0) {
acpi_write_throttling_state(pr, value);
pr->throttling.state = state;
}
-   local_irq_enable();
 
return 0;
 }
 
 int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
 {
-   return pr->throttling.acpi_processor_set_throttling(pr, state);
+   cpumask_t saved_mask;
+   int ret;
+   /*
+* Migrate task to the cpu pointed by pr.
+*/
+   saved_mask = current->cpus_allowed;
+   set_cpus_allowed(current, cpumask_of_cpu(pr->id));
+   ret = pr->throttling.acpi_processor_set_throttling(pr, state);
+   /* restore the previous state */
+   set_cpus_allowed(current, saved_mask);
+   return ret;
 }
 
 int acpi_processor_get_throttling_info(struct acpi_processor *pr)

On Wed, 2007-11-28 at 14:42 +0800, Pallipadi, Venkatesh wrote:
> Yakui,
> 
> Can you look at this. Seems to be coming from commit f79f06ab9f86
> FixedHW support tries to read MSR with interrupts disabled.
> 
> Thanks,
> Venki 
> 
> >-Original Message-
> >From: [EMAIL PROTECTED] 
> >[mailto:[EMAIL PROTECTED] On Behalf Of 
> >Rafael J. Wysocki
> >Sent: Tuesday, November 27, 2007 7:37 AM
> >To: Lukas Hejtmanek
> >Cc: linux-kernel@vger.kernel.org; ACPI Devel Maling List; Len 
> >Brown; Alexey Starikovskiy
> >Subject: Re: ACPI related Warning in 2.6.24-rc3-git2
> >
> >On Tuesday, 27 of November 2007, Lukas Hejtmanek wrote:
> >> Hello,
> >> 
> >> in recent kernel, I got the following warnings while 
> >booting. It's ACPI
> >> related. Does anybode care? Lenovo ThinkPad T61 (6465CTO).
> >
> >Appropriate Ccs added.
> >
> >Did it happen before?
> >
> >> [   13.114814] Pid: 1, comm: swapper Not tainted 2.6.24-rc3-git2 #3
> >> [   13.114885] 
> >> [   13.114885] Call Trace:
> >> [   13.115020

[PATCH] PCI: Add PCI quirk function for some chipsets

2007-11-15 Thread Zhao Yakui
Subject: PCI: Add PCI quirk function for some chipsets
From: Zhao Yakui  <[EMAIL PROTECTED]>

PCI quirk function is added for some chipsets so that the resources
behind LPC bridge can be reserved.

Signed-off-by: Li Shaohua <[EMAIL PROTECTED]>
Signed-off-by: Zhao Yakui <[EMAIL PROTECTED]>

---
 drivers/pci/quirks.c|6 ++
 include/linux/pci_ids.h |2 ++
 2 files changed, 8 insertions(+)

Index: linux-2.6.24-rc2/drivers/pci/quirks.c
===
--- linux-2.6.24-rc2.orig/drivers/pci/quirks.c
+++ linux-2.6.24-rc2/drivers/pci/quirks.c
@@ -465,6 +465,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_0, 
quirk_ich6_lpc_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_2, 
quirk_ich6_lpc_acpi );
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_3, 
quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_1, 
quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH8_4, 
quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH9_2, 
quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH9_4, 
quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH9_7, 
quirk_ich6_lpc_acpi );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_ICH9_8, 
quirk_ich6_lpc_acpi );
 
 /*
  * VIA ACPI: One IO region pointed to by longword at
Index: linux-2.6.24-rc2/include/linux/pci_ids.h
===
--- linux-2.6.24-rc2.orig/include/linux/pci_ids.h
+++ linux-2.6.24-rc2/include/linux/pci_ids.h
@@ -2314,6 +2314,8 @@
 #define PCI_DEVICE_ID_INTEL_ICH9_4 0x2914
 #define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919
 #define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
+#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916
+#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918
 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
 #define PCI_DEVICE_ID_INTEL_82830_HB   0x3575
 #define PCI_DEVICE_ID_INTEL_82830_CGC  0x3577
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH]: PNP: Increase the value of PNP constant

2007-11-15 Thread Zhao Yakui
Subject: PNP: Increase the value of PNP constant
From: Zhao Yakui  <[EMAIL PROTECTED]>

On some systems the number of resources(IO,MEM) returnedy by PNP
device is greater than the PNP constant, for example motherboard devices. 
It brings that some resources can't be reserved and resource confilicts.
This will cause PCI resources are assigned wrongly in some systems, and
cause hang. This is a regression since we deleted ACPI motherboard
driver and use PNP system driver.

Andrew, I thought this is an urgent issue and should be fixed ASAP, and
this is a good candidate for -stable tree

Signed-off-by: Li Shaohua <[EMAIL PROTECTED]>
Signed-off-by: Zhao Yakui <[EMAIL PROTECTED]>

---
 drivers/pnp/pnpacpi/rsparser.c |   18 --
 include/linux/pnp.h|4 ++--
 2 files changed, 18 insertions(+), 4 deletions(-)

Index: linux-2.6.24-rc2/include/linux/pnp.h
===
--- linux-2.6.24-rc2.orig/include/linux/pnp.h
+++ linux-2.6.24-rc2/include/linux/pnp.h
@@ -13,8 +13,8 @@
 #include 
 #include 
 
-#define PNP_MAX_PORT   8
-#define PNP_MAX_MEM4
+#define PNP_MAX_PORT   24
+#define PNP_MAX_MEM12
 #define PNP_MAX_IRQ2
 #define PNP_MAX_DMA2
 #define PNP_NAME_LEN   50
Index: linux-2.6.24-rc2/drivers/pnp/pnpacpi/rsparser.c
===
--- linux-2.6.24-rc2.orig/drivers/pnp/pnpacpi/rsparser.c
+++ linux-2.6.24-rc2/drivers/pnp/pnpacpi/rsparser.c
@@ -82,9 +82,11 @@ static void pnpacpi_parse_allocated_irqr
while (!(res->irq_resource[i].flags & IORESOURCE_UNSET) &&
   i < PNP_MAX_IRQ)
i++;
-   if (i >= PNP_MAX_IRQ)
+   if (i >= PNP_MAX_IRQ) {
+   printk(KERN_ERR "Exceed the max number of IRQ resource: "
+   "%d \n",PNP_MAX_IRQ);
return;
-
+   }
 #ifdef CONFIG_X86
if (gsi < 16 && (triggering != ACPI_EDGE_SENSITIVE ||
polarity != ACPI_ACTIVE_HIGH)) {
@@ -173,6 +175,10 @@ static void pnpacpi_parse_allocated_dmar
}
res->dma_resource[i].start = dma;
res->dma_resource[i].end = dma;
+   } else {
+   printk(KERN_ERR "Exceed the max number of DMA resource: "
+   "%d \n",PNP_MAX_DMA);
+   return;
}
 }
 
@@ -194,6 +200,10 @@ static void pnpacpi_parse_allocated_iore
}
res->port_resource[i].start = io;
res->port_resource[i].end = io + len - 1;
+   } else {
+   printk(KERN_ERR "Exceed the max number of IO Resource: "
+   "%d \n",PNP_MAX_PORT);
+   return;
}
 }
 
@@ -217,6 +227,10 @@ static void pnpacpi_parse_allocated_memr
 
res->mem_resource[i].start = mem;
res->mem_resource[i].end = mem + len - 1;
+   } else {
+   printk(KERN_ERR "Exceed the max number of Mem Resource: "
+   "%d \n",PNP_MAX_MEM);
+   return;
}
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/