hf_mailbox_receive should not block if there is a pending interrupt.
This matches the behaviour of WFI, which only traps (and so causes Hafnium
to block the vCPU) if there is not currently a pending interrupt, ignoring
PSTATE.
Bug: 127686530
Change-Id: I06ef4513d3b9f5adf7988f6f77c178cba40b1762
diff --git a/test/vmapi/primary_with_secondaries/interrupts.c b/test/vmapi/primary_with_secondaries/interrupts.c
index 0193f69..5f12565 100644
--- a/test/vmapi/primary_with_secondaries/interrupts.c
+++ b/test/vmapi/primary_with_secondaries/interrupts.c
@@ -195,3 +195,30 @@
0);
EXPECT_EQ(hf_mailbox_clear(), 0);
}
+
+/**
+ * If a secondary VM has an enabled and pending interrupt, even if interrupts
+ * are disabled globally via PSTATE, then hf_mailbox_receive should not block
+ * even if `block` is true.
+ */
+TEST(interrupts, pending_interrupt_no_blocking_receive)
+{
+ const char expected_response[] = "Done waiting";
+ struct hf_vcpu_run_return run_res;
+ struct mailbox_buffers mb = set_up_mailbox();
+
+ SERVICE_SELECT(SERVICE_VM0, "receive_block", mb.send);
+
+ /*
+ * Inject the interrupt and run the VM. It should disable interrupts
+ * globally, enable the specific interrupt, and then send us a message
+ * back after failing to receive a message a few times.
+ */
+ hf_interrupt_inject(SERVICE_VM0, 0, EXTERNAL_INTERRUPT_ID_A);
+ run_res = hf_vcpu_run(SERVICE_VM0, 0);
+ EXPECT_EQ(run_res.code, HF_VCPU_RUN_MESSAGE);
+ EXPECT_EQ(run_res.message.size, sizeof(expected_response));
+ EXPECT_EQ(memcmp(mb.recv, expected_response, sizeof(expected_response)),
+ 0);
+ EXPECT_EQ(hf_mailbox_clear(), 0);
+}