Skip to content

Commit 3ce9f33

Browse files
ouptonMarc Zyngier
authored andcommitted
KVM: arm64: Fold DBGxVR/DBGxCR accessors into common set
There is a nauseating amount of boilerplate for accessing the breakpoint and watchpoint registers. Fold everything together into a single set of accessors and select the right storage based on the sysreg encoding. Signed-off-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 8c02c2b commit 3ce9f33

File tree

1 file changed

+69
-128
lines changed

1 file changed

+69
-128
lines changed

arch/arm64/kvm/sys_regs.c

Lines changed: 69 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -658,143 +658,78 @@ static void dbg_to_reg(struct kvm_vcpu *vcpu,
658658
p->regval = (*dbg_reg & mask) >> shift;
659659
}
660660

661-
static bool trap_bvr(struct kvm_vcpu *vcpu,
662-
struct sys_reg_params *p,
663-
const struct sys_reg_desc *rd)
664-
{
665-
u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm];
666-
667-
if (p->is_write)
668-
reg_to_dbg(vcpu, p, rd, dbg_reg);
669-
else
670-
dbg_to_reg(vcpu, p, rd, dbg_reg);
671-
672-
return true;
673-
}
674-
675-
static int set_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
676-
u64 val)
677-
{
678-
vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm] = val;
679-
return 0;
680-
}
681-
682-
static int get_bvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
683-
u64 *val)
684-
{
685-
*val = vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm];
686-
return 0;
661+
static u64 *demux_wb_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd)
662+
{
663+
struct kvm_guest_debug_arch *dbg = &vcpu->arch.vcpu_debug_state;
664+
665+
switch (rd->Op2) {
666+
case 0b100:
667+
return &dbg->dbg_bvr[rd->CRm];
668+
case 0b101:
669+
return &dbg->dbg_bcr[rd->CRm];
670+
case 0b110:
671+
return &dbg->dbg_wvr[rd->CRm];
672+
case 0b111:
673+
return &dbg->dbg_wcr[rd->CRm];
674+
default:
675+
KVM_BUG_ON(1, vcpu->kvm);
676+
return NULL;
677+
}
687678
}
688679

689-
static u64 reset_bvr(struct kvm_vcpu *vcpu,
690-
const struct sys_reg_desc *rd)
680+
static bool trap_dbg_wb_reg(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
681+
const struct sys_reg_desc *rd)
691682
{
692-
vcpu->arch.vcpu_debug_state.dbg_bvr[rd->CRm] = rd->val;
693-
return rd->val;
694-
}
683+
u64 *reg = demux_wb_reg(vcpu, rd);
695684

696-
static bool trap_bcr(struct kvm_vcpu *vcpu,
697-
struct sys_reg_params *p,
698-
const struct sys_reg_desc *rd)
699-
{
700-
u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm];
685+
if (!reg)
686+
return false;
701687

702688
if (p->is_write)
703-
reg_to_dbg(vcpu, p, rd, dbg_reg);
689+
reg_to_dbg(vcpu, p, rd, reg);
704690
else
705-
dbg_to_reg(vcpu, p, rd, dbg_reg);
691+
dbg_to_reg(vcpu, p, rd, reg);
706692

707693
return true;
708694
}
709695

710-
static int set_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
711-
u64 val)
712-
{
713-
vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm] = val;
714-
return 0;
715-
}
716-
717-
static int get_bcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
718-
u64 *val)
719-
{
720-
*val = vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm];
721-
return 0;
722-
}
723-
724-
static u64 reset_bcr(struct kvm_vcpu *vcpu,
725-
const struct sys_reg_desc *rd)
696+
static int set_dbg_wb_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
697+
u64 val)
726698
{
727-
vcpu->arch.vcpu_debug_state.dbg_bcr[rd->CRm] = rd->val;
728-
return rd->val;
729-
}
699+
u64 *reg = demux_wb_reg(vcpu, rd);
730700

731-
static bool trap_wvr(struct kvm_vcpu *vcpu,
732-
struct sys_reg_params *p,
733-
const struct sys_reg_desc *rd)
734-
{
735-
u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm];
736-
737-
if (p->is_write)
738-
reg_to_dbg(vcpu, p, rd, dbg_reg);
739-
else
740-
dbg_to_reg(vcpu, p, rd, dbg_reg);
741-
742-
return true;
743-
}
744-
745-
static int set_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
746-
u64 val)
747-
{
748-
vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm] = val;
749-
return 0;
750-
}
701+
if (!reg)
702+
return -EINVAL;
751703

752-
static int get_wvr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
753-
u64 *val)
754-
{
755-
*val = vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm];
704+
*reg = val;
756705
return 0;
757706
}
758707

759-
static u64 reset_wvr(struct kvm_vcpu *vcpu,
760-
const struct sys_reg_desc *rd)
761-
{
762-
vcpu->arch.vcpu_debug_state.dbg_wvr[rd->CRm] = rd->val;
763-
return rd->val;
764-
}
765-
766-
static bool trap_wcr(struct kvm_vcpu *vcpu,
767-
struct sys_reg_params *p,
768-
const struct sys_reg_desc *rd)
708+
static int get_dbg_wb_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
709+
u64 *val)
769710
{
770-
u64 *dbg_reg = &vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm];
771-
772-
if (p->is_write)
773-
reg_to_dbg(vcpu, p, rd, dbg_reg);
774-
else
775-
dbg_to_reg(vcpu, p, rd, dbg_reg);
711+
u64 *reg = demux_wb_reg(vcpu, rd);
776712

