blob: 9e9fce0177cd820aa08500f873040a917c7b9ee0 [file] [log] [blame]
Andrew Scullc9ccb3f2018-08-13 15:27:12 +01001#include <assert.h>
2#include <stdalign.h>
Andrew Scullf35a5c92018-08-07 18:09:46 +01003#include <stdint.h>
4
Andrew Scull18c78fc2018-08-20 12:57:41 +01005#include "hf/mm.h"
Andrew Scull4b6c2fc2018-10-05 18:14:02 +01006#include "hf/std.h"
Andrew Scull18c78fc2018-08-20 12:57:41 +01007
Andrew Scullf35a5c92018-08-07 18:09:46 +01008#include "vmapi/hf/call.h"
9
Andrew Scull4b6c2fc2018-10-05 18:14:02 +010010#include "hftest.h"
Andrew Scull18c78fc2018-08-20 12:57:41 +010011
Andrew Scullbc7189d2018-08-14 09:35:13 +010012static alignas(PAGE_SIZE) uint8_t send_page[PAGE_SIZE];
13static alignas(PAGE_SIZE) uint8_t recv_page[PAGE_SIZE];
Andrew Scullc9ccb3f2018-08-13 15:27:12 +010014static_assert(sizeof(send_page) == PAGE_SIZE, "Send page is not a page.");
15static_assert(sizeof(recv_page) == PAGE_SIZE, "Recv page is not a page.");
Andrew Scullf35a5c92018-08-07 18:09:46 +010016
Andrew Scullbc7189d2018-08-14 09:35:13 +010017static hf_ipaddr_t send_page_addr = (hf_ipaddr_t)send_page;
18static hf_ipaddr_t recv_page_addr = (hf_ipaddr_t)recv_page;
19
Andrew Scull3a942572018-10-05 21:36:09 +010020/* Keep macro alignment */
21/* clang-format off */
22
23#define RELAY_A_VM_ID 1
24#define RELAY_B_VM_ID 2
25#define ECHO_VM_ID 3
26
27/* clang-format on */
Andrew Scull4b6c2fc2018-10-05 18:14:02 +010028
Andrew Scullbc7189d2018-08-14 09:35:13 +010029/**
Andrew Scull3a942572018-10-05 21:36:09 +010030 * Confirm there are 3 secondary VMs.
Andrew Scullbc7189d2018-08-14 09:35:13 +010031 */
Andrew Scull3a942572018-10-05 21:36:09 +010032TEST(hf_vm_get_count, three_secondary_vms)
Andrew Scullf35a5c92018-08-07 18:09:46 +010033{
Andrew Scull3a942572018-10-05 21:36:09 +010034 EXPECT_EQ(hf_vm_get_count(), 4);
Andrew Scullf35a5c92018-08-07 18:09:46 +010035}
36
Andrew Scullbc7189d2018-08-14 09:35:13 +010037/**
38 * Confirm there that secondary VM has 1 VCPU.
39 */
40TEST(hf_vcpu_get_count, secondary_has_one_vcpu)
Andrew Scullf35a5c92018-08-07 18:09:46 +010041{
Andrew Scull19503262018-09-20 14:48:39 +010042 EXPECT_EQ(hf_vcpu_get_count(1), 1);
Andrew Scullf35a5c92018-08-07 18:09:46 +010043}
44
Andrew Scullbc7189d2018-08-14 09:35:13 +010045/**
46 * Confirm it is an error to query how many VCPUs are assigned to a nonexistent
47 * secondary VM.
48 */
49TEST(hf_vcpu_get_count, large_invalid_vm_index)
Andrew Scullf35a5c92018-08-07 18:09:46 +010050{
51 EXPECT_EQ(hf_vcpu_get_count(0xffffffff), -1);
52}
53
Andrew Scullbc7189d2018-08-14 09:35:13 +010054/**
55 * The configured send/receive addresses can't be unaligned.
56 */
57TEST(hf_vm_configure, fails_with_unaligned_pointer)
Andrew Scullc9ccb3f2018-08-13 15:27:12 +010058{
59 uint8_t maybe_aligned[2];
60 hf_ipaddr_t unaligned_addr = (hf_ipaddr_t)&maybe_aligned[1];
Andrew Scullbc7189d2018-08-14 09:35:13 +010061 hf_ipaddr_t aligned_addr = (hf_ipaddr_t)send_page;
Andrew Scullc9ccb3f2018-08-13 15:27:12 +010062
63 /* Check the the address is unaligned. */
64 ASSERT_EQ(unaligned_addr & 1, 1);
65
66 EXPECT_EQ(hf_vm_configure(aligned_addr, unaligned_addr), -1);
67 EXPECT_EQ(hf_vm_configure(unaligned_addr, aligned_addr), -1);
68 EXPECT_EQ(hf_vm_configure(unaligned_addr, unaligned_addr), -1);
69}
70
Andrew Scullbc7189d2018-08-14 09:35:13 +010071/**
72 * The configured send/receive addresses can't be the same page.
73 */
74TEST(hf_vm_configure, fails_with_same_page)
Andrew Scullc9ccb3f2018-08-13 15:27:12 +010075{
Andrew Scullbc7189d2018-08-14 09:35:13 +010076 EXPECT_EQ(hf_vm_configure(send_page_addr, send_page_addr), -1);
77 EXPECT_EQ(hf_vm_configure(recv_page_addr, recv_page_addr), -1);
Andrew Scullc9ccb3f2018-08-13 15:27:12 +010078}
79
Andrew Scullbc7189d2018-08-14 09:35:13 +010080/**
81 * The configuration of the send/receive addresses can only happen once.
82 */
83TEST(hf_vm_configure, fails_if_already_succeeded)
Andrew Scullc9ccb3f2018-08-13 15:27:12 +010084{
Andrew Scullbc7189d2018-08-14 09:35:13 +010085 EXPECT_EQ(hf_vm_configure(send_page_addr, recv_page_addr), 0);
86 EXPECT_EQ(hf_vm_configure(send_page_addr, recv_page_addr), -1);
Andrew Scullc9ccb3f2018-08-13 15:27:12 +010087}
88
Andrew Scullbc7189d2018-08-14 09:35:13 +010089/**
90 * The configuration of the send/receive address is successful with valid
91 * arguments.
92 */
93TEST(hf_vm_configure, succeeds)
Andrew Scullc9ccb3f2018-08-13 15:27:12 +010094{
Andrew Scullbc7189d2018-08-14 09:35:13 +010095 EXPECT_EQ(hf_vm_configure(send_page_addr, recv_page_addr), 0);
Andrew Scullf35a5c92018-08-07 18:09:46 +010096}
Andrew Scull4b6c2fc2018-10-05 18:14:02 +010097
98/**
99 * Send and receive the same message from the echo VM.
100 */
101TEST(mailbox, echo)
102{
103 const char message[] = "Echo this back to me!";
104
105 /* Configure mailbox pages. */
106 EXPECT_EQ(hf_vm_configure(send_page_addr, recv_page_addr), 0);
107 EXPECT_EQ(hf_vcpu_run(ECHO_VM_ID, 0),
108 HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAIT_FOR_INTERRUPT, 0, 0));
109
110 /* Set the message, echo it and check it didn't change. */
111 memcpy(send_page, message, sizeof(message));
112 EXPECT_EQ(hf_mailbox_send(ECHO_VM_ID, sizeof(message)), 0);
113 EXPECT_EQ(
114 hf_vcpu_run(ECHO_VM_ID, 0),
115 HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_MESSAGE, 0, sizeof(message)));
116 EXPECT_EQ(memcmp(recv_page, message, sizeof(message)), 0);
117 EXPECT_EQ(hf_mailbox_clear(), 0);
118}
Andrew Scull3a942572018-10-05 21:36:09 +0100119
120/**
121 * Send a message to relay_a which will forward it to relay_b where it will be
122 * sent back here.
123 */
124TEST(mailbox, relay)
125{
126 const char message[] = "Send this round the relay!";
127
128 /* Configure mailbox pages. */
129 EXPECT_EQ(hf_vm_configure(send_page_addr, recv_page_addr), 0);
130 EXPECT_EQ(hf_vcpu_run(RELAY_A_VM_ID, 0),
131 HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAIT_FOR_INTERRUPT, 0, 0));
132 EXPECT_EQ(hf_vcpu_run(RELAY_B_VM_ID, 0),
133 HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAIT_FOR_INTERRUPT, 0, 0));
134
135 /*
136 * Send the message to relay_a which is then sent to relay_b before
137 * checking that relay_b send the message back here.
138 */
139 memcpy(send_page, message, sizeof(message));
140 EXPECT_EQ(hf_mailbox_send(RELAY_A_VM_ID, sizeof(message)), 0);
141 EXPECT_EQ(hf_vcpu_run(RELAY_A_VM_ID, 0),
142 HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_WAKE_UP, RELAY_B_VM_ID, 0));
143 EXPECT_EQ(
144 hf_vcpu_run(RELAY_B_VM_ID, 0),
145 HF_VCPU_RUN_RESPONSE(HF_VCPU_RUN_MESSAGE, 0, sizeof(message)));
146 EXPECT_EQ(memcmp(recv_page, message, sizeof(message)), 0);
147 EXPECT_EQ(hf_mailbox_clear(), 0);
148}