Linux Audio

Check our new training course

Loading...
v6.2
 1// SPDX-License-Identifier: GPL-2.0
 2#include <linux/acpi.h>
 3#include <linux/export.h>
 
 4
 5#include <xen/hvc-console.h>
 
 6
 
 7#include <asm/io_apic.h>
 8#include <asm/hypervisor.h>
 9#include <asm/e820/api.h>
 
10
11#include <xen/xen.h>
12#include <asm/xen/interface.h>
13#include <asm/xen/hypercall.h>
14
15#include <xen/interface/memory.h>
16
17#include "xen-ops.h"
18
19/*
20 * PVH variables.
21 *
22 * The variable xen_pvh needs to live in a data segment since it is used
23 * after startup_{32|64} is invoked, which will clear the .bss segment.
24 */
25bool __ro_after_init xen_pvh;
26EXPORT_SYMBOL_GPL(xen_pvh);
27
28void __init xen_pvh_init(struct boot_params *boot_params)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29{
30	u32 msr;
31	u64 pfn;
32
 
 
 
 
 
 
33	xen_pvh = 1;
34	xen_domain_type = XEN_HVM_DOMAIN;
35	xen_start_flags = pvh_start_info.flags;
36
37	msr = cpuid_ebx(xen_cpuid_base() + 2);
38	pfn = __pa(hypercall_page);
39	wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
40
41	if (xen_initial_domain())
42		x86_init.oem.arch_setup = xen_add_preferred_consoles;
43	x86_init.oem.banner = xen_banner;
44
45	xen_efi_init(boot_params);
 
 
 
 
 
 
 
 
 
 
 
 
 
46}
47
48void __init mem_map_via_hcall(struct boot_params *boot_params_p)
49{
50	struct xen_memory_map memmap;
51	int rc;
52
53	memmap.nr_entries = ARRAY_SIZE(boot_params_p->e820_table);
54	set_xen_guest_handle(memmap.buffer, boot_params_p->e820_table);
55	rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
56	if (rc) {
57		xen_raw_printk("XENMEM_memory_map failed (%d)\n", rc);
58		BUG();
59	}
60	boot_params_p->e820_entries = memmap.nr_entries;
61}
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/acpi.h>
  3#include <linux/export.h>
  4#include <linux/mm.h>
  5
  6#include <xen/hvc-console.h>
  7#include <xen/acpi.h>
  8
  9#include <asm/bootparam.h>
 10#include <asm/io_apic.h>
 11#include <asm/hypervisor.h>
 12#include <asm/e820/api.h>
 13#include <asm/setup.h>
 14
 15#include <xen/xen.h>
 16#include <asm/xen/interface.h>
 17#include <asm/xen/hypercall.h>
 18
 19#include <xen/interface/memory.h>
 20
 21#include "xen-ops.h"
 22
 23/*
 24 * PVH variables.
 25 *
 26 * The variable xen_pvh needs to live in a data segment since it is used
 27 * after startup_{32|64} is invoked, which will clear the .bss segment.
 28 */
 29bool __ro_after_init xen_pvh;
 30EXPORT_SYMBOL_GPL(xen_pvh);
 31
 32#ifdef CONFIG_XEN_DOM0
 33int xen_pvh_setup_gsi(int gsi, int trigger, int polarity)
 34{
 35	int ret;
 36	struct physdev_setup_gsi setup_gsi;
 37
 38	setup_gsi.gsi = gsi;
 39	setup_gsi.triggering = (trigger == ACPI_EDGE_SENSITIVE ? 0 : 1);
 40	setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
 41
 42	ret = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi);
 43	if (ret == -EEXIST) {
 44		xen_raw_printk("Already setup the GSI :%d\n", gsi);
 45		ret = 0;
 46	} else if (ret)
 47		xen_raw_printk("Fail to setup GSI (%d)!\n", gsi);
 48
 49	return ret;
 50}
 51EXPORT_SYMBOL_GPL(xen_pvh_setup_gsi);
 52#endif
 53
 54/*
 55 * Reserve e820 UNUSABLE regions to inflate the memory balloon.
 56 *
 57 * On PVH dom0 the host memory map is used, RAM regions available to dom0 are
 58 * located as the same place as in the native memory map, but since dom0 gets
 59 * less memory than the total amount of host RAM the ranges that can't be
 60 * populated are converted from RAM -> UNUSABLE.  Use such regions (up to the
 61 * ratio signaled in EXTRA_MEM_RATIO) in order to inflate the balloon driver at
 62 * boot.  Doing so prevents the guest (even if just temporary) from using holes
 63 * in the memory map in order to map grants or foreign addresses, and
 64 * hopefully limits the risk of a clash with a device MMIO region.  Ideally the
 65 * hypervisor should notify us which memory ranges are suitable for creating
 66 * foreign mappings, but that's not yet implemented.
 67 */
 68static void __init pvh_reserve_extra_memory(void)
 69{
 70	struct boot_params *bootp = &boot_params;
 71	unsigned int i, ram_pages = 0, extra_pages;
 72
 73	for (i = 0; i < bootp->e820_entries; i++) {
 74		struct boot_e820_entry *e = &bootp->e820_table[i];
 75
 76		if (e->type != E820_TYPE_RAM)
 77			continue;
 78		ram_pages += PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr);
 79	}
 80
 81	/* Max amount of extra memory. */
 82	extra_pages = EXTRA_MEM_RATIO * ram_pages;
 83
 84	/*
 85	 * Convert UNUSABLE ranges to RAM and reserve them for foreign mapping
 86	 * purposes.
 87	 */
 88	for (i = 0; i < bootp->e820_entries && extra_pages; i++) {
 89		struct boot_e820_entry *e = &bootp->e820_table[i];
 90		unsigned long pages;
 91
 92		if (e->type != E820_TYPE_UNUSABLE)
 93			continue;
 94
 95		pages = min(extra_pages,
 96			PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr));
 97
 98		if (pages != (PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr))) {
 99			struct boot_e820_entry *next;
100
101			if (bootp->e820_entries ==
102			    ARRAY_SIZE(bootp->e820_table))
103				/* No space left to split - skip region. */
104				continue;
105
106			/* Split entry. */
107			next = e + 1;
108			memmove(next, e,
109				(bootp->e820_entries - i) * sizeof(*e));
110			bootp->e820_entries++;
111			next->addr = PAGE_ALIGN(e->addr) + PFN_PHYS(pages);
112			e->size = next->addr - e->addr;
113			next->size -= e->size;
114		}
115		e->type = E820_TYPE_RAM;
116		extra_pages -= pages;
117
118		xen_add_extra_mem(PFN_UP(e->addr), pages);
119	}
120}
121
122static void __init pvh_arch_setup(void)
123{
124	pvh_reserve_extra_memory();
 
125
126	if (xen_initial_domain())
127		xen_add_preferred_consoles();
128}
129
130void __init xen_pvh_init(struct boot_params *boot_params)
131{
132	xen_pvh = 1;
133	xen_domain_type = XEN_HVM_DOMAIN;
134	xen_start_flags = pvh_start_info.flags;
135
136	x86_init.oem.arch_setup = pvh_arch_setup;
 
 
 
 
 
137	x86_init.oem.banner = xen_banner;
138
139	xen_efi_init(boot_params);
140
141	if (xen_initial_domain()) {
142		struct xen_platform_op op = {
143			.cmd = XENPF_get_dom0_console,
144		};
145		int ret = HYPERVISOR_platform_op(&op);
146
147		if (ret > 0)
148			xen_init_vga(&op.u.dom0_console,
149				     min(ret * sizeof(char),
150					 sizeof(op.u.dom0_console)),
151				     &boot_params->screen_info);
152	}
153}
154
155void __init mem_map_via_hcall(struct boot_params *boot_params_p)
156{
157	struct xen_memory_map memmap;
158	int rc;
159
160	memmap.nr_entries = ARRAY_SIZE(boot_params_p->e820_table);
161	set_xen_guest_handle(memmap.buffer, boot_params_p->e820_table);
162	rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap);
163	if (rc) {
164		xen_raw_printk("XENMEM_memory_map failed (%d)\n", rc);
165		BUG();
166	}
167	boot_params_p->e820_entries = memmap.nr_entries;
168}