atos-tools / qemu

QEMU with instrumentation support, ref to tcg/plugins/README
https://guillon.github.io/qemu-plugins
Other
5 stars 8 forks source link

Cannot access mmap'ed memory region from TCG helper #15

Closed Kmambu closed 4 years ago

Kmambu commented 4 years ago

Hello, I want to model an MMIO device which is memory-mapped in two different regions, let's say REGION1 and REGION2. And the idea is that when any program writes data in REGION1, side effects are applied in REGION2. So I wrote a TCG plugin in the likes of the following :

static uint64_t tcg_helper_mmio_sim(uint32_t address, uint32_t value) {
  if (address < REGION1_BASE || address > REGION1_BASE + REGION1_SIZE)
    return 1;
  uin32_t op = get_op(address);
  uint32_t idx = get_index(value);
  uint32_t data = *((uint32_t)((uintptr_tr)(REGION2_BASE + idx * sizeof(uint32_t))));
  // afterwards some processing is performed on the data, which is written back in another place of REGION2
  ...
}

Problem is, I have a segmentation fault when I want to read the data at ~REGION1~ (EDIT: REGION2), and I don't understand why. The comprehension I had of TCG helpers was that they could be used to modify guest memory. Do I need to do something in particular to achieve what I described ?

Thanks in advance, Kévin

Kmambu commented 4 years ago

I managed to find the issue with my problem : what I had to do was find the base host address of guest memory, with tpi_guest_ptr(tpi, 0x0) in my tpi_init() function, and add it to my address calculations :smile:

...
// So, I declare this global variable, guest_phys_base_addr, which I set in my tpi_init()
uint64_t guest_phys_base_addr;
static uint64_t tcg_helper_mmio_sim(uint32_t address, uint32_t value) {
  if (address < REGION1_BASE || address > REGION1_BASE + REGION1_SIZE)
    return 1;
  uin32_t op = get_op(address);
  uint32_t idx = get_index(value);
  uint32_t data = *((uint32_t)((uintptr_tr)(guest_phys_base_addr + REGION2_BASE + idx * sizeof(uint32_t))));
  // afterwards some processing is performed on the data, which is written back in another place of REGION2
  ...
}
void tpi_init(TCGPluginInterface *tpi) {
  ...
  guest_phys_base_addr = tpi_guest_ptr(tpi, 0x0);
}