1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <xen/sched.h>
4 #include <xen/static-memory.h>
5 
6 #include <asm/setup.h>
7 
append_static_memory_to_bank(struct domain * d,struct membank * bank,mfn_t smfn,paddr_t size)8 static bool __init append_static_memory_to_bank(struct domain *d,
9                                                 struct membank *bank,
10                                                 mfn_t smfn,
11                                                 paddr_t size)
12 {
13     int res;
14     unsigned int nr_pages = PFN_DOWN(size);
15     gfn_t sgfn;
16 
17     /*
18      * For direct-mapped domain, the GFN match the MFN.
19      * Otherwise, this is inferred on what has already been allocated
20      * in the bank.
21      */
22     if ( !is_domain_direct_mapped(d) )
23         sgfn = gaddr_to_gfn(bank->start + bank->size);
24     else
25         sgfn = gaddr_to_gfn(mfn_to_maddr(smfn));
26 
27     res = guest_physmap_add_pages(d, sgfn, smfn, nr_pages);
28     if ( res )
29     {
30         dprintk(XENLOG_ERR, "Failed to map pages to DOMU: %d", res);
31         return false;
32     }
33 
34     bank->size = bank->size + size;
35 
36     return true;
37 }
38 
acquire_static_memory_bank(struct domain * d,const __be32 ** cell,u32 addr_cells,u32 size_cells,paddr_t * pbase,paddr_t * psize)39 static mfn_t __init acquire_static_memory_bank(struct domain *d,
40                                                const __be32 **cell,
41                                                u32 addr_cells, u32 size_cells,
42                                                paddr_t *pbase, paddr_t *psize)
43 {
44     mfn_t smfn;
45     int res;
46 
47     device_tree_get_reg(cell, addr_cells, size_cells, pbase, psize);
48     ASSERT(IS_ALIGNED(*pbase, PAGE_SIZE) && IS_ALIGNED(*psize, PAGE_SIZE));
49     if ( PFN_DOWN(*psize) > UINT_MAX )
50     {
51         printk(XENLOG_ERR "%pd: static memory size too large: %#"PRIpaddr,
52                d, *psize);
53         return INVALID_MFN;
54     }
55 
56     smfn = maddr_to_mfn(*pbase);
57     res = acquire_domstatic_pages(d, smfn, PFN_DOWN(*psize), 0);
58     if ( res )
59     {
60         printk(XENLOG_ERR
61                "%pd: failed to acquire static memory: %d.\n", d, res);
62         return INVALID_MFN;
63     }
64 
65     return smfn;
66 }
67 
parse_static_mem_prop(const struct dt_device_node * node,u32 * addr_cells,u32 * size_cells,int * length,const __be32 ** cell)68 static int __init parse_static_mem_prop(const struct dt_device_node *node,
69                                         u32 *addr_cells, u32 *size_cells,
70                                         int *length, const __be32 **cell)
71 {
72     const struct dt_property *prop;
73 
74     prop = dt_find_property(node, "xen,static-mem", NULL);
75 
76     *addr_cells = dt_n_addr_cells(node);
77     *size_cells = dt_n_size_cells(node);
78 
79     *cell = (const __be32 *)prop->value;
80     *length = prop->length;
81 
82     return 0;
83 }
84 
85 /* Allocate memory from static memory as RAM for one specific domain d. */
allocate_static_memory(struct domain * d,struct kernel_info * kinfo,const struct dt_device_node * node)86 void __init allocate_static_memory(struct domain *d, struct kernel_info *kinfo,
87                                    const struct dt_device_node *node)
88 {
89     struct membanks *mem = kernel_info_get_mem(kinfo);
90     u32 addr_cells, size_cells, reg_cells;
91     unsigned int nr_banks, gbank, bank = 0;
92     const uint64_t rambase[] = GUEST_RAM_BANK_BASES;
93     const uint64_t ramsize[] = GUEST_RAM_BANK_SIZES;
94     const __be32 *cell;
95     u64 tot_size = 0;
96     paddr_t pbase, psize, gsize;
97     mfn_t smfn;
98     int length;
99 
100     if ( parse_static_mem_prop(node, &addr_cells, &size_cells, &length, &cell) )
101         goto fail;
102     reg_cells = addr_cells + size_cells;
103 
104     /*
105      * The static memory will be mapped in the guest at the usual guest memory
106      * addresses (GUEST_RAM0_BASE, GUEST_RAM1_BASE) defined by
107      * xen/include/public/arch-arm.h.
108      */
109     gbank = 0;
110     gsize = ramsize[gbank];
111     mem->bank[gbank].start = rambase[gbank];
112     nr_banks = length / (reg_cells * sizeof (u32));
113 
114     for ( ; bank < nr_banks; bank++ )
115     {
116         smfn = acquire_static_memory_bank(d, &cell, addr_cells, size_cells,
117                                           &pbase, &psize);
118         if ( mfn_eq(smfn, INVALID_MFN) )
119             goto fail;
120 
121         printk(XENLOG_INFO "%pd: STATIC BANK[%u] %#"PRIpaddr"-%#"PRIpaddr"\n",
122                d, bank, pbase, pbase + psize);
123 
124         while ( 1 )
125         {
126             /* Map as much as possible the static range to the guest bank */
127             if ( !append_static_memory_to_bank(d, &mem->bank[gbank], smfn,
128                                                min(psize, gsize)) )
129                 goto fail;
130 
131             /*
132              * The current physical bank is fully mapped.
133              * Handle the next physical bank.
134              */
135             if ( gsize >= psize )
136             {
137                 gsize = gsize - psize;
138                 break;
139             }
140             /*
141              * When current guest bank is not enough to map, exhaust
142              * the current one and seek to the next.
143              * Before seeking to the next, check if we still have available
144              * guest bank.
145              */
146             else if ( (gbank + 1) >= GUEST_RAM_BANKS )
147             {
148                 printk(XENLOG_ERR "Exhausted all possible guest banks.\n");
149                 goto fail;
150             }
151             else
152             {
153                 psize = psize - gsize;
154                 smfn = mfn_add(smfn, gsize >> PAGE_SHIFT);
155                 /* Update to the next guest bank. */
156                 gbank++;
157                 gsize = ramsize[gbank];
158                 mem->bank[gbank].start = rambase[gbank];
159             }
160         }
161 
162         tot_size += psize;
163     }
164 
165     mem->nr_banks = ++gbank;
166 
167     kinfo->unassigned_mem -= tot_size;
168     /*
169      * The property 'memory' should match the amount of memory given to the
170      * guest.
171      * Currently, it is only possible to either acquire static memory or let
172      * Xen allocate. *Mixing* is not supported.
173      */
174     if ( kinfo->unassigned_mem )
175     {
176         printk(XENLOG_ERR
177                "Size of \"memory\" property doesn't match up with the sum-up of \"xen,static-mem\". Unsupported configuration.\n");
178         goto fail;
179     }
180 
181     return;
182 
183  fail:
184     panic("Failed to allocate requested static memory for domain %pd.\n", d);
185 }
186 
187 /*
188  * Allocate static memory as RAM for one specific domain d.
189  * The static memory will be directly mapped in the guest(Guest Physical
190  * Address == Physical Address).
191  */
assign_static_memory_11(struct domain * d,struct kernel_info * kinfo,const struct dt_device_node * node)192 void __init assign_static_memory_11(struct domain *d, struct kernel_info *kinfo,
193                                     const struct dt_device_node *node)
194 {
195     struct membanks *mem = kernel_info_get_mem(kinfo);
196     u32 addr_cells, size_cells, reg_cells;
197     unsigned int nr_banks, bank = 0;
198     const __be32 *cell;
199     paddr_t pbase, psize;
200     mfn_t smfn;
201     int length;
202 
203     if ( parse_static_mem_prop(node, &addr_cells, &size_cells, &length, &cell) )
204     {
205         printk(XENLOG_ERR
206                "%pd: failed to parse \"xen,static-mem\" property.\n", d);
207         goto fail;
208     }
209     reg_cells = addr_cells + size_cells;
210     nr_banks = length / (reg_cells * sizeof(u32));
211 
212     if ( nr_banks > mem->max_banks )
213     {
214         printk(XENLOG_ERR
215                "%pd: exceed max number of supported guest memory banks.\n", d);
216         goto fail;
217     }
218 
219     for ( ; bank < nr_banks; bank++ )
220     {
221         smfn = acquire_static_memory_bank(d, &cell, addr_cells, size_cells,
222                                           &pbase, &psize);
223         if ( mfn_eq(smfn, INVALID_MFN) )
224             goto fail;
225 
226         printk(XENLOG_INFO "%pd: STATIC BANK[%u] %#"PRIpaddr"-%#"PRIpaddr"\n",
227                d, bank, pbase, pbase + psize);
228 
229         /* One guest memory bank is matched with one physical memory bank. */
230         mem->bank[bank].start = pbase;
231         if ( !append_static_memory_to_bank(d, &mem->bank[bank],
232                                            smfn, psize) )
233             goto fail;
234 
235         kinfo->unassigned_mem -= psize;
236     }
237 
238     mem->nr_banks = nr_banks;
239 
240     /*
241      * The property 'memory' should match the amount of memory given to
242      * the guest.
243      * Currently, it is only possible to either acquire static memory or
244      * let Xen allocate. *Mixing* is not supported.
245      */
246     if ( kinfo->unassigned_mem != 0 )
247     {
248         printk(XENLOG_ERR
249                "Size of \"memory\" property doesn't match up with the sum-up of \"xen,static-mem\".\n");
250         goto fail;
251     }
252 
253     return;
254 
255  fail:
256     panic("Failed to assign requested static memory for direct-map domain %pd.\n",
257           d);
258 }
259 
260 /* Static memory initialization */
init_staticmem_pages(void)261 void __init init_staticmem_pages(void)
262 {
263     const struct membanks *reserved_mem = bootinfo_get_reserved_mem();
264     unsigned int bank;
265 
266     for ( bank = 0 ; bank < reserved_mem->nr_banks; bank++ )
267     {
268         if ( reserved_mem->bank[bank].type == MEMBANK_STATIC_DOMAIN )
269             init_staticmem_bank(&reserved_mem->bank[bank]);
270     }
271 }
272 
273 /*
274  * Local variables:
275  * mode: C
276  * c-file-style: "BSD"
277  * c-basic-offset: 4
278  * tab-width: 4
279  * indent-tabs-mode: nil
280  * End:
281  */
282