777-
return true;
778-
}
713+
if (!reg)
714+
return -EINVAL;
779715

780-
static int set_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
781-
u64 val)
782-
{
783-
vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm] = val;
716+
*val = *reg;
784717
return 0;
785718
}
786719

787-
static int get_wcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
788-
u64 *val)
720+
static u64 reset_dbg_wb_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd)
789721
{
790-
*val = vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm];
791-
return 0;
792-
}
722+
u64 *reg = demux_wb_reg(vcpu, rd);
793723

794-
static u64 reset_wcr(struct kvm_vcpu *vcpu,
795-
const struct sys_reg_desc *rd)
796-
{
797-
vcpu->arch.vcpu_debug_state.dbg_wcr[rd->CRm] = rd->val;
724+
/*
725+
* Bail early if we couldn't find storage for the register, the
726+
* KVM_BUG_ON() in demux_wb_reg() will prevent this VM from ever
727+
* being run.
728+
*/
729+
if (!reg)
730+
return 0;
731+
732+
*reg = rd->val;
798733
return rd->val;
799734
}
800735

@@ -1303,13 +1238,17 @@ static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
13031238
/* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
13041239
#define DBG_BCR_BVR_WCR_WVR_EL1(n) \
13051240
{ SYS_DESC(SYS_DBGBVRn_EL1(n)), \
1306-
trap_bvr, reset_bvr, 0, 0, get_bvr, set_bvr }, \
1241+
trap_dbg_wb_reg, reset_dbg_wb_reg, 0, 0, \
1242+
get_dbg_wb_reg, set_dbg_wb_reg }, \
13071243
{ SYS_DESC(SYS_DBGBCRn_EL1(n)), \
1308-
trap_bcr, reset_bcr, 0, 0, get_bcr, set_bcr }, \
1244+
trap_dbg_wb_reg, reset_dbg_wb_reg, 0, 0, \
1245+
get_dbg_wb_reg, set_dbg_wb_reg }, \
13091246
{ SYS_DESC(SYS_DBGWVRn_EL1(n)), \
1310-
trap_wvr, reset_wvr, 0, 0, get_wvr, set_wvr }, \
1247+
trap_dbg_wb_reg, reset_dbg_wb_reg, 0, 0, \
1248+
get_dbg_wb_reg, set_dbg_wb_reg }, \
13111249
{ SYS_DESC(SYS_DBGWCRn_EL1(n)), \
1312-
trap_wcr, reset_wcr, 0, 0, get_wcr, set_wcr }
1250+
trap_dbg_wb_reg, reset_dbg_wb_reg, 0, 0, \
1251+
get_dbg_wb_reg, set_dbg_wb_reg }
13131252

13141253
#define PMU_SYS_REG(name) \
13151254
SYS_DESC(SYS_##name), .reset = reset_pmu_reg, \
@@ -3523,18 +3462,20 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
35233462
* None of the other registers share their location, so treat them as
35243463
* if they were 64bit.
35253464
*/
3526-
#define DBG_BCR_BVR_WCR_WVR(n) \
3527-
/* DBGBVRn */ \
3528-
{ AA32(LO), Op1( 0), CRn( 0), CRm((n)), Op2( 4), trap_bvr, NULL, n }, \
3529-
/* DBGBCRn */ \
3530-
{ Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_bcr, NULL, n }, \
3531-
/* DBGWVRn */ \
3532-
{ Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_wvr, NULL, n }, \
3533-
/* DBGWCRn */ \
3534-
{ Op1( 0), CRn( 0), CRm((n)), Op2( 7), trap_wcr, NULL, n }
3535-
3536-
#define DBGBXVR(n) \
3537-
{ AA32(HI), Op1( 0), CRn( 1), CRm((n)), Op2( 1), trap_bvr, NULL, n }
3465+
#define DBG_BCR_BVR_WCR_WVR(n) \
3466+
/* DBGBVRn */ \
3467+
{ AA32(LO), Op1( 0), CRn( 0), CRm((n)), Op2( 4), \
3468+
trap_dbg_wb_reg, NULL, n }, \
3469+
/* DBGBCRn */ \
3470+
{ Op1( 0), CRn( 0), CRm((n)), Op2( 5), trap_dbg_wb_reg, NULL, n }, \
3471+
/* DBGWVRn */ \
3472+
{ Op1( 0), CRn( 0), CRm((n)), Op2( 6), trap_dbg_wb_reg, NULL, n }, \
3473+
/* DBGWCRn */ \
3474+
{ Op1( 0), CRn( 0), CRm((n)), Op2( 7), trap_dbg_wb_reg, NULL, n }
3475+
3476+
#define DBGBXVR(n) \
3477+
{ AA32(HI), Op1( 0), CRn( 1), CRm((n)), Op2( 1), \
3478+
trap_dbg_wb_reg, NULL, n }
35383479

35393480
/*
35403481
* Trapped cp14 registers. We generally ignore most of the external

0 commit comments

Comments
 (0)