Lock vCPU when accessing enabled_and_pending_count.

Change-Id: Ic71d89c3b7a8acec71ac593228219e4044e58664
diff --git a/src/api.c b/src/api.c
index b3cab1a..081865e 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1016,6 +1016,27 @@
 }
 
 /**
+ * Checks whether the vCPU's attempt to block for a message has already been
+ * interrupted or whether it is allowed to block.
+ */
+bool api_spci_msg_recv_block_interrupted(struct vcpu *current)
+{
+	bool interrupted;
+
+	sl_lock(&current->lock);
+
+	/*
+	 * Don't block if there are enabled and pending interrupts, to match
+	 * behaviour of wait_for_interrupt.
+	 */
+	interrupted = (current->interrupts.enabled_and_pending_count > 0);
+
+	sl_unlock(&current->lock);
+
+	return interrupted;
+}
+
+/**
  * Receives a message from the mailbox. If one isn't available, this function
  * can optionally block the caller until one becomes available.
  *
@@ -1058,12 +1079,7 @@
 	 * that time to SPCI_SUCCESS.
 	 */
 	return_code = SPCI_INTERRUPTED;
-
-	/*
-	 * Don't block if there are enabled and pending interrupts, to match
-	 * behaviour of wait_for_interrupt.
-	 */
-	if (current->interrupts.enabled_and_pending_count > 0) {
+	if (api_spci_msg_recv_block_interrupted(current)) {
 		goto out;
 	}
 
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 621b847..0658051 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -391,16 +391,22 @@
 		 * Not switching vCPUs, set the bit for the current vCPU
 		 * directly in the register.
 		 */
+		struct vcpu *vcpu = current();
+
+		sl_lock(&vcpu->lock);
 		set_virtual_interrupt_current(
-			current()->interrupts.enabled_and_pending_count > 0);
+			vcpu->interrupts.enabled_and_pending_count > 0);
+		sl_unlock(&vcpu->lock);
 	} else {
 		/*
 		 * About to switch vCPUs, set the bit for the vCPU to which we
 		 * are switching in the saved copy of the register.
 		 */
+		sl_lock(&ret.new->lock);
 		set_virtual_interrupt(
 			&ret.new->regs,
 			ret.new->interrupts.enabled_and_pending_count > 0);
+		sl_unlock(&ret.new->lock);
 	}
 
 	return ret;