Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


HVM synchronous operation facility
Peter Dinda [Mon, 3 Aug 2015 22:19:23 +0000 (17:19 -0500)]
This lets the ROS and HRT synchronize, via the VMM, on a memory
location for for future synchronization indepedent of the VMM

palacios/include/palacios/vmm_hvm.h
palacios/src/palacios/vmm_hvm.c

index 7f82220..cb37225 100644 (file)
@@ -48,7 +48,7 @@ struct v3_vm_hvm {
     void     *comm_page_hpa;
     void     *comm_page_hva;
 
-    enum {HRT_IDLE=0, HRT_CALL, HRT_PARCALL, HRT_MERGE} trans_state;
+    enum {HRT_IDLE=0, HRT_CALL=1, HRT_PARCALL=2, HRT_SYNCSETUP=3, HRT_SYNC=4, HRT_SYNCTEARDOWN=5, HRT_MERGE=6} trans_state;
     uint64_t  trans_count;
 };
 
index 3e506d7..43a8672 100644 (file)
@@ -228,21 +228,92 @@ static int hvm_hcall_handler(struct guest_info * core , hcall_id_t hcall_id, voi
            break;
 
 
-       case 0x2f: // function exec done
+       case 0x28: // setup for synchronous operation (ROS->HRT)
+       case 0x29: // teardown for synchronous operation (ROS->HRT)
+           if (v3_is_hvm_hrt_core(core)) { 
+               PrintError(core->vm_info,core,"hvm: %ssynchronization invocation not supported from HRT core\n",a1==0x29 ? "de" : "");
+               core->vm_regs.rax = -1;
+           } else {
+               if (ENFORCE_STATE_MACHINE && 
+                   ((a1==0x28 && h->trans_state!=HRT_IDLE) || (a1==0x29 && h->trans_state!=HRT_SYNC))) { 
+                   PrintError(core->vm_info,core, "hvm: cannot invoke %ssynchronization in state %d\n",a1==0x29 ? "de" : "", h->trans_state);
+                   core->vm_regs.rax = -1;
+               } else {
+                   uint64_t *page = (uint64_t *) h->comm_page_hva;
+                   uint64_t first, last, cur;
+
+                   PrintDebug(core->vm_info,core, "hvm: invoke %ssynchronization on address %p\n",a1==0x29 ? "de" : "",(void*)a2);
+                   page[0] = a1;
+                   page[1] = a2;
+
+                   first=last=h->first_hrt_core;  // initially we will sync only with BSP
+
+                   core->vm_regs.rax = 0;
+
+                   h->trans_count = last-first+1;
+
+                   for (cur=first;cur<=last;cur++) { 
+
+#if USE_UPCALL_MAGIC_PF
+                       PrintDebug(core->vm_info,core,"hvm: injecting magic #PF into core %llu\n",cur);
+                       core->vm_info->cores[cur].ctrl_regs.cr2 = UPCALL_MAGIC_ADDRESS;
+                       if (v3_raise_exception_with_error(&core->vm_info->cores[cur],
+                                                         PF_EXCEPTION, 
+                                                         UPCALL_MAGIC_ERROR)) { 
+                           PrintError(core->vm_info,core, "hvm: cannot inject HRT #PF to core %llu\n",cur);
+                           core->vm_regs.rax = -1;
+                           break;
+                       }
+#else
+                       PrintDebug(core->vm_info,core,"hvm: injecting SW intr 0x%u into core %llu\n",h->hrt_int_vector,cur);
+                       if (v3_raise_swintr(&core->vm_info->cores[cur],h->hrt_int_vector)) { 
+                           PrintError(core->vm_info,core, "hvm: cannot inject HRT interrupt to core %llu\n",cur);
+                           core->vm_regs.rax = -1;
+                           break;
+                       }
+#endif
+                       // Force core to exit now
+                       v3_interrupt_cpu(core->vm_info,core->vm_info->cores[cur].pcpu_id,0);
+                         
+                   }
+                   if (core->vm_regs.rax==0) { 
+                       if (a1==0x28) { 
+                           h->trans_state = HRT_SYNCSETUP;
+                       } else {
+                           h->trans_state = HRT_SYNCTEARDOWN;                      
+                       }
+                   }  else {
+                       PrintError(core->vm_info,core,"hvm: in inconsistent state due to HRT call failure\n");
+                       h->trans_state = HRT_IDLE;
+                       h->trans_count = 0;
+                   }
+               }
+           }
+           break;
+
+       case 0x2f: // function exec or sync done
            if (v3_is_hvm_ros_core(core)) { 
-               PrintError(core->vm_info,core, "hvm: request for exec done from ROS core\n");
+               PrintError(core->vm_info,core, "hvm: request for exec or sync done from ROS core\n");
                core->vm_regs.rax=-1;
            } else {
-               if (ENFORCE_STATE_MACHINE && h->trans_state!=HRT_CALL && h->trans_state!=HRT_PARCALL) {
-                   PrintError(core->vm_info,core,"hvm: function completion when not in HRT_CALL or HRT_PARCALL state\n");
+               if (ENFORCE_STATE_MACHINE && 
+                   h->trans_state!=HRT_CALL && 
+                   h->trans_state!=HRT_PARCALL && 
+                   h->trans_state!=HRT_SYNCSETUP &&
+                   h->trans_state!=HRT_SYNCTEARDOWN) {
+                   PrintError(core->vm_info,core,"hvm: function or sync completion when not in HRT_CALL, HRT_PARCALL, HRT_SYNCSETUP, or HRT_SYNCTEARDOWN state\n");
                    core->vm_regs.rax=-1;
                } else {
                    uint64_t one=1;
-                   PrintDebug(core->vm_info,core, "hvm: function complete\n");
+                   PrintDebug(core->vm_info,core, "hvm: function or sync complete\n");
                    if (__sync_fetch_and_sub(&h->trans_count,one)==1) {
                        // last one, switch state
-                       h->trans_state=HRT_IDLE;
-                       PrintDebug(core->vm_info,core, "hvm: function complete - back to idle\n");
+                       if (h->trans_state==HRT_SYNCSETUP) { 
+                           h->trans_state=HRT_SYNC;
+                           PrintDebug(core->vm_info,core, "hvm: function complete - now synchronous\n");
+                       } else {
+                           h->trans_state=HRT_IDLE;
+                       }
                    }
                    core->vm_regs.rax=0;
                }