Skip to content

Commit

Permalink
ANDROID: KVM: arm64: add support for early enablement nVHE hyp events
Browse files Browse the repository at this point in the history
Set hyp_event="event1,event2" in the commandline to start tracing as
soon as possible the nVHE hypervisor.

Bug: 229972309
Change-Id: I878e342a8758a78a01d6ddf26355020945b2df33
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
  • Loading branch information
vdonnefort committed Jan 27, 2023
1 parent a7640ce commit 8f1f4a1
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 9 deletions.
91 changes: 82 additions & 9 deletions arch/arm64/kvm/hyp_events.c
Expand Up @@ -8,12 +8,15 @@

#include <asm/kvm_host.h>
#include <asm/kvm_hypevents_defs.h>
#include <asm/setup.h>

#include "hyp_trace.h"

#define HYP_EVENT_NAME_MAX 32

struct hyp_event {
struct trace_event_call *call;
char name[32];
char name[HYP_EVENT_NAME_MAX];
bool *enabled;
};

Expand Down Expand Up @@ -81,12 +84,41 @@ extern struct hyp_event __stop_hyp_events[];
extern struct hyp_event_id __hyp_event_ids_start[];
extern struct hyp_event_id __hyp_event_ids_end[];

static struct hyp_event *find_hyp_event(const char *name)
{
struct hyp_event *event = __start_hyp_events;

for (; (unsigned long)event < (unsigned long)__stop_hyp_events;
event++) {
if (!strncmp(name, event->name, HYP_EVENT_NAME_MAX))
return event;
}

return NULL;
}

static int enable_hyp_event(struct hyp_event *event, bool enable)
{
unsigned short id = event->call->event.type;
int ret;

if (enable == *event->enabled)
return 0;

ret = kvm_call_hyp_nvhe(__pkvm_enable_event, id, enable);
if (ret)
return ret;

*event->enabled = enable;

return 0;
}

static ssize_t
hyp_event_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
{
struct seq_file *seq_file = (struct seq_file *)filp->private_data;
struct hyp_event *evt = (struct hyp_event *)seq_file->private;
unsigned short id = evt->call->event.type;
bool enabling;
int ret;
char c;
Expand All @@ -108,13 +140,9 @@ hyp_event_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *
return -EINVAL;
}

if (enabling != *evt->enabled) {
ret = kvm_call_hyp_nvhe(__pkvm_enable_event, id, enabling);
if (ret)
return ret;
}

*evt->enabled = enabling;
ret = enable_hyp_event(evt, enabling);
if (ret)
return ret;

return cnt;
}
Expand Down Expand Up @@ -163,6 +191,51 @@ static const struct file_operations hyp_event_id_fops = {
.release = single_release,
};

static char early_events[COMMAND_LINE_SIZE];

static __init int setup_hyp_event_early(char *str)
{
strscpy(early_events, str, COMMAND_LINE_SIZE);

return 1;
}
__setup("hyp_event=", setup_hyp_event_early);

bool kvm_hyp_events_enable_early(void)
{
char *token, *buf = early_events;
bool enabled = false;

while (true) {
token = strsep(&buf, ",");

if (!token)
break;

if (*token) {
struct hyp_event *event;
int ret;

event = find_hyp_event(token);
if (event) {
ret = enable_hyp_event(event, true);
if (ret)
pr_warn("Couldn't enable hyp event %s:%d\n",
token, ret);
else
enabled = true;
} else {
pr_warn("Couldn't find hyp event %s\n", token);
}
}

if (buf)
*(buf - 1) = ',';
}

return enabled;
}

void kvm_hyp_init_events_tracefs(struct dentry *parent)
{
struct hyp_event *event = __start_hyp_events;
Expand Down
7 changes: 7 additions & 0 deletions arch/arm64/kvm/hyp_trace.c
Expand Up @@ -730,12 +730,14 @@ static void hyp_tracefs_create_cpu_file(const char *file_name,
}

void kvm_hyp_init_events_tracefs(struct dentry *parent);
bool kvm_hyp_events_enable_early(void);

int init_hyp_tracefs(void)
{
struct dentry *d, *root_dir, *per_cpu_root_dir;
char per_cpu_name[16];
unsigned long cpu;
int err;

if (!is_protected_kvm_enabled())
return 0;
Expand Down Expand Up @@ -784,6 +786,11 @@ int init_hyp_tracefs(void)
}

kvm_hyp_init_events_tracefs(root_dir);
if (kvm_hyp_events_enable_early()) {
err = hyp_start_tracing();
if (err)
pr_warn("Failed to start early events tracing: %d\n", err);
}

return 0;
}

0 comments on commit 8f1f4a1

Please sign in to comment.