2021-02-02 09:04:53

by Chenyi Qiang

[permalink] [raw]
Subject: [PATCH v2 0/3] Add KVM support for bus lock debug exception

A bus lock is acquired either through split locked access to writeback
(WB) memory or by using locks to uncacheable (UC) memory. This is
typically > 1000 cycles slower than atomic opertaion within a cache
line. It also disrupts performance on other cores.

Bus lock debug exception is a sub-feature of bus lock detection. It is
an ability to notify the kernel by an #DB trap after the instruction
acquires a bus lock when CPL>0. This allows the kernel to enforce user
application throttling or mitigatioins.

Expose the bus lock debug exception to guest by the enumeration of
CPUID.(EAX=7,ECX=0).ECX[24]. Software in guest can enable these
exceptions by setting the DEBUGCTLMSR_BUS_LOCK_DETECT(bit 2) of
MSR_IA32_DEBUTCTL.

The bus lock #DB exception can also be intercepted by the VMM and
identified through the bit 11 of the exit qualification at VM exit. The
bit 11 (DR6_BUS_LOCK) of DR6 register is introduced to indicate a bus
lock #DB exception. DR6_BUS_LOCK has formerly always been 1 and delivery
of a bus lock #DB clears it. The VMM should emulate the exceptions by
clearing the bit 11 of the guest DR6.

Bus lock debug exception kernel patches are available at:
https://lore.kernel.org/lkml/[email protected]

Document for Bus Lock Detection is now available at the latest "Intel
Architecture Instruction Set Extensions Programming Reference".

Document Link:
https://software.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.html

---

Changelogs

v1->v2:
- rename the DR6_INIT to DR6_LOW_ACTIVE suggested by Paolo and split it
out as a new commit.
- KVM v1:https://lore.kernel.org/lkml/[email protected]


Chenyi Qiang (3):
KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW
KVM: X86: Add support for the emulation of DR6_BUS_LOCK bit
KVM: X86: Expose bus lock debug exception to guest

arch/x86/include/asm/kvm_host.h | 14 +++++++--
arch/x86/kvm/cpuid.c | 3 +-
arch/x86/kvm/emulate.c | 2 +-
arch/x86/kvm/svm/nested.c | 2 +-
arch/x86/kvm/svm/svm.c | 6 ++--
arch/x86/kvm/vmx/nested.c | 4 +--
arch/x86/kvm/vmx/vmx.c | 27 ++++++++++++++---
arch/x86/kvm/x86.c | 52 +++++++++++++++------------------
arch/x86/kvm/x86.h | 2 ++
9 files changed, 69 insertions(+), 43 deletions(-)

--
2.17.1


2021-02-02 09:05:06

by Chenyi Qiang

[permalink] [raw]
Subject: [PATCH v2 2/3] KVM: X86: Add support for the emulation of DR6_BUS_LOCK bit

Bus lock debug exception introduces a new bit DR6_BUS_LOCK (bit 11 of
DR6) to indicate that bus lock #DB exception is generated. The set/clear
of DR6_BUS_LOCK is similar to the DR6_RTM. The processor clears
DR6_BUS_LOCK when the exception is generated. For all other #DB, the
processor sets this bit to 1. Software #DB handler should set this bit
before returning to the interrupted task.

In VMM, to avoid breaking the CPUs without bus lock #DB exception
support, activate the DR6_BUS_LOCK conditionally in DR6_FIXED_1 bits.
When intercepting the #DB exception caused by bus locks, bit 11 of the
exit qualification is set to identify it. The VMM should emulate the
exception by clearing the bit 11 of the guest DR6.

Co-developed-by: Xiaoyao Li <[email protected]>
Signed-off-by: Xiaoyao Li <[email protected]>
Signed-off-by: Chenyi Qiang <[email protected]>
---
arch/x86/include/asm/kvm_host.h | 5 +++--
arch/x86/kvm/x86.c | 3 +++
2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 5b80f92a7fde..44d790cff6aa 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -196,11 +196,12 @@ enum x86_intercept_stage;

#define KVM_NR_DB_REGS 4

+#define DR6_BUS_LOCK (1 << 11)
#define DR6_BD (1 << 13)
#define DR6_BS (1 << 14)
#define DR6_BT (1 << 15)
#define DR6_RTM (1 << 16)
-#define DR6_FIXED_1 0xfffe0ff0
+#define DR6_FIXED_1 0xfffe07f0
/*
* DR6_ACTIVE_LOW is actual the result of DR6_FIXED_1 | ACTIVE_LOW_BITS.
* We can regard all the current FIXED_1 bits as active_low bits even
@@ -209,7 +210,7 @@ enum x86_intercept_stage;
* At the same time, it can be served as the init/reset value for DR6.
*/
#define DR6_ACTIVE_LOW 0xffff0ff0
-#define DR6_VOLATILE 0x0001e00f
+#define DR6_VOLATILE 0x0001e80f

#define DR7_BP_EN_MASK 0x000000ff
#define DR7_GE (1 << 9)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1946e6710919..e149cb2c921c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1131,6 +1131,9 @@ static u64 kvm_dr6_fixed(struct kvm_vcpu *vcpu)

if (!guest_cpuid_has(vcpu, X86_FEATURE_RTM))
fixed |= DR6_RTM;
+
+ if (!guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT))
+ fixed |= DR6_BUS_LOCK;
return fixed;
}

--
2.17.1

2021-02-02 09:05:07

by Chenyi Qiang

[permalink] [raw]
Subject: [PATCH v2 3/3] KVM: X86: Expose bus lock debug exception to guest

Bus lock debug exception is an ability to notify the kernel by an #DB
trap after the instruction acquires a bus lock and is executed when
CPL>0. This allows the kernel to enforce user application throttling or
mitigations.

Existence of bus lock debug exception is enumerated via
CPUID.(EAX=7,ECX=0).ECX[24]. Software can enable these exceptions by
setting bit 2 of the MSR_IA32_DEBUGCTL. Expose the CPUID to guest and
emulate the MSR handling when guest enables it.

Since SVM already has specific handlers of MSR_IA32_DEBUGMSR in the
svm_get/set_msr, move x86 commmon part to VMX and add the bus lock debug
exception support.

Co-developed-by: Xiaoyao Li <[email protected]>
Signed-off-by: Xiaoyao Li <[email protected]>
Signed-off-by: Chenyi Qiang <[email protected]>
---
arch/x86/kvm/cpuid.c | 3 ++-
arch/x86/kvm/vmx/vmx.c | 23 +++++++++++++++++++++--
arch/x86/kvm/x86.c | 16 ++--------------
arch/x86/kvm/x86.h | 2 ++
4 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 13036cf0b912..ea7c593794d2 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -402,7 +402,8 @@ void kvm_set_cpu_caps(void)
F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) |
F(AVX512_VPOPCNTDQ) | F(UMIP) | F(AVX512_VBMI2) | F(GFNI) |
F(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) |
- F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/
+ F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/ |
+ F(BUS_LOCK_DETECT)
);
/* Set LA57 based on hardware capability. */
if (cpuid_ecx(7) & F(LA57))
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index ae79284e6199..e1d2b5db1179 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -147,6 +147,9 @@ module_param(allow_smaller_maxphyaddr, bool, S_IRUGO);
RTIT_STATUS_ERROR | RTIT_STATUS_STOPPED | \
RTIT_STATUS_BYTECNT))

+#define MSR_VMX_SUPPORTED_DEBUGCTL (DEBUGCTLMSR_LBR | \
+ DEBUGCTLMSR_BTF | DEBUGCTLMSR_BUS_LOCK_DETECT)
+
/*
* List of MSRs that can be directly passed to the guest.
* In addition to these x2apic and PT MSRs are handled specially.
@@ -1924,6 +1927,9 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
!guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP))
return 1;
goto find_uret_msr;
+ case MSR_IA32_DEBUGCTLMSR:
+ msr_info->data = vmcs_read64(GUEST_IA32_DEBUGCTL);
+ break;
default:
find_uret_msr:
msr = vmx_find_uret_msr(vmx, msr_info->index);
@@ -2002,9 +2008,22 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
VM_EXIT_SAVE_DEBUG_CONTROLS)
get_vmcs12(vcpu)->guest_ia32_debugctl = data;

- ret = kvm_set_msr_common(vcpu, msr_info);
- break;
+ if (data & ~MSR_VMX_SUPPORTED_DEBUGCTL)
+ return 1;

+ if (!msr_info->host_initiated &&
+ (data & DEBUGCTLMSR_BUS_LOCK_DETECT) &&
+ !guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT))
+ return 1;
+
+ if (data & (DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR)) {
+ if (report_ignored_msrs)
+ vcpu_unimpl(vcpu, "%s: BTF|LBR in IA32_DEBUGCTLMSR 0x%llx, nop\n",
+ __func__, data);
+ data &= ~(DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR);
+ }
+ vmcs_write64(GUEST_IA32_DEBUGCTL, data);
+ return 0;
case MSR_IA32_BNDCFGS:
if (!kvm_mpx_supported() ||
(!msr_info->host_initiated &&
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e149cb2c921c..0e66acffa2e9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -116,8 +116,9 @@ EXPORT_SYMBOL_GPL(kvm_x86_ops);
static bool __read_mostly ignore_msrs = 0;
module_param(ignore_msrs, bool, S_IRUGO | S_IWUSR);

-static bool __read_mostly report_ignored_msrs = true;
+bool __read_mostly report_ignored_msrs = true;
module_param(report_ignored_msrs, bool, S_IRUGO | S_IWUSR);
+EXPORT_SYMBOL_GPL(report_ignored_msrs);

unsigned int min_timer_period_us = 200;
module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR);
@@ -3071,18 +3072,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
return 1;
}
break;
- case MSR_IA32_DEBUGCTLMSR:
- if (!data) {
- /* We support the non-activated case already */
- break;
- } else if (data & ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_BTF)) {
- /* Values other than LBR and BTF are vendor-specific,
- thus reserved and should throw a #GP */
- return 1;
- } else if (report_ignored_msrs)
- vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n",
- __func__, data);
- break;
case 0x200 ... 0x2ff:
return kvm_mtrr_set_msr(vcpu, msr, data);
case MSR_IA32_APICBASE:
@@ -3355,7 +3344,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
switch (msr_info->index) {
case MSR_IA32_PLATFORM_ID:
case MSR_IA32_EBL_CR_POWERON:
- case MSR_IA32_DEBUGCTLMSR:
case MSR_IA32_LASTBRANCHFROMIP:
case MSR_IA32_LASTBRANCHTOIP:
case MSR_IA32_LASTINTFROMIP:
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index c5ee0f5ce0f1..f13aa386e536 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -296,6 +296,8 @@ extern int pi_inject_timer;

extern struct static_key kvm_no_apic_vcpu;

+extern bool report_ignored_msrs;
+
static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
{
return pvclock_scale_delta(nsec, vcpu->arch.virtual_tsc_mult,
--
2.17.1

2021-02-02 09:06:22

by Chenyi Qiang

[permalink] [raw]
Subject: [PATCH v2 1/3] KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW

DR6_INIT contains the 1-reserved bits as well as the bit that is cleared
to 0 when the condition (e.g. RTM) happens. The value can be used to
initialize dr6 and also be the XOR mask between the #DB exit
qualification (or payload) and DR6.

Concerning that DR6_INIT is used as initial value only once, rename it
to DR6_ACTIVE_LOW and apply it in other places, which would make the
incoming changes for bus lock debug exception more simple.

Signed-off-by: Chenyi Qiang <[email protected]>
---
arch/x86/include/asm/kvm_host.h | 9 ++++++++-
arch/x86/kvm/emulate.c | 2 +-
arch/x86/kvm/svm/nested.c | 2 +-
arch/x86/kvm/svm/svm.c | 6 +++---
arch/x86/kvm/vmx/nested.c | 4 ++--
arch/x86/kvm/vmx/vmx.c | 4 ++--
arch/x86/kvm/x86.c | 33 +++++++++++++++++++--------------
7 files changed, 36 insertions(+), 24 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 3ab7b46087b7..5b80f92a7fde 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -201,7 +201,14 @@ enum x86_intercept_stage;
#define DR6_BT (1 << 15)
#define DR6_RTM (1 << 16)
#define DR6_FIXED_1 0xfffe0ff0
-#define DR6_INIT 0xffff0ff0
+/*
+ * DR6_ACTIVE_LOW is actual the result of DR6_FIXED_1 | ACTIVE_LOW_BITS.
+ * We can regard all the current FIXED_1 bits as active_low bits even
+ * though in no case they will be turned into 0. But if they are defined
+ * in the future, it will require no code change.
+ * At the same time, it can be served as the init/reset value for DR6.
+ */
+#define DR6_ACTIVE_LOW 0xffff0ff0
#define DR6_VOLATILE 0x0001e00f

#define DR7_BP_EN_MASK 0x000000ff
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 56cae1ff9e3f..db78ade570f0 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -4327,7 +4327,7 @@ static int check_dr_read(struct x86_emulate_ctxt *ctxt)

ctxt->ops->get_dr(ctxt, 6, &dr6);
dr6 &= ~DR_TRAP_BITS;
- dr6 |= DR6_BD | DR6_RTM;
+ dr6 |= DR6_BD | DR6_ACTIVE_LOW;
ctxt->ops->set_dr(ctxt, 6, dr6);
return emulate_db(ctxt);
}
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index b0b667456b2e..6db85fbcf5d0 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -395,7 +395,7 @@ static void nested_prepare_vmcb_save(struct vcpu_svm *svm, struct vmcb *vmcb12)
svm->vmcb->save.rsp = vmcb12->save.rsp;
svm->vmcb->save.rip = vmcb12->save.rip;
svm->vmcb->save.dr7 = vmcb12->save.dr7 | DR7_FIXED_1;
- svm->vcpu.arch.dr6 = vmcb12->save.dr6 | DR6_FIXED_1 | DR6_RTM;
+ svm->vcpu.arch.dr6 = vmcb12->save.dr6 | DR6_ACTIVE_LOW;
svm->vmcb->save.cpl = vmcb12->save.cpl;
}

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index cce0143a6f80..eaf1c523d16a 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1860,7 +1860,7 @@ static void svm_sync_dirty_debug_regs(struct kvm_vcpu *vcpu)
get_debugreg(vcpu->arch.db[2], 2);
get_debugreg(vcpu->arch.db[3], 3);
/*
- * We cannot reset svm->vmcb->save.dr6 to DR6_FIXED_1|DR6_RTM here,
+ * We cannot reset svm->vmcb->save.dr6 to DR6_ACTIVE_LOW here,
* because db_interception might need it. We can do it before vmentry.
*/
vcpu->arch.dr6 = svm->vmcb->save.dr6;
@@ -1911,7 +1911,7 @@ static int db_interception(struct vcpu_svm *svm)
if (!(svm->vcpu.guest_debug &
(KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) &&
!svm->nmi_singlestep) {
- u32 payload = (svm->vmcb->save.dr6 ^ DR6_RTM) & ~DR6_FIXED_1;
+ u32 payload = svm->vmcb->save.dr6 ^ DR6_ACTIVE_LOW;
kvm_queue_exception_p(&svm->vcpu, DB_VECTOR, payload);
return 1;
}
@@ -3778,7 +3778,7 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu)
if (unlikely(svm->vcpu.arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT))
svm_set_dr6(svm, vcpu->arch.dr6);
else
- svm_set_dr6(svm, DR6_FIXED_1 | DR6_RTM);
+ svm_set_dr6(svm, DR6_ACTIVE_LOW);

clgi();
kvm_load_guest_xsave_state(vcpu);
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index e2f26564a12d..ef72278e67bb 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -411,8 +411,8 @@ static int nested_vmx_check_exception(struct kvm_vcpu *vcpu, unsigned long *exit
if (nr == DB_VECTOR) {
if (!has_payload) {
payload = vcpu->arch.dr6;
- payload &= ~(DR6_FIXED_1 | DR6_BT);
- payload ^= DR6_RTM;
+ payload &= ~DR6_BT;
+ payload ^= DR6_ACTIVE_LOW;
}
*exit_qual = payload;
} else
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 75c9c6a0a3a4..ae79284e6199 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -4824,7 +4824,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
kvm_queue_exception_p(vcpu, DB_VECTOR, dr6);
return 1;
}
- kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1 | DR6_RTM;
+ kvm_run->debug.arch.dr6 = dr6 | DR6_ACTIVE_LOW;
kvm_run->debug.arch.dr7 = vmcs_readl(GUEST_DR7);
fallthrough;
case BP_VECTOR:
@@ -5068,7 +5068,7 @@ static int handle_dr(struct kvm_vcpu *vcpu)
* guest debugging itself.
*/
if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
- vcpu->run->debug.arch.dr6 = DR6_BD | DR6_RTM | DR6_FIXED_1;
+ vcpu->run->debug.arch.dr6 = DR6_BD | DR6_ACTIVE_LOW;
vcpu->run->debug.arch.dr7 = dr7;
vcpu->run->debug.arch.pc = kvm_get_linear_rip(vcpu);
vcpu->run->debug.arch.exception = DB_VECTOR;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3f7c1fc7a3ce..1946e6710919 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -483,19 +483,24 @@ void kvm_deliver_exception_payload(struct kvm_vcpu *vcpu)
*/
vcpu->arch.dr6 &= ~DR_TRAP_BITS;
/*
- * DR6.RTM is set by all #DB exceptions that don't clear it.
+ * In order to reflect the #DB exception payload in guest
+ * dr6, three components need to be considered: active low
+ * bit, FIXED_1 bits and active high bits (e.g. DR6_BD,
+ * DR6_BS and DR6_BT)
+ * DR6_ACTIVE_LOW contains the FIXED_1 and active low bits.
+ * In the target guest dr6:
+ * FIXED_1 bits should always be set.
+ * Active low bits should be cleared if 1-setting in payload.
+ * Active high bits should be set if 1-setting in payload.
+ *
+ * Note, the payload is compatible with the pending debug
+ * exceptions/exit qualification under VMX, that active_low bits
+ * are active high in payload.
+ * So they need to be flipped for DR6.
*/
- vcpu->arch.dr6 |= DR6_RTM;
+ vcpu->arch.dr6 |= DR6_ACTIVE_LOW;
vcpu->arch.dr6 |= payload;
- /*
- * Bit 16 should be set in the payload whenever the #DB
- * exception should clear DR6.RTM. This makes the payload
- * compatible with the pending debug exceptions under VMX.
- * Though not currently documented in the SDM, this also
- * makes the payload compatible with the exit qualification
- * for #DB exceptions under VMX.
- */
- vcpu->arch.dr6 ^= payload & DR6_RTM;
+ vcpu->arch.dr6 ^= payload & DR6_ACTIVE_LOW;

/*
* The #DB payload is defined as compatible with the 'pending
@@ -7197,7 +7202,7 @@ static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu)
struct kvm_run *kvm_run = vcpu->run;

if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
- kvm_run->debug.arch.dr6 = DR6_BS | DR6_FIXED_1 | DR6_RTM;
+ kvm_run->debug.arch.dr6 = DR6_BS | DR6_ACTIVE_LOW;
kvm_run->debug.arch.pc = kvm_get_linear_rip(vcpu);
kvm_run->debug.arch.exception = DB_VECTOR;
kvm_run->exit_reason = KVM_EXIT_DEBUG;
@@ -7241,7 +7246,7 @@ static bool kvm_vcpu_check_breakpoint(struct kvm_vcpu *vcpu, int *r)
vcpu->arch.eff_db);

if (dr6 != 0) {
- kvm_run->debug.arch.dr6 = dr6 | DR6_FIXED_1 | DR6_RTM;
+ kvm_run->debug.arch.dr6 = dr6 | DR6_ACTIVE_LOW;
kvm_run->debug.arch.pc = eip;
kvm_run->debug.arch.exception = DB_VECTOR;
kvm_run->exit_reason = KVM_EXIT_DEBUG;
@@ -10086,7 +10091,7 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)

memset(vcpu->arch.db, 0, sizeof(vcpu->arch.db));
kvm_update_dr0123(vcpu);
- vcpu->arch.dr6 = DR6_INIT;
+ vcpu->arch.dr6 = DR6_ACTIVE_LOW;
vcpu->arch.dr7 = DR7_FIXED_1;
kvm_update_dr7(vcpu);

--
2.17.1

2021-02-02 22:29:14

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW

On 02/02/21 10:04, Chenyi Qiang wrote:
>
> #define DR6_FIXED_1 0xfffe0ff0
> -#define DR6_INIT 0xffff0ff0
> +/*
> + * DR6_ACTIVE_LOW is actual the result of DR6_FIXED_1 | ACTIVE_LOW_BITS.
> + * We can regard all the current FIXED_1 bits as active_low bits even
> + * though in no case they will be turned into 0. But if they are defined
> + * in the future, it will require no code change.
> + * At the same time, it can be served as the init/reset value for DR6.
> + */
> +#define DR6_ACTIVE_LOW 0xffff0ff0
> #define DR6_VOLATILE 0x0001e00f
>

Committed with some changes in the wording of the comment.

Also, DR6_FIXED_1 is (DR6_ACTIVE_LOW & ~DR6_VOLATILE).

Paolo

2021-02-02 22:31:36

by Xiaoyao Li

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW

On 2/2/2021 10:49 PM, Paolo Bonzini wrote:
> On 02/02/21 10:04, Chenyi Qiang wrote:
>>
>>  #define DR6_FIXED_1    0xfffe0ff0
>> -#define DR6_INIT    0xffff0ff0
>> +/*
>> + * DR6_ACTIVE_LOW is actual the result of DR6_FIXED_1 | ACTIVE_LOW_BITS.
>> + * We can regard all the current FIXED_1 bits as active_low bits even
>> + * though in no case they will be turned into 0. But if they are defined
>> + * in the future, it will require no code change.
>> + * At the same time, it can be served as the init/reset value for DR6.
>> + */
>> +#define DR6_ACTIVE_LOW    0xffff0ff0
>>  #define DR6_VOLATILE    0x0001e00f
>>
>
> Committed with some changes in the wording of the comment.
>
> Also, DR6_FIXED_1 is (DR6_ACTIVE_LOW & ~DR6_VOLATILE).

Maybe we can add BUILD_BUG_ON() to make sure the correctness?

> Paolo
>

2021-02-02 22:51:47

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW

On 02/02/21 16:02, Xiaoyao Li wrote:
> On 2/2/2021 10:49 PM, Paolo Bonzini wrote:
>> On 02/02/21 10:04, Chenyi Qiang wrote:
>>>
>>>  #define DR6_FIXED_1    0xfffe0ff0
>>> -#define DR6_INIT    0xffff0ff0
>>> +/*
>>> + * DR6_ACTIVE_LOW is actual the result of DR6_FIXED_1 |
>>> ACTIVE_LOW_BITS.
>>> + * We can regard all the current FIXED_1 bits as active_low bits even
>>> + * though in no case they will be turned into 0. But if they are
>>> defined
>>> + * in the future, it will require no code change.
>>> + * At the same time, it can be served as the init/reset value for DR6.
>>> + */
>>> +#define DR6_ACTIVE_LOW    0xffff0ff0
>>>  #define DR6_VOLATILE    0x0001e00f
>>>
>>
>> Committed with some changes in the wording of the comment.
>>
>> Also, DR6_FIXED_1 is (DR6_ACTIVE_LOW & ~DR6_VOLATILE).
>
> Maybe we can add BUILD_BUG_ON() to make sure the correctness?

We can even

#define DR_FIXED_1 (DR6_ACTIVE_LOW & ~DR6_VOLATILE)

directly. I have pushed this patch to kvm/queue, but the other two will
have to wait for Fenghua's bare metal support.

Paolo

2021-04-02 08:55:42

by Xiaoyao Li

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW

On 2/3/2021 12:05 AM, Paolo Bonzini wrote:
> On 02/02/21 16:02, Xiaoyao Li wrote:
>> On 2/2/2021 10:49 PM, Paolo Bonzini wrote:
>>> On 02/02/21 10:04, Chenyi Qiang wrote:
>>>>
>>>>  #define DR6_FIXED_1    0xfffe0ff0
>>>> -#define DR6_INIT    0xffff0ff0
>>>> +/*
>>>> + * DR6_ACTIVE_LOW is actual the result of DR6_FIXED_1 |
>>>> ACTIVE_LOW_BITS.
>>>> + * We can regard all the current FIXED_1 bits as active_low bits even
>>>> + * though in no case they will be turned into 0. But if they are
>>>> defined
>>>> + * in the future, it will require no code change.
>>>> + * At the same time, it can be served as the init/reset value for DR6.
>>>> + */
>>>> +#define DR6_ACTIVE_LOW    0xffff0ff0
>>>>  #define DR6_VOLATILE    0x0001e00f
>>>>
>>>
>>> Committed with some changes in the wording of the comment.
>>>
>>> Also, DR6_FIXED_1 is (DR6_ACTIVE_LOW & ~DR6_VOLATILE).
>>
>> Maybe we can add BUILD_BUG_ON() to make sure the correctness?
>
> We can even
>
> #define DR_FIXED_1  (DR6_ACTIVE_LOW & ~DR6_VOLATILE)
>
> directly.  I have pushed this patch to kvm/queue, but the other two will
> have to wait for Fenghua's bare metal support.
>

Hi Paolo,

Fenghua's bare metal support is in tip tree now.
https://lore.kernel.org/lkml/[email protected]/

Will the rest KVM patches get into 5.13 together?



2021-04-02 09:02:55

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW

On 02/04/21 10:53, Xiaoyao Li wrote:
>>
>
> Hi Paolo,
>
> Fenghua's bare metal support is in tip tree now.
> https://lore.kernel.org/lkml/[email protected]/
>
> Will the rest KVM patches get into 5.13 together?

Yes, they will.

Thanks for the notice!

Paolo

2021-05-06 08:28:04

by Chenyi Qiang

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW



On 4/2/2021 5:01 PM, Paolo Bonzini wrote:
> On 02/04/21 10:53, Xiaoyao Li wrote:
>>>
>>
>> Hi Paolo,
>>
>> Fenghua's bare metal support is in tip tree now.
>> https://lore.kernel.org/lkml/[email protected]/
>>
>> Will the rest KVM patches get into 5.13 together?
>
> Yes, they will.
>
> Thanks for the notice!
>

Hi Paolo,

I notice the patch 1 is merged but the remaining patch 2 and 3 are not
included yet. The bare metal support is merged. Will the rest KVM parts
be in 5.13 as well?

> Paolo
>

2021-05-06 11:52:33

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] KVM: X86: Rename DR6_INIT to DR6_ACTIVE_LOW

On 06/05/21 10:21, Chenyi Qiang wrote:
>
>
> On 4/2/2021 5:01 PM, Paolo Bonzini wrote:
>> On 02/04/21 10:53, Xiaoyao Li wrote:
>>>>
>>>
>>> Hi Paolo,
>>>
>>> Fenghua's bare metal support is in tip tree now.
>>> https://lore.kernel.org/lkml/[email protected]/
>>>
>>>
>>> Will the rest KVM patches get into 5.13 together?
>>
>> Yes, they will.
>>
>> Thanks for the notice!
>>
>
> Hi Paolo,
>
> I notice the patch 1 is merged but the remaining patch 2 and 3 are not
> included yet. The bare metal support is merged. Will the rest KVM parts
> be in 5.13 as well?

Yes.

Paolo