Re: Oopses and invalid addresses under Hatari

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Finn,

Am 10.04.2019 um 14:42 schrieb Finn Thain:
On Wed, 10 Apr 2019, Michael Schmitz wrote:

On 10/04/19 12:58 PM, Finn Thain wrote:
On Wed, 10 Apr 2019, Michael Schmitz wrote:

A potentially good question is why kthread_probe_data() would return
NULL on 030:
----------------------------
/**
  * kthread_probe_data - speculative version of kthread_data()
  * @task: possible kthread task in question
  *
  * @task could be a kthread task.  Return the data value specified when
it
  * was created if accessible.  If @task isn't a kthread task or its
data is
  * inaccessible for any reason, %NULL is returned.  This function
requires
  * that @task itself is safe to dereference.
  */
void *kthread_probe_data(struct task_struct *task)
{
         struct kthread *kthread = to_kthread(task);
         void *data = NULL;

         probe_kernel_read(&data, &kthread->data, sizeof(data));
         return data;
}
----------------------------

My guess would be that it's inaccessible, and warnings Hatari was
giving on every syscall are somehow related to it.

Had kthread->data been inaccessible, probe_kernel_read() would have
taken a fault right there, wouldn't it?

AFAICS, the pointer is not dereferenced until copy_from_user is
called.

Yes, but that happens inside probe_kernel_read() here. But
kthread_probe_data() is not on the stack, only print_worker_info() is.


Sorry but __probe_kernel_read is on the stack, as is
__generic_copy_from_user:

...
Data read fault at 0x00000004 in Super Data (pc=0x2449e6)
...
PC: [<002449e6>] __generic_copy_from_user+0x1e/0x46
...
Call Trace: [<00068c16>] __probe_kernel_read+0x2a/0x50
...

kthread_probe_data isn't, and that's where what kthread->data is accessed to find the kthread worker struct. But I misread that code - it only copies out the null pointer in kthread->data, without dereferencing it. The result gets dereferenced later in print_worker_info, but the offset of current_func in the worker struct isn't 4.

Adding output in bus_error030() when the pagefault handler is disabled gives this log:

[ 1373.870000] sysrq: SysRq : Show State
[ 1373.880000]   task                PC stack   pid father
[ 1373.890000] init            S    0     1      0 0x00000000
[ 1373.900000] Stack from 00821fcc:
[ 1373.900000]         0000000b efe8aa7c 00000000 00000000 efe8aa74 00000000 0000000a 800017ec
[ 1373.900000]         0000008e 0000008e 00000000 0200c00b e0be0080
[ 1373.930000] Call Trace:
[ 1373.940000] kthreadd        S    0     2      0 0x00000000
[ 1373.950000] Stack from 00829fcc:
[ 1373.950000]         00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1373.950000]         00000000 00000000 00000000 20000000 00000000
[ 1373.990000] Call Trace:
[ 1374.000000] kworker/0:0     I    0     3      2 0x00000000
[ 1374.010000] Data read fault at 0x00000004 in Super Data (pc=0x28a872)
[ 1374.030000] Pagefault handler disabled!
[ 1374.050000] BAD KERNEL BUSERR
[ 1374.060000] Oops: 00000000
[ 1374.070000] Modules linked in: ne 8390p
[ 1374.100000] PC: [<0028a872>] __generic_copy_from_user+0x1a/0x40
[ 1374.110000] SR: 2200  SP: 07066a31  a2: 00900ac0
[ 1374.120000] d0: 00000001    d1: 00000000    d2: 00000003    d3: 0003d068
[ 1374.130000] d4: 00000002    d5: 8008b408    a0: 00000008    a1: 00651e64
[ 1374.140000] Process bash (pid: 1147, task=9c440a25)
[ 1374.150000] Frame format=B ssw=074d isc=22c2 isb=5380 daddr=00000004 dobuf=0006f9ec
[ 1374.170000] baddr=0028a878 dibuf=007f0001 ver=f
[ 1374.180000] Stack from 00651dd8:
[ 1374.180000]         00000001 0006fa02 00651e64 00000004 00000004 00815430 00037376 00651e64
[ 1374.180000]         00000004 00000004 00651e60 00815440 00000004 00651e5c 0081543c 00000004
[ 1374.180000]         0081e010 00000000 0081e010 000473b4 0081e14c 00000000 00000000 00000000
[ 1374.180000]         00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 1374.180000]         00000000 00000000 00000000 00000000 00651e98 0003d10c 002f94fd 0081e010
[ 1374.180000]         002f94e5 00000000 00000003 00000002 00000000 00000000 0081e010 0081e010
[ 1374.230000] Call Trace: [<0006fa02>] __probe_kernel_read+0x2a/0x4c
[ 1374.240000]  [<00037376>] print_worker_info+0x8c/0x11e
[ 1374.250000]  [<000473b4>] printk+0x0/0x18
[ 1374.270000]  [<0003d10c>] sched_show_task+0xa4/0xbc
[ 1374.280000]  [<0003e9dc>] show_state_filter+0x52/0x84
[ 1374.300000]  [<001acb00>] sysrq_handle_showstate+0x8/0x10
[ 1374.320000]  [<001ace6e>] write_sysrq_trigger+0x22/0x2e
[ 1374.330000]  [<00002204>] do_one_initcall+0x104/0x148
[ 1374.340000]  [<000ea29a>] proc_reg_write+0x46/0x76
[ 1374.350000]  [<000aa294>] __vfs_write+0x2e/0x144
[ 1374.370000]  [<00049d9c>] handle_simple_irq+0x4e/0x54
[ 1374.390000]  [<00047740>] generic_handle_irq+0x28/0x36
[ 1374.410000]  [<00002b86>] do_IRQ+0x26/0x32
[ 1374.420000]  [<000aa4e6>] vfs_write+0x8a/0x118
[ 1374.440000]  [<000aa688>] ksys_write+0x3e/0x88
[ 1374.450000]  [<000aa6e4>] sys_write+0x12/0x18
[ 1374.470000]  [<0000298c>] syscall+0x8/0xc
[ 1374.490000] Code: 7403 c282 206f 000c 226f 0008 4a80 670a <0e98> 2000 22c2 5380 66f6 0801 0001 6706 0e58 2000 32c2 0801 0000 6706 0e18 2000
[ 1374.520000] Disabling lock debugging due to kernel taint

so we take a read fault because of an invalid MMU descriptor here (line 559 in arch/m68k/kernel/traps.c) that we don't suppress even though __probe_kernel_read() asked us to.

What would happen if we just ignore the fault, and let print_worker_info() carry on?





The situation we encounter here (kthread->data == NULL)
If kthread == NULL then &kthread->data should be 0x00000008. But the log
says, "Data read fault at 0x00000004". That suggests kthread ==
0xFFFFFFFC.

I don't think kthread is NULL here, but the data pointer in the kthread
struct may be.


Where does that pointer get de-referenced?


On Motorola '030, the register dumps seem to show the effect of the
postincrement on a0, that is, 0x00000008. But on Hatari, a0 equals the
fault address, that is 0x00000004. Weird.

Yes, you always have to factor in post-increment - by the time the fault is
taken, the increment has already happened. Not that you _have_ to stick to
that in an emulator though.


That really depends what you want the emulator for. The NetBSD/mac68k
53C80 SCSI driver utilizes the fault address, for example.

Right - someone writing an emulator for the 5380 might want to fix up the processor emulation then. But the fault address was correct - the contents of the register used in the faulting read isn't. As long as the fault address from the exception frame is used (and is correct in emulation), no worries?


Even if you are right and such code never runs on Atari, this may be a bug
in the UAE code, which could affect a bunch of other emulators, such as
Previous.

Depends on whether register contents after an exception get used.

Cheers,

	Michael




[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux