7 #include <interfaces/vmm_numa.h>
23 unsigned int num_nodes;
24 unsigned int num_cpus;
25 unsigned int num_mem_regions;
27 u32 * cpu_to_node_map;
29 // For now an array, but we might want to move this to an rbtree
30 struct mem_region * mem_to_node_map;
36 int create_numa_topology_from_user(void __user * argp) {
37 struct v3_numa_topo user_topo;
39 if (copy_from_user(&user_topo, argp, sizeof(struct v3_numa_topo))) {
40 ERROR("Could not read in NUMA topology from user\n");
44 argp += sizeof(struct v3_numa_topo);
46 topology.num_nodes = user_topo.num_nodes;
47 topology.num_cpus = user_topo.num_cpus;
48 topology.num_mem_regions = user_topo.num_mem_regions;
51 /* Read in the CPU to Node mapping */
53 topology.cpu_to_node_map = palacios_alloc(sizeof(u32) * topology.num_cpus);
55 if (IS_ERR(topology.cpu_to_node_map)) {
56 ERROR("Could not allocate cpu to node map\n");
61 if (copy_from_user(topology.cpu_to_node_map, argp,
62 sizeof(u32) * topology.num_cpus)) {
63 ERROR("Could not copy cpu to node map from user space\n");
64 palacios_free(topology.cpu_to_node_map);
68 argp += sizeof(u32) * topology.num_cpus;
71 /* Read in the memory to Node Mapping */
75 topology.mem_to_node_map = palacios_alloc(sizeof(struct mem_region) * topology.num_mem_regions);
77 if (IS_ERR(topology.mem_to_node_map)) {
78 ERROR("Could not allocate mem to node map\n");
79 palacios_free(topology.cpu_to_node_map);
83 if (copy_from_user(topology.mem_to_node_map, argp,
84 sizeof(struct mem_region) * topology.num_mem_regions)) {
85 ERROR("Coudl not copy mem to node map from user space\n");
86 palacios_free(topology.cpu_to_node_map);
87 palacios_free(topology.mem_to_node_map);
91 /* The memory range comes in as the base_addr and the number of pages
92 We need to fix it up to be the base addr and end addr instead
93 We just perform the transformation inline
95 for (i = 0; i < topology.num_mem_regions; i++) {
96 struct mem_region * region = &(topology.mem_to_node_map[i]);
98 region->end_addr = region->base_addr + (region->end_addr * 4096);
104 /* Read in the distance table */
106 topology.distance_table = palacios_alloc(sizeof(u32) * (topology.num_nodes * topology.num_nodes));
108 if (IS_ERR(topology.distance_table)) {
109 ERROR("Could not allocate distance table\n");
110 palacios_free(topology.cpu_to_node_map);
111 palacios_free(topology.mem_to_node_map);
116 if (copy_from_user(topology.distance_table, argp,
117 sizeof(u32) * (topology.num_nodes * topology.num_nodes))) {
118 ERROR("Could not copy distance table from user space\n");
119 palacios_free(topology.cpu_to_node_map);
120 palacios_free(topology.mem_to_node_map);
121 palacios_free(topology.distance_table);
127 /* Report what we found */
132 INFO("Created NUMA topology from user space\n");
133 INFO("Number of Nodes: %d, CPUs: %d, MEM regions: %d\n",
134 topology.num_nodes, topology.num_cpus, topology.num_mem_regions);
136 INFO("CPU mapping\n");
137 for (i = 0; i < topology.num_cpus; i++) {
138 INFO("\tCPU %d -> Node %d\n", i, topology.cpu_to_node_map[i]);
141 INFO("Memory mapping\n");
143 for (i = 0; i < topology.num_mem_regions; i++) {
144 struct mem_region * region = &(topology.mem_to_node_map[i]);
145 INFO("\tMEM %p - %p -> Node %d\n",
152 INFO("Distance Table\n");
153 for (i = 0; i < topology.num_nodes; i++) {
158 for (i = 0; i < topology.num_nodes; i++) {
161 for (j = 0; j < topology.num_nodes; j++) {
162 INFO("\t%d", topology.distance_table[j + (i * topology.num_nodes)]);
180 int numa_num_nodes(void) {
181 return num_online_nodes();
186 int numa_addr_to_node(uintptr_t phys_addr) {
187 return page_to_nid(pfn_to_page(phys_addr >> PAGE_SHIFT));
190 int numa_cpu_to_node(int cpu_id) {
191 return cpu_to_node(cpu_id);
195 int numa_get_distance(int node1, int node2) {
196 return node_distance(node1, node2);
200 /* Ugly fix for interface type differences... */
201 static int phys_ptr_to_node(void * phys_ptr) {
202 return numa_addr_to_node((uintptr_t)phys_ptr);
205 struct v3_numa_hooks numa_hooks = {
206 .cpu_to_node = numa_cpu_to_node,
207 .phys_addr_to_node = phys_ptr_to_node,
208 .get_distance = numa_get_distance,
212 int palacios_init_numa( void ) {
214 V3_Init_NUMA(&numa_hooks);