Hi Andre,

On 2/18/21 11:48 AM, Andre Przywara wrote:
> On Thu, 18 Feb 2021 11:17:58 +0000
> Alexandru Elisei <[email protected]> wrote:
>
>> Hi Andre,
>>
>> On 2/18/21 10:34 AM, Andre Przywara wrote:
>>> On Thu, 11 Feb 2021 17:23:13 +0000
>>> Alexandru Elisei <[email protected]> wrote:
>>>  
>>>> Hi Andre,
>>>>
>>>> On 12/10/20 2:28 PM, Andre Przywara wrote:  
>>>>> With the planned retirement of the special ioport emulation code, we
>>>>> need to provide an emulation function compatible with the MMIO
>>>>> prototype.
>>>>>
>>>>> Adjust the trap handler to use that new function, and provide shims to
>>>>> implement the old ioport interface, for now.
>>>>>
>>>>> Signed-off-by: Andre Przywara <[email protected]>
>>>>> ---
>>>>>  hw/i8042.c | 68 +++++++++++++++++++++++++++---------------------------
>>>>>  1 file changed, 34 insertions(+), 34 deletions(-)
>>>>>
>>>>> diff --git a/hw/i8042.c b/hw/i8042.c
>>>>> index 36ee183f..eb1f9d28 100644
>>>>> --- a/hw/i8042.c
>>>>> +++ b/hw/i8042.c
>>>>> @@ -292,52 +292,52 @@ static void kbd_reset(void)
>>>>>   };
>>>>>  }
>>>>>  
>>>>> -/*
>>>>> - * Called when the OS has written to one of the keyboard's ports (0x60 
>>>>> or 0x64)
>>>>> - */
>>>>> -static bool kbd_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 
>>>>> port, void *data, int size)
>>>>> +static void kbd_io(struct kvm_cpu *vcpu, u64 addr, u8 *data, u32 len,
>>>>> +            u8 is_write, void *ptr)
>>>>>  {
>>>>> - switch (port) {
>>>>> - case I8042_COMMAND_REG: {
>>>>> -         u8 value = kbd_read_status();
>>>>> -         ioport__write8(data, value);
>>>>> + u8 value;
>>>>> +
>>>>> + if (is_write)
>>>>> +         value = ioport__read8(data);
>>>>> +
>>>>> + switch (addr) {
>>>>> + case I8042_COMMAND_REG:
>>>>> +         if (is_write)
>>>>> +                 kbd_write_command(vcpu->kvm, value);
>>>>> +         else
>>>>> +                 value = kbd_read_status();
>>>>>           break;
>>>>> - }
>>>>> - case I8042_DATA_REG: {
>>>>> -         u8 value = kbd_read_data();
>>>>> -         ioport__write8(data, value);
>>>>> + case I8042_DATA_REG:
>>>>> +         if (is_write)
>>>>> +                 kbd_write_data(value);
>>>>> +         else
>>>>> +                 value = kbd_read_data();
>>>>>           break;
>>>>> - }
>>>>> - case I8042_PORT_B_REG: {
>>>>> -         ioport__write8(data, 0x20);
>>>>> + case I8042_PORT_B_REG:
>>>>> +         if (!is_write)
>>>>> +                 value = 0x20;
>>>>>           break;
>>>>> - }
>>>>>   default:
>>>>> -         return false;
>>>>> +         return;    
>>>> Any particular reason for removing the false return value? I don't see it
>>>> mentioned in the commit message. Otherwise this is identical to the two 
>>>> functions
>>>> it replaces.  
>>> Because the MMIO handler prototype is void, in contrast to the PIO one.
>>> Since on returning "false" we only seem to panic kvmtool, this is of
>>> quite limited use, I'd say.  
>> Actually, in ioport.c::kvm__emulate_io(), if kvm->cfg.ioport_debug is true, 
>> it
>> will print an error and then panic in kvm_cpu__start(); otherwise the error 
>> is
>> silently ignored. serial.c is another device where an unknown register 
>> returns
>> false. In rtc.c, the unknown register is ignored. cfi_flash.c prints 
>> debugging
>> information. So I guess kvmtool implements all possible methods of handling 
>> an
>> unknown register *at the same time*, so it's up to you how you want to 
>> handle it.
> Well, the MMIO prototype we are going to use is void anyway, so it's
> just one patch earlier that we get this new behaviour.
> For handling MMIO errors:
> - Hardware MMIO doesn't have a back channel: if the MMIO write triggers
>   some error condition, the device would need to deal with it (setting
>   internal error state, ignore, etc.). On some systems the device could
>   throw some kind of bus error or SError, but this is a rather drastic
>   measure, and is certainly not exercised by those ancient devices.
> - Any kind of error reporting which can be triggered by a guest is
>   frowned upon: it could spam the console or some log file, and so
>   impact host operation. At the end an administrator can't do much about
>   it, anyway.
> - Which leaves the only use to some kvmtool developer debugging some
>   device emulation or investigating weird guest behaviour. And in this
>   case we can more easily have a debug message *inside* the device
>   emulation code, can't we?

That's what I had in mind, debugging messages in the device emulation. If the
guest can access an unknown register offset this can mean one of two things in 
my
opinion: the emulated device registered a memory region bigger that necessary or
the emulated device is not handling all device registers. But that's a subject 
for
another series.

Thanks,

Alex

>
> And since the MMIO handler prototype is void, we have no choice anyway,
> at least not without another huge (and pointless) series to change
> those user as well ;-)
>
> Cheers,
> Andre
>
>>>>>   }
>>>>>  
>>>>> + if (!is_write)
>>>>> +         ioport__write8(data, value);
>>>>> +}
>>>>> +
>>>>> +/*
>>>>> + * Called when the OS has written to one of the keyboard's ports (0x60 
>>>>> or 0x64)
>>>>> + */
>>>>> +static bool kbd_in(struct ioport *ioport, struct kvm_cpu *vcpu, u16 
>>>>> port, void *data, int size)
>>>>> +{
>>>>> + kbd_io(vcpu, port, data, size, false, NULL);    
>>>> is_write is an u8, not a bool.  
>>> Right, will fix this.
>>>  
>>>> I never could wrap my head around the ioport convention of "in" (read) and 
>>>> "out"
>>>> (write). To be honest, changing is_write changed to an enum so it's 
>>>> crystal clear
>>>> what is happening would help with that a lot, but I guess that's a 
>>>> separate patch.  
>>> "in" and "out" are the x86 assembly mnemonics, but it's indeed
>>> confusing, because the device side has a different view (CPU "in" means
>>> pushing data "out" of the device). I usually look at the code to see
>>> what it's actually meant to do.
>>> So yeah, I feel like a lot of those device emulations could use
>>> some update. but that's indeed something for another day.  
>> Agreed.
>>
>> Thanks,
>>
>> Alex
>>
>>> Cheers,
>>> Andre
>>>  
>>>>> +
>>>>>   return true;
>>>>>  }
>>>>>  
>>>>>  static bool kbd_out(struct ioport *ioport, struct kvm_cpu *vcpu, u16 
>>>>> port, void *data, int size)
>>>>>  {
>>>>> - switch (port) {
>>>>> - case I8042_COMMAND_REG: {
>>>>> -         u8 value = ioport__read8(data);
>>>>> -         kbd_write_command(vcpu->kvm, value);
>>>>> -         break;
>>>>> - }
>>>>> - case I8042_DATA_REG: {
>>>>> -         u8 value = ioport__read8(data);
>>>>> -         kbd_write_data(value);
>>>>> -         break;
>>>>> - }
>>>>> - case I8042_PORT_B_REG: {
>>>>> -         break;
>>>>> - }
>>>>> - default:
>>>>> -         return false;
>>>>> - }
>>>>> + kbd_io(vcpu, port, data, size, true, NULL);
>>>>>  
>>>>>   return true;
>>>>>  }    
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reply via email to