lib: sm: Allow different client ids for compatibility VMs

Android under pKVM uses VM ID 1. Allow the compatibility
VM to have different client IDs to cover this case, for
compatibility with older kernels and hypervisors which
do not send the VM availability messages.

Bug: 280886201
Change-Id: I198a4e294945b42e4c4e54ca8e4d806646376df8
diff --git a/lib/sm/sm.c b/lib/sm/sm.c
index 0a2ef8a..965961a 100644
--- a/lib/sm/sm.c
+++ b/lib/sm/sm.c
@@ -116,12 +116,12 @@
  * initialized. This pseudo-VM does not get creation or destruction messages
  * so we add and remove it from the tree manually.
  */
-static struct sm_vm sm_vm_compat0 = {
+static struct sm_vm sm_vm_compat_vm = {
         .node = BST_NODE_INITIAL_VALUE,
         .state = SM_VM_STATE_FRESH,
         .client_id = 0,
-        .notifiers = LIST_INITIAL_VALUE(sm_vm_compat0.notifiers),
-        .self_ref = OBJ_REF_INITIAL_VALUE(sm_vm_compat0.self_ref),
+        .notifiers = LIST_INITIAL_VALUE(sm_vm_compat_vm.notifiers),
+        .self_ref = OBJ_REF_INITIAL_VALUE(sm_vm_compat_vm.self_ref),
 };
 
 static event_t nsirqevent[SMP_MAX_CPUS];
@@ -388,13 +388,13 @@
     return sm_vm_compare_key(a, &vm_b->client_id);
 }
 
-static void sm_vm_add_compat0_locked(void) {
+static void sm_vm_add_compat_vm_locked(ext_mem_client_id_t client_id) {
     DEBUG_ASSERT(spin_lock_held(&sm_vm_lock));
 
     if (!bst_is_empty(&sm_vm_tree)) {
         /*
          * There is already a VM in the tree, so we don't need
-         * to add the compatibility VM 0 explicitly.
+         * to add the compatibility VM explicitly.
          */
         return;
     }
@@ -403,13 +403,15 @@
         return;
     }
 
-    DEBUG_ASSERT(sm_vm_compat0.state == SM_VM_STATE_FRESH ||
-                 sm_vm_compat0.state == SM_VM_STATE_READY_TO_FREE);
-    obj_init(&sm_vm_compat0.refobj, &sm_vm_compat0.self_ref);
-    if (!bst_insert(&sm_vm_tree, &sm_vm_compat0.node, sm_vm_compare)) {
-        panic("failed to insert compatibility VM 0\n");
+    DEBUG_ASSERT(sm_vm_compat_vm.state == SM_VM_STATE_FRESH ||
+                 sm_vm_compat_vm.state == SM_VM_STATE_READY_TO_FREE);
+
+    sm_vm_compat_vm.client_id = client_id;
+    obj_init(&sm_vm_compat_vm.refobj, &sm_vm_compat_vm.self_ref);
+    if (!bst_insert(&sm_vm_tree, &sm_vm_compat_vm.node, sm_vm_compare)) {
+        panic("failed to insert compatibility VM\n");
     }
-    sm_vm_compat0.state = SM_VM_STATE_AVAILABLE;
+    sm_vm_compat_vm.state = SM_VM_STATE_AVAILABLE;
 }
 
 status_t sm_vm_notifier_register(struct sm_vm_notifier* notif) {
@@ -425,7 +427,7 @@
     }
 
     spin_lock_irqsave(&sm_vm_lock, state);
-    sm_vm_add_compat0_locked();
+    sm_vm_add_compat_vm_locked(notif->client_id);
 
     vm = bst_search_key_type(&sm_vm_tree, &notif->client_id, sm_vm_compare_key,
                              struct sm_vm, node);
@@ -512,7 +514,7 @@
     }
 
     spin_lock_irqsave(&sm_vm_lock, state);
-    sm_vm_add_compat0_locked();
+    sm_vm_add_compat_vm_locked(client_id);
 
     vm = bst_search_key_type(&sm_vm_tree, &client_id, sm_vm_compare_key,
                              struct sm_vm, node);
@@ -689,9 +691,9 @@
 
             spin_lock_irqsave(&sm_vm_lock, state);
             if (sm_vm_to_create != -1 &&
-                sm_vm_compat0.state == SM_VM_STATE_AVAILABLE) {
+                sm_vm_compat_vm.state == SM_VM_STATE_AVAILABLE) {
                 /* We got an actual VM, tear down the compatibility one */
-                sm_vm_compat0.state = SM_VM_STATE_DESTROY_NOTIFYING;
+                sm_vm_compat_vm.state = SM_VM_STATE_DESTROY_NOTIFYING;
                 /*
                  * Signal the event so we continue the outer loop because
                  * the remainder of the current iteration will handle the
@@ -700,7 +702,7 @@
                  * back here and create the new VM.
                  */
                 event_signal(&sm_vm_event, false);
-                /* Defer creation of the new VM until compat0 is gone */
+                /* Defer creation of the new VM until compat_vm is gone */
                 vm_id = -1;
             } else {
                 vm_id = sm_vm_to_create;
@@ -777,9 +779,9 @@
                      */
                     vm->state = SM_VM_STATE_DESTROY_NOTIFIED;
 
-                    if (vm == &sm_vm_compat0) {
+                    if (vm == &sm_vm_compat_vm) {
                         /*
-                         * We are done with compatibility VM 0,
+                         * We are done with the compatibility VM,
                          * remove it from the tree permanently.
                          */
                         vm->state = SM_VM_STATE_READY_TO_FREE;