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>
21 static efi_char16_t vendor
[100] __initdata
;
23 static efi_system_table_t efi_systab_xen __initdata
= {
25 .signature
= EFI_SYSTEM_TABLE_SIGNATURE
,
26 .revision
= 0, /* Initialized later. */
27 .headersize
= 0, /* Ignored by Linux Kernel. */
28 .crc32
= 0, /* Ignored by Linux Kernel. */
31 .fw_vendor
= EFI_INVALID_TABLE_ADDR
, /* Initialized later. */
32 .fw_revision
= 0, /* Initialized later. */
33 .con_in_handle
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
34 .con_in
= NULL
, /* Not used under Xen. */
35 .con_out_handle
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
36 .con_out
= NULL
, /* Not used under Xen. */
37 .stderr_handle
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
38 .stderr
= EFI_INVALID_TABLE_ADDR
, /* Not used under Xen. */
39 .runtime
= (efi_runtime_services_t
*)EFI_INVALID_TABLE_ADDR
,
40 /* Not used under Xen. */
41 .boottime
= (efi_boot_services_t
*)EFI_INVALID_TABLE_ADDR
,
42 /* Not used under Xen. */
43 .nr_tables
= 0, /* Initialized later. */
44 .tables
= EFI_INVALID_TABLE_ADDR
/* Initialized later. */
47 static efi_system_table_t __init
*xen_efi_probe(void)
49 struct xen_platform_op op
= {
50 .cmd
= XENPF_firmware_info
,
52 .type
= XEN_FW_EFI_INFO
,
53 .index
= XEN_FW_EFI_CONFIG_TABLE
56 union xenpf_efi_info
*info
= &op
.u
.firmware_info
.u
.efi_info
;
58 if (!xen_initial_domain() || HYPERVISOR_platform_op(&op
) < 0)
61 /* Here we know that Xen runs on EFI platform. */
62 xen_efi_runtime_setup();
64 efi_systab_xen
.tables
= info
->cfg
.addr
;
65 efi_systab_xen
.nr_tables
= info
->cfg
.nent
;
67 op
.cmd
= XENPF_firmware_info
;
68 op
.u
.firmware_info
.type
= XEN_FW_EFI_INFO
;
69 op
.u
.firmware_info
.index
= XEN_FW_EFI_VENDOR
;
70 info
->vendor
.bufsz
= sizeof(vendor
);
71 set_xen_guest_handle(info
->vendor
.name
, vendor
);
73 if (HYPERVISOR_platform_op(&op
) == 0) {
74 efi_systab_xen
.fw_vendor
= __pa_symbol(vendor
);
75 efi_systab_xen
.fw_revision
= info
->vendor
.revision
;
77 efi_systab_xen
.fw_vendor
= __pa_symbol(L
"UNKNOWN");
79 op
.cmd
= XENPF_firmware_info
;
80 op
.u
.firmware_info
.type
= XEN_FW_EFI_INFO
;
81 op
.u
.firmware_info
.index
= XEN_FW_EFI_VERSION
;
83 if (HYPERVISOR_platform_op(&op
) == 0)
84 efi_systab_xen
.hdr
.revision
= info
->version
;
86 op
.cmd
= XENPF_firmware_info
;
87 op
.u
.firmware_info
.type
= XEN_FW_EFI_INFO
;
88 op
.u
.firmware_info
.index
= XEN_FW_EFI_RT_VERSION
;
90 if (HYPERVISOR_platform_op(&op
) == 0)
91 efi
.runtime_version
= info
->version
;
93 return &efi_systab_xen
;
97 * Determine whether we're in secure boot mode.
99 static enum efi_secureboot_mode
xen_efi_get_secureboot(void)
101 static efi_guid_t shim_guid
= EFI_SHIM_LOCK_GUID
;
102 enum efi_secureboot_mode mode
;
107 mode
= efi_get_secureboot_mode(efi
.get_variable
);
108 if (mode
== efi_secureboot_mode_unknown
) {
109 pr_err("Could not determine UEFI Secure Boot status.\n");
110 return efi_secureboot_mode_unknown
;
112 if (mode
!= efi_secureboot_mode_enabled
)
115 /* See if a user has put the shim into insecure mode. */
116 size
= sizeof(moksbstate
);
117 status
= efi
.get_variable(L
"MokSBStateRT", &shim_guid
,
118 NULL
, &size
, &moksbstate
);
120 /* If it fails, we don't care why. Default to secure. */
121 if (status
!= EFI_SUCCESS
)
122 goto secure_boot_enabled
;
125 return efi_secureboot_mode_disabled
;
128 pr_info("UEFI Secure Boot is enabled.\n");
129 return efi_secureboot_mode_enabled
;
132 void __init
xen_efi_init(struct boot_params
*boot_params
)
134 efi_system_table_t
*efi_systab_xen
;
136 efi_systab_xen
= xen_efi_probe();
138 if (efi_systab_xen
== NULL
)
141 strscpy((char *)&boot_params
->efi_info
.efi_loader_signature
, "Xen",
142 sizeof(boot_params
->efi_info
.efi_loader_signature
));
143 boot_params
->efi_info
.efi_systab
= (__u32
)__pa(efi_systab_xen
);
144 boot_params
->efi_info
.efi_systab_hi
= (__u32
)(__pa(efi_systab_xen
) >> 32);
146 boot_params
->secure_boot
= xen_efi_get_secureboot();
148 set_bit(EFI_BOOT
, &efi
.flags
);
149 set_bit(EFI_PARAVIRT
, &efi
.flags
);
150 set_bit(EFI_64BIT
, &efi
.flags
);