/*
 * Copyright 2018 The Hafnium Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "hf/arch/vm/interrupts.h"

#include "hf/mm.h"
#include "hf/std.h"

#include "vmapi/hf/call.h"

#include "primary_with_secondary.h"
#include "test/hftest.h"
#include "test/vmapi/exception_handler.h"
#include "test/vmapi/spci.h"

alignas(PAGE_SIZE) static uint8_t page[PAGE_SIZE];

TEST_SERVICE(memory_increment)
{
	/* Loop, writing message to the shared memory. */
	for (;;) {
		struct spci_value ret = spci_msg_wait();
		uint8_t *ptr;
		size_t i;
		void *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)recv_buf;
		struct spci_memory_region_constituent *constituents =
			spci_memory_region_get_constituents(memory_region);
		spci_vm_id_t sender = memory_region->sender;

		EXPECT_EQ(ret.func, SPCI_MEM_SHARE_32);

		ptr = (uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[0]);

		/* Check the memory was cleared. */
		for (i = 0; i < PAGE_SIZE; ++i) {
			ASSERT_EQ(ptr[i], 0);
		}

		/* Allow the memory to be populated. */
		EXPECT_EQ(spci_yield().func, SPCI_SUCCESS_32);

		/* Increment each byte of memory. */
		for (i = 0; i < PAGE_SIZE; ++i) {
			++ptr[i];
		}

		/* Signal completion and reset. */
		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
		spci_msg_send(hf_vm_get_id(), sender, sizeof(ptr), 0);
	}
}

TEST_SERVICE(give_memory_and_fault)
{
	void *send_buf = SERVICE_SEND_BUFFER();

	/* Give memory to the primary. */
	struct spci_memory_region_constituent constituents[] = {
		spci_memory_region_constituent_init((uint64_t)&page, 1),
	};
	uint32_t msg_size = spci_memory_region_init(
		send_buf, hf_vm_get_id(), HF_PRIMARY_VM_ID, constituents,
		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_REGION_FLAG_CLEAR,
		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_EQ(spci_mem_donate(msg_size, msg_size, 0).func, SPCI_SUCCESS_32);

	exception_setup(NULL, exception_handler_yield_data_abort);

	/* Try using the memory that isn't valid unless it's been returned. */
	page[16] = 123;

	FAIL("Exception not generated by invalid access.");
}

TEST_SERVICE(lend_memory_and_fault)
{
	void *send_buf = SERVICE_SEND_BUFFER();

	/* Lend memory to the primary. */
	struct spci_memory_region_constituent constituents[] = {
		spci_memory_region_constituent_init((uint64_t)&page, 1),
	};
	uint32_t msg_size = spci_memory_region_init(
		send_buf, hf_vm_get_id(), HF_PRIMARY_VM_ID, constituents,
		ARRAY_SIZE(constituents), 0, SPCI_MEMORY_REGION_FLAG_CLEAR,
		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_EQ(spci_mem_lend(msg_size, msg_size, 0).func, SPCI_SUCCESS_32);

	exception_setup(NULL, exception_handler_yield_data_abort);

	/* Try using the memory that isn't valid unless it's been returned. */
	page[633] = 180;

	FAIL("Exception not generated by invalid access.");
}

TEST_SERVICE(spci_memory_return)
{
	exception_setup(NULL, exception_handler_yield_data_abort);

	/* Loop, giving memory back to the sender. */
	for (;;) {
		struct spci_value ret = spci_msg_wait();
		uint8_t *ptr;
		uint32_t msg_size;
		size_t i;
		void *recv_buf = SERVICE_RECV_BUFFER();
		void *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region;
		struct spci_memory_region_constituent *constituents;

		/*
		 * The memory may have been sent in one of several different
		 * ways.
		 */
		EXPECT_TRUE(ret.func == SPCI_MEM_DONATE_32 ||
			    ret.func == SPCI_MEM_LEND_32 ||
			    ret.func == SPCI_MEM_SHARE_32);

		memory_region = (struct spci_memory_region *)recv_buf;
		constituents =
			spci_memory_region_get_constituents(memory_region);
		ptr = (uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[0]);

		/* Check that one has access to the shared region. */
		for (i = 0; i < PAGE_SIZE; ++i) {
			ptr[i]++;
		}

		/* Give the memory back and notify the sender. */
		msg_size = spci_memory_region_init(
			send_buf, hf_vm_get_id(), memory_region->sender,
			constituents, memory_region->constituent_count, 0, 0,
			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
			SPCI_MEMORY_CACHE_WRITE_BACK,
			SPCI_MEMORY_OUTER_SHAREABLE);
		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
		EXPECT_EQ(spci_mem_donate(msg_size, msg_size, 0).func,
			  SPCI_SUCCESS_32);

		/*
		 * Try and access the memory which will cause a fault unless the
		 * memory has been shared back again.
		 */
		ptr[0] = 123;

		FAIL("Exception not generated by invalid access.");
	}
}

TEST_SERVICE(spci_donate_check_upper_bound)
{
	exception_setup(NULL, exception_handler_yield_data_abort);

	for (;;) {
		struct spci_value ret = spci_msg_wait();
		uint8_t *ptr;
		uint8_t index;
		void *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_memory_region *memory_region;
		struct spci_memory_region_constituent *constituents;

		exception_handler_reset();

		EXPECT_EQ(ret.func, SPCI_MEM_DONATE_32);

		memory_region = (struct spci_memory_region *)recv_buf;
		constituents =
			spci_memory_region_get_constituents(memory_region);

		/* Choose which constituent we want to test. */
		index = *(uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[0]);
		ptr = (uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[index]);
		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);

		/*
		 * Check that one cannot access out of bounds after donated
		 * region. This should trigger the exception handler.
		 */
		ptr[PAGE_SIZE]++;
	}
}

TEST_SERVICE(spci_donate_check_lower_bound)
{
	exception_setup(NULL, exception_handler_yield_data_abort);

	for (;;) {
		struct spci_value ret = spci_msg_wait();
		uint8_t *ptr;
		uint8_t index;
		void *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_memory_region *memory_region;
		struct spci_memory_region_constituent *constituents;

		exception_handler_reset();

		EXPECT_EQ(ret.func, SPCI_MEM_DONATE_32);

		memory_region = (struct spci_memory_region *)recv_buf;
		constituents =
			spci_memory_region_get_constituents(memory_region);

		/* Choose which constituent we want to test. */
		index = *(uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[0]);
		ptr = (uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[index]);
		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);

		/*
		 * Check that one cannot access out of bounds after donated
		 * region. This should trigger the exception handler.
		 */
		ptr[-1]++;
	}
}

/**
 * Attempt to donate memory and then modify.
 */
TEST_SERVICE(spci_donate_secondary_and_fault)
{
	struct spci_value ret = spci_msg_wait();
	uint8_t *ptr;
	uint32_t msg_size;
	void *recv_buf = SERVICE_RECV_BUFFER();
	void *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)recv_buf;
	struct spci_memory_region_constituent *constituents =
		spci_memory_region_get_constituents(memory_region);

	EXPECT_EQ(ret.func, SPCI_MEM_DONATE_32);

	exception_setup(NULL, exception_handler_yield_data_abort);

	ptr = (uint8_t *)spci_memory_region_constituent_get_address(
		&constituents[0]);

	/* Donate memory to next VM. */
	msg_size = spci_memory_region_init(
		send_buf, hf_vm_get_id(), SERVICE_VM2, constituents,
		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
		SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
	EXPECT_EQ(spci_mem_donate(msg_size, msg_size, 0).func, SPCI_SUCCESS_32);

	/* Ensure that we are unable to modify memory any more. */
	ptr[0] = 'c';

	FAIL("Exception not generated by invalid access.");
}

/**
 * Attempt to donate memory twice from VM.
 */
TEST_SERVICE(spci_donate_twice)
{
	uint32_t msg_size;
	struct spci_value ret = spci_msg_wait();
	void *recv_buf = SERVICE_RECV_BUFFER();
	void *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)recv_buf;
	struct spci_memory_region_constituent constituent =
		spci_memory_region_get_constituents(memory_region)[0];

	EXPECT_EQ(ret.func, SPCI_MEM_DONATE_32);
	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);

	/* Yield to allow attempt to re donate from primary. */
	spci_yield();

	/* Give the memory back and notify the sender. */
	msg_size = spci_memory_region_init(
		send_buf, SERVICE_VM1, HF_PRIMARY_VM_ID, &constituent, 1, 0, 0,
		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_EQ(spci_mem_donate(msg_size, msg_size, 0).func, SPCI_SUCCESS_32);

	/* Attempt to donate the memory to another VM. */
	msg_size = spci_memory_region_init(
		send_buf, hf_vm_get_id(), SERVICE_VM2, &constituent, 1, 0, 0,
		SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
		SPCI_MEMORY_CACHE_WRITE_BACK, SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_SPCI_ERROR(spci_mem_donate(msg_size, msg_size, 0),
			  SPCI_INVALID_PARAMETERS);

	spci_yield();
}

/**
 * Continually receive memory, check if we have access and ensure it is not
 * changed by a third party.
 */
TEST_SERVICE(spci_memory_receive)
{
	for (;;) {
		struct spci_value ret = spci_msg_wait();
		uint8_t *ptr;
		void *recv_buf = SERVICE_RECV_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)recv_buf;
		struct spci_memory_region_constituent *constituents =
			spci_memory_region_get_constituents(memory_region);

		EXPECT_EQ(ret.func, SPCI_MEM_DONATE_32);

		ptr = (uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[0]);
		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
		ptr[0] = 'd';
		spci_yield();

		/* Ensure memory has not changed. */
		EXPECT_EQ(ptr[0], 'd');
		spci_yield();
	}
}

