Skip to content

Commit 8917665

Browse files
Marc Zyngieroupton
authored andcommitted
KVM: arm64: Add debugfs file for guest's ID registers
Debugging ID register setup can be a complicated affair. Give the kernel hacker a way to dump that state in an easy to parse way. Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent b80b701 commit 8917665

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,9 @@ struct kvm_arch {
319319
/* PMCR_EL0.N value for the guest */
320320
u8 pmcr_n;
321321

322+
/* Iterator for idreg debugfs */
323+
u8 idreg_debugfs_iter;
324+
322325
/* Hypercall features firmware registers' descriptor */
323326
struct kvm_smccc_features smccc_feat;
324327
struct maple_tree smccc_filter;

arch/arm64/kvm/sys_regs.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/bitfield.h>
1313
#include <linux/bsearch.h>
1414
#include <linux/cacheinfo.h>
15+
#include <linux/debugfs.h>
1516
#include <linux/kvm_host.h>
1617
#include <linux/mm.h>
1718
#include <linux/printk.h>
@@ -3422,6 +3423,81 @@ static bool emulate_sys_reg(struct kvm_vcpu *vcpu,
34223423
return false;
34233424
}
34243425

3426+
static void *idregs_debug_start(struct seq_file *s, loff_t *pos)
3427+
{
3428+
struct kvm *kvm = s->private;
3429+
u8 *iter;
3430+
3431+
mutex_lock(&kvm->arch.config_lock);
3432+
3433+
iter = &kvm->arch.idreg_debugfs_iter;
3434+
if (*iter == (u8)~0) {
3435+
*iter = *pos;
3436+
if (*iter >= KVM_ARM_ID_REG_NUM)
3437+
iter = NULL;
3438+
} else {
3439+
iter = ERR_PTR(-EBUSY);
3440+
}
3441+
3442+
mutex_unlock(&kvm->arch.config_lock);
3443+
3444+
return iter;
3445+
}
3446+
3447+
static void *idregs_debug_next(struct seq_file *s, void *v, loff_t *pos)
3448+
{
3449+
struct kvm *kvm = s->private;
3450+
3451+
(*pos)++;
3452+
3453+
if ((kvm->arch.idreg_debugfs_iter + 1) < KVM_ARM_ID_REG_NUM) {
3454+
kvm->arch.idreg_debugfs_iter++;
3455+
3456+
return &kvm->arch.idreg_debugfs_iter;
3457+
}
3458+
3459+
return NULL;
3460+
}
3461+
3462+
static void idregs_debug_stop(struct seq_file *s, void *v)
3463+
{
3464+
struct kvm *kvm = s->private;
3465+
3466+
if (IS_ERR(v))
3467+
return;
3468+
3469+
mutex_lock(&kvm->arch.config_lock);
3470+
3471+
kvm->arch.idreg_debugfs_iter = ~0;
3472+
3473+
mutex_unlock(&kvm->arch.config_lock);
3474+
}
3475+
3476+
static int idregs_debug_show(struct seq_file *s, void *v)
3477+
{
3478+
struct kvm *kvm = s->private;
3479+
const struct sys_reg_desc *desc;
3480+
3481+
desc = first_idreg + kvm->arch.idreg_debugfs_iter;
3482+
3483+
if (!desc->name)
3484+
return 0;
3485+
3486+
seq_printf(s, "%20s:\t%016llx\n",
3487+
desc->name, IDREG(kvm, IDX_IDREG(kvm->arch.idreg_debugfs_iter)));
3488+
3489+
return 0;
3490+
}
3491+
3492+
static const struct seq_operations idregs_debug_sops = {
3493+
.start = idregs_debug_start,
3494+
.next = idregs_debug_next,
3495+
.stop = idregs_debug_stop,
3496+
.show = idregs_debug_show,
3497+
};
3498+
3499+
DEFINE_SEQ_ATTRIBUTE(idregs_debug);
3500+
34253501
static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
34263502
{
34273503
const struct sys_reg_desc *idreg = first_idreg;
@@ -3441,6 +3517,11 @@ static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
34413517
id = reg_to_encoding(idreg);
34423518
}
34433519

3520+
kvm->arch.idreg_debugfs_iter = ~0;
3521+
3522+
debugfs_create_file("idregs", 0444, kvm->debugfs_dentry, kvm,
3523+
&idregs_debug_fops);
3524+
34443525
set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
34453526
}
34463527

0 commit comments

Comments
 (0)