[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH V2 1/8] xen/mem_event: Cleanup of mem_event structures
From: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> The public mem_event structures used to communicate with helper applications via shared rings have been used in different settings. However, the variable names within this structure have not reflected this fact, resulting in the reuse of variables to mean different things under different scenarios. This patch remedies the issue by clearly defining the structure members based on the actual context within which the structure is used. Signed-off-by: Razvan Cojocaru <rcojocaru@xxxxxxxxxxxxxxx> Signed-off-by: Tamas K Lengyel <tamas.lengyel@xxxxxxxxxxxx> --- tools/tests/xen-access/xen-access.c | 33 ++++--- tools/xenpaging/xenpaging.c | 34 +++---- xen/arch/x86/hvm/hvm.c | 185 ++++++++++++++++++++---------------- xen/arch/x86/mm/mem_sharing.c | 7 +- xen/arch/x86/mm/p2m.c | 129 +++++++++++++------------ xen/include/Makefile | 2 +- xen/include/public/mem_event.h | 99 +++++++++++++++---- 7 files changed, 292 insertions(+), 197 deletions(-) diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c index 6cb382d..9d53fb3 100644 --- a/tools/tests/xen-access/xen-access.c +++ b/tools/tests/xen-access/xen-access.c @@ -556,8 +556,8 @@ int main(int argc, char *argv[]) rsp.flags = req.flags; switch (req.reason) { - case MEM_EVENT_REASON_VIOLATION: - rc = xc_get_mem_access(xch, domain_id, req.gfn, &access); + case MEM_EVENT_REASON_MEM_ACCESS_VIOLATION: + rc = xc_get_mem_access(xch, domain_id, req.mem_access_event.gfn, &access); if (rc < 0) { ERROR("Error %d getting mem_access event\n", rc); @@ -567,21 +567,21 @@ int main(int argc, char *argv[]) printf("PAGE ACCESS: %c%c%c for GFN %"PRIx64" (offset %06" PRIx64") gla %016"PRIx64" (valid: %c; fault in gpt: %c; fault with gla: %c) (vcpu %u)\n", - req.access_r ? 'r' : '-', - req.access_w ? 'w' : '-', - req.access_x ? 'x' : '-', - req.gfn, - req.offset, - req.gla, - req.gla_valid ? 'y' : 'n', - req.fault_in_gpt ? 'y' : 'n', - req.fault_with_gla ? 'y': 'n', + req.mem_access_event.access_r ? 'r' : '-', + req.mem_access_event.access_w ? 'w' : '-', + req.mem_access_event.access_x ? 'x' : '-', + req.mem_access_event.gfn, + req.mem_access_event.offset, + req.mem_access_event.gla, + req.mem_access_event.gla_valid ? 'y' : 'n', + req.mem_access_event.fault_in_gpt ? 'y' : 'n', + req.mem_access_event.fault_with_gla ? 'y': 'n', req.vcpu_id); if ( default_access != after_first_access ) { rc = xc_set_mem_access(xch, domain_id, after_first_access, - req.gfn, 1); + req.mem_access_event.gfn, 1); if (rc < 0) { ERROR("Error %d setting gfn to access_type %d\n", rc, @@ -592,13 +592,12 @@ int main(int argc, char *argv[]) } - rsp.gfn = req.gfn; - rsp.p2mt = req.p2mt; + rsp.mem_access_event.gfn = req.mem_access_event.gfn; break; case MEM_EVENT_REASON_INT3: - printf("INT3: rip=%016"PRIx64", gfn=%"PRIx64" (vcpu %d)\n", - req.gla, - req.gfn, + printf("INT3: rip=%016"PRIx64", gfn=%"PRIx64" (vcpu %d)\n", + req.int3_event.gla, + req.int3_event.gfn, req.vcpu_id); /* Reinject */ diff --git a/tools/xenpaging/xenpaging.c b/tools/xenpaging/xenpaging.c index 82c1ee4..148b3e7 100644 --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -684,9 +684,9 @@ static int xenpaging_resume_page(struct xenpaging *paging, mem_event_response_t * This allows page-out of these gfns if the target grows again. */ if (paging->num_paged_out > paging->policy_mru_size) - policy_notify_paged_in(rsp->gfn); + policy_notify_paged_in(rsp->mem_paging_event.gfn); else - policy_notify_paged_in_nomru(rsp->gfn); + policy_notify_paged_in_nomru(rsp->mem_paging_event.gfn); /* Record number of resumed pages */ paging->num_paged_out--; @@ -910,49 +910,49 @@ int main(int argc, char *argv[]) get_request(&paging->mem_event, &req); - if ( req.gfn > paging->max_pages ) + if ( req.mem_paging_event.gfn > paging->max_pages ) { - ERROR("Requested gfn %"PRIx64" higher than max_pages %x\n", req.gfn, paging->max_pages); + ERROR("Requested gfn %"PRIx64" higher than max_pages %x\n", req.mem_paging_event.gfn, paging->max_pages); goto out; } /* Check if the page has already been paged in */ - if ( test_and_clear_bit(req.gfn, paging->bitmap) ) + if ( test_and_clear_bit(req.mem_paging_event.gfn, paging->bitmap) ) { /* Find where in the paging file to read from */ - slot = paging->gfn_to_slot[req.gfn]; + slot = paging->gfn_to_slot[req.mem_paging_event.gfn]; /* Sanity check */ - if ( paging->slot_to_gfn[slot] != req.gfn ) + if ( paging->slot_to_gfn[slot] != req.mem_paging_event.gfn ) { - ERROR("Expected gfn %"PRIx64" in slot %d, but found gfn %lx\n", req.gfn, slot, paging->slot_to_gfn[slot]); + ERROR("Expected gfn %"PRIx64" in slot %d, but found gfn %lx\n", req.mem_paging_event.gfn, slot, paging->slot_to_gfn[slot]); goto out; } if ( req.flags & MEM_EVENT_FLAG_DROP_PAGE ) { - DPRINTF("drop_page ^ gfn %"PRIx64" pageslot %d\n", req.gfn, slot); + DPRINTF("drop_page ^ gfn %"PRIx64" pageslot %d\n", req.mem_paging_event.gfn, slot); /* Notify policy of page being dropped */ - policy_notify_dropped(req.gfn); + policy_notify_dropped(req.mem_paging_event.gfn); } else { /* Populate the page */ - if ( xenpaging_populate_page(paging, req.gfn, slot) < 0 ) + if ( xenpaging_populate_page(paging, req.mem_paging_event.gfn, slot) < 0 ) { - ERROR("Error populating page %"PRIx64"", req.gfn); + ERROR("Error populating page %"PRIx64"", req.mem_paging_event.gfn); goto out; } } /* Prepare the response */ - rsp.gfn = req.gfn; + rsp.mem_paging_event.gfn = req.mem_paging_event.gfn; rsp.vcpu_id = req.vcpu_id; rsp.flags = req.flags; if ( xenpaging_resume_page(paging, &rsp, 1) < 0 ) { - PERROR("Error resuming page %"PRIx64"", req.gfn); + PERROR("Error resuming page %"PRIx64"", req.mem_paging_event.gfn); goto out; } @@ -967,7 +967,7 @@ int main(int argc, char *argv[]) DPRINTF("page %s populated (domain = %d; vcpu = %d;" " gfn = %"PRIx64"; paused = %d; evict_fail = %d)\n", req.flags & MEM_EVENT_FLAG_EVICT_FAIL ? "not" : "already", - paging->mem_event.domain_id, req.vcpu_id, req.gfn, + paging->mem_event.domain_id, req.vcpu_id, req.mem_paging_event.gfn, !!(req.flags & MEM_EVENT_FLAG_VCPU_PAUSED) , !!(req.flags & MEM_EVENT_FLAG_EVICT_FAIL) ); @@ -975,13 +975,13 @@ int main(int argc, char *argv[]) if (( req.flags & MEM_EVENT_FLAG_VCPU_PAUSED ) || ( req.flags & MEM_EVENT_FLAG_EVICT_FAIL )) { /* Prepare the response */ - rsp.gfn = req.gfn; + rsp.mem_paging_event.gfn = req.mem_paging_event.gfn; rsp.vcpu_id = req.vcpu_id; rsp.flags = req.flags; if ( xenpaging_resume_page(paging, &rsp, 0) < 0 ) { - PERROR("Error resuming page %"PRIx64"", req.gfn); + PERROR("Error resuming page %"PRIx64"", req.mem_paging_event.gfn); goto out; } } diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index bc414ff..bd8c393 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -6176,48 +6176,42 @@ static void hvm_mem_event_fill_regs(mem_event_request_t *req) const struct cpu_user_regs *regs = guest_cpu_user_regs(); const struct vcpu *curr = current; - req->x86_regs.rax = regs->eax; - req->x86_regs.rcx = regs->ecx; - req->x86_regs.rdx = regs->edx; - req->x86_regs.rbx = regs->ebx; - req->x86_regs.rsp = regs->esp; - req->x86_regs.rbp = regs->ebp; - req->x86_regs.rsi = regs->esi; - req->x86_regs.rdi = regs->edi; - - req->x86_regs.r8 = regs->r8; - req->x86_regs.r9 = regs->r9; - req->x86_regs.r10 = regs->r10; - req->x86_regs.r11 = regs->r11; - req->x86_regs.r12 = regs->r12; - req->x86_regs.r13 = regs->r13; - req->x86_regs.r14 = regs->r14; - req->x86_regs.r15 = regs->r15; - - req->x86_regs.rflags = regs->eflags; - req->x86_regs.rip = regs->eip; - - req->x86_regs.msr_efer = curr->arch.hvm_vcpu.guest_efer; - req->x86_regs.cr0 = curr->arch.hvm_vcpu.guest_cr[0]; - req->x86_regs.cr3 = curr->arch.hvm_vcpu.guest_cr[3]; - req->x86_regs.cr4 = curr->arch.hvm_vcpu.guest_cr[4]; -} - -static int hvm_memory_event_traps(long p, uint32_t reason, - unsigned long value, unsigned long old, - bool_t gla_valid, unsigned long gla) -{ - struct vcpu* v = current; - struct domain *d = v->domain; - mem_event_request_t req = { .reason = reason }; + req->regs.x86.rax = regs->eax; + req->regs.x86.rcx = regs->ecx; + req->regs.x86.rdx = regs->edx; + req->regs.x86.rbx = regs->ebx; + req->regs.x86.rsp = regs->esp; + req->regs.x86.rbp = regs->ebp; + req->regs.x86.rsi = regs->esi; + req->regs.x86.rdi = regs->edi; + + req->regs.x86.r8 = regs->r8; + req->regs.x86.r9 = regs->r9; + req->regs.x86.r10 = regs->r10; + req->regs.x86.r11 = regs->r11; + req->regs.x86.r12 = regs->r12; + req->regs.x86.r13 = regs->r13; + req->regs.x86.r14 = regs->r14; + req->regs.x86.r15 = regs->r15; + + req->regs.x86.rflags = regs->eflags; + req->regs.x86.rip = regs->eip; + + req->regs.x86.msr_efer = curr->arch.hvm_vcpu.guest_efer; + req->regs.x86.cr0 = curr->arch.hvm_vcpu.guest_cr[0]; + req->regs.x86.cr3 = curr->arch.hvm_vcpu.guest_cr[3]; + req->regs.x86.cr4 = curr->arch.hvm_vcpu.guest_cr[4]; +} + +static int hvm_memory_event_traps(long parameters, mem_event_request_t *req) +{ int rc; + struct vcpu *v = current; + struct domain *d = v->domain; - if ( !(p & HVMPME_MODE_MASK) ) + if ( !(parameters & HVMPME_MODE_MASK) ) return 0; - if ( (p & HVMPME_onchangeonly) && (value == old) ) - return 1; - rc = mem_event_claim_slot(d, &d->mem_event->access); if ( rc == -ENOSYS ) { @@ -6228,85 +6222,114 @@ static int hvm_memory_event_traps(long p, uint32_t reason, else if ( rc < 0 ) return rc; - if ( (p & HVMPME_MODE_MASK) == HVMPME_mode_sync ) + if ( (parameters & HVMPME_MODE_MASK) == HVMPME_mode_sync ) { - req.flags |= MEM_EVENT_FLAG_VCPU_PAUSED; + req->flags |= MEM_EVENT_FLAG_VCPU_PAUSED; mem_event_vcpu_pause(v); } - req.gfn = value; - req.vcpu_id = v->vcpu_id; - if ( gla_valid ) - { - req.offset = gla & ((1 << PAGE_SHIFT) - 1); - req.gla = gla; - req.gla_valid = 1; - } - else - { - req.gla = old; - } - - hvm_mem_event_fill_regs(&req); - mem_event_put_request(d, &d->mem_event->access, &req); - + hvm_mem_event_fill_regs(req); + mem_event_put_request(d, &d->mem_event->access, req); + return 1; } void hvm_memory_event_cr0(unsigned long value, unsigned long old) { - hvm_memory_event_traps(current->domain->arch.hvm_domain - .params[HVM_PARAM_MEMORY_EVENT_CR0], - MEM_EVENT_REASON_CR0, - value, old, 0, 0); + mem_event_request_t req = { + .reason = MEM_EVENT_REASON_CR0, + .vcpu_id = current->vcpu_id, + .cr_event.new_value = value, + .cr_event.old_value = old + }; + + long parameters = current->domain->arch.hvm_domain + .params[HVM_PARAM_MEMORY_EVENT_CR0]; + + if ( (parameters & HVMPME_onchangeonly) && (value == old) ) + return; + + hvm_memory_event_traps(parameters, &req); } void hvm_memory_event_cr3(unsigned long value, unsigned long old) { - hvm_memory_event_traps(current->domain->arch.hvm_domain - .params[HVM_PARAM_MEMORY_EVENT_CR3], - MEM_EVENT_REASON_CR3, - value, old, 0, 0); + mem_event_request_t req = { + .reason = MEM_EVENT_REASON_CR3, + .vcpu_id = current->vcpu_id, + .cr_event.new_value = value, + .cr_event.old_value = old + }; + + long parameters = current->domain->arch.hvm_domain + .params[HVM_PARAM_MEMORY_EVENT_CR3]; + + if ( (parameters & HVMPME_onchangeonly) && (value == old) ) + return; + + hvm_memory_event_traps(parameters, &req); } void hvm_memory_event_cr4(unsigned long value, unsigned long old) { - hvm_memory_event_traps(current->domain->arch.hvm_domain - .params[HVM_PARAM_MEMORY_EVENT_CR4], - MEM_EVENT_REASON_CR4, - value, old, 0, 0); + mem_event_request_t req = { + .reason = MEM_EVENT_REASON_CR4, + .vcpu_id = current->vcpu_id, + .cr_event.new_value = value, + .cr_event.old_value = old + }; + + long parameters = current->domain->arch.hvm_domain + .params[HVM_PARAM_MEMORY_EVENT_CR4]; + + if ( (parameters & HVMPME_onchangeonly) && (value == old) ) + return; + + hvm_memory_event_traps(parameters, &req); } void hvm_memory_event_msr(unsigned long msr, unsigned long value) { + mem_event_request_t req = { + .reason = MEM_EVENT_REASON_MSR, + .vcpu_id = current->vcpu_id, + .msr_event.msr = msr, + .msr_event.new_value = value, + }; + hvm_memory_event_traps(current->domain->arch.hvm_domain - .params[HVM_PARAM_MEMORY_EVENT_MSR], - MEM_EVENT_REASON_MSR, - value, ~value, 1, msr); + .params[HVM_PARAM_MEMORY_EVENT_MSR], + &req); } int hvm_memory_event_int3(unsigned long gla) { uint32_t pfec = PFEC_page_present; - unsigned long gfn; - gfn = paging_gva_to_gfn(current, gla, &pfec); + mem_event_request_t req = { + .reason = MEM_EVENT_REASON_INT3, + .vcpu_id = current->vcpu_id, + .int3_event.gla = gla, + .int3_event.gfn = paging_gva_to_gfn(current, gla, &pfec) + }; return hvm_memory_event_traps(current->domain->arch.hvm_domain - .params[HVM_PARAM_MEMORY_EVENT_INT3], - MEM_EVENT_REASON_INT3, - gfn, 0, 1, gla); + .params[HVM_PARAM_MEMORY_EVENT_INT3], + &req); } int hvm_memory_event_single_step(unsigned long gla) { uint32_t pfec = PFEC_page_present; - unsigned long gfn; - gfn = paging_gva_to_gfn(current, gla, &pfec); + mem_event_request_t req = { + .reason = MEM_EVENT_REASON_SINGLESTEP, + .vcpu_id = current->vcpu_id, + .singlestep_event.gla = gla, + .singlestep_event.gfn = paging_gva_to_gfn(current, gla, &pfec) + }; return hvm_memory_event_traps(current->domain->arch.hvm_domain - .params[HVM_PARAM_MEMORY_EVENT_SINGLE_STEP], - MEM_EVENT_REASON_SINGLESTEP, - gfn, 0, 1, gla); + .params[HVM_PARAM_MEMORY_EVENT_SINGLE_STEP], + &req); } int nhvm_vcpu_hostrestore(struct vcpu *v, struct cpu_user_regs *regs) diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c index 7c0fc7d..c15edcc 100644 --- a/xen/arch/x86/mm/mem_sharing.c +++ b/xen/arch/x86/mm/mem_sharing.c @@ -559,7 +559,10 @@ int mem_sharing_notify_enomem(struct domain *d, unsigned long gfn, { struct vcpu *v = current; int rc; - mem_event_request_t req = { .gfn = gfn }; + mem_event_request_t req = { + .reason = MEM_EVENT_REASON_MEM_SHARING, + .mem_sharing_event.gfn = gfn + }; if ( (rc = __mem_event_claim_slot(d, &d->mem_event->share, allow_sleep)) < 0 ) @@ -571,7 +574,7 @@ int mem_sharing_notify_enomem(struct domain *d, unsigned long gfn, mem_event_vcpu_pause(v); } - req.p2mt = p2m_ram_shared; + req.mem_sharing_event.p2mt = p2m_ram_shared; req.vcpu_id = v->vcpu_id; mem_event_put_request(d, &d->mem_event->share, &req); diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index efa49dd..8ec0150 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1077,7 +1077,10 @@ int p2m_mem_paging_evict(struct domain *d, unsigned long gfn) void p2m_mem_paging_drop_page(struct domain *d, unsigned long gfn, p2m_type_t p2mt) { - mem_event_request_t req = { .gfn = gfn }; + mem_event_request_t req = { + .reason = MEM_EVENT_REASON_MEM_PAGING, + .mem_paging_event.gfn = gfn + }; /* We allow no ring in this unique case, because it won't affect * correctness of the guest execution at this point. If this is the only @@ -1124,7 +1127,10 @@ void p2m_mem_paging_drop_page(struct domain *d, unsigned long gfn, void p2m_mem_paging_populate(struct domain *d, unsigned long gfn) { struct vcpu *v = current; - mem_event_request_t req = { .gfn = gfn }; + mem_event_request_t req = { + .reason = MEM_EVENT_REASON_MEM_PAGING, + .mem_paging_event.gfn = gfn + }; p2m_type_t p2mt; p2m_access_t a; mfn_t mfn; @@ -1174,7 +1180,7 @@ void p2m_mem_paging_populate(struct domain *d, unsigned long gfn) } /* Send request to pager */ - req.p2mt = p2mt; + req.mem_paging_event.p2mt = p2mt; req.vcpu_id = v->vcpu_id; mem_event_put_request(d, &d->mem_event->paging, &req); @@ -1309,15 +1315,15 @@ void p2m_mem_paging_resume(struct domain *d) if ( !(rsp.flags & MEM_EVENT_FLAG_DROP_PAGE) ) { gfn_lock(p2m, rsp.gfn, 0); - mfn = p2m->get_entry(p2m, rsp.gfn, &p2mt, &a, 0, NULL); + mfn = p2m->get_entry(p2m, rsp.mem_access_event.gfn, &p2mt, &a, 0, NULL); /* Allow only pages which were prepared properly, or pages which * were nominated but not evicted */ if ( mfn_valid(mfn) && (p2mt == p2m_ram_paging_in) ) { - p2m_set_entry(p2m, rsp.gfn, mfn, PAGE_ORDER_4K, + p2m_set_entry(p2m, rsp.mem_access_event.gfn, mfn, PAGE_ORDER_4K, paging_mode_log_dirty(d) ? p2m_ram_logdirty : p2m_ram_rw, a); - set_gpfn_from_mfn(mfn_x(mfn), rsp.gfn); + set_gpfn_from_mfn(mfn_x(mfn), rsp.mem_access_event.gfn); } gfn_unlock(p2m, rsp.gfn, 0); } @@ -1337,49 +1343,49 @@ static void p2m_mem_event_fill_regs(mem_event_request_t *req) /* Architecture-specific vmcs/vmcb bits */ hvm_funcs.save_cpu_ctxt(curr, &ctxt); - req->x86_regs.rax = regs->eax; - req->x86_regs.rcx = regs->ecx; - req->x86_regs.rdx = regs->edx; - req->x86_regs.rbx = regs->ebx; - req->x86_regs.rsp = regs->esp; - req->x86_regs.rbp = regs->ebp; - req->x86_regs.rsi = regs->esi; - req->x86_regs.rdi = regs->edi; - - req->x86_regs.r8 = regs->r8; - req->x86_regs.r9 = regs->r9; - req->x86_regs.r10 = regs->r10; - req->x86_regs.r11 = regs->r11; - req->x86_regs.r12 = regs->r12; - req->x86_regs.r13 = regs->r13; - req->x86_regs.r14 = regs->r14; - req->x86_regs.r15 = regs->r15; - - req->x86_regs.rflags = regs->eflags; - req->x86_regs.rip = regs->eip; - - req->x86_regs.dr7 = curr->arch.debugreg[7]; - req->x86_regs.cr0 = ctxt.cr0; - req->x86_regs.cr2 = ctxt.cr2; - req->x86_regs.cr3 = ctxt.cr3; - req->x86_regs.cr4 = ctxt.cr4; - - req->x86_regs.sysenter_cs = ctxt.sysenter_cs; - req->x86_regs.sysenter_esp = ctxt.sysenter_esp; - req->x86_regs.sysenter_eip = ctxt.sysenter_eip; - - req->x86_regs.msr_efer = ctxt.msr_efer; - req->x86_regs.msr_star = ctxt.msr_star; - req->x86_regs.msr_lstar = ctxt.msr_lstar; + req->regs.x86.rax = regs->eax; + req->regs.x86.rcx = regs->ecx; + req->regs.x86.rdx = regs->edx; + req->regs.x86.rbx = regs->ebx; + req->regs.x86.rsp = regs->esp; + req->regs.x86.rbp = regs->ebp; + req->regs.x86.rsi = regs->esi; + req->regs.x86.rdi = regs->edi; + + req->regs.x86.r8 = regs->r8; + req->regs.x86.r9 = regs->r9; + req->regs.x86.r10 = regs->r10; + req->regs.x86.r11 = regs->r11; + req->regs.x86.r12 = regs->r12; + req->regs.x86.r13 = regs->r13; + req->regs.x86.r14 = regs->r14; + req->regs.x86.r15 = regs->r15; + + req->regs.x86.rflags = regs->eflags; + req->regs.x86.rip = regs->eip; + + req->regs.x86.dr7 = curr->arch.debugreg[7]; + req->regs.x86.cr0 = ctxt.cr0; + req->regs.x86.cr2 = ctxt.cr2; + req->regs.x86.cr3 = ctxt.cr3; + req->regs.x86.cr4 = ctxt.cr4; + + req->regs.x86.sysenter_cs = ctxt.sysenter_cs; + req->regs.x86.sysenter_esp = ctxt.sysenter_esp; + req->regs.x86.sysenter_eip = ctxt.sysenter_eip; + + req->regs.x86.msr_efer = ctxt.msr_efer; + req->regs.x86.msr_star = ctxt.msr_star; + req->regs.x86.msr_lstar = ctxt.msr_lstar; hvm_get_segment_register(curr, x86_seg_fs, &seg); - req->x86_regs.fs_base = seg.base; + req->regs.x86.fs_base = seg.base; hvm_get_segment_register(curr, x86_seg_gs, &seg); - req->x86_regs.gs_base = seg.base; + req->regs.x86.gs_base = seg.base; hvm_get_segment_register(curr, x86_seg_cs, &seg); - req->x86_regs.cs_arbytes = seg.attr.bytes; + req->regs.x86.cs_arbytes = seg.attr.bytes; } void p2m_mem_event_emulate_check(struct vcpu *v, const mem_event_response_t *rsp) @@ -1390,39 +1396,40 @@ void p2m_mem_event_emulate_check(struct vcpu *v, const mem_event_response_t *rsp xenmem_access_t access; bool_t violation = 1; - if ( p2m_get_mem_access(v->domain, rsp->gfn, &access) == 0 ) + if ( p2m_get_mem_access(v->domain, rsp->mem_access_event.gfn, &access) == 0 ) { switch ( access ) { case XENMEM_access_n: case XENMEM_access_n2rwx: default: - violation = rsp->access_r || rsp->access_w || rsp->access_x; + violation = rsp->mem_access_event.access_r || rsp->mem_access_event.access_w || + rsp->mem_access_event.access_x; break; case XENMEM_access_r: - violation = rsp->access_w || rsp->access_x; + violation = rsp->mem_access_event.access_w || rsp->mem_access_event.access_x; break; case XENMEM_access_w: - violation = rsp->access_r || rsp->access_x; + violation = rsp->mem_access_event.access_r || rsp->mem_access_event.access_x; break; case XENMEM_access_x: - violation = rsp->access_r || rsp->access_w; + violation = rsp->mem_access_event.access_r || rsp->mem_access_event.access_w; break; case XENMEM_access_rx: case XENMEM_access_rx2rw: - violation = rsp->access_w; + violation = rsp->mem_access_event.access_w; break; case XENMEM_access_wx: - violation = rsp->access_r; + violation = rsp->mem_access_event.access_r; break; case XENMEM_access_rw: - violation = rsp->access_x; + violation = rsp->mem_access_event.access_x; break; case XENMEM_access_rwx: @@ -1540,24 +1547,24 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned long gla, if ( req ) { *req_ptr = req; - req->reason = MEM_EVENT_REASON_VIOLATION; + req->reason = MEM_EVENT_REASON_MEM_ACCESS_VIOLATION; /* Pause the current VCPU */ if ( p2ma != p2m_access_n2rwx ) req->flags |= MEM_EVENT_FLAG_VCPU_PAUSED; /* Send request to mem event */ - req->gfn = gfn; - req->offset = gpa & ((1 << PAGE_SHIFT) - 1); - req->gla_valid = npfec.gla_valid; - req->gla = gla; + req->mem_access_event.gfn = gfn; + req->mem_access_event.offset = gpa & ((1 << PAGE_SHIFT) - 1); + req->mem_access_event.gla_valid = npfec.gla_valid; + req->mem_access_event.gla = gla; if ( npfec.kind == npfec_kind_with_gla ) - req->fault_with_gla = 1; + req->mem_access_event.fault_with_gla = 1; else if ( npfec.kind == npfec_kind_in_gpt ) - req->fault_in_gpt = 1; - req->access_r = npfec.read_access; - req->access_w = npfec.write_access; - req->access_x = npfec.insn_fetch; + req->mem_access_event.fault_in_gpt = 1; + req->mem_access_event.access_r = npfec.read_access; + req->mem_access_event.access_w = npfec.write_access; + req->mem_access_event.access_x = npfec.insn_fetch; req->vcpu_id = v->vcpu_id; p2m_mem_event_fill_regs(req); diff --git a/xen/include/Makefile b/xen/include/Makefile index f7ccbc9..530db83 100644 --- a/xen/include/Makefile +++ b/xen/include/Makefile @@ -90,7 +90,7 @@ ifeq ($(XEN_TARGET_ARCH),$(XEN_COMPILE_ARCH)) all: headers.chk -headers.chk: $(filter-out public/arch-% public/%ctl.h public/xsm/% public/%hvm/save.h, $(wildcard public/*.h public/*/*.h) $(public-y)) Makefile +headers.chk: $(filter-out public/arch-% public/%ctl.h public/mem_event.h public/xsm/% public/%hvm/save.h, $(wildcard public/*.h public/*/*.h) $(public-y)) Makefile for i in $(filter %.h,$^); do $(CC) -ansi -include stdint.h -Wall -W -Werror -S -o /dev/null -x c $$i || exit 1; echo $$i; done >$@.new mv $@.new $@ diff --git a/xen/include/public/mem_event.h b/xen/include/public/mem_event.h index 599f9e8..dbcc48b 100644 --- a/xen/include/public/mem_event.h +++ b/xen/include/public/mem_event.h @@ -27,9 +27,15 @@ #ifndef _XEN_PUBLIC_MEM_EVENT_H #define _XEN_PUBLIC_MEM_EVENT_H +#if !defined(__XEN__) && !defined(__XEN_TOOLS__) +#error "vm event operations are intended for use only by Xen or node control tools" +#endif + #include "xen.h" #include "io/ring.h" +#define MEM_EVENT_INTERFACE_VERSION 0x00000001 + /* Memory event flags */ #define MEM_EVENT_FLAG_VCPU_PAUSED (1 << 0) #define MEM_EVENT_FLAG_DROP_PAGE (1 << 1) @@ -48,16 +54,27 @@ */ #define MEM_EVENT_FLAG_EMULATE_NOWRITE (1 << 6) -/* Reasons for the memory event request */ -#define MEM_EVENT_REASON_UNKNOWN 0 /* typical reason */ -#define MEM_EVENT_REASON_VIOLATION 1 /* access violation, GFN is address */ -#define MEM_EVENT_REASON_CR0 2 /* CR0 was hit: gfn is new CR0 value, gla is previous */ -#define MEM_EVENT_REASON_CR3 3 /* CR3 was hit: gfn is new CR3 value, gla is previous */ -#define MEM_EVENT_REASON_CR4 4 /* CR4 was hit: gfn is new CR4 value, gla is previous */ -#define MEM_EVENT_REASON_INT3 5 /* int3 was hit: gla/gfn are RIP */ -#define MEM_EVENT_REASON_SINGLESTEP 6 /* single step was invoked: gla/gfn are RIP */ -#define MEM_EVENT_REASON_MSR 7 /* MSR was hit: gfn is MSR value, gla is MSR address; - does NOT honour HVMPME_onchangeonly */ +/* Reasons for the vm event request */ +/* Default case */ +#define MEM_EVENT_REASON_UNKNOWN 0 +/* Memory access violation */ +#define MEM_EVENT_REASON_MEM_ACCESS_VIOLATION 1 +/* Memory sharing event */ +#define MEM_EVENT_REASON_MEM_SHARING 2 +/* Memory paging event */ +#define MEM_EVENT_REASON_MEM_PAGING 3 +/* CR0 was updated */ +#define MEM_EVENT_REASON_CR0 4 +/* CR3 was updated */ +#define MEM_EVENT_REASON_CR3 5 +/* CR4 was updated */ +#define MEM_EVENT_REASON_CR4 6 +/* Debug operation executed (int3) */ +#define MEM_EVENT_REASON_INT3 7 +/* Single-step (MTF) */ +#define MEM_EVENT_REASON_SINGLESTEP 8 +/* An MSR was updated. Does NOT honour HVMPME_onchangeonly */ +#define MEM_EVENT_REASON_MSR 9 /* Using a custom struct (not hvm_hw_cpu) so as to not fill * the mem_event ring buffer too quickly. */ @@ -97,16 +114,16 @@ struct mem_event_regs_x86 { uint32_t _pad; }; -typedef struct mem_event_st { - uint32_t flags; - uint32_t vcpu_id; +struct mem_event_regs { + union { + struct mem_event_regs_x86 x86; + }; +}; +struct mem_event_mem_access_data { uint64_t gfn; uint64_t offset; uint64_t gla; /* if gla_valid */ - - uint32_t p2mt; - uint16_t access_r:1; uint16_t access_w:1; uint16_t access_x:1; @@ -114,9 +131,55 @@ typedef struct mem_event_st { uint16_t fault_with_gla:1; uint16_t fault_in_gpt:1; uint16_t available:10; +}; + +struct mem_event_cr_data { + uint64_t new_value; + uint64_t old_value; +}; + +struct mem_event_int3_data { + uint64_t gfn; + uint64_t gla; +}; + +struct mem_event_singlestep_data { + uint64_t gfn; + uint64_t gla; +}; + +struct mem_event_msr_data { + uint64_t msr; + uint64_t old_value; + uint64_t new_value; +}; + +struct mem_event_paging_data { + uint64_t gfn; + uint32_t p2mt; +}; + +struct mem_event_sharing_data { + uint64_t gfn; + uint32_t p2mt; +}; + +typedef struct mem_event_st { + uint32_t flags; + uint32_t vcpu_id; + uint32_t reason; + + union { + struct mem_event_paging_data mem_paging_event; + struct mem_event_sharing_data mem_sharing_event; + struct mem_event_mem_access_data mem_access_event; + struct mem_event_cr_data cr_event; + struct mem_event_int3_data int3_event; + struct mem_event_singlestep_data singlestep_event; + struct mem_event_msr_data msr_event; + }; - uint16_t reason; - struct mem_event_regs_x86 x86_regs; + struct mem_event_regs regs; } mem_event_request_t, mem_event_response_t; DEFINE_RING_TYPES(mem_event, mem_event_request_t, mem_event_response_t); -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |