Hi Greg,

On Sun, Nov 25, 2018 at 10:13:52AM -0800, Greg Steuck wrote:
> Hi Anton,
> 
> I tried to boot a kernel with kcov based on GENERIC.MP and the machine
> reboots without a peep immediately after
> 
> vmm0 at mainbus0: VMX (using slow L1TF mitigation)
> 
> Switching off either of kcov or MP results in normally working kernels. I'm
> attaching two concatenated dmesgs. The effect is reproducible on real HW
> and on GCE VM. Broken config is just:
> $ cat /sys/arch/amd64/conf/SYZKALLER
> include "arch/amd64/conf/GENERIC.MP"
> pseudo-device kcov 1
> 
> Disabling either vmm or kcov in broken kernel UKC doesn't prevent crashes.

Known limitation, I haven't spent much time on making kcov MP-safe.
Especially since it's primarily used inside a VM through vmm which
currently is limited to a single CPU.

However, I did some investigation before and concluded that the problem
resides in the trace routine which is called from
cpu_boot_secondary_processors() before the secondary CPU is accessible
through curcpu(). I came up with a hackish solution to this problem (see
diff below) that got rejected; kettenis@ mentioned that we instead
should set MSR_GSBASE earlier in cpu_hatch() but I never managed to get
the right people involved with knowledge in this area. I might take a
look myself.

In the meantime, you could give the diff a try. It might be the case
that more functions are not eligible for tracing. OpenBSD as no method
of turning of tracing for a given source file like Linux does. This
might become necessary since I fear many more functions will not cope
with tracing.

Index: dev/kcov.c
===================================================================
RCS file: /cvs/src/sys/dev/kcov.c,v
retrieving revision 1.4
diff -u -p -r1.4 kcov.c
--- dev/kcov.c  27 Aug 2018 15:57:39 -0000      1.4
+++ dev/kcov.c  8 Sep 2018 21:51:20 -0000
@@ -49,6 +49,7 @@ struct kcov_dev {
 };
 
 void kcovattach(int);
+void kcov_attachhook(struct device *);
 
 int kd_alloc(struct kcov_dev *, unsigned long);
 void kd_free(struct kcov_dev *);
@@ -57,6 +58,7 @@ struct kcov_dev *kd_lookup(int);
 static inline int inintr(void);
 
 TAILQ_HEAD(, kcov_dev) kd_list = TAILQ_HEAD_INITIALIZER(kd_list);
+int kcov_attached = 0;
 
 #ifdef KCOV_DEBUG
 int kcov_debug = 1;
@@ -76,12 +78,11 @@ int kcov_debug = 1;
 void
 __sanitizer_cov_trace_pc(void)
 {
-       extern int cold;
        struct kcov_dev *kd;
        uint64_t idx;
 
-       /* Do not trace during boot. */
-       if (cold)
+       /* Do not trace before the root file system is mounted. */
+       if (!kcov_attached)
                return;
 
        /* Do not trace in interrupts to prevent noisy coverage. */
@@ -102,6 +103,13 @@ __sanitizer_cov_trace_pc(void)
 void
 kcovattach(int count)
 {
+       config_mountroot(NULL, kcov_attachhook);
+}
+
+void
+kcov_attachhook(struct device *dev)
+{
+       kcov_attached = 1;
 }
 
 int

Reply via email to