[OpenBIOS] [Qemu-ppc] Running client with MMU off

BALATON Zoltan balaton at eik.bme.hu
Wed Jul 30 16:42:16 CEST 2014


On Mon, 28 Jul 2014, Alexander Graf wrote:
> On 27.06.14 23:34, BALATON Zoltan wrote:
>> On Thu, 26 Jun 2014, Alexander Graf wrote:
>>> On 26.06.14 13:20, BALATON Zoltan wrote:
>>>> On Thu, 26 Jun 2014, Alexander Graf wrote:
>>>>> You could enable write protection on the first page before you enter the 
>>>>> payload. Then you could unprotect it and disable interrupts as soon as 
>>>>> someone wrote to it. I guess that'd be a pretty solid hack.
>>>> 
>>>> Good idea, I'll look into this. But 0x00-0xff is reserved for operating 
>>>> system use and MorphOS does write to 0x80 before touching the vectors 
>>>> (that's why I can't just check from the DSI handler). Can I selectively 
>>>> enable writes on a write protected page? (I'll need to read about it some 
>>>> more.)
>>> 
>>> Not easily. You could emulate the 0x80 write maybe. Is it too early if you 
>>> just disable DR/IR on the 0x80 touch? I don't think any other OS really 
>>> accesses these ranges, but only time will tell ;).
>> 
>> As a start I've tried this patch:
>> 
>> --- a/openbios-devel/arch/ppc/qemu/ofmem.c
>> +++ b/openbios-devel/arch/ppc/qemu/ofmem.c
>> @@ -460,15 +460,26 @@ static void hash_page(unsigned long ea, phys_addr_t 
>> phys,
>>  void
>>  dsi_exception(void)
>>  {
>> -    unsigned long dar, dsisr;
>> +    unsigned long dar, dsisr, srr1;
>>      ucell mode;
>>      phys_addr_t phys;
>>
>>      asm volatile("mfdar %0" : "=r" (dar) : );
>>      asm volatile("mfdsisr %0" : "=r" (dsisr) : );
>> -
>> +    asm volatile("mfsrr1 %0" : "=r" (srr1) : );
>>      phys = ea_to_phys(dar, &mode);
>> -    hash_page(dar, phys, mode);
>> +
>> +    if (dsisr & BIT(1)) {
>> +        /* handle page fault */
>> +        hash_page(dar, phys, mode);
>> +    }
>> +
>> +    if (dsisr & BIT(4) && dar == 0) {
>> +        /* handle protection violation */
>> +        hash_page(dar, phys, mode);
>> +        srr1 &= ~(MSR_IR | MSR_DR);
>> +        asm volatile("mtsrr1 %0" :: "r" (srr1));
>> +    }
>>  }
>>
>>  void
>> @@ -554,9 +565,10 @@ ofmem_init(void)
>>      ofmem_claim_virt(PAGE_SIZE, get_ram_bottom() - PAGE_SIZE, 0);
>>      ofmem_map(PAGE_SIZE, PAGE_SIZE, get_ram_bottom() - PAGE_SIZE, 0);
>> 
>> -    /* Mark the first page as non-free */
>> +    /* Mark the first page as non-free and write protect it */
>>      ofmem_claim_phys(0, PAGE_SIZE, 0);
>>      ofmem_claim_virt(0, PAGE_SIZE, 0);
>> +    hash_page(0, 0, 3);
>>
>>      /* Map everything at the top of physical RAM 1:1, minus the OpenBIOS 
>> ROM in
>>      ofmem_claim_phys(get_ram_top(), get_hash_base() + HASH_SIZE - 
>> get_ram_top()
>> 
>> which does not break Finnix but does not work with MorphOS because it 
>> catches the write to 0x80 as it should but instead of ignoring it this 
>> protection violation exception is always retrigerring infinitely and it 
>> does not go further. What am I missing to ignore protection violations for 
>> writes to page 0 without emulating the writes at the moment. (The initial 
>> write to 0x80 is setting it to 0 which is the value it already has.) 
>> Unfortunatly it is hard to debug because if I call printk from the 
>> exception handler it seems to break beyond repair possibly due to side 
>> effects.
>> 
>> I've also looked at the code you've referred to but that uses kvm functions 
>> not included in the patch so it may be more complicated than that. If I get 
>> it correctly I can get the instruction from the address in srr0, the target 
>> memory cell from dar but still need to find out the source which is 
>> probably a register that does not contain the value by the time I get it so 
>> it may not be trivial to emulate the write.
>
> They have to be somewhere, because we have to swap them all back in after the 
> interrupt.

They are probably on a stack somewhere but the handlers replace the stack 
if I remember correctly so it's not trivial to access that from C code. 
But my question was primarily about why the exception is retriggering? Do 
I need to do something else to signal to the CPU that the protection 
violation is handled or how can I ignore an exception so the execution 
continues?

Regards,
BALATON Zoltan



More information about the OpenBIOS mailing list