1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2014 Oracle Co., Daniel Kiper
6 #include <linux/bitops.h>
8 #include <linux/init.h>
9 #include <linux/string.h>
12 #include <xen/xen-ops.h>
13 #include <xen/interface/platform.h>
16 #include <asm/setup.h>
17 #include <asm/xen/hypercall.h>
19 static efi_char16_t vendor
[100] __initdata
;
21 static efi_system_table_t efi_systab_xen __initdata
= {
23 .signature
= EFI_SYSTEM_TABLE_SIGNATURE
,
24 .revision
= 0, /* Initialized later. */
25 .headersize
= 0, /* Ignored by Linux Kernel. */
26 .crc32
= 0, /* Ignored by Linux Kernel. */
29 .fw_vendor
= EFI_INVALID_TABLE_ADDR
, /* Initialized later. */
30 .fw_revision
= 0, /* Initialized later. */
31 .con_in_handle
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
32 .con_in
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
33 .con_out_handle
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
34 .con_out
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
35 .stderr_handle
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
36 .stderr
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
37 .runtime
= (efi_runtime_services_t
*)EFI_INVALID_TABLE_ADDR
,
38 /* Not used under Xen. */
39 .boottime
= (efi_boot_services_t
*)EFI_INVALID_TABLE_ADDR
,
40 /* Not used under Xen. */
41 .nr_tables
= 0, /* Initialized later. */
42 .tables
= EFI_INVALID_TABLE_ADDR
/* Initialized later. */
45 static efi_system_table_t __init
*xen_efi_probe(void)
47 struct xen_platform_op op
= {
48 .cmd
= XENPF_firmware_info
,
50 .type
= XEN_FW_EFI_INFO
,
51 .index
= XEN_FW_EFI_CONFIG_TABLE
54 union xenpf_efi_info
*info
= &op
.u
.firmware_info
.u
.efi_info
;
56 if (!xen_initial_domain() || HYPERVISOR_platform_op(&op
) < 0)
59 /* Here we know that Xen runs on EFI platform. */
61 efi
.get_time
= xen_efi_get_time
;
62 efi
.set_time
= xen_efi_set_time
;
63 efi
.get_wakeup_time
= xen_efi_get_wakeup_time
;
64 efi
.set_wakeup_time
= xen_efi_set_wakeup_time
;
65 efi
.get_variable
= xen_efi_get_variable
;
66 efi
.get_next_variable
= xen_efi_get_next_variable
;
67 efi
.set_variable
= xen_efi_set_variable
;
68 efi
.query_variable_info
= xen_efi_query_variable_info
;
69 efi
.update_capsule
= xen_efi_update_capsule
;
70 efi
.query_capsule_caps
= xen_efi_query_capsule_caps
;
71 efi
.get_next_high_mono_count
= xen_efi_get_next_high_mono_count
;
72 efi
.reset_system
= xen_efi_reset_system
;
74 efi_systab_xen
.tables
= info
->cfg
.addr
;
75 efi_systab_xen
.nr_tables
= info
->cfg
.nent
;
77 op
.cmd
= XENPF_firmware_info
;
78 op
.u
.firmware_info
.type
= XEN_FW_EFI_INFO
;
79 op
.u
.firmware_info
.index
= XEN_FW_EFI_VENDOR
;
80 info
->vendor
.bufsz
= sizeof(vendor
);
81 set_xen_guest_handle(info
->vendor
.name
, vendor
);
83 if (HYPERVISOR_platform_op(&op
) == 0) {
84 efi_systab_xen
.fw_vendor
= __pa_symbol(vendor
);
85 efi_systab_xen
.fw_revision
= info
->vendor
.revision
;
87 efi_systab_xen
.fw_vendor
= __pa_symbol(L
"UNKNOWN");
89 op
.cmd
= XENPF_firmware_info
;
90 op
.u
.firmware_info
.type
= XEN_FW_EFI_INFO
;
91 op
.u
.firmware_info
.index
= XEN_FW_EFI_VERSION
;
93 if (HYPERVISOR_platform_op(&op
) == 0)
94 efi_systab_xen
.hdr
.revision
= info
->version
;
96 op
.cmd
= XENPF_firmware_info
;
97 op
.u
.firmware_info
.type
= XEN_FW_EFI_INFO
;
98 op
.u
.firmware_info
.index
= XEN_FW_EFI_RT_VERSION
;
100 if (HYPERVISOR_platform_op(&op
) == 0)
101 efi
.runtime_version
= info
->version
;
103 return &efi_systab_xen
;
107 * Determine whether we're in secure boot mode.
109 * Please keep the logic in sync with
110 * drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot().
112 static enum efi_secureboot_mode
xen_efi_get_secureboot(void)
114 static efi_guid_t efi_variable_guid
= EFI_GLOBAL_VARIABLE_GUID
;
115 static efi_guid_t shim_guid
= EFI_SHIM_LOCK_GUID
;
117 u8 moksbstate
, secboot
, setupmode
;
120 size
= sizeof(secboot
);
121 status
= efi
.get_variable(L
"SecureBoot", &efi_variable_guid
,
122 NULL
, &size
, &secboot
);
124 if (status
== EFI_NOT_FOUND
)
125 return efi_secureboot_mode_disabled
;
127 if (status
!= EFI_SUCCESS
)
130 size
= sizeof(setupmode
);
131 status
= efi
.get_variable(L
"SetupMode", &efi_variable_guid
,
132 NULL
, &size
, &setupmode
);
134 if (status
!= EFI_SUCCESS
)
137 if (secboot
== 0 || setupmode
== 1)
138 return efi_secureboot_mode_disabled
;
140 /* See if a user has put the shim into insecure mode. */
141 size
= sizeof(moksbstate
);
142 status
= efi
.get_variable(L
"MokSBStateRT", &shim_guid
,
143 NULL
, &size
, &moksbstate
);
145 /* If it fails, we don't care why. Default to secure. */
146 if (status
!= EFI_SUCCESS
)
147 goto secure_boot_enabled
;
150 return efi_secureboot_mode_disabled
;
153 pr_info("UEFI Secure Boot is enabled.\n");
154 return efi_secureboot_mode_enabled
;
157 pr_err("Could not determine UEFI Secure Boot status.\n");
158 return efi_secureboot_mode_unknown
;
161 void __init
xen_efi_init(struct boot_params
*boot_params
)
163 efi_system_table_t
*efi_systab_xen
;
165 efi_systab_xen
= xen_efi_probe();
167 if (efi_systab_xen
== NULL
)
170 strncpy((char *)&boot_params
->efi_info
.efi_loader_signature
, "Xen",
171 sizeof(boot_params
->efi_info
.efi_loader_signature
));
172 boot_params
->efi_info
.efi_systab
= (__u32
)__pa(efi_systab_xen
);
173 boot_params
->efi_info
.efi_systab_hi
= (__u32
)(__pa(efi_systab_xen
) >> 32);
175 boot_params
->secure_boot
= xen_efi_get_secureboot();
177 set_bit(EFI_BOOT
, &efi
.flags
);
178 set_bit(EFI_PARAVIRT
, &efi
.flags
);
179 set_bit(EFI_64BIT
, &efi
.flags
);