/**
 * Receive memory and attempt to donate from primary VM.
 */
TEST_SERVICE(spci_donate_invalid_source)
{
	uint32_t msg_size;
	struct spci_value ret = spci_msg_wait();
	void *recv_buf = SERVICE_RECV_BUFFER();
	void *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)recv_buf;
	struct spci_memory_region_constituent *constituents =
		spci_memory_region_get_constituents(memory_region);

	EXPECT_EQ(ret.func, SPCI_MEM_DONATE_32);

	/* Give the memory back and notify the sender. */
	msg_size = spci_memory_region_init(
		send_buf, hf_vm_get_id(), HF_PRIMARY_VM_ID, constituents,
		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
		SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_EQ(spci_mem_donate(msg_size, msg_size, 0).func, SPCI_SUCCESS_32);

	/* Fail to donate the memory from the primary to VM2. */
	msg_size = spci_memory_region_init(
		send_buf, HF_PRIMARY_VM_ID, SERVICE_VM2, constituents,
		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
		SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
	EXPECT_SPCI_ERROR(spci_mem_donate(msg_size, msg_size, 0),
			  SPCI_INVALID_PARAMETERS);
	spci_yield();
}

TEST_SERVICE(spci_memory_lend_relinquish)
{
	exception_setup(NULL, exception_handler_yield_data_abort);

	/* Loop, giving memory back to the sender. */
	for (;;) {
		struct spci_value ret = spci_msg_wait();
		uint8_t *ptr;
		uint8_t *ptr2;
		uint32_t count;
		uint32_t count2;
		uint32_t msg_size;
		size_t i;

		void *recv_buf = SERVICE_RECV_BUFFER();
		void *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)recv_buf;
		struct spci_memory_region_constituent *constituents =
			spci_memory_region_get_constituents(memory_region);

		/*
		 * The memory may have been sent in one of several different
		 * ways.
		 */
		EXPECT_TRUE(ret.func == SPCI_MEM_DONATE_32 ||
			    ret.func == SPCI_MEM_LEND_32 ||
			    ret.func == SPCI_MEM_SHARE_32);

		ptr = (uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[0]);
		count = constituents[0].page_count;
		ptr2 = (uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[1]);
		count2 = constituents[1].page_count;

		/* Check that one has access to the shared region. */
		for (i = 0; i < PAGE_SIZE * count; ++i) {
			ptr[i]++;
		}
		for (i = 0; i < PAGE_SIZE * count2; ++i) {
			ptr2[i]++;
		}

		/* Give the memory back and notify the sender. */
		msg_size = spci_memory_region_init(
			send_buf, hf_vm_get_id(), memory_region->sender,
			constituents, memory_region->constituent_count, 0, 0,
			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
			SPCI_MEMORY_CACHE_WRITE_BACK,
			SPCI_MEMORY_OUTER_SHAREABLE);
		/* Relevant information read, mailbox can be cleared. */
		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
		EXPECT_EQ(hf_spci_mem_relinquish(msg_size, msg_size, 0).func,
			  SPCI_SUCCESS_32);

		/*
		 * Try and access the memory which will cause a fault unless the
		 * memory has been shared back again.
		 */
		ptr[0] = 123;
	}
}

