1 /*
2 * Copyright (C) 2022 Intel Corporation.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 
7 #include "ivshmemlib.h"
8 
9 //The shared memory region that is used for inter-vm shared memory
10 char *ivshmem_ptr = NULL;
11 
12 /*
13 int setup_ivshmem_region(const char *f_path)
14 input: char *f_path - A string containing the pci resource2 filepath
15 output: int - Whether the setup succeeded or not
16 
17 This function attempts to open the file whose path is f_path
18 On success it returns 0
19 On failure it returns -1
20 */
setup_ivshmem_region(const char * f_path)21 int setup_ivshmem_region(const char *f_path)
22 {
23 
24 	//Open the file so we can map it into memory
25 	int pci_file = open(f_path, O_RDWR | O_SYNC);
26 	if (pci_file == failure) {
27 
28 		perror("Failed to open the resource2 file\n");
29 		return failure;
30 
31 	}
32 
33 	//Map the file into memory
34 	ivshmem_ptr = (char *)mmap(0, REGION_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, pci_file , 0);
35 	close(pci_file);
36 	if (!ivshmem_ptr) {
37 
38 		perror("Failed to map the shared memory region into our address space\n");
39 		return failure;
40 
41 	}
42 
43 	return success;
44 }
45 
46 /*
47 int close_ivshmem_region(void)
48 output: int - Whether unmapping the region succeeded or not.
49 
50 This function closes the ivshmem region
51 On success it returns 0
52 On failure it returns -1
53 */
close_ivshmem_region(void)54 int close_ivshmem_region(void)
55 {
56 
57 	int ret_val = failure;
58 
59 	//Determine if ivshmem region is set up
60 	if (ivshmem_ptr) {
61 
62 		ret_val =  munmap(ivshmem_ptr, REGION_SIZE);
63 		ivshmem_ptr = NULL;
64 
65 	}
66 
67 	else
68 
69 		printf("Ivshmem region is not set up.");
70 
71 	return ret_val;
72 
73 }
74 
75 /*
76 size_t read_ivshmem_region(char *ivshmemPtr, char *user_ptr, size_t size)
77 input: char *user_ptr - The memory to write to
78 input: size_t size - the number of bytes to read from the memory
79 output: size_t - The number of bytes that were successfully read or -1 on failure
80 
81 This function reads from the ivshmem region and copies size - 1 bytes
82 from the shared memory region to the user_ptr
83 and null-terminates the string
84 */
read_ivshmem_region(char * user_ptr,size_t size)85 size_t read_ivshmem_region(char *user_ptr, size_t size)
86 {
87 	//Number of bytes copied
88 	size_t ret = failure;
89 
90 	//Make sure that we actually need to read something
91 	if (size == 0)
92 		return ret;
93 
94 	//Determine if ivshmem region is set up
95 	if ((ivshmem_ptr) && (size < REGION_SIZE - 1)) {
96 
97 		//Do the copy and zero out the ivshmem region
98 		bzero(user_ptr, size);
99 		strncpy(user_ptr, ivshmem_ptr, size);
100 		ivshmem_ptr[size] = '\0';
101 		user_ptr[size] = '\0';
102 		ret = strlen(user_ptr);
103 		bzero(ivshmem_ptr, size);
104 
105 	}
106 
107 	else
108 
109 		printf("Ivshmem region is not set up.");
110 
111 	return ret;
112 }
113 
114 /*
115 size_t write_ivshmem_region(char *ivshmemPtr, char *user_ptr, size_t size)
116 input: char *user_ptr - The memory to read from
117 input: int size - the number of bytes to write from the memory
118 output: int - The number of bytes that were successfully written or -1 on failure
119 
120 This function reads from the user_ptr and copies size - 1 bytes
121 to the shared memory region
122 and null-terminates the string
123 */
write_ivshmem_region(char * user_ptr,size_t size)124 size_t write_ivshmem_region(char *user_ptr, size_t size)
125 {
126 	//Return value that holds the amount of bytes that were copied from the user_ptr
127 	size_t ret = failure;
128 
129 	//Make sure that we need to actually write something
130 	if (size == 0)
131 
132 		return ret;
133 
134 	//Determine if ivshmem region is set up
135 	if ((ivshmem_ptr) && (size < REGION_SIZE - 1)){
136 
137 		//Do the copy and zero out the user_ptr
138 		bzero(ivshmem_ptr, size);
139 		strncpy(ivshmem_ptr, user_ptr, size);
140 		user_ptr[size] = '\0';
141 		ivshmem_ptr[size] = '\0';
142 		ret = strlen(ivshmem_ptr);
143 		bzero(user_ptr, size);
144 
145 	}
146 
147 	else
148 
149 		printf("Ivshmem region is not set up.");
150 
151 	return ret;
152 }
153