ANDROID: virt: gunyah: Probe for the info_area page

The Gunyah info_area page contains a series of descriptors of
"information". Probe the info_area page during probe and expose a
function to fetch information by its identifier.

Bug: 395833312
Change-Id: I380fa59259f487f1ca9b48c12eb07957603ea099
Signed-off-by: Elliot Berman <elliot.berman@oss.qualcomm.com>
This commit is contained in:
Elliot Berman
2025-02-07 13:43:52 -08:00
committed by Todd Kjos
parent ae558bb094
commit 0df02d448a
2 changed files with 60 additions and 0 deletions
+48
View File
@@ -8,9 +8,45 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
struct gunyah_info_desc {
__le16 id;
__le16 owner;
__le32 size;
__le32 offset;
#define INFO_DESC_VALID BIT(31)
__le32 flags;
};
static void *info_area;
void *gunyah_get_info(u16 owner, u16 id, size_t *size)
{
struct gunyah_info_desc *desc = info_area;
__le16 le_owner = cpu_to_le16(owner);
__le16 le_id = cpu_to_le16(id);
if (!desc)
return ERR_PTR(-ENOENT);
for (desc = info_area; le32_to_cpu(desc->offset); desc++) {
if (!(le32_to_cpu(desc->flags) & INFO_DESC_VALID))
continue;
mb();
if (le_owner == desc->owner && le_id == desc->id) {
if (size)
*size = le32_to_cpu(desc->size);
return info_area + le32_to_cpu(desc->offset);
}
}
return ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL_GPL(gunyah_get_info);
static int gunyah_probe(struct platform_device *pdev)
{
struct gunyah_hypercall_hyp_identify_resp gunyah_api;
unsigned long info_ipa, info_size;
enum gunyah_error gh_error;
if (!arch_is_gunyah_guest())
return -ENODEV;
@@ -28,6 +64,18 @@ static int gunyah_probe(struct platform_device *pdev)
return -ENODEV;
}
gh_error = gunyah_hypercall_addrspace_find_info_area(&info_ipa, &info_size);
/* ignore errors for compatability with gh without info_area support */
if (gh_error != GUNYAH_ERROR_OK)
goto out;
info_area = memremap(info_ipa, info_size, MEMREMAP_WB);
if (!info_area) {
pr_err("Failed to map addrspace info area\n");
return -ENOMEM;
}
out:
return devm_of_platform_populate(&pdev->dev);
}
+12
View File
@@ -363,6 +363,18 @@ enum gunyah_api_feature {
bool arch_is_gunyah_guest(void);
enum gunyah_info_owner {
/* clang-format off */
GUNYAH_INFO_OWNER_INVALID = 0,
GUNYAH_INFO_OWNER_HYP = 1,
GUNYAH_INFO_OWNER_ROOTVM = 2,
GUNYAH_INFO_OWNER_RM = 3,
GUNYAH_INFO_OWNER_QCRM = 16,
/* clang-format on */
};
void *gunyah_get_info(u16 owner, u16 id, size_t *size);
#define GUNYAH_API_V1 1
/* Other bits reserved for future use and will be zero */