/**
 * Ensure that we can't relinquish donated memory.
 */
TEST_SERVICE(spci_memory_donate_relinquish)
{
	for (;;) {
		struct spci_value ret = spci_msg_wait();
		uint8_t *ptr;
		uint32_t msg_size;
		size_t i;

		void *recv_buf = SERVICE_RECV_BUFFER();
		void *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)recv_buf;
		struct spci_memory_region_constituent *constituents =
			spci_memory_region_get_constituents(memory_region);

		EXPECT_EQ(ret.func, SPCI_MEM_DONATE_32);

		ptr = (uint8_t *)spci_memory_region_constituent_get_address(
			&constituents[0]);

		/* Check that we have access to the shared region. */
		for (i = 0; i < PAGE_SIZE; ++i) {
			ptr[i]++;
		}
		/*
		 * Attempt to relinquish the memory, which should fail because
		 * it was donated not lent.
		 */
		msg_size = spci_memory_region_init(
			send_buf, hf_vm_get_id(), HF_PRIMARY_VM_ID,
			constituents, memory_region->constituent_count, 0, 0,
			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
			SPCI_MEMORY_CACHE_WRITE_BACK,
			SPCI_MEMORY_OUTER_SHAREABLE);
		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
		EXPECT_SPCI_ERROR(hf_spci_mem_relinquish(msg_size, msg_size, 0),
				  SPCI_INVALID_PARAMETERS);

		/* Ensure we still have access to the memory. */
		ptr[0] = 123;

		spci_yield();
	}
}

/**
 * Receive memory and attempt to donate from primary VM.
 */
TEST_SERVICE(spci_lend_invalid_source)
{
	uint32_t msg_size;
	struct spci_value ret = spci_msg_wait();

	void *recv_buf = SERVICE_RECV_BUFFER();
	void *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)recv_buf;
	struct spci_memory_region_constituent *constituents =
		spci_memory_region_get_constituents(memory_region);

	EXPECT_EQ(ret.func, SPCI_MEM_LEND_32);

	/* Attempt to relinquish to this same VM. */
	msg_size = spci_memory_region_init(
		send_buf, HF_PRIMARY_VM_ID, hf_vm_get_id(), constituents,
		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
		SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_SPCI_ERROR(hf_spci_mem_relinquish(msg_size, msg_size, 0),
			  SPCI_INVALID_PARAMETERS);

	/* Give the memory back and notify the sender. */
	msg_size = spci_memory_region_init(
		send_buf, hf_vm_get_id(), HF_PRIMARY_VM_ID, constituents,
		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
		SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_EQ(hf_spci_mem_relinquish(msg_size, msg_size, 0).func,
		  SPCI_SUCCESS_32);

	/* Ensure we cannot lend from the primary to another secondary. */
	msg_size = spci_memory_region_init(
		send_buf, HF_PRIMARY_VM_ID, SERVICE_VM2, constituents,
		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
		SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_SPCI_ERROR(spci_mem_lend(msg_size, msg_size, 0),
			  SPCI_INVALID_PARAMETERS);

	/* Ensure we cannot share from the primary to another secondary. */
	msg_size = spci_memory_region_init(
		send_buf, HF_PRIMARY_VM_ID, SERVICE_VM2, constituents,
		memory_region->constituent_count, 0, 0, SPCI_MEMORY_RW_X,
		SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
		SPCI_MEMORY_OUTER_SHAREABLE);
	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
	EXPECT_SPCI_ERROR(spci_mem_share(msg_size, msg_size, 0),
			  SPCI_INVALID_PARAMETERS);

	spci_yield();
}

/**
 * Attempt to execute an instruction from the lent memory.
 */
TEST_SERVICE(spci_memory_lend_relinquish_X)
{
	exception_setup(NULL, exception_handler_yield_instruction_abort);

	for (;;) {
		struct spci_value ret = spci_msg_wait();
		uint64_t *ptr;
		uint32_t msg_size;

		void *recv_buf = SERVICE_RECV_BUFFER();
		void *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)recv_buf;
		struct spci_memory_region_constituent *constituents =
			spci_memory_region_get_constituents(memory_region);

		EXPECT_EQ(ret.func, SPCI_MEM_LEND_32);

		ptr = (uint64_t *)spci_memory_region_constituent_get_address(
			&constituents[0]);
		/*
		 * Verify that the instruction in memory is the encoded RET
		 * instruction.
		 */
		EXPECT_EQ(*ptr, 0xD65F03C0);
		/* Try to execute instruction from the shared memory region. */
		__asm__ volatile("blr %0" ::"r"(ptr));

		/* Release the memory again. */
		msg_size = spci_memory_region_init(
			send_buf, hf_vm_get_id(), HF_PRIMARY_VM_ID,
			constituents, memory_region->constituent_count, 0, 0,
			SPCI_MEMORY_RW_X, SPCI_MEMORY_NORMAL_MEM,
			SPCI_MEMORY_CACHE_WRITE_BACK,
			SPCI_MEMORY_OUTER_SHAREABLE);
		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
		EXPECT_EQ(hf_spci_mem_relinquish(msg_size, msg_size, 0).func,
			  SPCI_SUCCESS_32);
	}
}

/**
 * Attempt to read and write to a shared page.
 */
TEST_SERVICE(spci_memory_lend_relinquish_RW)
{
	exception_setup(NULL, exception_handler_yield_data_abort);

	for (;;) {
		struct spci_value ret = spci_msg_wait();
		uint8_t *ptr;
		uint32_t msg_size;
		size_t i;

		void *recv_buf = SERVICE_RECV_BUFFER();
		void *send_buf = SERVICE_SEND_BUFFER();
		struct spci_memory_region *memory_region =
			(struct spci_memory_region *)recv_buf;
		struct spci_memory_region_constituent *constituents =
			spci_memory_region_get_constituents(memory_region);
		struct spci_memory_region_constituent constituent_copy =
			constituents[0];

		/*
		 * The memory may have been sent in one of several different
		 * ways.
		 */
		EXPECT_TRUE(ret.func == SPCI_MEM_DONATE_32 ||
			    ret.func == SPCI_MEM_LEND_32 ||
			    ret.func == SPCI_MEM_SHARE_32);

		EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);

		ptr = (uint8_t *)spci_memory_region_constituent_get_address(
			&constituent_copy);

		/* Check that we have read access. */
		for (i = 0; i < PAGE_SIZE; ++i) {
			EXPECT_EQ(ptr[i], 'b');
		}

		/* Return control to primary, to verify shared access. */
		spci_yield();

		/* Attempt to modify the memory. */
		for (i = 0; i < PAGE_SIZE; ++i) {
			ptr[i]++;
		}

		msg_size = spci_memory_region_init(
			send_buf, hf_vm_get_id(), HF_PRIMARY_VM_ID,
			&constituent_copy, 1, 0, 0, SPCI_MEMORY_RW_X,
			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
			SPCI_MEMORY_OUTER_SHAREABLE);
		EXPECT_EQ(hf_spci_mem_relinquish(msg_size, msg_size, 0).func,
			  SPCI_SUCCESS_32);
	}
}

/**
 * Attempt to modify above the upper bound for the lent memory.
 */
