On Tue, Nov 21, 2017 at 3:11 PM, Mihail Abakumov
<mikhail.abaku...@ispras.ru> wrote:
> Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru>
> Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru>
> Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru>
> ---
>  include/exec/windbgstub-utils.h |    2
>  target/i386/windbgstub.c        |  319 
> +++++++++++++++++++++++++++++++++++++++
>  windbgstub.c                    |    8 +
>  3 files changed, 329 insertions(+)
>
> diff --git a/include/exec/windbgstub-utils.h b/include/exec/windbgstub-utils.h
> index bc5b6a8468..73d49b774d 100755
> --- a/include/exec/windbgstub-utils.h
> +++ b/include/exec/windbgstub-utils.h
> @@ -100,6 +100,8 @@ void kd_api_write_io_space(CPUState *cpu, PacketData *pd);
>  void kd_api_read_physical_memory(CPUState *cpu, PacketData *pd);
>  void kd_api_write_physical_memory(CPUState *cpu, PacketData *pd);
>  void kd_api_get_version(CPUState *cpu, PacketData *pd);
> +void kd_api_read_msr(CPUState *cpu, PacketData *pd);
> +void kd_api_write_msr(CPUState *cpu, PacketData *pd);
>  void kd_api_unsupported(CPUState *cpu, PacketData *pd);
>
>  SizedBuf kd_gen_exception_sc(CPUState *cpu);
> diff --git a/target/i386/windbgstub.c b/target/i386/windbgstub.c
> index 43e6d45df9..735b2edd5f 100755
> --- a/target/i386/windbgstub.c
> +++ b/target/i386/windbgstub.c
> @@ -1003,6 +1003,325 @@ void kd_api_write_control_space(CPUState *cpu, 
> PacketData *pd)
>      stl_p(&mem->ActualBytesWritten, len);
>  }
>
> +void kd_api_read_msr(CPUState *cpu, PacketData *pd)
> +{
> +    DBGKD_READ_WRITE_MSR *m64c = &pd->m64.u.ReadWriteMsr;
> +    CPUArchState *env = cpu->env_ptr;
> +
> +    uint64_t val;
> +
> +    cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, 0);
> +
> +    switch ((uint32_t)env->regs[R_ECX]) {
> +    case MSR_IA32_SYSENTER_CS:
> +        val = env->sysenter_cs;
> +        break;
> +    case MSR_IA32_SYSENTER_ESP:
> +        val = env->sysenter_esp;
> +        break;
> +    case MSR_IA32_SYSENTER_EIP:
> +        val = env->sysenter_eip;
> +        break;
> +    case MSR_IA32_APICBASE:
> +        val = cpu_get_apic_base(x86_env_get_cpu(env)->apic_state);
> +        break;
> +    case MSR_EFER:
> +        val = env->efer;
> +        break;
> +    case MSR_STAR:
> +        val = env->star;
> +        break;
> +    case MSR_PAT:
> +        val = env->pat;
> +        break;
> +    case MSR_VM_HSAVE_PA:
> +        val = env->vm_hsave;
> +        break;
> +    case MSR_IA32_PERF_STATUS:
> +        /* tsc_increment_by_tick */
> +        val = 1000ULL;
> +        /* CPU multiplier */
> +        val |= (((uint64_t)4ULL) << 40);
> +        break;
> +#ifdef TARGET_X86_64
> +    case MSR_LSTAR:
> +        val = env->lstar;
> +        break;
> +    case MSR_CSTAR:
> +        val = env->cstar;
> +        break;
> +    case MSR_FMASK:
> +        val = env->fmask;
> +        break;
> +    case MSR_FSBASE:
> +        val = env->segs[R_FS].base;
> +        break;
> +    case MSR_GSBASE:
> +        val = env->segs[R_GS].base;
> +        break;
> +    case MSR_KERNELGSBASE:
> +        val = env->kernelgsbase;
> +        break;
> +    case MSR_TSC_AUX:
> +        val = env->tsc_aux;
> +        break;
> +#endif
> +    case MSR_MTRRphysBase(0):
> +    case MSR_MTRRphysBase(1):
> +    case MSR_MTRRphysBase(2):
> +    case MSR_MTRRphysBase(3):
> +    case MSR_MTRRphysBase(4):
> +    case MSR_MTRRphysBase(5):
> +    case MSR_MTRRphysBase(6):
> +    case MSR_MTRRphysBase(7):
> +        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
> +                             MSR_MTRRphysBase(0)) / 2].base;
> +        break;
> +    case MSR_MTRRphysMask(0):
> +    case MSR_MTRRphysMask(1):
> +    case MSR_MTRRphysMask(2):
> +    case MSR_MTRRphysMask(3):
> +    case MSR_MTRRphysMask(4):
> +    case MSR_MTRRphysMask(5):
> +    case MSR_MTRRphysMask(6):
> +    case MSR_MTRRphysMask(7):
> +        val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
> +                             MSR_MTRRphysMask(0)) / 2].mask;
> +        break;
> +    case MSR_MTRRfix64K_00000:
> +        val = env->mtrr_fixed[0];
> +        break;
> +    case MSR_MTRRfix16K_80000:
> +    case MSR_MTRRfix16K_A0000:
> +        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
> +                              MSR_MTRRfix16K_80000 + 1];
> +        break;
> +    case MSR_MTRRfix4K_C0000:
> +    case MSR_MTRRfix4K_C8000:
> +    case MSR_MTRRfix4K_D0000:
> +    case MSR_MTRRfix4K_D8000:
> +    case MSR_MTRRfix4K_E0000:
> +    case MSR_MTRRfix4K_E8000:
> +    case MSR_MTRRfix4K_F0000:
> +    case MSR_MTRRfix4K_F8000:
> +        val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
> +                              MSR_MTRRfix4K_C0000 + 3];
> +        break;
> +    case MSR_MTRRdefType:
> +        val = env->mtrr_deftype;
> +        break;
> +    case MSR_MTRRcap:
> +        if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
> +            val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
> +                MSR_MTRRcap_WC_SUPPORTED;
> +        } else {
> +            /* XXX: exception? */
> +            val = 0;
> +        }
> +        break;
> +    case MSR_MCG_CAP:
> +        val = env->mcg_cap;
> +        break;
> +    case MSR_MCG_CTL:
> +        if (env->mcg_cap & MCG_CTL_P) {
> +            val = env->mcg_ctl;
> +        } else {
> +            val = 0;
> +        }
> +        break;
> +    case MSR_MCG_STATUS:
> +        val = env->mcg_status;
> +        break;
> +    case MSR_IA32_MISC_ENABLE:
> +        val = env->msr_ia32_misc_enable;
> +        break;
> +    case MSR_IA32_BNDCFGS:
> +        val = env->msr_bndcfgs;
> +        break;
> +    default:
> +        if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
> +            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
> +            (4 * env->mcg_cap & 0xff)) {
> +            uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
> +            val = env->mce_banks[offset];
> +            break;
> +        }
> +        /* XXX: exception? */
> +        val = 0;
> +        break;
> +    }
> +
> +    stq_p(&val, val);
> +    m64c->DataValueLow  = UINT32_P(val)[0];
> +    m64c->DataValueHigh = UINT32_P(val)[1];
> +    pd->m64.ReturnStatus = STATUS_SUCCESS;
> +}
> +
> +void kd_api_write_msr(CPUState *cpu, PacketData *pd)
> +{
> +    DBGKD_READ_WRITE_MSR *m64c = &pd->m64.u.ReadWriteMsr;
> +    CPUArchState *env = cpu->env_ptr;
> +
> +    uint64_t val;
> +
> +    cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, 0);
> +
> +    val = m64c->DataValueLow | ((uint64_t) m64c->DataValueHigh) << 32;
> +    val = ldq_p(&val);
> +
> +    switch ((uint32_t)env->regs[R_ECX]) {
> +    case MSR_IA32_SYSENTER_CS:
> +        env->sysenter_cs = val & 0xffff;
> +        break;
> +    case MSR_IA32_SYSENTER_ESP:
> +        env->sysenter_esp = val;
> +        break;
> +    case MSR_IA32_SYSENTER_EIP:
> +        env->sysenter_eip = val;
> +        break;
> +    case MSR_IA32_APICBASE:
> +        cpu_set_apic_base(x86_env_get_cpu(env)->apic_state, val);
> +        break;
> +    case MSR_EFER:
> +        {
> +            uint64_t update_mask;
> +
> +            update_mask = 0;
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) {
> +                update_mask |= MSR_EFER_SCE;
> +            }
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
> +                update_mask |= MSR_EFER_LME;
> +            }
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
> +                update_mask |= MSR_EFER_FFXSR;
> +            }
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) {
> +                update_mask |= MSR_EFER_NXE;
> +            }
> +            if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
> +                update_mask |= MSR_EFER_SVME;
> +            }
> +            if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
> +                update_mask |= MSR_EFER_FFXSR;
> +            }
> +            cpu_load_efer(env, (env->efer & ~update_mask) |
> +                          (val & update_mask));
> +        }
> +        break;
> +    case MSR_STAR:
> +        env->star = val;
> +        break;
> +    case MSR_PAT:
> +        env->pat = val;
> +        break;
> +    case MSR_VM_HSAVE_PA:
> +        env->vm_hsave = val;
> +        break;
> +#ifdef TARGET_X86_64
> +    case MSR_LSTAR:
> +        env->lstar = val;
> +        break;
> +    case MSR_CSTAR:
> +        env->cstar = val;
> +        break;
> +    case MSR_FMASK:
> +        env->fmask = val;
> +        break;
> +    case MSR_FSBASE:
> +        env->segs[R_FS].base = val;
> +        break;
> +    case MSR_GSBASE:
> +        env->segs[R_GS].base = val;
> +        break;
> +    case MSR_KERNELGSBASE:
> +        env->kernelgsbase = val;
> +        break;
> +#endif
> +    case MSR_MTRRphysBase(0):
> +    case MSR_MTRRphysBase(1):
> +    case MSR_MTRRphysBase(2):
> +    case MSR_MTRRphysBase(3):
> +    case MSR_MTRRphysBase(4):
> +    case MSR_MTRRphysBase(5):
> +    case MSR_MTRRphysBase(6):
> +    case MSR_MTRRphysBase(7):
> +        env->mtrr_var[((uint32_t)env->regs[R_ECX] -
> +                       MSR_MTRRphysBase(0)) / 2].base = val;
> +        break;
> +    case MSR_MTRRphysMask(0):
> +    case MSR_MTRRphysMask(1):
> +    case MSR_MTRRphysMask(2):
> +    case MSR_MTRRphysMask(3):
> +    case MSR_MTRRphysMask(4):
> +    case MSR_MTRRphysMask(5):
> +    case MSR_MTRRphysMask(6):
> +    case MSR_MTRRphysMask(7):
> +        env->mtrr_var[((uint32_t)env->regs[R_ECX] -
> +                       MSR_MTRRphysMask(0)) / 2].mask = val;
> +        break;
> +    case MSR_MTRRfix64K_00000:
> +        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
> +                        MSR_MTRRfix64K_00000] = val;
> +        break;
> +    case MSR_MTRRfix16K_80000:
> +    case MSR_MTRRfix16K_A0000:
> +        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
> +                        MSR_MTRRfix16K_80000 + 1] = val;
> +        break;
> +    case MSR_MTRRfix4K_C0000:
> +    case MSR_MTRRfix4K_C8000:
> +    case MSR_MTRRfix4K_D0000:
> +    case MSR_MTRRfix4K_D8000:
> +    case MSR_MTRRfix4K_E0000:
> +    case MSR_MTRRfix4K_E8000:
> +    case MSR_MTRRfix4K_F0000:
> +    case MSR_MTRRfix4K_F8000:
> +        env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
> +                        MSR_MTRRfix4K_C0000 + 3] = val;
> +        break;
> +    case MSR_MTRRdefType:
> +        env->mtrr_deftype = val;
> +        break;
> +    case MSR_MCG_STATUS:
> +        env->mcg_status = val;
> +        break;
> +    case MSR_MCG_CTL:
> +        if ((env->mcg_cap & MCG_CTL_P)
> +            && (val == 0 || val == ~(uint64_t)0)) {
> +            env->mcg_ctl = val;
> +        }
> +        break;
> +    case MSR_TSC_AUX:
> +        env->tsc_aux = val;
> +        break;
> +    case MSR_IA32_MISC_ENABLE:
> +        env->msr_ia32_misc_enable = val;
> +        break;
> +    case MSR_IA32_BNDCFGS:
> +        /* FIXME: #GP if reserved bits are set.  */
> +        /* FIXME: Extend highest implemented bit of linear address.  */
> +        env->msr_bndcfgs = val;
> +        cpu_sync_bndcs_hflags(env);
> +        break;
> +    default:
> +        if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
> +            && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
> +            (4 * env->mcg_cap & 0xff)) {
> +            uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
> +            if ((offset & 0x3) != 0
> +                || (val == 0 || val == ~(uint64_t)0)) {
> +                env->mce_banks[offset] = val;
> +            }
> +            break;
> +        }
> +        /* XXX: exception? */
> +        break;
> +    }
> +
> +    pd->m64.ReturnStatus = STATUS_SUCCESS;
> +}
> +

It looks like you copied most of this code from helper_rdmsr() and
helper_wrmsr(). That's a bunch of duplicated non-trivial logic. Any
chance it could be de-duped by having one call the other or
introducing common helper functions?

>  bool windbg_on_load(void)
>  {
>      CPUState *cpu = qemu_get_cpu(0);
> diff --git a/windbgstub.c b/windbgstub.c
> index ddca290694..0268d0818e 100755
> --- a/windbgstub.c
> +++ b/windbgstub.c
> @@ -197,6 +197,14 @@ static void 
> windbg_process_manipulate_packet(ParsingContext *ctx)
>          kd_api_write_physical_memory(cpu, &ctx->data);
>          break;
>
> +    case DbgKdReadMachineSpecificRegister:
> +        kd_api_read_msr(cpu, &ctx->data);
> +        break;
> +
> +    case DbgKdWriteMachineSpecificRegister:
> +        kd_api_write_msr(cpu, &ctx->data);
> +        break;
> +
>      case DbgKdGetVersionApi:
>          kd_api_get_version(cpu, &ctx->data);
>          break;
>

Reply via email to