kvm, x86: unify sigbus handling
PATCH 8/11 kvm, x86: unify sigbus handling
Now kvm_handle_sigbus can handle both cases of SIGBUS.
Note that env is NULL when main thread receives SIGBUS via signalfd, otherwise env points vcpu thread that receives SIGBUS.
Signed-off-by Hidetoshi Seto <[email protected]>
Tested-by Jin Dongming <[email protected]>
--- qemu-kvm.c | 94 +++++++++++++++++++++++++++--------------------------------- 1 files changed, 42 insertions(+), 52 deletions(-)
qemu-kvm.c +42 -52
@@ -1219,10 +1219,12 @@ static void kvm_mce_inj_srao_broadcast(target_phys_addr_t paddr) }#endif -static void kvm_handle_sigbus (int code,void *vaddr) +static void kvm_handle_sigbus (CPUState *env,int code,void *vaddr) {#if defined(KVM_CAP_MCE ) && defined(TARGET_I386 ) -if ((first_cpu->mcg_cap &MCG_SER_P ) && vaddr && code ==BUS_MCEERR_AO ) { +/* env == NULL: when main thread received a SIGBUS */ +if (!env && (first_cpu->mcg_cap &MCG_SER_P ) && vaddr + && code ==BUS_MCEERR_AO ) {ram_addr_t ram_addr;target_phys_addr_t paddr;
@@ -1235,7 +1237,42 @@ static void kvm_handle_sigbus(int code, void *vaddr) return; }kvm_mce_inj_srao_broadcast (paddr); - } else +return ; + } + +/* env != NULL: when vcpu thread received a SIGBUS */ +if (env && (env->mcg_cap &MCG_SER_P ) && vaddr + && (code ==BUS_MCEERR_AR || code ==BUS_MCEERR_AO )) { +ram_addr_t ram_addr; +unsigned long paddr; + +/* +* If there is an MCE excpetion being processed, ignore this SRAO MCE +*/ +if (code ==BUS_MCEERR_AO &&kvm_mce_in_progress (env)) { +return ; + } + +if (do_qemu_ram_addr_from_host (vaddr, &ram_addr) || + !kvm_physical_memory_addr_from_ram (kvm_state, ram_addr, &paddr)) { +fprintf (stderr,"Hardware memory error for memory used by " +"QEMU itself instaed of guest system!\n" ); +/* Hope we are lucky for AO MCE */ +if (code ==BUS_MCEERR_AO ) { +return ; + }else { +hardware_memory_error (); + } + } +if (code ==BUS_MCEERR_AR ) { +/* Fake an Intel architectural Data Load SRAR UCR */ +kvm_mce_inj_srar_dataload (env, paddr); + }else { +/* Fake an Intel architectural Memory scrubbing UCR */ +kvm_mce_inj_srao_memscrub (env, paddr); + } +return ; + }#endif {if (code ==BUS_MCEERR_AO ) {
@@ -1250,7 +1287,7 @@ static void kvm_handle_sigbus(int code, void *vaddr)static void sigbus_handler (int n,struct qemu_signalfd_siginfo *ssi,void *ctx) { -kvm_handle_sigbus (ssi->ssi_code, (void *)(intptr_t )ssi->ssi_addr); +kvm_handle_sigbus (NULL , ssi->ssi_code, (void *)(intptr_t )ssi->ssi_addr); }static void on_vcpu (CPUState *env,void (*func)(void *data),void *data)
@@ -1378,53 +1415,6 @@ static void flush_queued_work(CPUState *env)pthread_cond_broadcast (&qemu_work_cond); } -static void kvm_on_sigbus (CPUState *env,int code,void *vaddr) -{ -#if defined(KVM_CAP_MCE ) && defined(TARGET_I386 ) -ram_addr_t ram_addr; -target_phys_addr_t paddr; - -if ((env->mcg_cap &MCG_SER_P ) && vaddr - && (code ==BUS_MCEERR_AR || code ==BUS_MCEERR_AO )) { - -/* -* If there is an MCE excpetion being processed, ignore this SRAO MCE -*/ - if (code == BUS_MCEERR_AO && kvm_mce_in_progress(env)) } -return ; - } - -if (do_qemu_ram_addr_from_host (vaddr, &ram_addr) || - !kvm_physical_memory_addr_from_ram (kvm_state, ram_addr, &paddr)) { -fprintf (stderr,"Hardware memory error for memory used by " -"QEMU itself instead of guest system!\n" ); -/* Hope we are lucky for AO MCE */ -if (code ==BUS_MCEERR_AO ) { -return ; - }else { -hardware_memory_error (); - } - } -if (code ==BUS_MCEERR_AR ) { -/* Fake an Intel architectural Data Load SRAR UCR */ -kvm_mce_inj_srar_dataload (env, paddr); - }else { -/* Fake an Intel architectural Memory scrubbing UCR */ -kvm_mce_inj_srao_memscrub (env, paddr); - } - } else -#endif - { -if (code ==BUS_MCEERR_AO ) { -return ; - }else if (code ==BUS_MCEERR_AR ) { -hardware_memory_error (); - }else { -sigbus_reraise (); - } - } -} -static void kvm_main_loop_wait (CPUState *env,int timeout) {struct timespec ts;
@@ -1454,7 +1444,7 @@ static void kvm_main_loop_wait(CPUState *env, int timeout)switch (r) {case SIGBUS : -kvm_on_sigbus (env, siginfo.si_code, (void *)siginfo.si_addr); +kvm_handle_sigbus (env, siginfo.si_code, (void *)siginfo.si_addr);break ;default :break ;
Signature · 1 line
1.7.1.1