Re: [PATCH v6 02/23] exec: add ram_debug_ops support

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

 




On 1/30/18 3:59 PM, Edgar E. Iglesias wrote:
> On Mon, Jan 29, 2018 at 11:41:11AM -0600, Brijesh Singh wrote:
>> Currently, the guest memory access for the debug purpose is performed
>> using the memcpy(). Lets extend the 'struct MemoryRegion' to include
>> ram_debug_ops callbacks. The ram_debug_ops can be used to override
>> memcpy() with something else.
>>
>> The feature can be used by encrypted guest -- which can register
>> callbacks to override memcpy() with memory encryption/decryption APIs.
>>
>> a typical usage:
>>
>> mem_read(uint8_t *dst, uint8_t *src, uint32_t len, MemTxAttrs *attrs);
>> mem_write(uint8_t *dst, uint8_t *src, uint32_t len, MemTxAttrs *attrs);
>>
>> MemoryRegionRAMReadWriteOps ops;
>> ops.read = mem_read;
>> ops.write = mem_write;
>
> Hi,
>
> Do these really need to be RAM specific (ram_debug_ops -> debug_ops) ?
> I was hoping a similar infrastructure could be used for MMIO
> debug accesses.

Hi Edgar,

The MMIO regions will contains unencrypted data hence I do not find the
need to add debug hooks for it. A memcpy() to/from MMIO should be fine.
If we see the need for MMIO case then it can extended later.

