Commit 914178d34b08a1bc9b274ea97d332cf4d16f4009
1 parent
5efc27bb
32 bit SVM fixes - INVLPG and INVLPGA updates
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4660 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
47 additions
and
25 deletions
target-i386/exec.h
@@ -61,7 +61,6 @@ extern int loglevel; | @@ -61,7 +61,6 @@ extern int loglevel; | ||
61 | void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); | 61 | void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); |
62 | void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3); | 62 | void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3); |
63 | void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4); | 63 | void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4); |
64 | -void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr); | ||
65 | int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, | 64 | int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, |
66 | int is_write, int mmu_idx, int is_softmmu); | 65 | int is_write, int mmu_idx, int is_softmmu); |
67 | void tlb_fill(target_ulong addr, int is_write, int mmu_idx, | 66 | void tlb_fill(target_ulong addr, int is_write, int mmu_idx, |
target-i386/helper.h
@@ -102,14 +102,14 @@ DEF_HELPER(void, helper_svm_check_intercept_param, (uint32_t type, uint64_t para | @@ -102,14 +102,14 @@ DEF_HELPER(void, helper_svm_check_intercept_param, (uint32_t type, uint64_t para | ||
102 | DEF_HELPER(void, helper_vmexit, (uint32_t exit_code, uint64_t exit_info_1)) | 102 | DEF_HELPER(void, helper_vmexit, (uint32_t exit_code, uint64_t exit_info_1)) |
103 | DEF_HELPER(void, helper_svm_check_io, (uint32_t port, uint32_t param, | 103 | DEF_HELPER(void, helper_svm_check_io, (uint32_t port, uint32_t param, |
104 | uint32_t next_eip_addend)) | 104 | uint32_t next_eip_addend)) |
105 | -DEF_HELPER(void, helper_vmrun, (void)) | 105 | +DEF_HELPER(void, helper_vmrun, (int aflag)) |
106 | DEF_HELPER(void, helper_vmmcall, (void)) | 106 | DEF_HELPER(void, helper_vmmcall, (void)) |
107 | -DEF_HELPER(void, helper_vmload, (void)) | ||
108 | -DEF_HELPER(void, helper_vmsave, (void)) | 107 | +DEF_HELPER(void, helper_vmload, (int aflag)) |
108 | +DEF_HELPER(void, helper_vmsave, (int aflag)) | ||
109 | DEF_HELPER(void, helper_stgi, (void)) | 109 | DEF_HELPER(void, helper_stgi, (void)) |
110 | DEF_HELPER(void, helper_clgi, (void)) | 110 | DEF_HELPER(void, helper_clgi, (void)) |
111 | DEF_HELPER(void, helper_skinit, (void)) | 111 | DEF_HELPER(void, helper_skinit, (void)) |
112 | -DEF_HELPER(void, helper_invlpga, (void)) | 112 | +DEF_HELPER(void, helper_invlpga, (int aflag)) |
113 | 113 | ||
114 | /* x86 FPU */ | 114 | /* x86 FPU */ |
115 | 115 |
target-i386/op_helper.c
@@ -2994,7 +2994,7 @@ void helper_movl_drN_T0(int reg, target_ulong t0) | @@ -2994,7 +2994,7 @@ void helper_movl_drN_T0(int reg, target_ulong t0) | ||
2994 | void helper_invlpg(target_ulong addr) | 2994 | void helper_invlpg(target_ulong addr) |
2995 | { | 2995 | { |
2996 | helper_svm_check_intercept_param(SVM_EXIT_INVLPG, 0); | 2996 | helper_svm_check_intercept_param(SVM_EXIT_INVLPG, 0); |
2997 | - cpu_x86_flush_tlb(env, addr); | 2997 | + tlb_flush_page(env, addr); |
2998 | } | 2998 | } |
2999 | 2999 | ||
3000 | void helper_rdtsc(void) | 3000 | void helper_rdtsc(void) |
@@ -4721,16 +4721,16 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) | @@ -4721,16 +4721,16 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr) | ||
4721 | 4721 | ||
4722 | #if defined(CONFIG_USER_ONLY) | 4722 | #if defined(CONFIG_USER_ONLY) |
4723 | 4723 | ||
4724 | -void helper_vmrun(void) | 4724 | +void helper_vmrun(int aflag) |
4725 | { | 4725 | { |
4726 | } | 4726 | } |
4727 | void helper_vmmcall(void) | 4727 | void helper_vmmcall(void) |
4728 | { | 4728 | { |
4729 | } | 4729 | } |
4730 | -void helper_vmload(void) | 4730 | +void helper_vmload(int aflag) |
4731 | { | 4731 | { |
4732 | } | 4732 | } |
4733 | -void helper_vmsave(void) | 4733 | +void helper_vmsave(int aflag) |
4734 | { | 4734 | { |
4735 | } | 4735 | } |
4736 | void helper_stgi(void) | 4736 | void helper_stgi(void) |
@@ -4742,7 +4742,7 @@ void helper_clgi(void) | @@ -4742,7 +4742,7 @@ void helper_clgi(void) | ||
4742 | void helper_skinit(void) | 4742 | void helper_skinit(void) |
4743 | { | 4743 | { |
4744 | } | 4744 | } |
4745 | -void helper_invlpga(void) | 4745 | +void helper_invlpga(int aflag) |
4746 | { | 4746 | { |
4747 | } | 4747 | } |
4748 | void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) | 4748 | void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1) |
@@ -4791,7 +4791,7 @@ static inline void svm_load_seg_cache(target_phys_addr_t addr, | @@ -4791,7 +4791,7 @@ static inline void svm_load_seg_cache(target_phys_addr_t addr, | ||
4791 | sc->base, sc->limit, sc->flags); | 4791 | sc->base, sc->limit, sc->flags); |
4792 | } | 4792 | } |
4793 | 4793 | ||
4794 | -void helper_vmrun(void) | 4794 | +void helper_vmrun(int aflag) |
4795 | { | 4795 | { |
4796 | target_ulong addr; | 4796 | target_ulong addr; |
4797 | uint32_t event_inj; | 4797 | uint32_t event_inj; |
@@ -4799,7 +4799,11 @@ void helper_vmrun(void) | @@ -4799,7 +4799,11 @@ void helper_vmrun(void) | ||
4799 | 4799 | ||
4800 | helper_svm_check_intercept_param(SVM_EXIT_VMRUN, 0); | 4800 | helper_svm_check_intercept_param(SVM_EXIT_VMRUN, 0); |
4801 | 4801 | ||
4802 | - addr = EAX; | 4802 | + if (aflag == 2) |
4803 | + addr = EAX; | ||
4804 | + else | ||
4805 | + addr = (uint32_t)EAX; | ||
4806 | + | ||
4803 | if (loglevel & CPU_LOG_TB_IN_ASM) | 4807 | if (loglevel & CPU_LOG_TB_IN_ASM) |
4804 | fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr); | 4808 | fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr); |
4805 | 4809 | ||
@@ -4970,13 +4974,16 @@ void helper_vmmcall(void) | @@ -4970,13 +4974,16 @@ void helper_vmmcall(void) | ||
4970 | raise_exception(EXCP06_ILLOP); | 4974 | raise_exception(EXCP06_ILLOP); |
4971 | } | 4975 | } |
4972 | 4976 | ||
4973 | -void helper_vmload(void) | 4977 | +void helper_vmload(int aflag) |
4974 | { | 4978 | { |
4975 | target_ulong addr; | 4979 | target_ulong addr; |
4976 | helper_svm_check_intercept_param(SVM_EXIT_VMLOAD, 0); | 4980 | helper_svm_check_intercept_param(SVM_EXIT_VMLOAD, 0); |
4977 | 4981 | ||
4978 | - /* XXX: invalid in 32 bit */ | ||
4979 | - addr = EAX; | 4982 | + if (aflag == 2) |
4983 | + addr = EAX; | ||
4984 | + else | ||
4985 | + addr = (uint32_t)EAX; | ||
4986 | + | ||
4980 | if (loglevel & CPU_LOG_TB_IN_ASM) | 4987 | if (loglevel & CPU_LOG_TB_IN_ASM) |
4981 | fprintf(logfile,"vmload! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", | 4988 | fprintf(logfile,"vmload! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", |
4982 | addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), | 4989 | addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), |
@@ -5003,11 +5010,16 @@ void helper_vmload(void) | @@ -5003,11 +5010,16 @@ void helper_vmload(void) | ||
5003 | env->sysenter_eip = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_eip)); | 5010 | env->sysenter_eip = ldq_phys(addr + offsetof(struct vmcb, save.sysenter_eip)); |
5004 | } | 5011 | } |
5005 | 5012 | ||
5006 | -void helper_vmsave(void) | 5013 | +void helper_vmsave(int aflag) |
5007 | { | 5014 | { |
5008 | target_ulong addr; | 5015 | target_ulong addr; |
5009 | helper_svm_check_intercept_param(SVM_EXIT_VMSAVE, 0); | 5016 | helper_svm_check_intercept_param(SVM_EXIT_VMSAVE, 0); |
5010 | - addr = EAX; | 5017 | + |
5018 | + if (aflag == 2) | ||
5019 | + addr = EAX; | ||
5020 | + else | ||
5021 | + addr = (uint32_t)EAX; | ||
5022 | + | ||
5011 | if (loglevel & CPU_LOG_TB_IN_ASM) | 5023 | if (loglevel & CPU_LOG_TB_IN_ASM) |
5012 | fprintf(logfile,"vmsave! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", | 5024 | fprintf(logfile,"vmsave! " TARGET_FMT_lx "\nFS: %016" PRIx64 " | " TARGET_FMT_lx "\n", |
5013 | addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), | 5025 | addr, ldq_phys(addr + offsetof(struct vmcb, save.fs.base)), |
@@ -5050,15 +5062,22 @@ void helper_skinit(void) | @@ -5050,15 +5062,22 @@ void helper_skinit(void) | ||
5050 | { | 5062 | { |
5051 | helper_svm_check_intercept_param(SVM_EXIT_SKINIT, 0); | 5063 | helper_svm_check_intercept_param(SVM_EXIT_SKINIT, 0); |
5052 | /* XXX: not implemented */ | 5064 | /* XXX: not implemented */ |
5053 | - if (loglevel & CPU_LOG_TB_IN_ASM) | ||
5054 | - fprintf(logfile,"skinit!\n"); | ||
5055 | raise_exception(EXCP06_ILLOP); | 5065 | raise_exception(EXCP06_ILLOP); |
5056 | } | 5066 | } |
5057 | 5067 | ||
5058 | -void helper_invlpga(void) | 5068 | +void helper_invlpga(int aflag) |
5059 | { | 5069 | { |
5070 | + target_ulong addr; | ||
5060 | helper_svm_check_intercept_param(SVM_EXIT_INVLPGA, 0); | 5071 | helper_svm_check_intercept_param(SVM_EXIT_INVLPGA, 0); |
5061 | - tlb_flush(env, 0); | 5072 | + |
5073 | + if (aflag == 2) | ||
5074 | + addr = EAX; | ||
5075 | + else | ||
5076 | + addr = (uint32_t)EAX; | ||
5077 | + | ||
5078 | + /* XXX: could use the ASID to see if it is needed to do the | ||
5079 | + flush */ | ||
5080 | + tlb_flush_page(env, addr); | ||
5062 | } | 5081 | } |
5063 | 5082 | ||
5064 | void helper_svm_check_intercept_param(uint32_t type, uint64_t param) | 5083 | void helper_svm_check_intercept_param(uint32_t type, uint64_t param) |
target-i386/translate.c
@@ -6569,7 +6569,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | @@ -6569,7 +6569,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
6569 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); | 6569 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); |
6570 | break; | 6570 | break; |
6571 | } else { | 6571 | } else { |
6572 | - tcg_gen_helper_0_0(helper_vmrun); | 6572 | + tcg_gen_helper_0_1(helper_vmrun, |
6573 | + tcg_const_i32(s->aflag)); | ||
6573 | s->cc_op = CC_OP_EFLAGS; | 6574 | s->cc_op = CC_OP_EFLAGS; |
6574 | gen_eob(s); | 6575 | gen_eob(s); |
6575 | } | 6576 | } |
@@ -6586,7 +6587,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | @@ -6586,7 +6587,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
6586 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); | 6587 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); |
6587 | break; | 6588 | break; |
6588 | } else { | 6589 | } else { |
6589 | - tcg_gen_helper_0_0(helper_vmload); | 6590 | + tcg_gen_helper_0_1(helper_vmload, |
6591 | + tcg_const_i32(s->aflag)); | ||
6590 | } | 6592 | } |
6591 | break; | 6593 | break; |
6592 | case 3: /* VMSAVE */ | 6594 | case 3: /* VMSAVE */ |
@@ -6596,7 +6598,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | @@ -6596,7 +6598,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
6596 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); | 6598 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); |
6597 | break; | 6599 | break; |
6598 | } else { | 6600 | } else { |
6599 | - tcg_gen_helper_0_0(helper_vmsave); | 6601 | + tcg_gen_helper_0_1(helper_vmsave, |
6602 | + tcg_const_i32(s->aflag)); | ||
6600 | } | 6603 | } |
6601 | break; | 6604 | break; |
6602 | case 4: /* STGI */ | 6605 | case 4: /* STGI */ |
@@ -6635,7 +6638,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | @@ -6635,7 +6638,8 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) | ||
6635 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); | 6638 | gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); |
6636 | break; | 6639 | break; |
6637 | } else { | 6640 | } else { |
6638 | - tcg_gen_helper_0_0(helper_invlpga); | 6641 | + tcg_gen_helper_0_1(helper_invlpga, |
6642 | + tcg_const_i32(s->aflag)); | ||
6639 | } | 6643 | } |
6640 | break; | 6644 | break; |
6641 | default: | 6645 | default: |