TEST_SERVICE(spci_lend_check_upper_bound)
{
	struct spci_value ret = spci_msg_wait();
	uint8_t *ptr;
	uint8_t index;

	void *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)recv_buf;
	struct spci_memory_region_constituent *constituents =
		spci_memory_region_get_constituents(memory_region);

	EXPECT_EQ(ret.func, SPCI_MEM_LEND_32);

	exception_setup(NULL, exception_handler_yield_data_abort);

	/* Choose which constituent we want to test. */
	index = *(uint8_t *)spci_memory_region_constituent_get_address(
		&constituents[0]);
	ptr = (uint8_t *)spci_memory_region_constituent_get_address(
		&constituents[index]);
	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);

	/* Check that one cannot access after lent region. */
	ASSERT_EQ(ptr[PAGE_SIZE], 0);

	FAIL("Exception not generated by invalid access.");
}

/**
 * Attempt to modify below the lower bound for the lent memory.
 */
TEST_SERVICE(spci_lend_check_lower_bound)
{
	struct spci_value ret = spci_msg_wait();
	uint8_t *ptr;
	uint8_t index;

	void *recv_buf = SERVICE_RECV_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)recv_buf;
	struct spci_memory_region_constituent *constituents =
		spci_memory_region_get_constituents(memory_region);

	exception_setup(NULL, exception_handler_yield_data_abort);

	EXPECT_EQ(ret.func, SPCI_MEM_LEND_32);

	/* Choose which constituent we want to test. */
	index = *(uint8_t *)spci_memory_region_constituent_get_address(
		&constituents[0]);
	ptr = (uint8_t *)spci_memory_region_constituent_get_address(
		&constituents[index]);
	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);

	/* Check that one cannot access after lent region. */
	ptr[-1]++;

	FAIL("Exception not generated by invalid access.");
}

TEST_SERVICE(spci_memory_lend_twice)
{
	struct spci_value ret = spci_msg_wait();
	uint8_t *ptr;
	uint32_t msg_size;
	size_t i;

	void *recv_buf = SERVICE_RECV_BUFFER();
	void *send_buf = SERVICE_SEND_BUFFER();
	struct spci_memory_region *memory_region =
		(struct spci_memory_region *)recv_buf;
	struct spci_memory_region_constituent *constituents =
		spci_memory_region_get_constituents(memory_region);
	struct spci_memory_region_constituent constituent_copy =
		constituents[0];

	/* The memory may have been sent in one of several different ways. */
	EXPECT_TRUE(ret.func == SPCI_MEM_DONATE_32 ||
		    ret.func == SPCI_MEM_LEND_32 ||
		    ret.func == SPCI_MEM_SHARE_32);

	EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);

	ptr = (uint8_t *)spci_memory_region_constituent_get_address(
		&constituent_copy);

	/* Check that we have read access. */
	for (i = 0; i < PAGE_SIZE; ++i) {
		EXPECT_EQ(ptr[i], 'b');
	}

	/* Attempt to modify the memory. */
	for (i = 0; i < PAGE_SIZE; ++i) {
		ptr[i]++;
	}

	for (i = 1; i < PAGE_SIZE * 2; i++) {
		uint64_t address = (uint64_t)ptr + i;
		constituent_copy.address_high = address << 32;
		constituent_copy.address_low = (uint32_t)address;

		/* Fail to lend or share the memory from the primary. */
		msg_size = spci_memory_region_init(
			send_buf, HF_PRIMARY_VM_ID, SERVICE_VM2,
			&constituent_copy, 1, 0, 0, SPCI_MEMORY_RW_X,
			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
			SPCI_MEMORY_OUTER_SHAREABLE);
		EXPECT_SPCI_ERROR(spci_mem_lend(msg_size, msg_size, 0),
				  SPCI_INVALID_PARAMETERS);
		msg_size = spci_memory_region_init(
			send_buf, HF_PRIMARY_VM_ID, SERVICE_VM2,
			&constituent_copy, 1, 0, 0, SPCI_MEMORY_RW_X,
			SPCI_MEMORY_NORMAL_MEM, SPCI_MEMORY_CACHE_WRITE_BACK,
			SPCI_MEMORY_OUTER_SHAREABLE);
		EXPECT_SPCI_ERROR(spci_mem_share(msg_size, msg_size, 0),
				  SPCI_INVALID_PARAMETERS);
	}

	/* Return control to primary. */
	spci_yield();
}