Brijesh
> Best regards,
> Edgar
>
>
>
>> memory_region_init_ram(mem, NULL, "memory", size, NULL);
>> memory_region_set_ram_debug_ops(mem, ops);
>>
>> Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>
>> Cc: Peter Crosthwaite <crosthwaite.peter@xxxxxxxxx>
>> Cc: Richard Henderson <rth@xxxxxxxxxxx>
>> Signed-off-by: Brijesh Singh <brijesh.singh@xxxxxxx>
>> ---
>>  exec.c                | 66 ++++++++++++++++++++++++++++++++++++++-------------
>>  include/exec/memory.h | 27 +++++++++++++++++++++
>>  2 files changed, 77 insertions(+), 16 deletions(-)
>>
>> diff --git a/exec.c b/exec.c
>> index 629a5083851d..1919052b7385 100644
>> --- a/exec.c
>> +++ b/exec.c
>> @@ -3050,7 +3050,11 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
>>          } else {
>>              /* RAM case */
>>              ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
>> -            memcpy(ptr, buf, l);
>> +            if (attrs.debug && mr->ram_debug_ops) {
>> +                mr->ram_debug_ops->write(ptr, buf, l, attrs);
>> +            } else {
>> +                memcpy(ptr, buf, l);
>> +            }
>>              invalidate_and_set_dirty(mr, addr1, l);
>>          }
>>  
>> @@ -3148,7 +3152,11 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
>>          } else {
>>              /* RAM case */
>>              ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l, false);
>> -            memcpy(buf, ptr, l);
>> +            if (attrs.debug && mr->ram_debug_ops) {
>> +                mr->ram_debug_ops->read(buf, ptr, l, attrs);
>> +            } else {
>> +                memcpy(buf, ptr, l);
>> +            }
>>          }
>>  
>>          if (release_lock) {
>> @@ -3218,11 +3226,13 @@ void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf,
>>  
>>  enum write_rom_type {
>>      WRITE_DATA,
>> +    READ_DATA,
>>      FLUSH_CACHE,
>>  };
>>  
>> -static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
>> -    hwaddr addr, const uint8_t *buf, int len, enum write_rom_type type)
>> +static inline void cpu_physical_memory_rw_internal(AddressSpace *as,
>> +    hwaddr addr, uint8_t *buf, int len, MemTxAttrs attrs,
>> +    enum write_rom_type type)
>>  {
>>      hwaddr l;
>>      uint8_t *ptr;
>> @@ -3237,12 +3247,33 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
>>          if (!(memory_region_is_ram(mr) ||
>>                memory_region_is_romd(mr))) {
>>              l = memory_access_size(mr, l, addr1);
>> +            /* Pass MMIO down to address address_space_rw */
>> +            switch (type) {
>> +            case READ_DATA:
>> +            case WRITE_DATA:
>> +                address_space_rw(as, addr1, attrs, buf, l,
>> +                                 type == WRITE_DATA);
>> +                break;
>> +            case FLUSH_CACHE:
>> +                break;
>> +            }
>>          } else {
>>              /* ROM/RAM case */
>>              ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
>>              switch (type) {
>> +            case READ_DATA:
>> +                if (mr->ram_debug_ops) {
>> +                    mr->ram_debug_ops->read(buf, ptr, l, attrs);
>> +                } else {
>> +                    memcpy(buf, ptr, l);
>> +                }
>> +                break;
>>              case WRITE_DATA:
>> -                memcpy(ptr, buf, l);
>> +                if (mr->ram_debug_ops) {
>> +                    mr->ram_debug_ops->write(ptr, buf, l, attrs);
>> +                } else {
>> +                    memcpy(ptr, buf, l);
>> +                }
>>                  invalidate_and_set_dirty(mr, addr1, l);
>>                  break;
>>              case FLUSH_CACHE:
>> @@ -3261,7 +3292,8 @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
>>  void cpu_physical_memory_write_rom(AddressSpace *as, hwaddr addr,
>>                                     const uint8_t *buf, int len)
>>  {
>> -    cpu_physical_memory_write_rom_internal(as, addr, buf, len, WRITE_DATA);
>> +    cpu_physical_memory_rw_internal(as, addr, (uint8_t *)buf, len,
>> +            MEMTXATTRS_UNSPECIFIED, WRITE_DATA);
>>  }
>>  
>>  void cpu_flush_icache_range(hwaddr start, int len)
>> @@ -3276,8 +3308,10 @@ void cpu_flush_icache_range(hwaddr start, int len)
>>          return;
>>      }
>>  
>> -    cpu_physical_memory_write_rom_internal(&address_space_memory,
>> -                                           start, NULL, len, FLUSH_CACHE);
>> +    cpu_physical_memory_rw_internal(&address_space_memory,
>> +                                    start, NULL, len,
>> +                                    MEMTXATTRS_UNSPECIFIED,
>> +                                    FLUSH_CACHE);
>>  }
>>  
>>  typedef struct {
>> @@ -3583,6 +3617,7 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
>>      int l;
>>      hwaddr phys_addr;
>>      target_ulong page;
>> +    int type = is_write ? WRITE_DATA : READ_DATA;
>>  
>>      cpu_synchronize_state(cpu);
>>      while (len > 0) {
>> @@ -3592,6 +3627,10 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
>>          page = addr & TARGET_PAGE_MASK;
>>          phys_addr = cpu_get_phys_page_attrs_debug(cpu, page, &attrs);
>>          asidx = cpu_asidx_from_attrs(cpu, attrs);
>> +
>> +        /* set debug attrs to indicate memory access is from the debugger */
>> +        attrs.debug = 1;
>> +
>>          /* if no physical page mapped, return an error */
>>          if (phys_addr == -1)
>>              return -1;
>> @@ -3599,14 +3638,9 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,
>>          if (l > len)
>>              l = len;
>>          phys_addr += (addr & ~TARGET_PAGE_MASK);
>> -        if (is_write) {
>> -            cpu_physical_memory_write_rom(cpu->cpu_ases[asidx].as,
>> -                                          phys_addr, buf, l);
>> -        } else {
>> -            address_space_rw(cpu->cpu_ases[asidx].as, phys_addr,
>> -                             MEMTXATTRS_UNSPECIFIED,
>> -                             buf, l, 0);
>> -        }
>> +        cpu_physical_memory_rw_internal(cpu->cpu_ases[asidx].as,
>> +                                        phys_addr, buf, l, attrs,
>> +                                        type);
>>          len -= l;
>>          buf += l;
>>          addr += l;
>> diff --git a/include/exec/memory.h b/include/exec/memory.h
>> index 07c5d6d59796..4d027fffeebf 100644
>> --- a/include/exec/memory.h
>> +++ b/include/exec/memory.h
>> @@ -215,6 +215,18 @@ typedef struct IOMMUMemoryRegionClass {
>>  typedef struct CoalescedMemoryRange CoalescedMemoryRange;
>>  typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
>>  
>> +/* Memory Region RAM debug callback */
>> +typedef struct MemoryRegionRAMReadWriteOps MemoryRegionRAMReadWriteOps;
>> +
>> +struct MemoryRegionRAMReadWriteOps {
>> +    /* Write data into guest memory */
>> +    int (*write) (uint8_t *dest, const uint8_t *src,
>> +                  uint32_t len, MemTxAttrs attrs);
>> +    /* Read data from guest memory */
>> +    int (*read) (uint8_t *dest, const uint8_t *src,
>> +                 uint32_t len, MemTxAttrs attrs);
>> +};
>> +
>>  struct MemoryRegion {
>>      Object parent_obj;
>>  
>> @@ -254,6 +266,7 @@ struct MemoryRegion {
>>      const char *name;
>>      unsigned ioeventfd_nb;
>>      MemoryRegionIoeventfd *ioeventfds;
>> +    const MemoryRegionRAMReadWriteOps *ram_debug_ops;
>>  };
>>  
>>  struct IOMMUMemoryRegion {
>> @@ -624,6 +637,20 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr,
>>                                               Error **errp);
>>  
>>  /**
>> + * memory_region_set_ram_debug_ops: Set debug access ops for a given memory region
>> + *
>> + * @mr: the #MemoryRegion to be initialized
>> + * @ops: a function that will be used for when accessing @target region during
>> + *       debug
>> + */
>> +static inline void
>> +memory_region_set_ram_debug_ops(MemoryRegion *mr,
>> +                                const MemoryRegionRAMReadWriteOps *ops)
>> +{
>> +    mr->ram_debug_ops = ops;
>> +}
>> +
>> +/**
>>   * memory_region_init_reservation: Initialize a memory region that reserves
>>   *                                 I/O space.
>>   *
>> -- 
>> 2.9.5
>>




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux