diff options
Diffstat (limited to 'include/exec')
| -rw-r--r-- | include/exec/confidential-guest-support.h | 99 | ||||
| -rw-r--r-- | include/exec/cpu-all.h | 119 | ||||
| -rw-r--r-- | include/exec/cpu-common.h | 24 | ||||
| -rw-r--r-- | include/exec/cpu-defs.h | 8 | ||||
| -rw-r--r-- | include/exec/cpu_ldst.h | 50 | ||||
| -rw-r--r-- | include/exec/exec-all.h | 89 | ||||
| -rw-r--r-- | include/exec/page-protection.h | 24 | ||||
| -rw-r--r-- | include/exec/ram_addr.h | 7 | ||||
| -rw-r--r-- | include/exec/translate-all.h | 33 | ||||
| -rw-r--r-- | include/exec/translation-block.h | 5 | ||||
| -rw-r--r-- | include/exec/translator.h | 15 |
11 files changed, 69 insertions, 404 deletions
diff --git a/include/exec/confidential-guest-support.h b/include/exec/confidential-guest-support.h deleted file mode 100644 index 02dc4e518f..0000000000 --- a/include/exec/confidential-guest-support.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * QEMU Confidential Guest support - * This interface describes the common pieces between various - * schemes for protecting guest memory or other state against a - * compromised hypervisor. This includes memory encryption (AMD's - * SEV and Intel's MKTME) or special protection modes (PEF on POWER, - * or PV on s390x). - * - * Copyright Red Hat. - * - * Authors: - * David Gibson <david@gibson.dropbear.id.au> - * - * This work is licensed under the terms of the GNU GPL, version 2 or - * later. See the COPYING file in the top-level directory. - * - */ -#ifndef QEMU_CONFIDENTIAL_GUEST_SUPPORT_H -#define QEMU_CONFIDENTIAL_GUEST_SUPPORT_H - -#ifndef CONFIG_USER_ONLY - -#include "qom/object.h" - -#define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support" -OBJECT_DECLARE_TYPE(ConfidentialGuestSupport, - ConfidentialGuestSupportClass, - CONFIDENTIAL_GUEST_SUPPORT) - - -struct ConfidentialGuestSupport { - Object parent; - - /* - * True if the machine should use guest_memfd for RAM. - */ - bool require_guest_memfd; - - /* - * ready: flag set by CGS initialization code once it's ready to - * start executing instructions in a potentially-secure - * guest - * - * The definition here is a bit fuzzy, because this is essentially - * part of a self-sanity-check, rather than a strict mechanism. - * - * It's not feasible to have a single point in the common machine - * init path to configure confidential guest support, because - * different mechanisms have different interdependencies requiring - * initialization in different places, often in arch or machine - * type specific code. It's also usually not possible to check - * for invalid configurations until that initialization code. - * That means it would be very easy to have a bug allowing CGS - * init to be bypassed entirely in certain configurations. - * - * Silently ignoring a requested security feature would be bad, so - * to avoid that we check late in init that this 'ready' flag is - * set if CGS was requested. If the CGS init hasn't happened, and - * so 'ready' is not set, we'll abort. - */ - bool ready; -}; - -typedef struct ConfidentialGuestSupportClass { - ObjectClass parent; - - int (*kvm_init)(ConfidentialGuestSupport *cgs, Error **errp); - int (*kvm_reset)(ConfidentialGuestSupport *cgs, Error **errp); -} ConfidentialGuestSupportClass; - -static inline int confidential_guest_kvm_init(ConfidentialGuestSupport *cgs, - Error **errp) -{ - ConfidentialGuestSupportClass *klass; - - klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs); - if (klass->kvm_init) { - return klass->kvm_init(cgs, errp); - } - - return 0; -} - -static inline int confidential_guest_kvm_reset(ConfidentialGuestSupport *cgs, - Error **errp) -{ - ConfidentialGuestSupportClass *klass; - - klass = CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs); - if (klass->kvm_reset) { - return klass->kvm_reset(cgs, errp); - } - - return 0; -} - -#endif /* !CONFIG_USER_ONLY */ - -#endif /* QEMU_CONFIDENTIAL_GUEST_SUPPORT_H */ diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 45e6676938..09f537d06f 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -64,39 +64,7 @@ /* MMU memory access macros */ -#if defined(CONFIG_USER_ONLY) -#include "user/abitypes.h" - -/* - * If non-zero, the guest virtual address space is a contiguous subset - * of the host virtual address space, i.e. '-R reserved_va' is in effect - * either from the command-line or by default. The value is the last - * byte of the guest address space e.g. UINT32_MAX. - * - * If zero, the host and guest virtual address spaces are intermingled. - */ -extern unsigned long reserved_va; - -/* - * Limit the guest addresses as best we can. - * - * When not using -R reserved_va, we cannot really limit the guest - * to less address space than the host. For 32-bit guests, this - * acts as a sanity check that we're not giving the guest an address - * that it cannot even represent. For 64-bit guests... the address - * might not be what the real kernel would give, but it is at least - * representable in the guest. - * - * TODO: Improve address allocation to avoid this problem, and to - * avoid setting bits at the top of guest addresses that might need - * to be used for tags. - */ -#define GUEST_ADDR_MAX_ \ - ((MIN_CONST(TARGET_VIRT_ADDR_SPACE_BITS, TARGET_ABI_BITS) <= 32) ? \ - UINT32_MAX : ~0ul) -#define GUEST_ADDR_MAX (reserved_va ? : GUEST_ADDR_MAX_) - -#else +#if !defined(CONFIG_USER_ONLY) #include "exec/hwaddr.h" @@ -136,7 +104,7 @@ static inline void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val #endif /* page related stuff */ - +#include "exec/cpu-defs.h" #ifdef TARGET_PAGE_BITS_VARY # include "exec/page-vary.h" extern const TargetPageBits target_page; @@ -158,84 +126,6 @@ extern const TargetPageBits target_page; #define TARGET_PAGE_ALIGN(addr) ROUND_UP((addr), TARGET_PAGE_SIZE) -#if defined(CONFIG_USER_ONLY) -void page_dump(FILE *f); - -typedef int (*walk_memory_regions_fn)(void *, target_ulong, - target_ulong, unsigned long); -int walk_memory_regions(void *, walk_memory_regions_fn); - -int page_get_flags(target_ulong address); - -/** - * page_set_flags: - * @start: first byte of range - * @last: last byte of range - * @flags: flags to set - * Context: holding mmap lock - * - * Modify the flags of a page and invalidate the code if necessary. - * The flag PAGE_WRITE_ORG is positioned automatically depending - * on PAGE_WRITE. The mmap_lock should already be held. - */ -void page_set_flags(target_ulong start, target_ulong last, int flags); - -void page_reset_target_data(target_ulong start, target_ulong last); - -/** - * page_check_range - * @start: first byte of range - * @len: length of range - * @flags: flags required for each page - * - * Return true if every page in [@start, @start+@len) has @flags set. - * Return false if any page is unmapped. Thus testing flags == 0 is - * equivalent to testing for flags == PAGE_VALID. - */ -bool page_check_range(target_ulong start, target_ulong last, int flags); - -/** - * page_check_range_empty: - * @start: first byte of range - * @last: last byte of range - * Context: holding mmap lock - * - * Return true if the entire range [@start, @last] is unmapped. - * The memory lock must be held so that the caller will can ensure - * the result stays true until a new mapping can be installed. - */ -bool page_check_range_empty(target_ulong start, target_ulong last); - -/** - * page_find_range_empty - * @min: first byte of search range - * @max: last byte of search range - * @len: size of the hole required - * @align: alignment of the hole required (power of 2) - * - * If there is a range [x, x+@len) within [@min, @max] such that - * x % @align == 0, then return x. Otherwise return -1. - * The memory lock must be held, as the caller will want to ensure - * the returned range stays empty until a new mapping can be installed. - */ -target_ulong page_find_range_empty(target_ulong min, target_ulong max, - target_ulong len, target_ulong align); - -/** - * page_get_target_data(address) - * @address: guest virtual address - * - * Return TARGET_PAGE_DATA_SIZE bytes of out-of-band data to associate - * with the guest page at @address, allocating it if necessary. The - * caller should already have verified that the address is valid. - * - * The memory will be freed when the guest page is deallocated, - * e.g. with the munmap system call. - */ -void *page_get_target_data(target_ulong address) - __attribute__((returns_nonnull)); -#endif - CPUArchState *cpu_copy(CPUArchState *env); /* Flags for use in ENV->INTERRUPT_PENDING. @@ -290,8 +180,12 @@ CPUArchState *cpu_copy(CPUArchState *env); | CPU_INTERRUPT_TGT_EXT_3 \ | CPU_INTERRUPT_TGT_EXT_4) +#include "cpu.h" + #ifdef CONFIG_USER_ONLY +static inline int cpu_mmu_index(CPUState *cs, bool ifetch); + /* * Allow some level of source compatibility with softmmu. We do not * support any of the more exotic features, so only invalid pages may @@ -381,7 +275,6 @@ static inline bool tlb_hit(uint64_t tlb_addr, vaddr addr) #endif /* !CONFIG_USER_ONLY */ /* Validate correct placement of CPUArchState. */ -#include "cpu.h" QEMU_BUILD_BUG_ON(offsetof(ArchCPU, parent_obj) != 0); QEMU_BUILD_BUG_ON(offsetof(ArchCPU, env) != sizeof(CPUState)); diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 638dc806a5..b1d76d6985 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -186,12 +186,7 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr, void list_cpus(void); #ifdef CONFIG_TCG - -bool tcg_cflags_has(CPUState *cpu, uint32_t flags); -void tcg_cflags_set(CPUState *cpu, uint32_t flags); - -/* current cflags for hashing/comparison */ -uint32_t curr_cflags(CPUState *cpu); +#include "qemu/atomic.h" /** * cpu_unwind_state_data: @@ -218,6 +213,23 @@ bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data); */ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc); +/** + * cpu_loop_exit_requested: + * @cpu: The CPU state to be tested + * + * Indicate if somebody asked for a return of the CPU to the main loop + * (e.g., via cpu_exit() or cpu_interrupt()). + * + * This is helpful for architectures that support interruptible + * instructions. After writing back all state to registers/memory, this + * call can be used to check if it makes sense to return to the main loop + * or to continue executing the interruptible instruction. + */ +static inline bool cpu_loop_exit_requested(CPUState *cpu) +{ + return (int32_t)qatomic_read(&cpu->neg.icount_decr.u32) < 0; +} + G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu); G_NORETURN void cpu_loop_exit_atomic(CPUState *cpu, uintptr_t pc); #endif /* CONFIG_TCG */ diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 0dbef3010c..ae18398fa9 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -23,14 +23,6 @@ #error cpu.h included from common code #endif -#include "qemu/host-utils.h" -#include "qemu/thread.h" -#ifndef CONFIG_USER_ONLY -#include "exec/hwaddr.h" -#endif -#include "exec/memattrs.h" -#include "hw/core/cpu.h" - #include "cpu-param.h" #ifndef TARGET_LONG_BITS diff --git a/include/exec/cpu_ldst.h b/include/exec/cpu_ldst.h index dac12bd8eb..769e9fc440 100644 --- a/include/exec/cpu_ldst.h +++ b/include/exec/cpu_ldst.h @@ -67,57 +67,13 @@ #endif #include "exec/memopidx.h" +#include "exec/vaddr.h" #include "exec/abi_ptr.h" #include "exec/mmu-access-type.h" #include "qemu/int128.h" #if defined(CONFIG_USER_ONLY) - -#include "user/guest-base.h" - -#ifndef TARGET_TAGGED_ADDRESSES -static inline abi_ptr cpu_untagged_addr(CPUState *cs, abi_ptr x) -{ - return x; -} -#endif - -/* All direct uses of g2h and h2g need to go away for usermode softmmu. */ -static inline void *g2h_untagged(abi_ptr x) -{ - return (void *)((uintptr_t)(x) + guest_base); -} - -static inline void *g2h(CPUState *cs, abi_ptr x) -{ - return g2h_untagged(cpu_untagged_addr(cs, x)); -} - -static inline bool guest_addr_valid_untagged(abi_ulong x) -{ - return x <= GUEST_ADDR_MAX; -} - -static inline bool guest_range_valid_untagged(abi_ulong start, abi_ulong len) -{ - return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1; -} - -#define h2g_valid(x) \ - (HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS || \ - (uintptr_t)(x) - guest_base <= GUEST_ADDR_MAX) - -#define h2g_nocheck(x) ({ \ - uintptr_t __ret = (uintptr_t)(x) - guest_base; \ - (abi_ptr)__ret; \ -}) - -#define h2g(x) ({ \ - /* Check if given address fits target address space */ \ - assert(h2g_valid(x)); \ - h2g_nocheck(x); \ -}) - +#include "user/guest-host.h" #endif /* CONFIG_USER_ONLY */ uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr); @@ -375,7 +331,7 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, return g2h(env_cpu(env), addr); } #else -void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, +void *tlb_vaddr_to_host(CPUArchState *env, vaddr addr, MMUAccessType access_type, int mmu_idx); #endif diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 2e4c4cc4b4..d9045c9ac4 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -22,29 +22,10 @@ #include "cpu.h" #if defined(CONFIG_USER_ONLY) -#include "exec/abi_ptr.h" #include "exec/cpu_ldst.h" #endif #include "exec/mmu-access-type.h" #include "exec/translation-block.h" -#include "qemu/clang-tsa.h" - -/** - * cpu_loop_exit_requested: - * @cpu: The CPU state to be tested - * - * Indicate if somebody asked for a return of the CPU to the main loop - * (e.g., via cpu_exit() or cpu_interrupt()). - * - * This is helpful for architectures that support interruptible - * instructions. After writing back all state to registers/memory, this - * call can be used to check if it makes sense to return to the main loop - * or to continue executing the interruptible instruction. - */ -static inline bool cpu_loop_exit_requested(CPUState *cpu) -{ - return (int32_t)qatomic_read(&cpu->neg.icount_decr.u32) < 0; -} #if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG) /* cputlb.c */ @@ -519,75 +500,7 @@ static inline tb_page_addr_t get_page_addr_code(CPUArchState *env, return get_page_addr_code_hostp(env, addr, NULL); } -#if defined(CONFIG_USER_ONLY) -void TSA_NO_TSA mmap_lock(void); -void TSA_NO_TSA mmap_unlock(void); -bool have_mmap_lock(void); - -static inline void mmap_unlock_guard(void *unused) -{ - mmap_unlock(); -} - -#define WITH_MMAP_LOCK_GUARD() \ - for (int _mmap_lock_iter __attribute__((cleanup(mmap_unlock_guard))) \ - = (mmap_lock(), 0); _mmap_lock_iter == 0; _mmap_lock_iter = 1) - -/** - * adjust_signal_pc: - * @pc: raw pc from the host signal ucontext_t. - * @is_write: host memory operation was write, or read-modify-write. - * - * Alter @pc as required for unwinding. Return the type of the - * guest memory access -- host reads may be for guest execution. - */ -MMUAccessType adjust_signal_pc(uintptr_t *pc, bool is_write); - -/** - * handle_sigsegv_accerr_write: - * @cpu: the cpu context - * @old_set: the sigset_t from the signal ucontext_t - * @host_pc: the host pc, adjusted for the signal - * @host_addr: the host address of the fault - * - * Return true if the write fault has been handled, and should be re-tried. - */ -bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, - uintptr_t host_pc, abi_ptr guest_addr); - -/** - * cpu_loop_exit_sigsegv: - * @cpu: the cpu context - * @addr: the guest address of the fault - * @access_type: access was read/write/execute - * @maperr: true for invalid page, false for permission fault - * @ra: host pc for unwinding - * - * Use the TCGCPUOps hook to record cpu state, do guest operating system - * specific things to raise SIGSEGV, and jump to the main cpu loop. - */ -G_NORETURN void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr, - MMUAccessType access_type, - bool maperr, uintptr_t ra); - -/** - * cpu_loop_exit_sigbus: - * @cpu: the cpu context - * @addr: the guest address of the alignment fault - * @access_type: access was read/write/execute - * @ra: host pc for unwinding - * - * Use the TCGCPUOps hook to record cpu state, do guest operating system - * specific things to raise SIGBUS, and jump to the main cpu loop. - */ -G_NORETURN void cpu_loop_exit_sigbus(CPUState *cpu, target_ulong addr, - MMUAccessType access_type, - uintptr_t ra); - -#else -static inline void mmap_lock(void) {} -static inline void mmap_unlock(void) {} -#define WITH_MMAP_LOCK_GUARD() +#if !defined(CONFIG_USER_ONLY) void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length); void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length); diff --git a/include/exec/page-protection.h b/include/exec/page-protection.h index c43231af8b..bae3355f62 100644 --- a/include/exec/page-protection.h +++ b/include/exec/page-protection.h @@ -38,4 +38,28 @@ */ #define PAGE_PASSTHROUGH 0x0800 +#ifdef CONFIG_USER_ONLY + +#include "qemu/clang-tsa.h" + +void TSA_NO_TSA mmap_lock(void); +void TSA_NO_TSA mmap_unlock(void); +bool have_mmap_lock(void); + +static inline void mmap_unlock_guard(void *unused) +{ + mmap_unlock(); +} + +#define WITH_MMAP_LOCK_GUARD() \ + for (int _mmap_lock_iter __attribute__((cleanup(mmap_unlock_guard))) \ + = (mmap_lock(), 0); _mmap_lock_iter == 0; _mmap_lock_iter = 1) +#else + +static inline void mmap_lock(void) {} +static inline void mmap_unlock(void) {} +#define WITH_MMAP_LOCK_GUARD() + +#endif /* !CONFIG_USER_ONLY */ + #endif diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index 891c44cf2d..ff157c1f42 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -21,13 +21,16 @@ #ifndef CONFIG_USER_ONLY #include "cpu.h" -#include "sysemu/xen.h" -#include "sysemu/tcg.h" +#include "system/xen.h" +#include "system/tcg.h" #include "exec/ramlist.h" #include "exec/ramblock.h" #include "exec/exec-all.h" #include "qemu/rcu.h" +#include "exec/hwaddr.h" +#include "exec/cpu-common.h" + extern uint64_t total_dirty_pages; /** diff --git a/include/exec/translate-all.h b/include/exec/translate-all.h deleted file mode 100644 index 85c9460c7c..0000000000 --- a/include/exec/translate-all.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Translated block handling - * - * Copyright (c) 2003 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.1 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 <http://www.gnu.org/licenses/>. - */ -#ifndef TRANSLATE_ALL_H -#define TRANSLATE_ALL_H - -#include "exec/exec-all.h" - - -/* translate-all.c */ -void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr); - -#ifdef CONFIG_USER_ONLY -void page_protect(tb_page_addr_t page_addr); -int page_unprotect(target_ulong address, uintptr_t pc); -#endif - -#endif /* TRANSLATE_ALL_H */ diff --git a/include/exec/translation-block.h b/include/exec/translation-block.h index a6d1af6e9b..3c69bc71a9 100644 --- a/include/exec/translation-block.h +++ b/include/exec/translation-block.h @@ -7,8 +7,10 @@ #ifndef EXEC_TRANSLATION_BLOCK_H #define EXEC_TRANSLATION_BLOCK_H +#include "qemu/atomic.h" #include "qemu/thread.h" #include "exec/cpu-common.h" +#include "exec/vaddr.h" #ifdef CONFIG_USER_ONLY #include "qemu/interval-tree.h" #endif @@ -152,4 +154,7 @@ static inline uint32_t tb_cflags(const TranslationBlock *tb) return qatomic_read(&tb->cflags); } +bool tcg_cflags_has(CPUState *cpu, uint32_t flags); +void tcg_cflags_set(CPUState *cpu, uint32_t flags); + #endif /* EXEC_TRANSLATION_BLOCK_H */ diff --git a/include/exec/translator.h b/include/exec/translator.h index d8dcb77b5f..41e2a41180 100644 --- a/include/exec/translator.h +++ b/include/exec/translator.h @@ -267,16 +267,15 @@ bool translator_st(const DisasContextBase *db, void *dest, */ size_t translator_st_len(const DisasContextBase *db); -#ifdef COMPILING_PER_TARGET -/* - * Return whether addr is on the same page as where disassembly started. +/** + * translator_is_same_page + * @db: disassembly context + * @addr: virtual address within TB + * + * Return whether @addr is on the same page as where disassembly started. * Translators can use this to enforce the rule that only single-insn * translation blocks are allowed to cross page boundaries. */ -static inline bool is_same_page(const DisasContextBase *db, vaddr addr) -{ - return ((addr ^ db->pc_first) & TARGET_PAGE_MASK) == 0; -} -#endif +bool translator_is_same_page(const DisasContextBase *db, vaddr addr); #endif /* EXEC__TRANSLATOR_H */ |