From: Zhang Yunfei <[email protected]>

By making a contribution to this project, I certify that:

    (a) The contribution was created in whole or in part by me and I
        have the right to submit it under the open source license
        indicated in the file; or

    (b) The contribution is based upon previous work that, to the best
        of my knowledge, is covered under an appropriate open source
        license and I have the right under that license to submit that
        work with modifications, whether created in whole or in part
        by me, under the same open source license (unless I am
        permitted to submit under a different license), as indicated
        in the file; or

    (c) The contribution was provided directly to me by some other
        person who certified (a), (b) or (c) and I have not modified
        it.

    (d) I understand and agree that this project and the contribution
        are public and that a record of the contribution (including all
        personal information I submit with it, including my sign-off) is
        maintained indefinitely and may be redistributed consistent with
        this project or the open source license(s) involved.
Signed-off-by: Zhang Yunfei <[email protected]>
---
 hypervisor/mmio.c | 91 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 75 insertions(+), 16 deletions(-)

diff --git a/hypervisor/mmio.c b/hypervisor/mmio.c
index 3747bf6f..489c849c 100644
--- a/hypervisor/mmio.c
+++ b/hypervisor/mmio.c
@@ -18,6 +18,23 @@
 #include <jailhouse/unit.h>
 #include <jailhouse/percpu.h>
 
+#define JAILHOUSE_MAX_SUBPAGE_DEVICES 32
+
+struct subpage_device {
+
+       u32 id;
+       bool used_flag;
+       void *mapping_base;
+       u64 phys_start;
+};
+
+/* Considering that there maybe fewer subpage devices,it is currently
+implemented with an array, and a linked list can be considered in the future */
+static struct subpage_device subpage_devices[JAILHOUSE_MAX_SUBPAGE_DEVICES];
+#define for_each_subpage(subpage, counter)                                     
\
+       for((subpage) = &subpage_devices[0], (counter) = 0;                     
   \
+           (counter) < JAILHOUSE_MAX_SUBPAGE_DEVICES; (subpage)++, (counter)++)
+
 /**
  * Perform MMIO-specific initialization for a new cell.
  * @param cell         Cell to be initialized.
@@ -308,11 +325,9 @@ static enum mmio_result mmio_handle_subpage(void *arg, 
struct mmio_access *mmio)
 {
        const struct jailhouse_memory *mem = arg;
        u64 perm = mmio->is_write ? JAILHOUSE_MEM_WRITE : JAILHOUSE_MEM_READ;
-       unsigned long page_phys =
-               ((unsigned long)mem->phys_start + mmio->address) & PAGE_MASK;
-       unsigned long virt_base;
-       int err;
-
+       void *virt_base = NULL;
+       struct subpage_device *subpage;
+       u32 dev;
        /* check read/write access permissions */
        if (!(mem->flags & perm))
                goto invalid_access;
@@ -326,11 +341,14 @@ static enum mmio_result mmio_handle_subpage(void *arg, 
struct mmio_access *mmio)
            !(mem->flags & JAILHOUSE_MEM_IO_UNALIGNED))
                goto invalid_access;
 
-       err = paging_create(&this_cpu_data()->pg_structs, page_phys, PAGE_SIZE,
-                           TEMPORARY_MAPPING_BASE,
-                           PAGE_DEFAULT_FLAGS | PAGE_FLAG_DEVICE,
-                           PAGING_NON_COHERENT | PAGING_NO_HUGE);
-       if (err)
+       for_each_subpage(subpage, dev)
+       {
+               if(subpage->phys_start == mem->phys_start) {
+                       virt_base = subpage->mapping_base;
+                       break;
+               }
+       }
+       if (dev == JAILHOUSE_MAX_SUBPAGE_DEVICES)
                goto invalid_access;
 
        /*
@@ -342,9 +360,9 @@ static enum mmio_result mmio_handle_subpage(void *arg, 
struct mmio_access *mmio)
         *
         * Reason: mmio_perform_access does addr = base + mmio->address.
         */
-       virt_base = TEMPORARY_MAPPING_BASE + (mem->phys_start & PAGE_OFFS_MASK)
-               - (mmio->address & PAGE_MASK);
-       mmio_perform_access((void *)virt_base, mmio);
+       virt_base = (void *)((u64)virt_base + (mem->phys_start & 
PAGE_OFFS_MASK) -
+                            (mmio->address & PAGE_MASK));
+       mmio_perform_access(virt_base, mmio);
        return MMIO_HANDLED;
 
 invalid_access:
@@ -357,13 +375,54 @@ invalid_access:
 
 int mmio_subpage_register(struct cell *cell, const struct jailhouse_memory 
*mem)
 {
-       mmio_region_register(cell, mem->virt_start, mem->size,
-                            mmio_handle_subpage, (void *)mem);
+       unsigned long page_phys;
+       struct subpage_device *subpage;
+       u32 dev;
+       mmio_region_register(cell, mem->virt_start, mem->size, 
mmio_handle_subpage,
+                            (void *)mem);
+       for_each_subpage(subpage, dev)
+       {
+               if(!subpage->used_flag) {
+                       subpage->id         = dev;
+                       subpage->used_flag  = true;
+                       subpage->phys_start = mem->phys_start;
+                       page_phys = ((unsigned long)mem->phys_start) & 
PAGE_MASK;
+                       break;
+               }       
+       }
+       if(dev == JAILHOUSE_MAX_SUBPAGE_DEVICES) {
+               panic_printk("FATAL: Subpage_devices is full\n");
+               return MMIO_ERROR;
+       }
+       subpage->mapping_base = paging_map_device(page_phys, PAGE_SIZE);
+       if(!subpage->mapping_base) {
+               goto invalid_pagemap;
+       }
+       
        return 0;
+
+invalid_pagemap:
+       panic_printk("FATAL: Subpage_devices paging_map_device error\n");
+
+       return MMIO_ERROR;
 }
 
 void mmio_subpage_unregister(struct cell *cell,
-                            const struct jailhouse_memory *mem)
+                             const struct jailhouse_memory *mem)
 {
+       struct subpage_device *subpage;
+       u32 dev;
        mmio_region_unregister(cell, mem->virt_start);
+       for_each_subpage(subpage, dev)
+       {
+               if(subpage->phys_start == mem->phys_start) {
+                       subpage->id        = 0;
+                       subpage->used_flag = false;
+                       paging_unmap_device(subpage->phys_start, 
subpage->mapping_base,
+                                           PAGE_SIZE);
+                       subpage->phys_start   = 0;
+                       subpage->mapping_base = 0;
+                       break;
+               }
+       }
 }
-- 
2.27.0

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/20230404065704.92082-1-zhangyunfei%40kylinos.cn.

Reply via email to