|
19 | 19 | #include <linux/kernel.h>
|
20 | 20 | #include <linux/mm.h>
|
21 | 21 | #include <linux/cpumask.h>
|
| 22 | +#include <linux/efi.h> |
| 23 | +#include <linux/platform_device.h> |
| 24 | +#include <linux/io.h> |
22 | 25 |
|
23 | 26 | #include <asm/cpu_entry_area.h>
|
24 | 27 | #include <asm/stacktrace.h>
|
@@ -2163,3 +2166,56 @@ int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, unsigned
|
2163 | 2166 | return ret;
|
2164 | 2167 | }
|
2165 | 2168 | EXPORT_SYMBOL_GPL(snp_issue_guest_request);
|
| 2169 | + |
| 2170 | +static struct platform_device guest_req_device = { |
| 2171 | + .name = "snp-guest", |
| 2172 | + .id = -1, |
| 2173 | +}; |
| 2174 | + |
| 2175 | +static u64 get_secrets_page(void) |
| 2176 | +{ |
| 2177 | + u64 pa_data = boot_params.cc_blob_address; |
| 2178 | + struct cc_blob_sev_info info; |
| 2179 | + void *map; |
| 2180 | + |
| 2181 | + /* |
| 2182 | + * The CC blob contains the address of the secrets page, check if the |
| 2183 | + * blob is present. |
| 2184 | + */ |
| 2185 | + if (!pa_data) |
| 2186 | + return 0; |
| 2187 | + |
| 2188 | + map = early_memremap(pa_data, sizeof(info)); |
| 2189 | + memcpy(&info, map, sizeof(info)); |
| 2190 | + early_memunmap(map, sizeof(info)); |
| 2191 | + |
| 2192 | + /* smoke-test the secrets page passed */ |
| 2193 | + if (!info.secrets_phys || info.secrets_len != PAGE_SIZE) |
| 2194 | + return 0; |
| 2195 | + |
| 2196 | + return info.secrets_phys; |
| 2197 | +} |
| 2198 | + |
| 2199 | +static int __init snp_init_platform_device(void) |
| 2200 | +{ |
| 2201 | + struct snp_guest_platform_data data; |
| 2202 | + u64 gpa; |
| 2203 | + |
| 2204 | + if (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) |
| 2205 | + return -ENODEV; |
| 2206 | + |
| 2207 | + gpa = get_secrets_page(); |
| 2208 | + if (!gpa) |
| 2209 | + return -ENODEV; |
| 2210 | + |
| 2211 | + data.secrets_gpa = gpa; |
| 2212 | + if (platform_device_add_data(&guest_req_device, &data, sizeof(data))) |
| 2213 | + return -ENODEV; |
| 2214 | + |
| 2215 | + if (platform_device_register(&guest_req_device)) |
| 2216 | + return -ENODEV; |
| 2217 | + |
| 2218 | + pr_info("SNP guest platform device initialized.\n"); |
| 2219 | + return 0; |
| 2220 | +} |
| 2221 | +device_initcall(snp_init_platform_device); |
0 commit comments