Skip to content

Commit e1dda3a

Browse files
minipli-osssean-jc
authored andcommitted
KVM: x86: Fix broken debugregs ABI for 32 bit kernels
The ioctl()s to get and set KVM's debug registers are broken for 32 bit kernels as they'd only copy half of the user register state because of a UAPI and in-kernel type mismatch (__u64 vs. unsigned long; 8 vs. 4 bytes). This makes it impossible for userland to set anything but DR0 without resorting to bit folding tricks. Switch to a loop for copying debug registers that'll implicitly do the type conversion for us, if needed. There are likely no users (left) for 32bit KVM, fix the bug nonetheless. Fixes: a1efbe7 ("KVM: x86: Add support for saving&restoring debug registers") Signed-off-by: Mathias Krause <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sean Christopherson <[email protected]>
1 parent 955997e commit e1dda3a

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

arch/x86/kvm/x86.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5510,9 +5510,14 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
55105510
struct kvm_debugregs *dbgregs)
55115511
{
55125512
unsigned long val;
5513+
unsigned int i;
55135514

55145515
memset(dbgregs, 0, sizeof(*dbgregs));
5515-
memcpy(dbgregs->db, vcpu->arch.db, sizeof(vcpu->arch.db));
5516+
5517+
BUILD_BUG_ON(ARRAY_SIZE(vcpu->arch.db) != ARRAY_SIZE(dbgregs->db));
5518+
for (i = 0; i < ARRAY_SIZE(vcpu->arch.db); i++)
5519+
dbgregs->db[i] = vcpu->arch.db[i];
5520+
55165521
kvm_get_dr(vcpu, 6, &val);
55175522
dbgregs->dr6 = val;
55185523
dbgregs->dr7 = vcpu->arch.dr7;
@@ -5521,6 +5526,8 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
55215526
static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
55225527
struct kvm_debugregs *dbgregs)
55235528
{
5529+
unsigned int i;
5530+
55245531
if (dbgregs->flags)
55255532
return -EINVAL;
55265533

@@ -5529,7 +5536,9 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
55295536
if (!kvm_dr7_valid(dbgregs->dr7))
55305537
return -EINVAL;
55315538

5532-
memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
5539+
for (i = 0; i < ARRAY_SIZE(vcpu->arch.db); i++)
5540+
vcpu->arch.db[i] = dbgregs->db[i];
5541+
55335542
kvm_update_dr0123(vcpu);
55345543
vcpu->arch.dr6 = dbgregs->dr6;
55355544
vcpu->arch.dr7 = dbgregs->dr7;

0 commit comments

Comments
 (0)