/* * User emulator execution * * Copyright (c) 2003-2005 Fabrice Bellard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ #include "qemu/osdep.h" #include "cpu.h" #include "disas/disas.h" #include "tcg.h" #include "qemu/bitops.h" #include "exec/cpu_ldst.h" #include "translate-all.h" #undef EAX #undef ECX #undef EDX #undef EBX #undef ESP #undef EBP #undef ESI #undef EDI #undef EIP #ifdef __linux__ #include #endif //#define DEBUG_SIGNAL static void exception_action(CPUState *cpu) { #if defined(TARGET_I386) X86CPU *x86_cpu = X86_CPU(cpu); CPUX86State *env1 = &x86_cpu->env; raise_exception_err(env1, cpu->exception_index, env1->error_code); #else cpu_loop_exit(cpu); #endif } /* exit the current TB from a signal handler. The host registers are restored in a state compatible with the CPU emulator */ void cpu_resume_from_signal(CPUState *cpu, void *puc) { #ifdef __linux__ struct ucontext *uc = puc; #elif defined(__OpenBSD__) struct sigcontext *uc = puc; #endif if (puc) { /* XXX: use siglongjmp ? */ #ifdef __linux__ #ifdef __ia64 sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL); #else sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL); #endif #elif defined(__OpenBSD__) sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL); #endif } cpu->exception_index = -1; siglongjmp(cpu->jmp_env, 1); } /* 'pc' is the host PC at which the exception was raised. 'address' is the effective address of the memory exception. 'is_write' is 1 if a write caused the exception and otherwise 0'. 'old_set' is the signal set which should be restored */ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address, int is_write, sigset_t *old_set, void *puc) { CPUState *cpu; CPUClass *cc; int ret; #if defined(DEBUG_SIGNAL) printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", pc, address, is_write, *(unsigned long *)old_set); #endif /* XXX: locking issue */ if (is_write && h2g_valid(address) && page_unprotect(h2g(address), pc, puc)) { return 1; } /* Convert forcefully to guest address space, invalid addresses are still valid segv ones */ address = h2g_nocheck(address); cpu = current_cpu; cc = CPU_GET_CLASS(cpu); /* see if it is an MMU fault */ g_assert(cc->handle_mmu_fault); ret = cc->handle_mmu_fault(cpu, address, is_write, MMU_USER_IDX); if (ret < 0) { return 0; /* not an MMU fault */ } if (ret == 0) { return 1; /* the MMU fault was handled without causing real CPU fault */ } /* now we have a real cpu fault */ cpu_restore_state(cpu, pc); /* we restore the process signal mask as the sigreturn should do it (XXX: use sigsetjmp) */ sigprocmask(SIG_SETMASK, old_set, NULL); exception_action(cpu); /* never comes here */ return 1; } #if defined(__i386__) #if defined(__APPLE__) #include #define EIP_sig(context) (*((unsigned long *)&(context)->uc_mcontext->ss.eip)) #define TRAP_sig(context) ((context)->uc_mcontext->es.trapno) #define ERROR_sig(context) ((context)->uc_mcontext->es.err) #define MASK_sig(context) ((context)->uc_sigmask) #elif defined(__NetBSD__) #include #define EIP_sig(context) ((context)->uc_mcontext.__gregs[_REG_EIP]) #define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO]) #define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) #define MASK_s
#!/bin/bash
##############################################################################
# Copyright (c) 2018 Mirantis Inc., Enea AB and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Apache License, Version 2.0
# which accompanies this distribution, and is available at
# http://www.apache.org/licenses/LICENSE-2.0
##############################################################################
rm /etc/salt/minion_id
rm -f /etc/salt/pki/minion/minion_master.pub
echo "id: $(hostname).{{ conf.cluster.domain }}" > /etc/salt/minion
echo "master: {{ conf.SALT_MASTER }}" >> /etc/salt/minion
service salt-minion restart
pc = uc->uc_mcontext.arm_pc; #endif /* error_code is the FSR value, in which bit 11 is WnR (assuming a v6 or * later processor; on v5 we will always report this as a read). */ is_write = extract32(uc->uc_mcontext.error_code, 11, 1); return handle_cpu_signal(pc, (unsigned long)info->si_addr, is_write, &uc->uc_sigmask, puc); } #elif defined(__aarch64__) int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { siginfo_t *info = pinfo; struct ucontext *uc = puc; uintptr_t pc = uc->uc_mcontext.pc; uint32_t insn = *(uint32_t *)pc; bool is_write; /* XXX: need kernel patch to get write flag faster. */ is_write = ( (insn & 0xbfff0000) == 0x0c000000 /* C3.3.1 */ || (insn & 0xbfe00000) == 0x0c800000 /* C3.3.2 */ || (insn & 0xbfdf0000) == 0x0d000000 /* C3.3.3 */ || (insn & 0xbfc00000) == 0x0d800000 /* C3.3.4 */ || (insn & 0x3f400000) == 0x08000000 /* C3.3.6 */ || (insn & 0x3bc00000) == 0x39000000 /* C3.3.13 */ || (insn & 0x3fc00000) == 0x3d800000 /* ... 128bit */ /* Ingore bits 10, 11 & 21, controlling indexing. */ || (insn & 0x3bc00000) == 0x38000000 /* C3.3.8-12 */ || (insn & 0x3fe00000) == 0x3c800000 /* ... 128bit */ /* Ignore bits 23 & 24, controlling indexing. */ || (insn & 0x3a400000) == 0x28000000); /* C3.3.7,14-16 */ return handle_cpu_signal(pc, (uintptr_t)info->si_addr, is_write, &uc->uc_sigmask, puc); } #elif defined(__mc68000) int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long pc; int is_write; pc = uc->uc_mcontext.gregs[16]; /* XXX: compute is_write */ is_write = 0; return handle_cpu_signal(pc, (unsigned long)info->si_addr, is_write, &uc->uc_sigmask, puc); } #elif defined(__ia64) #ifndef __ISR_VALID /* This ought to be in ... */ # define __ISR_VALID 1 #endif int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long ip; int is_write = 0; ip = uc->uc_mcontext.sc_ip; switch (host_signum) { case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGTRAP: if (info->si_code && (info->si_segvflags & __ISR_VALID)) { /* ISR.W (write-access) is bit 33: */ is_write = (info->si_isr >> 33) & 1; } break; default: break; } return handle_cpu_signal(ip, (unsigned long)info->si_addr, is_write, (sigset_t *)&uc->uc_sigmask, puc); } #elif defined(__s390__) int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long pc; uint16_t *pinsn; int is_write = 0; pc = uc->uc_mcontext.psw.addr; /* ??? On linux, the non-rt signal handler has 4 (!) arguments instead of the normal 2 arguments. The 3rd argument contains the "int_code" from the hardware which does in fact contain the is_write value. The rt signal handler, as far as I can tell, does not give this value at all. Not that we could get to it from here even if it were. */ /* ??? This is not even close to complete, since it ignores all of the read-modify-write instructions. */ pinsn = (uint16_t *)pc; switch (pinsn[0] >> 8) { case 0x50: /* ST */ case 0x42: /* STC */ case 0x40: /* STH */ is_write = 1; break; case 0xc4: /* RIL format insns */ switch (pinsn[0] & 0xf) { case 0xf: /* STRL */ case 0xb: /* STGRL */ case 0x7: /* STHRL */ is_write = 1; } break; case 0xe3: /* RXY format insns */ switch (pinsn[2] & 0xff) { case 0x50: /* STY */ case 0x24: /* STG */ case 0x72: /* STCY */ case 0x70: /* STHY */ case 0x8e: /* STPQ */ case 0x3f: /* STRVH */ case 0x3e: /* STRV */ case 0x2f: /* STRVG */ is_write = 1; } break; } return handle_cpu_signal(pc, (unsigned long)info->si_addr, is_write, &uc->uc_sigmask, puc); } #elif defined(__mips__) int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { siginfo_t *info = pinfo; struct ucontext *uc = puc; greg_t pc = uc->uc_mcontext.pc; int is_write; /* XXX: compute is_write */ is_write = 0; return handle_cpu_signal(pc, (unsigned long)info->si_addr, is_write, &uc->uc_sigmask, puc); } #elif defined(__hppa__) int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long pc = uc->uc_mcontext.sc_iaoq[0]; uint32_t insn = *(uint32_t *)pc; int is_write = 0; /* XXX: need kernel patch to get write flag faster. */ switch (insn >> 26) { case 0x1a: /* STW */ case 0x19: /* STH */ case 0x18: /* STB */ case 0x1b: /* STWM */ is_write = 1; break; case 0x09: /* CSTWX, FSTWX, FSTWS */ case 0x0b: /* CSTDX, FSTDX, FSTDS */ /* Distinguish from coprocessor load ... */ is_write = (insn >> 9) & 1; break; case 0x03: switch ((insn >> 6) & 15) { case 0xa: /* STWS */ case 0x9: /* STHS */ case 0x8: /* STBS */ case 0xe: /* STWAS */ case 0xc: /* STBYS */ is_write = 1; } break; } return handle_cpu_signal(pc, (unsigned long)info->si_addr, is_write, &uc->uc_sigmask, puc); } #else #error host CPU specific signal handler needed #endif